From c083176afbb55536a67db58d8e00d31f3520a200 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 28 Apr 2010 12:13:06 -0400 Subject: [PATCH] --- yaml --- r: 196527 b: refs/heads/master c: f81f202402640c27b38e1452dcb4d3e447043f48 h: refs/heads/master i: 196525: 366f2d196fb676c6eba5d394ef70f72507f1790c 196523: ef2ceb7ac7a784fb57231a1896e891b805cd3dbf 196519: 1c7219a18feeb739e758754b24c1e20980171ce9 196511: 7555a70bfc145c04a47f01d1a0f4d781ce8f1ca3 v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/radeon/r500_reg.h | 2 ++ trunk/drivers/gpu/drm/radeon/r600.c | 26 ++++++++++++++++++++++++ trunk/drivers/gpu/drm/radeon/radeon.h | 1 + trunk/drivers/gpu/drm/radeon/radeon_pm.c | 11 +++++++++- 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 0987bd6ac079..799b6a95d9c0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 612e06ce9c78840c3a1a207dfbe489a059d87c28 +refs/heads/master: f81f202402640c27b38e1452dcb4d3e447043f48 diff --git a/trunk/drivers/gpu/drm/radeon/r500_reg.h b/trunk/drivers/gpu/drm/radeon/r500_reg.h index f5adf42a9d15..93c9a2bbccf8 100644 --- a/trunk/drivers/gpu/drm/radeon/r500_reg.h +++ b/trunk/drivers/gpu/drm/radeon/r500_reg.h @@ -351,6 +351,7 @@ #define AVIVO_D1CRTC_BLANK_CONTROL 0x6084 #define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 #define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c +#define AVIVO_D1CRTC_STATUS_POSITION 0x60a0 #define AVIVO_D1CRTC_FRAME_COUNT 0x60a4 #define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 @@ -489,6 +490,7 @@ #define AVIVO_D2CRTC_BLANK_CONTROL 0x6884 #define AVIVO_D2CRTC_INTERLACE_CONTROL 0x6888 #define AVIVO_D2CRTC_INTERLACE_STATUS 0x688c +#define AVIVO_D2CRTC_STATUS_POSITION 0x68a0 #define AVIVO_D2CRTC_FRAME_COUNT 0x68a4 #define AVIVO_D2CRTC_STEREO_CONTROL 0x68c4 diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index 1696cc277d8b..d3a79e0a9125 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -289,8 +289,34 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch) } } else { + u32 position; + u32 vbl; + radeon_sync_with_vblank(rdev); + if (!radeon_pm_in_vbl(rdev)) + return; + + if (rdev->pm.active_crtcs & (1 << 0)) { + vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); + position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); + position &= 0xfff; + vbl &= 0xfff; + + if (position < vbl && position > 1) + return; + } + + if (rdev->pm.active_crtcs & (1 << 1)) { + vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); + position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); + position &= 0xfff; + vbl &= 0xfff; + + if (position < vbl && position > 1) + return; + } + if (sclk != rdev->pm.current_sclk) { radeon_pm_debug_check_in_vbl(rdev, false); radeon_set_engine_clock(rdev, sclk); diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index bed84b316bba..93ac88eb6b3a 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -175,6 +175,7 @@ void radeon_pm_fini(struct radeon_device *rdev); void radeon_pm_compute_clocks(struct radeon_device *rdev); void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev); +bool radeon_pm_in_vbl(struct radeon_device *rdev); bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); void radeon_sync_with_vblank(struct radeon_device *rdev); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_pm.c b/trunk/drivers/gpu/drm/radeon/radeon_pm.c index 134b19537d11..88163e043fcf 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_pm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_pm.c @@ -387,7 +387,7 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) mutex_unlock(&rdev->pm.mutex); } -bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) +bool radeon_pm_in_vbl(struct radeon_device *rdev) { u32 stat_crtc = 0; bool in_vbl = true; @@ -446,6 +446,15 @@ bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) in_vbl = false; } } + + return in_vbl; +} + +bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) +{ + u32 stat_crtc = 0; + bool in_vbl = radeon_pm_in_vbl(rdev); + if (in_vbl == false) DRM_INFO("not in vbl for pm change %08x at %s\n", stat_crtc, finish ? "exit" : "entry");