drm/radeon/kms: more pm fixes
authorAlex Deucher <alexdeucher@gmail.com>
Thu, 29 Apr 2010 04:22:43 +0000 (00:22 -0400)
committerDave Airlie <airlied@redhat.com>
Tue, 18 May 2010 08:21:35 +0000 (18:21 +1000)
- disable gui idle interrupt use
  Seems to hang some r5xx chips
- move vbl range check into
  existing vbl check function in
  radeon_pm.c
- disable crtc mc acccess for the
  whole reclocking process

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/evergreen_reg.h
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_pm.c

index 93aab2ebd9d0b1238e2d7ad911ace0b10dbfd236..af86af836f13dcb446d78418c65f3c6c69a2660f 100644 (file)
 #define EVERGREEN_CRTC5_REGISTER_OFFSET                 (0x129f0 - 0x6df0)
 
 /* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */
+#define EVERGREEN_CRTC_V_BLANK_START_END                0x6e34
 #define EVERGREEN_CRTC_CONTROL                          0x6e70
 #       define EVERGREEN_CRTC_MASTER_EN                 (1 << 0)
 #       define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24)
 #define EVERGREEN_CRTC_STATUS                           0x6e8c
+#define EVERGREEN_CRTC_STATUS_POSITION                  0x6e90
 #define EVERGREEN_CRTC_UPDATE_LOCK                      0x6ed4
 
 #define EVERGREEN_DC_GPIO_HPD_MASK                      0x64b0
index a5f11c300f6ac4692f6df6183422e16b8ccfab5d..493b9b48da30ca3b7d9c42f3a5c75ca6db9cc831 100644 (file)
@@ -178,14 +178,12 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch)
                                rdev->pm.current_sclk = sclk;
                                DRM_INFO("Setting: e: %d\n", sclk);
                        }
-#if 0
                        /* set memory clock */
                        if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
                                radeon_set_memory_clock(rdev, mclk);
                                rdev->pm.current_mclk = mclk;
                                DRM_INFO("Setting: m: %d\n", mclk);
                        }
-#endif
                        radeon_pm_finish(rdev);
                } else {
                        radeon_sync_with_vblank(rdev);
@@ -193,6 +191,7 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch)
                        if (!radeon_pm_in_vbl(rdev))
                                return;
 
+                       radeon_pm_prepare(rdev);
                        /* set engine clock */
                        if (sclk != rdev->pm.current_sclk) {
                                radeon_pm_debug_check_in_vbl(rdev, false);
@@ -205,13 +204,12 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch)
                        /* set memory clock */
                        if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
                                radeon_pm_debug_check_in_vbl(rdev, false);
-                               radeon_pm_prepare(rdev);
                                radeon_set_memory_clock(rdev, mclk);
-                               radeon_pm_finish(rdev);
                                radeon_pm_debug_check_in_vbl(rdev, true);
                                rdev->pm.current_mclk = mclk;
                                DRM_INFO("Setting: m: %d\n", mclk);
                        }
+                       radeon_pm_finish(rdev);
                }
 
                rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
index d3a79e0a9125f1feb02bd716bd39affd44f9c5cc..75c825cb8790bedb1318b165206dae2ca98a0550 100644 (file)
@@ -256,7 +256,6 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch)
                return;
 
        if (radeon_gui_idle(rdev)) {
-
                sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
                        clock_info[rdev->pm.requested_clock_mode_index].sclk;
                if (sclk > rdev->clock.default_sclk)
@@ -271,52 +270,27 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch)
                radeon_pm_misc(rdev);
 
                if (static_switch) {
-
+                       radeon_pm_prepare(rdev);
                        /* set engine clock */
                        if (sclk != rdev->pm.current_sclk) {
                                radeon_set_engine_clock(rdev, sclk);
                                rdev->pm.current_sclk = sclk;
                                DRM_INFO("Setting: e: %d\n", sclk);
                        }
-
                        /* set memory clock */
                        if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
-                               radeon_pm_prepare(rdev);
                                radeon_set_memory_clock(rdev, mclk);
-                               radeon_pm_finish(rdev);
                                rdev->pm.current_mclk = mclk;
                                DRM_INFO("Setting: m: %d\n", mclk);
                        }
-
+                       radeon_pm_finish(rdev);
                } 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;
-                       }
-
+                       radeon_pm_prepare(rdev);
                        if (sclk != rdev->pm.current_sclk) {
                                radeon_pm_debug_check_in_vbl(rdev, false);
                                radeon_set_engine_clock(rdev, sclk);
@@ -328,13 +302,12 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch)
                        /* set memory clock */
                        if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
                                radeon_pm_debug_check_in_vbl(rdev, false);
