Commit c84ff24a authored by Robin Chen's avatar Robin Chen Committed by Alex Deucher

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: default avatarDennis Chan <dennis.chan@amd.com>
Reviewed-by: default avatarChunTao Tso <chuntao.tso@amd.com>
Acked-by: default avatarAlan Liu <HaoPing.Liu@amd.com>
Signed-off-by: default avatarRobin Chen <robin.chen@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6ca7415f
...@@ -122,7 +122,7 @@ bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream) ...@@ -122,7 +122,7 @@ bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream)
psr_config.allow_multi_disp_optimizations = psr_config.allow_multi_disp_optimizations =
(amdgpu_dc_feature_mask & DC_PSR_ALLOW_MULTI_DISP_OPT); (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; return false;
ret = dc_link_setup_psr(link, stream, &psr_config, &psr_context); ret = dc_link_setup_psr(link, stream, &psr_config, &psr_context);
......
...@@ -691,6 +691,7 @@ struct psr_config { ...@@ -691,6 +691,7 @@ struct psr_config {
uint8_t su_y_granularity; uint8_t su_y_granularity;
unsigned int line_time_in_us; unsigned int line_time_in_us;
uint8_t rate_control_caps; uint8_t rate_control_caps;
uint16_t dsc_slice_height;
}; };
union dmcu_psr_level { union dmcu_psr_level {
...@@ -802,6 +803,7 @@ struct psr_context { ...@@ -802,6 +803,7 @@ struct psr_context {
uint8_t su_y_granularity; uint8_t su_y_granularity;
unsigned int line_time_in_us; unsigned int line_time_in_us;
uint8_t rate_control_caps; uint8_t rate_control_caps;
uint16_t dsc_slice_height;
}; };
struct colorspace_transform { struct colorspace_transform {
......
...@@ -417,6 +417,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, ...@@ -417,6 +417,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
copy_settings_data->relock_delay_frame_cnt = 0; copy_settings_data->relock_delay_frame_cnt = 0;
if (link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8) if (link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8)
copy_settings_data->relock_delay_frame_cnt = 2; 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_queue(dc->dmub_srv, &cmd);
dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_cmd_execute(dc->dmub_srv);
......
...@@ -736,6 +736,8 @@ bool dc_link_setup_psr(struct dc_link *link, ...@@ -736,6 +736,8 @@ bool dc_link_setup_psr(struct dc_link *link,
*/ */
psr_context->frame_delay = 0; psr_context->frame_delay = 0;
psr_context->dsc_slice_height = psr_config->dsc_slice_height;
if (psr) { if (psr) {
link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr, link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr,
link, psr_context, panel_inst); link, psr_context, panel_inst);
......
...@@ -1968,6 +1968,14 @@ struct dmub_cmd_psr_copy_settings_data { ...@@ -1968,6 +1968,14 @@ struct dmub_cmd_psr_copy_settings_data {
* Explicit padding to 2 byte boundary. * Explicit padding to 2 byte boundary.
*/ */
uint8_t pad3; uint8_t pad3;
/**
* DSC Slice height.
*/
uint16_t dsc_slice_height;
/**
* Explicit padding to 4 byte boundary.
*/
uint16_t pad;
}; };
/** /**
......
...@@ -917,13 +917,14 @@ bool mod_power_only_edp(const struct dc_state *context, const struct dc_stream_s ...@@ -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); 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 dc_stream_state *stream,
struct psr_config *config) struct psr_config *config)
{ {
uint16_t pic_height; uint16_t pic_height;
uint8_t slice_height; uint16_t slice_height;
config->dsc_slice_height = 0;
if ((link->connector_signal & SIGNAL_TYPE_EDP) && if ((link->connector_signal & SIGNAL_TYPE_EDP) &&
(!dc->caps.edp_dsc_support || (!dc->caps.edp_dsc_support ||
link->panel_config.dsc.disable_dsc_edp || link->panel_config.dsc.disable_dsc_edp ||
...@@ -934,6 +935,7 @@ bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link, ...@@ -934,6 +935,7 @@ bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link,
pic_height = stream->timing.v_addressable + pic_height = stream->timing.v_addressable +
stream->timing.v_border_top + stream->timing.v_border_bottom; stream->timing.v_border_top + stream->timing.v_border_bottom;
slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v; slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v;
config->dsc_slice_height = slice_height;
if (slice_height) { if (slice_height) {
if (config->su_y_granularity && if (config->su_y_granularity &&
...@@ -941,8 +943,6 @@ bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link, ...@@ -941,8 +943,6 @@ bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link,
ASSERT(0); ASSERT(0);
return false; return false;
} }
config->su_y_granularity = slice_height;
} }
return true; return true;
......
...@@ -59,7 +59,7 @@ void mod_power_calc_psr_configs(struct psr_config *psr_config, ...@@ -59,7 +59,7 @@ void mod_power_calc_psr_configs(struct psr_config *psr_config,
const struct dc_stream_state *stream); const struct dc_stream_state *stream);
bool mod_power_only_edp(const struct dc_state *context, bool mod_power_only_edp(const struct dc_state *context,
const struct dc_stream_state *stream); 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 dc_stream_state *stream,
struct psr_config *config); struct psr_config *config);
#endif /* MODULES_POWER_POWER_HELPERS_H_ */ #endif /* MODULES_POWER_POWER_HELPERS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment