Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <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>

authored by

Robin Chen and committed by
Alex Deucher
c84ff24a 6ca7415f

+19 -6
+1 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
··· 122 122 psr_config.allow_multi_disp_optimizations = 123 123 (amdgpu_dc_feature_mask & DC_PSR_ALLOW_MULTI_DISP_OPT); 124 124 125 - if (!psr_su_set_y_granularity(dc, link, stream, &psr_config)) 125 + if (!psr_su_set_dsc_slice_height(dc, link, stream, &psr_config)) 126 126 return false; 127 127 128 128 ret = dc_link_setup_psr(link, stream, &psr_config, &psr_context);
+2
drivers/gpu/drm/amd/display/dc/dc_types.h
··· 691 691 uint8_t su_y_granularity; 692 692 unsigned int line_time_in_us; 693 693 uint8_t rate_control_caps; 694 + uint16_t dsc_slice_height; 694 695 }; 695 696 696 697 union dmcu_psr_level { ··· 803 802 uint8_t su_y_granularity; 804 803 unsigned int line_time_in_us; 805 804 uint8_t rate_control_caps; 805 + uint16_t dsc_slice_height; 806 806 }; 807 807 808 808 struct colorspace_transform {
+1
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
··· 417 417 copy_settings_data->relock_delay_frame_cnt = 0; 418 418 if (link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8) 419 419 copy_settings_data->relock_delay_frame_cnt = 2; 420 + copy_settings_data->dsc_slice_height = psr_context->dsc_slice_height; 420 421 421 422 dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); 422 423 dc_dmub_srv_cmd_execute(dc->dmub_srv);
+8
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
··· 1968 1968 * Explicit padding to 2 byte boundary. 1969 1969 */ 1970 1970 uint8_t pad3; 1971 + /** 1972 + * DSC Slice height. 1973 + */ 1974 + uint16_t dsc_slice_height; 1975 + /** 1976 + * Explicit padding to 4 byte boundary. 1977 + */ 1978 + uint16_t pad; 1971 1979 }; 1972 1980 1973 1981 /**
+4 -4
drivers/gpu/drm/amd/display/modules/power/power_helpers.c
··· 917 917 return context && context->stream_count == 1 && dc_is_embedded_signal(stream->signal); 918 918 } 919 919 920 - bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link, 920 + bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, 921 921 struct dc_stream_state *stream, 922 922 struct psr_config *config) 923 923 { 924 924 uint16_t pic_height; 925 - uint8_t slice_height; 925 + uint16_t slice_height; 926 926 927 + config->dsc_slice_height = 0; 927 928 if ((link->connector_signal & SIGNAL_TYPE_EDP) && 928 929 (!dc->caps.edp_dsc_support || 929 930 link->panel_config.dsc.disable_dsc_edp || ··· 935 934 pic_height = stream->timing.v_addressable + 936 935 stream->timing.v_border_top + stream->timing.v_border_bottom; 937 936 slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v; 937 + config->dsc_slice_height = slice_height; 938 938 939 939 if (slice_height) { 940 940 if (config->su_y_granularity && ··· 943 941 ASSERT(0); 944 942 return false; 945 943 } 946 - 947 - config->su_y_granularity = slice_height; 948 944 } 949 945 950 946 return true;
+1 -1
drivers/gpu/drm/amd/display/modules/power/power_helpers.h
··· 59 59 const struct dc_stream_state *stream); 60 60 bool mod_power_only_edp(const struct dc_state *context, 61 61 const struct dc_stream_state *stream); 62 - bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link, 62 + bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, 63 63 struct dc_stream_state *stream, 64 64 struct psr_config *config); 65 65 #endif /* MODULES_POWER_POWER_HELPERS_H_ */