drm/amd/display: Add pixel_clock to amd_pp_display_configuration
PATCH 1/2 drm/amd/display: Add pixel_clock to amd_pp_display_configuration
From: Timur Kristóf <[email protected]>
commit b515dcb0dc4e85d8254f5459cfb32fce88dacbfb upstream.
This commit adds the pixel_clock field to the display config struct so that power management (DPM) can use it.
We currently don't have a proper bandwidth calculation on old GPUs with DCE 6-10 because dce_calcs only supports DCE 11+. So the power management (DPM) on these GPUs may need to make ad-hoc decisions for display based on the pixel clock.
Also rename sym_clock to pixel_clock in dm_pp_single_disp_config to avoid confusion with other code where the sym_clock refers to the DisplayPort symbol clock.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 1 + drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 2 +- drivers/gpu/drm/amd/display/dc/dm_services_types.h | 2 +- drivers/gpu/drm/amd/include/dm_pp_interface.h | 1 + 4 files changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c +1 -0
@@ -97,6 +97,7 @@ bool dm_pp_apply_display_requirements(const struct dm_pp_single_disp_config *dc_cfg = &pp_display_cfg->disp_configs[i]; adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx +1 ; + adev->pm.pm_display_cfg.displays[i].pixel_clock = dc_cfg->pixel_clock; }amdgpu_dpm_display_configuration_change (adev, &adev->pm.pm_display_cfg);
drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c +1 -1
@@ -164,7 +164,7 @@ void dce110_fill_display_configs( stream->link->cur_link_settings.link_rate; cfg->link_settings.link_spread = stream->link->cur_link_settings.link_spread; - cfg->sym_clock = stream->phy_pix_clk; + cfg->pixel_clock = stream->phy_pix_clk;/* Round v_refresh*/ cfg->v_refresh = stream->timing.pix_clk_100hz *100 ; cfg->v_refresh /= stream->timing.h_total;
drivers/gpu/drm/amd/display/dc/dm_services_types.h +1 -1
@@ -127,7 +127,7 @@ struct dm_pp_single_disp_config {uint32_t src_height;uint32_t src_width;uint32_t v_refresh; -uint32_t sym_clock;/* HDMI only */ +uint32_t pixel_clock;/* Pixel clock in KHz (for HDMI only: normalized) */ struct dc_link_settings link_settings;/* DP only */ };
drivers/gpu/drm/amd/include/dm_pp_interface.h +1 -0
@@ -65,6 +65,7 @@ struct single_display_configuration {uint32_t view_resolution_cy;enum amd_pp_display_config_type displayconfigtype;uint32_t vertical_refresh;/* for active display */ +uint32_t pixel_clock;/* Pixel clock in KHz (for HDMI only: normalized) */ };#define MAX_NUM_DISPLAY 32
--
2.53.0
PATCH 2/2 drm/amd/pm: Use pm_display_cfg in legacy DPM (v2)
From: Timur Kristóf <[email protected]>
commit 9d73b107a61b73e7101d4b728ddac3d2c77db111 upstream.
This commit is necessary for DC to function well with chips that use the legacy power management code, ie. SI and KV. Communicate display information from DC to the legacy PM code.
Currently DC uses pm_display_cfg to communicate power management requirements from the display code to the DPM code. However, the legacy (non-DC) code path used different fields and therefore could not take into account anything from DC.
Change the legacy display code to fill the same pm_display_cfg struct as DC and use the same in the legacy DPM code.
To ease review and reduce churn, this commit does not yet delete the now unneeded code, that is done in the next commit.
v2:
Rebase.
Fix single_display in amdgpu_dpm_pick_power_state.
--- drivers/gpu/drm/amd/pm/amdgpu_dpm_internal.c | 67 +++++++++++++++++++ .../gpu/drm/amd/pm/inc/amdgpu_dpm_internal.h | 2 + drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c | 4 +- .../gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c | 6 +- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 65 ++++++------------ .../gpu/drm/amd/pm/powerplay/amd_powerplay.c | 11 +-- 6 files changed, 97 insertions(+), 58 deletions(-)
drivers/gpu/drm/amd/pm/amdgpu_dpm_internal.c +67 -0
@@ -100,3 +100,70 @@ u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev)return vrefresh; } + +void amdgpu_dpm_get_display_cfg (struct amdgpu_device *adev) +{ +struct drm_device *ddev =adev_to_drm (adev); +struct amd_pp_display_configuration *cfg = &adev->pm.pm_display_cfg; +struct single_display_configuration *display_cfg; +struct drm_crtc *crtc; +struct amdgpu_crtc *amdgpu_crtc; +struct amdgpu_connector *conn; +int num_crtcs =0 ; +int vrefresh; +u32 vblank_in_pixels, vblank_time_us; + + cfg->min_vblank_time =0xffffffff ;/* if the displays are off, vblank time is max */ + +if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { +list_for_each_entry (crtc, &ddev->mode_config.crtc_list, head) { + amdgpu_crtc =to_amdgpu_crtc (crtc); + +/* The array should only contain active displays. */ +if (!amdgpu_crtc->enabled) +continue ; + + conn =to_amdgpu_connector (amdgpu_crtc->connector); + display_cfg = &adev->pm.pm_display_cfg.displays[num_crtcs++]; + +if (amdgpu_crtc->hw_mode.clock) { + vrefresh =drm_mode_vrefresh (&amdgpu_crtc->hw_mode); + + vblank_in_pixels = + amdgpu_crtc->hw_mode.crtc_htotal * + (amdgpu_crtc->hw_mode.crtc_vblank_end - + amdgpu_crtc->hw_mode.crtc_vdisplay + + (amdgpu_crtc->v_border *2 )); + + vblank_time_us = + vblank_in_pixels *1000 / amdgpu_crtc->hw_mode.clock; + +/* The legacy (non-DC) code has issues with mclk switching +* with refresh rates over 120 Hz. Disable mclk switching. +*/ +if (vrefresh >120 ) + vblank_time_us =0 ; + +/* Find minimum vblank time. */ +if (vblank_time_us < cfg->min_vblank_time) + cfg->min_vblank_time = vblank_time_us; + +/* Find vertical refresh rate of first active display. */ +if (!cfg->vrefresh) + cfg->vrefresh = vrefresh; + } + +if (amdgpu_crtc->crtc_id < cfg->crtc_index) { +/* Find first active CRTC and its line time. */ + cfg->crtc_index = amdgpu_crtc->crtc_id; + cfg->line_time_in_us = amdgpu_crtc->line_time; + } + + display_cfg->controller_id = amdgpu_crtc->crtc_id; + display_cfg->pixel_clock = conn->pixelclock_for_modeset; + } + } + + cfg->display_clk = adev->clock.default_dispclk; + cfg->num_display = num_crtcs; +}
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm_internal.h +2 -0
@@ -29,4 +29,6 @@ u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev);u32 amdgpu_dpm_get_vrefresh (struct amdgpu_device *adev); +void amdgpu_dpm_get_display_cfg (struct amdgpu_device *adev); +#endif
drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +2 -2
@@ -2299,7 +2299,7 @@ static void kv_apply_state_adjust_rules(struct amdgpu_device *adev,if (pi->sys_info.nb_dpm_enable) { force_high = (mclk >= pi->sys_info.nbp_memory_clock[3 ]) || - pi->video_start || (adev->pm.dpm.new_active_crtc_count >=3 ) || + pi->video_start || (adev->pm.pm_display_cfg.num_display >=3 ) || pi->disable_nb_ps3_in_battery; ps->dpm0_pg_nb_ps_lo = force_high ?0x2 :0x3 ; ps->dpm0_pg_nb_ps_hi =0x2 ;
@@ -2358,7 +2358,7 @@ static int kv_calculate_nbps_level_settings(struct amdgpu_device *adev)return 0 ; force_high = ((mclk >= pi->sys_info.nbp_memory_clock[3 ]) || - (adev->pm.dpm.new_active_crtc_count >=3 ) || pi->video_start); + (adev->pm.pm_display_cfg.num_display >=3 ) || pi->video_start);if (force_high) {for (i = pi->lowest_valid; i <= pi->highest_valid; i++)
drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c +3 -3
@@ -797,8 +797,7 @@ static struct amdgpu_ps *amdgpu_dpm_pick_power_state(struct amdgpu_device *adev,int i;struct amdgpu_ps *ps;u32 ui_class; -bool single_display = (adev->pm.dpm.new_active_crtc_count <2 ) ? - true : false; +bool single_display = adev->pm.pm_display_cfg.num_display <2 ;/* check if the vblank period is too short to adjust the mclk */ if (single_display && adev->powerplay.pp_funcs->vblank_too_short) {
@@ -994,7 +993,8 @@ void amdgpu_legacy_dpm_compute_clocks(void *handle) {struct amdgpu_device *adev = (struct amdgpu_device *)handle; -amdgpu_dpm_get_active_displays (adev); +if (!adev->dc_enabled) +amdgpu_dpm_get_display_cfg (adev);amdgpu_dpm_change_power_state_locked (adev); }
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +22 -43
150 lines not on this page · raw message
drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +1 -10
@@ -1569,16 +1569,7 @@ static void pp_pm_compute_clocks(void *handle)struct amdgpu_device *adev = hwmgr->adev;if (!adev->dc_enabled) { -amdgpu_dpm_get_active_displays (adev); - adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count; - adev->pm.pm_display_cfg.vrefresh =amdgpu_dpm_get_vrefresh (adev); - adev->pm.pm_display_cfg.min_vblank_time =amdgpu_dpm_get_vblank_time (adev); -/* we have issues with mclk switching with -* refresh rates over 120 hz on the non-DC code. -*/ -if (adev->pm.pm_display_cfg.vrefresh >120 ) - adev->pm.pm_display_cfg.min_vblank_time =0 ; - +amdgpu_dpm_get_display_cfg (adev);pp_display_configuration_change (handle, &adev->pm.pm_display_cfg); }
--
2.53.0
Greg Kroah-Hartman
maintainerQuoted 16 lines · Rosen Penev
From: Timur Kristóf <[email protected]>
commit
b515dcb0dc4e85d8254f5459cfb32fce88dacbfbupstream.This commit adds the
pixel_clockfield to the display config struct so that power management (DPM) can use it.We currently don't have a proper bandwidth calculation on old GPUs with DCE 6-10 because
dce_calcsonly supports DCE 11+. So the power management (DPM) on these GPUs may need to make ad-hoc decisions for display based on the pixel clock.Also rename
sym_clocktopixel_clockindm_pp_single_disp_configto avoid confusion with other code where thesym_clockrefers to the DisplayPort symbol clock.
Quoted 8 lines
Signed-off-by Timur Kristóf <[email protected]>Signed-off-by Alex Deucher <[email protected]>--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 1 + drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 2 +- drivers/gpu/drm/amd/display/dc/dm_services_types.h | 2 +- drivers/gpu/drm/amd/include/dm_pp_interface.h | 1 + 4 files changed, 4 insertions(+), 2 deletions(-)
You did not sign-off on these backports :(