-                               radeon_pm_prepare(rdev);
                                radeon_set_memory_clock(rdev, mclk);
-                               radeon_pm_finish(rdev);
                                radeon_pm_debug_check_in_vbl(rdev, true);
                                rdev->pm.current_mclk = mclk;
                                DRM_INFO("Setting: m: %d\n", mclk);
                        }
+                       radeon_pm_finish(rdev);
                }
 
                rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
index 88163e043fcf5b6bad8251646be5257c808c9eac..2eb675e78440ed375e600ba5fb7a4823a8f13a6a 100644 (file)
@@ -64,7 +64,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
        mutex_lock(&rdev->ddev->struct_mutex);
        mutex_lock(&rdev->vram_mutex);
        mutex_lock(&rdev->cp.mutex);
-
+#if 0
        /* wait for GPU idle */
        rdev->pm.gui_idle = false;
        rdev->irq.gui_idle = true;
@@ -74,7 +74,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
                msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT));
        rdev->irq.gui_idle = false;
        radeon_irq_set(rdev);
-
+#endif
        radeon_unmap_vram_bos(rdev);
 
        if (!static_switch) {
@@ -85,7 +85,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
                        }
                }
        }
-       
+
        radeon_set_power_state(rdev, static_switch);
 
        if (!static_switch) {
@@ -389,51 +389,57 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
 
 bool radeon_pm_in_vbl(struct radeon_device *rdev)
 {
-       u32 stat_crtc = 0;
+       u32 stat_crtc = 0, vbl = 0, position = 0;
        bool in_vbl = true;
 
        if (ASIC_IS_DCE4(rdev)) {
                if (rdev->pm.active_crtcs & (1 << 0)) {
-                       stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
-                       if (!(stat_crtc & 1))
-                               in_vbl = false;
+                       vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
+                                    EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff;
+                       position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
+                                         EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff;
                }
                if (rdev->pm.active_crtcs & (1 << 1)) {
-                       stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
-                       if (!(stat_crtc & 1))
-                               in_vbl = false;
+                       vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
+                                    EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff;
+                       position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
+                                         EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff;
                }
                if (rdev->pm.active_crtcs & (1 << 2)) {
-                       stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
-                       if (!(stat_crtc & 1))
-                               in_vbl = false;
+                       vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
+                                    EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff;
+                       position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
+                                         EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff;
                }
                if (rdev->pm.active_crtcs & (1 << 3)) {
-                       stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
-                       if (!(stat_crtc & 1))
-                               in_vbl = false;
+                       vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
+                                    EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff;
+                       position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
+                                         EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff;
                }
                if (rdev->pm.active_crtcs & (1 << 4)) {
-                       stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
-                       if (!(stat_crtc & 1))
-                               in_vbl = false;
+                       vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
+                                    EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff;
+                       position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
+                                         EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff;
                }
                if (rdev->pm.active_crtcs & (1 << 5)) {
-                       stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
-                       if (!(stat_crtc & 1))
-                               in_vbl = false;
+                       vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
+                                    EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff;
+                       position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
+                                         EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff;
                }
        } else if (ASIC_IS_AVIVO(rdev)) {
                if (rdev->pm.active_crtcs & (1 << 0)) {
-                       stat_crtc = RREG32(D1CRTC_STATUS);
-                       if (!(stat_crtc & 1))
-                               in_vbl = false;
+                       vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END) & 0xfff;
+                       position = RREG32(AVIVO_D1CRTC_STATUS_POSITION) & 0xfff;
                }
                if (rdev->pm.active_crtcs & (1 << 1)) {
-                       stat_crtc = RREG32(D2CRTC_STATUS);
-                       if (!(stat_crtc & 1))
-                               in_vbl = false;
+                       vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END) & 0xfff;
+                       position = RREG32(AVIVO_D2CRTC_STATUS_POSITION) & 0xfff;
                }
+               if (position < vbl && position > 1)
+                       in_vbl = false;
        } else {
                if (rdev->pm.active_crtcs & (1 << 0)) {
                        stat_crtc = RREG32(RADEON_CRTC_STATUS);
@@ -447,6 +453,9 @@ bool radeon_pm_in_vbl(struct radeon_device *rdev)
                }
        }
 
+       if (position < vbl && position > 1)
+               in_vbl = false;
+
        return in_vbl;
 }