Hi >[why] >Currently the amdgpu DM psr configuration parameters are hardcoded before feeding into the DC helper to setup PSR. We would define a helper >which is to calculate parts of the psr config fields to avoid hard-coding. > >[how] >To make helper shareable, declare and define the helper in the module_helper, to set/update below fields: >- psr remote buffer setup time >- sdp tx line number deadline >- line time in us >- su_y_granularity >- su_granularity_required >- psr_frame_capture_indication_req >- psr_exit_link_training_required > >add another helper to check given the stream context, if there is only one stream and the output is eDP panel connected. > >Signed-off-by: David Zhang <dingchen.zhang@xxxxxxx> >--- > .../amd/display/modules/power/power_helpers.c | 73 +++++++++++++++++++ .../amd/display/modules/power/power_helpers.h | 6 ++ > 2 files changed, 79 insertions(+) > >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 97928d4c3b9a..1be4fcfa578a 100644 >--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c >+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c >@@ -822,3 +822,76 @@ bool is_psr_su_specific_panel(struct dc_link *link) > > return false; > } >+ >+/** >+ * mod_power_calc_psr_configs() - calculate/update generic psr configuration fields. >+ * @psr_config: [output], psr configuration structure to be updated >+ * @link: [input] dc link pointer >+ * @stream: [input] dc stream state pointer >+ * >+ * calculate and update the psr configuration fields that are not DM >+specific, i.e. such >+ * fields which are based on DPCD caps or timing information. To setup >+PSR in DMUB FW, >+ * this helper is assumed to be called before the call of the DC helper dc_link_setup_psr(). >+ * >+ * PSR config fields to be updated within the helper: >+ * - psr_rfb_setup_time >+ * - psr_sdp_transmit_line_num_deadline >+ * - line_time_in_us >+ * - su_y_granularity >+ * - su_granularity_required >+ * - psr_frame_capture_indication_req >+ * - psr_exit_link_training_required >+ * >+ * PSR config fields that are DM specific and NOT updated within the helper: >+ * - allow_smu_optimizations >+ * - allow_multi_disp_optimizations >+ */ >+void mod_power_calc_psr_configs(struct psr_config *psr_config, >+ struct dc_link *link, >+ const struct dc_stream_state *stream) { >+ unsigned int num_vblank_lines = 0; >+ unsigned int vblank_time_in_us = 0; >+ unsigned int sdp_tx_deadline_in_us = 0; >+ unsigned int line_time_in_us = 0; >+ struct dpcd_caps *dpcd_caps = &link->dpcd_caps; >+ const int psr_setup_time_step_in_us = 55; /* refer to eDP spec DPCD 0x071h */ >+ >+ /* timing parameters */ >+ num_vblank_lines = stream->timing.v_total - >+ stream->timing.v_addressable - >+ stream->timing.v_border_top - >+ stream->timing.v_border_bottom; >+ >+ vblank_time_in_us = (stream->timing.h_total * num_vblank_lines * 1000) >+/ (stream->timing.pix_clk_100hz / 10); >+ >+ line_time_in_us = ((stream->timing.h_total * 1000) / >+(stream->timing.pix_clk_100hz / 10)) + 1; >+ >+ /* psr configuration fields */ >+ psr_config->psr_rfb_setup_time = >+ (6 - dpcd_caps->psr_info.psr_dpcd_caps.bits.PSR_SETUP_TIME) * Is this " dpcd_caps->psr_info.psr_dpcd_caps.bits.PSR_SETUP_TIME" always expected to be less than '6'. What does this 6 indicate here? >+psr_setup_time_step_in_us; >+ >+ if (psr_config->psr_rfb_setup_time > vblank_time_in_us) { >+ link->psr_settings.psr_frame_capture_indication_req = true; >+ link->psr_settings.psr_sdp_transmit_line_num_deadline = num_vblank_lines; >+ } else { >+ sdp_tx_deadline_in_us = vblank_time_in_us - >+psr_config->psr_rfb_setup_time; >+ >+ /* Set the last possible line SDP may be transmitted without violating the RFB setup time */ >+ link->psr_settings.psr_frame_capture_indication_req = false; >+ link->psr_settings.psr_sdp_transmit_line_num_deadline = sdp_tx_deadline_in_us / line_time_in_us; >+ } >+ >+ psr_config->psr_sdp_transmit_line_num_deadline = link->psr_settings.psr_sdp_transmit_line_num_deadline; >+ psr_config->line_time_in_us = line_time_in_us; >+ psr_config->su_y_granularity = dpcd_caps->psr_info.psr2_su_y_granularity_cap; >+ psr_config->su_granularity_required = dpcd_caps->psr_info.psr_dpcd_caps.bits.SU_GRANULARITY_REQUIRED; >+ psr_config->psr_frame_capture_indication_req = link->psr_settings.psr_frame_capture_indication_req; >+ psr_config->psr_exit_link_training_required = >+ >+!link->dpcd_caps.psr_info.psr_dpcd_caps.bits.LINK_TRAINING_ON_EXIT_NOT_ >+REQUIRED; >+} >+ >+bool mod_power_only_edp(const struct dc_state *context, const struct >+dc_stream_state *stream) { >+ return context && context->stream_count == 1 && >+dc_is_embedded_signal(stream->signal); >+} >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 1a634d8c78c5..316452e9dbc9 100644 >--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h >+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h >@@ -27,6 +27,7 @@ > > #include "dc/inc/hw/dmcu.h" > #include "dc/inc/hw/abm.h" >+#include "dc/inc/core_types.h" > > struct resource_pool; > >@@ -53,4 +54,9 @@ bool dmub_init_abm_config(struct resource_pool *res_pool, > unsigned int inst); > > bool is_psr_su_specific_panel(struct dc_link *link); >+void mod_power_calc_psr_configs(struct psr_config *psr_config, >+ struct dc_link *link, >+ const struct dc_stream_state *stream); bool mod_power_only_edp(const >+struct dc_state *context, >+ const struct dc_stream_state *stream); > #endif /* MODULES_POWER_POWER_HELPERS_H_ */ >-- >2.25.1 >