diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn32')
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" |