From c84ff24a77fa66aaf7c591cdf806456dcb5c2fcd Mon Sep 17 00:00:00 2001 From: Robin Chen Date: Tue, 10 Jan 2023 16:53:55 +0800 Subject: [PATCH] drm/amd/display: Pass DSC slice height to PSR FW [Why] When DSC is enabled, the PSRSU seletive update region must be multiple number of DSC slice height number. The original solution is to overwrite the SU Y granularity by DSC slice height in DAL driver. However, the size of the SU Y granularity variable only has 8 bytes and the DSC slice height may over the 8 bytes size. [How] Instead of overwriting the SU Y granularity value, add a new DSC slice height pararmeter and pass it to DMUB PSRSU FW. The PSRSU FW will refer to the DSC slice height value and extend the SU region. Reviewed-by: Dennis Chan Reviewed-by: ChunTao Tso Acked-by: Alan Liu Signed-off-by: Robin Chen Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 2 +- drivers/gpu/drm/amd/display/dc/dc_types.h | 2 ++ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 1 + .../display/dc/link/protocols/link_edp_panel_control.c | 2 ++ drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 8 ++++++++ drivers/gpu/drm/amd/display/modules/power/power_helpers.c | 8 ++++---- drivers/gpu/drm/amd/display/modules/power/power_helpers.h | 2 +- 7 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c index 872d06fe14364..d647f68fd5630 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c @@ -122,7 +122,7 @@ bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream) psr_config.allow_multi_disp_optimizations = (amdgpu_dc_feature_mask & DC_PSR_ALLOW_MULTI_DISP_OPT); - if (!psr_su_set_y_granularity(dc, link, stream, &psr_config)) + if (!psr_su_set_dsc_slice_height(dc, link, stream, &psr_config)) return false; ret = dc_link_setup_psr(link, stream, &psr_config, &psr_context); diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index c73a655bd6877..f653eca09ba79 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -691,6 +691,7 @@ struct psr_config { uint8_t su_y_granularity; unsigned int line_time_in_us; uint8_t rate_control_caps; + uint16_t dsc_slice_height; }; union dmcu_psr_level { @@ -802,6 +803,7 @@ struct psr_context { uint8_t su_y_granularity; unsigned int line_time_in_us; uint8_t rate_control_caps; + uint16_t dsc_slice_height; }; struct colorspace_transform { diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 2d3201b77d6a0..1e2d2cbe2c373 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -417,6 +417,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, copy_settings_data->relock_delay_frame_cnt = 0; if (link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8) copy_settings_data->relock_delay_frame_cnt = 2; + copy_settings_data->dsc_slice_height = psr_context->dsc_slice_height; dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 04483ea4b0b88..97e02b5b21ae3 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -736,6 +736,8 @@ bool dc_link_setup_psr(struct dc_link *link, */ psr_context->frame_delay = 0; + psr_context->dsc_slice_height = psr_config->dsc_slice_height; + if (psr) { link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr, link, psr_context, panel_inst); diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 8d72af6d939bc..04df407092b1e 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -1968,6 +1968,14 @@ struct dmub_cmd_psr_copy_settings_data { * Explicit padding to 2 byte boundary. */ uint8_t pad3; + /** + * DSC Slice height. + */ + uint16_t dsc_slice_height; + /** + * Explicit padding to 4 byte boundary. + */ + uint16_t pad; }; /** diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index cf4fa87c7db60..e39b133d05af4 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -917,13 +917,14 @@ bool mod_power_only_edp(const struct dc_state *context, const struct dc_stream_s return context && context->stream_count == 1 && dc_is_embedded_signal(stream->signal); } -bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link, +bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, struct dc_stream_state *stream, struct psr_config *config) { uint16_t pic_height; - uint8_t slice_height; + uint16_t slice_height; + config->dsc_slice_height = 0; if ((link->connector_signal & SIGNAL_TYPE_EDP) && (!dc->caps.edp_dsc_support || link->panel_config.dsc.disable_dsc_edp || @@ -934,6 +935,7 @@ bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link, pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom; slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v; + config->dsc_slice_height = slice_height; if (slice_height) { if (config->su_y_granularity && @@ -941,8 +943,6 @@ bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link, ASSERT(0); return false; } - - config->su_y_granularity = slice_height; } return true; diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h index bb16b37b83da7..1d3079e56799f 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h @@ -59,7 +59,7 @@ void mod_power_calc_psr_configs(struct psr_config *psr_config, const struct dc_stream_state *stream); bool mod_power_only_edp(const struct dc_state *context, const struct dc_stream_state *stream); -bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link, +bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, struct dc_stream_state *stream, struct psr_config *config); #endif /* MODULES_POWER_POWER_HELPERS_H_ */ -- 2.30.2