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=73931 Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
This commit is contained in:
committed by
Christian König
parent
cb3e4e7c59
commit
3ed9a335cf
@@ -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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
/* 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++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user