Commit 3ed9a335 authored by Alex Deucher's avatar Alex Deucher Committed by Christian König

drm/radeon/pm: don't walk the crtc list before it has been initialized (v2)

Avoids a crash in certain cases when thermal irqs are generated
before the display structures have been initialized.

v2: fix the vblank and vrefresh helpers as well

bug:
https://bugzilla.kernel.org/show_bug.cgi?id=73931Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent cb3e4e7c
...@@ -158,16 +158,18 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev) ...@@ -158,16 +158,18 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
u32 line_time_us, vblank_lines; u32 line_time_us, vblank_lines;
u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
radeon_crtc = to_radeon_crtc(crtc); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { radeon_crtc = to_radeon_crtc(crtc);
line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
radeon_crtc->hw_mode.clock; line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - radeon_crtc->hw_mode.clock;
radeon_crtc->hw_mode.crtc_vdisplay + vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
(radeon_crtc->v_border * 2); radeon_crtc->hw_mode.crtc_vdisplay +
vblank_time_us = vblank_lines * line_time_us; (radeon_crtc->v_border * 2);
break; vblank_time_us = vblank_lines * line_time_us;
break;
}
} }
} }
...@@ -181,14 +183,15 @@ u32 r600_dpm_get_vrefresh(struct radeon_device *rdev) ...@@ -181,14 +183,15 @@ u32 r600_dpm_get_vrefresh(struct radeon_device *rdev)
struct radeon_crtc *radeon_crtc; struct radeon_crtc *radeon_crtc;
u32 vrefresh = 0; u32 vrefresh = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
radeon_crtc = to_radeon_crtc(crtc); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { radeon_crtc = to_radeon_crtc(crtc);
vrefresh = radeon_crtc->hw_mode.vrefresh; if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
break; vrefresh = radeon_crtc->hw_mode.vrefresh;
break;
}
} }
} }
return vrefresh; return vrefresh;
} }
......
...@@ -1406,12 +1406,14 @@ static void radeon_pm_compute_clocks_old(struct radeon_device *rdev) ...@@ -1406,12 +1406,14 @@ static void radeon_pm_compute_clocks_old(struct radeon_device *rdev)
rdev->pm.active_crtcs = 0; rdev->pm.active_crtcs = 0;
rdev->pm.active_crtc_count = 0; rdev->pm.active_crtc_count = 0;
list_for_each_entry(crtc, if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
&ddev->mode_config.crtc_list, head) { list_for_each_entry(crtc,
radeon_crtc = to_radeon_crtc(crtc); &ddev->mode_config.crtc_list, head) {
if (radeon_crtc->enabled) { radeon_crtc = to_radeon_crtc(crtc);
rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); if (radeon_crtc->enabled) {
rdev->pm.active_crtc_count++; rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
rdev->pm.active_crtc_count++;
}
} }
} }
...@@ -1478,12 +1480,14 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev) ...@@ -1478,12 +1480,14 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
/* update active crtc counts */ /* update active crtc counts */
rdev->pm.dpm.new_active_crtcs = 0; rdev->pm.dpm.new_active_crtcs = 0;
rdev->pm.dpm.new_active_crtc_count = 0; rdev->pm.dpm.new_active_crtc_count = 0;
list_for_each_entry(crtc, if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
&ddev->mode_config.crtc_list, head) { list_for_each_entry(crtc,
radeon_crtc = to_radeon_crtc(crtc); &ddev->mode_config.crtc_list, head) {
if (crtc->enabled) { radeon_crtc = to_radeon_crtc(crtc);
rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id); if (crtc->enabled) {
rdev->pm.dpm.new_active_crtc_count++; rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id);
rdev->pm.dpm.new_active_crtc_count++;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment