summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/dcn32
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn32')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c45
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c36
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c36
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c2
6 files changed, 104 insertions, 34 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
index 12633561be3f..5609ac6d6040 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
@@ -141,52 +141,45 @@ static void dccg32_set_dtbclk_p_src(
/* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
void dccg32_set_dtbclk_dto(
struct dccg *dccg,
- int otg_inst,
- int pixclk_khz,
- int num_odm_segments,
- const struct dc_crtc_timing *timing)
+ const struct dtbclk_dto_params *params)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
/* DTO Output Rate / Pixel Rate = 1/4 */
- int req_dtbclk_khz = pixclk_khz / 4;
+ int req_dtbclk_khz = params->pixclk_khz / 4;
- if (dccg->ref_dtbclk_khz && req_dtbclk_khz) {
+ if (params->ref_dtbclk_khz && req_dtbclk_khz) {
uint32_t modulo, phase;
// phase / modulo = dtbclk / dtbclk ref
- modulo = 0xffffffff;
- phase = (((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1) / dccg->ref_dtbclk_khz;
+ modulo = params->ref_dtbclk_khz * 1000;
+ phase = req_dtbclk_khz * 1000;
- REG_WRITE(DTBCLK_DTO_MODULO[otg_inst], modulo);
- REG_WRITE(DTBCLK_DTO_PHASE[otg_inst], phase);
+ REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
+ REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
- REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
- DTBCLK_DTO_ENABLE[otg_inst], 1);
+ REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ DTBCLK_DTO_ENABLE[params->otg_inst], 1);
- REG_WAIT(OTG_PIXEL_RATE_CNTL[otg_inst],
- DTBCLKDTO_ENABLE_STATUS[otg_inst], 1,
+ REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
1, 100);
/* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
- dccg32_set_pixel_rate_div(dccg, otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
+ dccg32_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
/* The recommended programming sequence to enable DTBCLK DTO to generate
* valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
* be set only after DTO is enabled
*/
- REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
- PIPE_DTO_SRC_SEL[otg_inst], 2);
-
- dccg->dtbclk_khz[otg_inst] = req_dtbclk_khz;
+ REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ PIPE_DTO_SRC_SEL[params->otg_inst], 2);
} else {
- REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[otg_inst],
- DTBCLK_DTO_ENABLE[otg_inst], 0,
- PIPE_DTO_SRC_SEL[otg_inst], 1);
-
- REG_WRITE(DTBCLK_DTO_MODULO[otg_inst], 0);
- REG_WRITE(DTBCLK_DTO_PHASE[otg_inst], 0);
+ REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ DTBCLK_DTO_ENABLE[params->otg_inst], 0,
+ PIPE_DTO_SRC_SEL[params->otg_inst], 1);
- dccg->dtbclk_khz[otg_inst] = 0;
+ REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
+ REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c
index 62532da94913..4d7588f2ee79 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c
@@ -211,8 +211,10 @@ static void enc32_stream_encoder_hdmi_set_stream_attribute(
HDMI_GC_SEND, 1,
HDMI_NULL_SEND, 1);
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
/* Disable Audio Content Protection packet transmission */
REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0);
+#endif
/* following belongs to audio */
/* Enable Audio InfoFrame packet transmission. */
@@ -301,6 +303,21 @@ static void enc32_stream_encoder_dp_unblank(
REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
+ /* DIG Resync FIFO now needs to be explicitly enabled
+ */
+ // TODO: Confirm if we need to wait for DIG_SYMCLK_FE_ON
+ REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000);
+
+ REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
+
+ REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000);
+
+ REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
+
+ REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 10, 5000);
+
+ REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1);
+
/* wait 100us for DIG/DP logic to prime
* (i.e. a few video lines)
*/
@@ -354,6 +371,23 @@ static void enc32_read_state(struct stream_encoder *enc, struct enc_state *s)
}
}
+static void enc32_stream_encoder_reset_fifo(struct stream_encoder *enc)
+{
+ struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+ uint32_t fifo_enabled;
+
+ REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &fifo_enabled);
+
+ if (fifo_enabled == 0) {
+ /* reset DIG resync FIFO */
+ REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
+ /* TODO: fix timeout when wait for DIG_FIFO_RESET_DONE */
+ //REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 1, 100);
+ udelay(1);
+ REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
+ REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 1, 100);
+ }
+}
static const struct stream_encoder_funcs dcn32_str_enc_funcs = {
.dp_set_odm_combine =
@@ -375,7 +409,7 @@ static const struct stream_encoder_funcs dcn32_str_enc_funcs = {
.stop_dp_info_packets =
enc1_stream_encoder_stop_dp_info_packets,
.reset_fifo =
- enc1_stream_encoder_reset_fifo,
+ enc32_stream_encoder_reset_fifo,
.dp_blank =
enc1_stream_encoder_dp_blank,
.dp_unblank =
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h
index 7241080b1553..77da0a13525b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h
@@ -89,7 +89,8 @@
SRI(DP_SEC_METADATA_TRANSMISSION, DP, id), \
SRI(HDMI_METADATA_PACKET_CONTROL, DIG, id), \
SRI(DIG_FE_CNTL, DIG, id), \
- SRI(DIG_CLOCK_PATTERN, DIG, id)
+ SRI(DIG_CLOCK_PATTERN, DIG, id), \
+ SRI(DIG_FIFO_CTRL0, DIG, id)
#define SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh)\
@@ -233,12 +234,22 @@
SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_LINE_REFERENCE, mask_sh),\
SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_LINE, mask_sh),\
SE_SF(DIG0_DIG_FE_CNTL, DOLBY_VISION_EN, mask_sh),\
+ SE_SF(DIG0_DIG_FE_CNTL, DIG_SYMCLK_FE_ON, mask_sh),\
SE_SF(DP0_DP_SEC_FRAMING4, DP_SST_SDP_SPLITTING, mask_sh),\
- SE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh)
+ SE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh),\
+ SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, mask_sh),\
+ SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, mask_sh),\
+ SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_RESET, mask_sh),\
+ SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, mask_sh)
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
#define SE_COMMON_MASK_SH_LIST_DCN32(mask_sh)\
SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh),\
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, mask_sh)
+#else
+#define SE_COMMON_MASK_SH_LIST_DCN32(mask_sh)\
+ SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh)
+#endif
void dcn32_dio_stream_encoder_construct(
struct dcn10_stream_encoder *enc1,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
index d0a222f1a09c..40afd33ffec6 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
@@ -649,7 +649,7 @@ void dcn32_init_hw(struct dc *dc)
* Otherwise, if taking control is not possible, we need to power
* everything down.
*/
- if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
+ if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.seamless_boot_edp_requested) {
hws->funcs.init_pipes(dc, dc->current_state);
if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
@@ -661,7 +661,7 @@ void dcn32_init_hw(struct dc *dc)
* To avoid this, power down hardware on boot
* if DIG is turned on and seamless boot not enabled
*/
- if (dc->config.power_down_display_on_boot) {
+ if (dc->config.seamless_boot_edp_requested) {
struct dc_link *edp_links[MAX_NUM_EDP];
struct dc_link *edp_link;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
index f1ed25e972f2..88275ea4193c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
@@ -91,10 +91,18 @@ static void optc32_set_odm_combine(struct timing_generator *optc, int *opp_id, i
REG_UPDATE(OPTC_WIDTH_CONTROL,
OPTC_SEGMENT_WIDTH, mpcc_hactive);
- REG_SET(OTG_H_TIMING_CNTL, 0, OTG_H_TIMING_DIV_MODE, opp_cnt - 1);
+ REG_UPDATE(OTG_H_TIMING_CNTL,
+ OTG_H_TIMING_DIV_MODE, opp_cnt - 1);
optc1->opp_count = opp_cnt;
}
+static void optc32_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode)
+{
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
+
+ REG_UPDATE(OTG_H_TIMING_CNTL,
+ OTG_H_TIMING_DIV_MODE_MANUAL, manual_mode ? 1 : 0);
+}
/**
* Enable CRTC
* Enable CRTC - call ASIC Control Object to enable Timing generator.
@@ -157,6 +165,29 @@ void optc32_phantom_crtc_post_enable(struct timing_generator *optc)
REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000);
}
+static void optc32_set_odm_bypass(struct timing_generator *optc,
+ const struct dc_crtc_timing *dc_crtc_timing)
+{
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
+ enum h_timing_div_mode h_div = H_TIMING_NO_DIV;
+
+ REG_SET_5(OPTC_DATA_SOURCE_SELECT, 0,
+ OPTC_NUM_OF_INPUT_SEGMENT, 0,
+ OPTC_SEG0_SRC_SEL, optc->inst,
+ OPTC_SEG1_SRC_SEL, 0xf,
+ OPTC_SEG2_SRC_SEL, 0xf,
+ OPTC_SEG3_SRC_SEL, 0xf
+ );
+
+ h_div = optc1_is_two_pixels_per_containter(dc_crtc_timing);
+ REG_UPDATE(OTG_H_TIMING_CNTL,
+ OTG_H_TIMING_DIV_MODE, h_div);
+
+ REG_SET(OPTC_MEMORY_CONFIG, 0,
+ OPTC_MEM_SEL, 0);
+ optc1->opp_count = 1;
+}
+
static struct timing_generator_funcs dcn32_tg_funcs = {
.validate_timing = optc1_validate_timing,
@@ -206,8 +237,9 @@ static struct timing_generator_funcs dcn32_tg_funcs = {
.set_dsc_config = optc3_set_dsc_config,
.get_dsc_status = optc2_get_dsc_status,
.set_dwb_source = NULL,
- .set_odm_bypass = optc3_set_odm_bypass,
+ .set_odm_bypass = optc32_set_odm_bypass,
.set_odm_combine = optc32_set_odm_combine,
+ .set_h_timing_div_manual_mode = optc32_set_h_timing_div_manual_mode,
.get_optc_source = optc2_get_optc_source,
.set_out_mux = optc3_set_out_mux,
.set_drr_trigger_window = optc3_set_drr_trigger_window,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
index 17a287bc89ce..7ac6428aae52 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
@@ -77,7 +77,7 @@
#include "dcn/dcn_3_2_0_offset.h"
#include "dcn/dcn_3_2_0_sh_mask.h"
-#include "dcn/nbio_4_3_0_offset.h"
+#include "nbio/nbio_4_3_0_offset.h"
#include "reg_helper.h"
#include "dce/dmub_abm.h"