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

drm/amd/display: add shared helpers to update psr config fields to power module

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

changes in v2:
------------------
- add detailed comment for how psr setup time is calculated as per
eDP 1.5 spec

Cc: Chandan Vurdigerenataraj <chandan.vurdigerenataraj@amd.com>

Signed-off-by: David Zhang <dingchen.zhang@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

David Zhang and committed by
Alex Deucher
65e7a174 e61a048e

+90
+84
drivers/gpu/drm/amd/display/modules/power/power_helpers.c
··· 822 822 823 823 return false; 824 824 } 825 + 826 + /** 827 + * mod_power_calc_psr_configs() - calculate/update generic psr configuration fields. 828 + * @psr_config: [output], psr configuration structure to be updated 829 + * @link: [input] dc link pointer 830 + * @stream: [input] dc stream state pointer 831 + * 832 + * calculate and update the psr configuration fields that are not DM specific, i.e. such 833 + * fields which are based on DPCD caps or timing information. To setup PSR in DMUB FW, 834 + * this helper is assumed to be called before the call of the DC helper dc_link_setup_psr(). 835 + * 836 + * PSR config fields to be updated within the helper: 837 + * - psr_rfb_setup_time 838 + * - psr_sdp_transmit_line_num_deadline 839 + * - line_time_in_us 840 + * - su_y_granularity 841 + * - su_granularity_required 842 + * - psr_frame_capture_indication_req 843 + * - psr_exit_link_training_required 844 + * 845 + * PSR config fields that are DM specific and NOT updated within the helper: 846 + * - allow_smu_optimizations 847 + * - allow_multi_disp_optimizations 848 + */ 849 + void mod_power_calc_psr_configs(struct psr_config *psr_config, 850 + struct dc_link *link, 851 + const struct dc_stream_state *stream) 852 + { 853 + unsigned int num_vblank_lines = 0; 854 + unsigned int vblank_time_in_us = 0; 855 + unsigned int sdp_tx_deadline_in_us = 0; 856 + unsigned int line_time_in_us = 0; 857 + struct dpcd_caps *dpcd_caps = &link->dpcd_caps; 858 + const int psr_setup_time_step_in_us = 55; /* refer to eDP spec DPCD 0x071h */ 859 + 860 + /* timing parameters */ 861 + num_vblank_lines = stream->timing.v_total - 862 + stream->timing.v_addressable - 863 + stream->timing.v_border_top - 864 + stream->timing.v_border_bottom; 865 + 866 + vblank_time_in_us = (stream->timing.h_total * num_vblank_lines * 1000) / (stream->timing.pix_clk_100hz / 10); 867 + 868 + line_time_in_us = ((stream->timing.h_total * 1000) / (stream->timing.pix_clk_100hz / 10)) + 1; 869 + 870 + /** 871 + * psr configuration fields 872 + * 873 + * as per eDP 1.5 pg. 377 of 459, DPCD 0x071h bits [3:1], psr setup time bits interpreted as below 874 + * 000b <--> 330 us (default) 875 + * 001b <--> 275 us 876 + * 010b <--> 220 us 877 + * 011b <--> 165 us 878 + * 100b <--> 110 us 879 + * 101b <--> 055 us 880 + * 110b <--> 000 us 881 + */ 882 + psr_config->psr_rfb_setup_time = 883 + (6 - dpcd_caps->psr_info.psr_dpcd_caps.bits.PSR_SETUP_TIME) * psr_setup_time_step_in_us; 884 + 885 + if (psr_config->psr_rfb_setup_time > vblank_time_in_us) { 886 + link->psr_settings.psr_frame_capture_indication_req = true; 887 + link->psr_settings.psr_sdp_transmit_line_num_deadline = num_vblank_lines; 888 + } else { 889 + sdp_tx_deadline_in_us = vblank_time_in_us - psr_config->psr_rfb_setup_time; 890 + 891 + /* Set the last possible line SDP may be transmitted without violating the RFB setup time */ 892 + link->psr_settings.psr_frame_capture_indication_req = false; 893 + link->psr_settings.psr_sdp_transmit_line_num_deadline = sdp_tx_deadline_in_us / line_time_in_us; 894 + } 895 + 896 + psr_config->psr_sdp_transmit_line_num_deadline = link->psr_settings.psr_sdp_transmit_line_num_deadline; 897 + psr_config->line_time_in_us = line_time_in_us; 898 + psr_config->su_y_granularity = dpcd_caps->psr_info.psr2_su_y_granularity_cap; 899 + psr_config->su_granularity_required = dpcd_caps->psr_info.psr_dpcd_caps.bits.SU_GRANULARITY_REQUIRED; 900 + psr_config->psr_frame_capture_indication_req = link->psr_settings.psr_frame_capture_indication_req; 901 + psr_config->psr_exit_link_training_required = 902 + !link->dpcd_caps.psr_info.psr_dpcd_caps.bits.LINK_TRAINING_ON_EXIT_NOT_REQUIRED; 903 + } 904 + 905 + bool mod_power_only_edp(const struct dc_state *context, const struct dc_stream_state *stream) 906 + { 907 + return context && context->stream_count == 1 && dc_is_embedded_signal(stream->signal); 908 + }
+6
drivers/gpu/drm/amd/display/modules/power/power_helpers.h
··· 27 27 28 28 #include "dc/inc/hw/dmcu.h" 29 29 #include "dc/inc/hw/abm.h" 30 + #include "dc/inc/core_types.h" 30 31 31 32 struct resource_pool; 32 33 ··· 54 53 unsigned int inst); 55 54 56 55 bool is_psr_su_specific_panel(struct dc_link *link); 56 + void mod_power_calc_psr_configs(struct psr_config *psr_config, 57 + struct dc_link *link, 58 + const struct dc_stream_state *stream); 59 + bool mod_power_only_edp(const struct dc_state *context, 60 + const struct dc_stream_state *stream); 57 61 #endif /* MODULES_POWER_POWER_HELPERS_H_ */