drm/amd/display: Pass DSC slice height to PSR FW
authorRobin Chen <robin.chen@amd.com>
Tue, 10 Jan 2023 08:53:55 +0000 (16:53 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 24 Jan 2023 18:26:25 +0000 (13:26 -0500)
[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 <dennis.chan@amd.com>
Reviewed-by: ChunTao Tso <chuntao.tso@amd.com>
Acked-by: Alan Liu <HaoPing.Liu@amd.com>
Signed-off-by: Robin Chen <robin.chen@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
drivers/gpu/drm/amd/display/modules/power/power_helpers.c
drivers/gpu/drm/amd/display/modules/power/power_helpers.h

index 872d06f..d647f68 100644 (file)
@@ -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);
index c73a655..f653eca 100644 (file)
@@ -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 {
index 2d3201b..1e2d2cb 100644 (file)
@@ -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);
index 04483ea..97e02b5 100644 (file)
@@ -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);
index 8d72af6..04df407 100644 (file)
@@ -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;
 };
 
 /**
index cf4fa87..e39b133 100644 (file)
@@ -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;
index bb16b37..1d3079e 100644 (file)
@@ -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_ */