diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_irq_kms.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_reg.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rs600.c | 22 |
9 files changed, 74 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index b3d168fb89e5..0137a4cd90f5 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1418,6 +1418,7 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
1418 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; | 1418 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; |
1419 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; | 1419 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; |
1420 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; | 1420 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; |
1421 | u32 grbm_int_cntl = 0; | ||
1421 | 1422 | ||
1422 | if (!rdev->irq.installed) { | 1423 | if (!rdev->irq.installed) { |
1423 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | 1424 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); |
@@ -1490,8 +1491,13 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
1490 | DRM_DEBUG("evergreen_irq_set: hpd 6\n"); | 1491 | DRM_DEBUG("evergreen_irq_set: hpd 6\n"); |
1491 | hpd6 |= DC_HPDx_INT_EN; | 1492 | hpd6 |= DC_HPDx_INT_EN; |
1492 | } | 1493 | } |
1494 | if (rdev->irq.gui_idle) { | ||
1495 | DRM_DEBUG("gui idle\n"); | ||
1496 | grbm_int_cntl |= GUI_IDLE_INT_ENABLE; | ||
1497 | } | ||
1493 | 1498 | ||
1494 | WREG32(CP_INT_CNTL, cp_int_cntl); | 1499 | WREG32(CP_INT_CNTL, cp_int_cntl); |
1500 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | ||
1495 | 1501 | ||
1496 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); | 1502 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); |
1497 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); | 1503 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); |
@@ -1853,6 +1859,11 @@ restart_ih: | |||
1853 | case 181: /* CP EOP event */ | 1859 | case 181: /* CP EOP event */ |
1854 | DRM_DEBUG("IH: CP EOP\n"); | 1860 | DRM_DEBUG("IH: CP EOP\n"); |
1855 | break; | 1861 | break; |
1862 | case 233: /* GUI IDLE */ | ||
1863 | DRM_DEBUG("IH: CP EOP\n"); | ||
1864 | rdev->pm.gui_idle = true; | ||
1865 | wake_up(&rdev->irq.idle_queue); | ||
1866 | break; | ||
1856 | default: | 1867 | default: |
1857 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | 1868 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
1858 | break; | 1869 | break; |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e62116e222a0..d35298684f30 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -262,6 +262,9 @@ int r100_irq_set(struct radeon_device *rdev) | |||
262 | if (rdev->irq.sw_int) { | 262 | if (rdev->irq.sw_int) { |
263 | tmp |= RADEON_SW_INT_ENABLE; | 263 | tmp |= RADEON_SW_INT_ENABLE; |
264 | } | 264 | } |
265 | if (rdev->irq.gui_idle) { | ||
266 | tmp |= RADEON_GUI_IDLE_MASK; | ||
267 | } | ||
265 | if (rdev->irq.crtc_vblank_int[0]) { | 268 | if (rdev->irq.crtc_vblank_int[0]) { |
266 | tmp |= RADEON_CRTC_VBLANK_MASK; | 269 | tmp |= RADEON_CRTC_VBLANK_MASK; |
267 | } | 270 | } |
@@ -296,6 +299,12 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | |||
296 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | | 299 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | |
297 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; | 300 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; |
298 | 301 | ||
302 | /* the interrupt works, but the status bit is permanently asserted */ | ||
303 | if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { | ||
304 | if (!rdev->irq.gui_idle_acked) | ||
305 | irq_mask |= RADEON_GUI_IDLE_STAT; | ||
306 | } | ||
307 | |||
299 | if (irqs) { | 308 | if (irqs) { |
300 | WREG32(RADEON_GEN_INT_STATUS, irqs); | 309 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
301 | } | 310 | } |
@@ -307,6 +316,9 @@ int r100_irq_process(struct radeon_device *rdev) | |||
307 | uint32_t status, msi_rearm; | 316 | uint32_t status, msi_rearm; |
308 | bool queue_hotplug = false; | 317 | bool queue_hotplug = false; |
309 | 318 | ||
319 | /* reset gui idle ack. the status bit is broken */ | ||
320 | rdev->irq.gui_idle_acked = false; | ||
321 | |||
310 | status = r100_irq_ack(rdev); | 322 | status = r100_irq_ack(rdev); |
311 | if (!status) { | 323 | if (!status) { |
312 | return IRQ_NONE; | 324 | return IRQ_NONE; |
@@ -319,6 +331,12 @@ int r100_irq_process(struct radeon_device *rdev) | |||
319 | if (status & RADEON_SW_INT_TEST) { | 331 | if (status & RADEON_SW_INT_TEST) { |
320 | radeon_fence_process(rdev); | 332 | radeon_fence_process(rdev); |
321 | } | 333 | } |
334 | /* gui idle interrupt */ | ||
335 | if (status & RADEON_GUI_IDLE_STAT) { | ||
336 | rdev->irq.gui_idle_acked = true; | ||
337 | rdev->pm.gui_idle = true; | ||
338 | wake_up(&rdev->irq.idle_queue); | ||
339 | } | ||
322 | /* Vertical blank interrupts */ | 340 | /* Vertical blank interrupts */ |
323 | if (status & RADEON_CRTC_VBLANK_STAT) { | 341 | if (status & RADEON_CRTC_VBLANK_STAT) { |
324 | drm_handle_vblank(rdev->ddev, 0); | 342 | drm_handle_vblank(rdev->ddev, 0); |
@@ -340,6 +358,8 @@ int r100_irq_process(struct radeon_device *rdev) | |||
340 | } | 358 | } |
341 | status = r100_irq_ack(rdev); | 359 | status = r100_irq_ack(rdev); |
342 | } | 360 | } |
361 | /* reset gui idle ack. the status bit is broken */ | ||
362 | rdev->irq.gui_idle_acked = false; | ||
343 | if (queue_hotplug) | 363 | if (queue_hotplug) |
344 | queue_work(rdev->wq, &rdev->hotplug_work); | 364 | queue_work(rdev->wq, &rdev->hotplug_work); |
345 | if (rdev->msi_enabled) { | 365 | if (rdev->msi_enabled) { |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 1c85dcb168a1..094c29dd96e3 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2535,6 +2535,7 @@ int r600_irq_set(struct radeon_device *rdev) | |||
2535 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; | 2535 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; |
2536 | u32 mode_int = 0; | 2536 | u32 mode_int = 0; |
2537 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | 2537 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
2538 | u32 grbm_int_cntl = 0; | ||
2538 | u32 hdmi1, hdmi2; | 2539 | u32 hdmi1, hdmi2; |
2539 | 2540 | ||
2540 | if (!rdev->irq.installed) { | 2541 | if (!rdev->irq.installed) { |
@@ -2611,9 +2612,14 @@ int r600_irq_set(struct radeon_device *rdev) | |||
2611 | DRM_DEBUG("r600_irq_set: hdmi 2\n"); | 2612 | DRM_DEBUG("r600_irq_set: hdmi 2\n"); |
2612 | hdmi2 |= R600_HDMI_INT_EN; | 2613 | hdmi2 |= R600_HDMI_INT_EN; |
2613 | } | 2614 | } |
2615 | if (rdev->irq.gui_idle) { | ||
2616 | DRM_DEBUG("gui idle\n"); | ||
2617 | grbm_int_cntl |= GUI_IDLE_INT_ENABLE; | ||
2618 | } | ||
2614 | 2619 | ||
2615 | WREG32(CP_INT_CNTL, cp_int_cntl); | 2620 | WREG32(CP_INT_CNTL, cp_int_cntl); |
2616 | WREG32(DxMODE_INT_MASK, mode_int); | 2621 | WREG32(DxMODE_INT_MASK, mode_int); |
2622 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | ||
2617 | WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); | 2623 | WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); |
2618 | if (ASIC_IS_DCE3(rdev)) { | 2624 | if (ASIC_IS_DCE3(rdev)) { |
2619 | WREG32(R600_HDMI_BLOCK3 + R600_HDMI_CNTL, hdmi2); | 2625 | WREG32(R600_HDMI_BLOCK3 + R600_HDMI_CNTL, hdmi2); |
@@ -2929,6 +2935,11 @@ restart_ih: | |||
2929 | case 181: /* CP EOP event */ | 2935 | case 181: /* CP EOP event */ |
2930 | DRM_DEBUG("IH: CP EOP\n"); | 2936 | DRM_DEBUG("IH: CP EOP\n"); |
2931 | break; | 2937 | break; |
2938 | case 233: /* GUI IDLE */ | ||
2939 | DRM_DEBUG("IH: CP EOP\n"); | ||
2940 | rdev->pm.gui_idle = true; | ||
2941 | wake_up(&rdev->irq.idle_queue); | ||
2942 | break; | ||
2932 | default: | 2943 | default: |
2933 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | 2944 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
2934 | break; | 2945 | break; |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index bb4a2a66f070..433937109afc 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -376,6 +376,9 @@ struct radeon_irq { | |||
376 | wait_queue_head_t vblank_queue; | 376 | wait_queue_head_t vblank_queue; |
377 | /* FIXME: use defines for max hpd/dacs */ | 377 | /* FIXME: use defines for max hpd/dacs */ |
378 | bool hpd[6]; | 378 | bool hpd[6]; |
379 | bool gui_idle; | ||
380 | bool gui_idle_acked; | ||
381 | wait_queue_head_t idle_queue; | ||
379 | /* FIXME: use defines for max HDMI blocks */ | 382 | /* FIXME: use defines for max HDMI blocks */ |
380 | bool hdmi[2]; | 383 | bool hdmi[2]; |
381 | spinlock_t sw_lock; | 384 | spinlock_t sw_lock; |
@@ -694,6 +697,7 @@ struct radeon_pm { | |||
694 | int active_crtcs; | 697 | int active_crtcs; |
695 | int req_vblank; | 698 | int req_vblank; |
696 | bool vblank_sync; | 699 | bool vblank_sync; |
700 | bool gui_idle; | ||
697 | fixed20_12 max_bandwidth; | 701 | fixed20_12 max_bandwidth; |
698 | fixed20_12 igp_sideport_mclk; | 702 | fixed20_12 igp_sideport_mclk; |
699 | fixed20_12 igp_system_mclk; | 703 | fixed20_12 igp_system_mclk; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 26217ffe0355..53a2c27dd8fa 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -602,6 +602,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
602 | rwlock_init(&rdev->fence_drv.lock); | 602 | rwlock_init(&rdev->fence_drv.lock); |
603 | INIT_LIST_HEAD(&rdev->gem.objects); | 603 | INIT_LIST_HEAD(&rdev->gem.objects); |
604 | init_waitqueue_head(&rdev->irq.vblank_queue); | 604 | init_waitqueue_head(&rdev->irq.vblank_queue); |
605 | init_waitqueue_head(&rdev->irq.idle_queue); | ||
605 | 606 | ||
606 | /* setup workqueue */ | 607 | /* setup workqueue */ |
607 | rdev->wq = create_workqueue("radeon"); | 608 | rdev->wq = create_workqueue("radeon"); |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 8fa40ed397ec..059bfa4098d7 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -68,6 +68,7 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | |||
68 | 68 | ||
69 | /* Disable *all* interrupts */ | 69 | /* Disable *all* interrupts */ |
70 | rdev->irq.sw_int = false; | 70 | rdev->irq.sw_int = false; |
71 | rdev->irq.gui_idle = false; | ||
71 | for (i = 0; i < rdev->num_crtc; i++) | 72 | for (i = 0; i < rdev->num_crtc; i++) |
72 | rdev->irq.crtc_vblank_int[i] = false; | 73 | rdev->irq.crtc_vblank_int[i] = false; |
73 | for (i = 0; i < 6; i++) | 74 | for (i = 0; i < 6; i++) |
@@ -97,6 +98,7 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) | |||
97 | } | 98 | } |
98 | /* Disable *all* interrupts */ | 99 | /* Disable *all* interrupts */ |
99 | rdev->irq.sw_int = false; | 100 | rdev->irq.sw_int = false; |
101 | rdev->irq.gui_idle = false; | ||
100 | for (i = 0; i < rdev->num_crtc; i++) | 102 | for (i = 0; i < rdev->num_crtc; i++) |
101 | rdev->irq.crtc_vblank_int[i] = false; | 103 | rdev->irq.crtc_vblank_int[i] = false; |
102 | for (i = 0; i < 6; i++) | 104 | for (i = 0; i < 6; i++) |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index a4b57493aa78..6dfeb9cf16ba 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #define RADEON_IDLE_LOOP_MS 100 | 27 | #define RADEON_IDLE_LOOP_MS 100 |
28 | #define RADEON_RECLOCK_DELAY_MS 200 | 28 | #define RADEON_RECLOCK_DELAY_MS 200 |
29 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 | 29 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 |
30 | #define RADEON_WAIT_IDLE_TIMEOUT 200 | ||
30 | 31 | ||
31 | static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); | 32 | static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); |
32 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); | 33 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index eabbc9cf30a7..74d1cbfa23a1 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -995,6 +995,7 @@ | |||
995 | # define RADEON_FP_DETECT_MASK (1 << 4) | 995 | # define RADEON_FP_DETECT_MASK (1 << 4) |
996 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) | 996 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) |
997 | # define RADEON_FP2_DETECT_MASK (1 << 10) | 997 | # define RADEON_FP2_DETECT_MASK (1 << 10) |
998 | # define RADEON_GUI_IDLE_MASK (1 << 19) | ||
998 | # define RADEON_SW_INT_ENABLE (1 << 25) | 999 | # define RADEON_SW_INT_ENABLE (1 << 25) |
999 | #define RADEON_GEN_INT_STATUS 0x0044 | 1000 | #define RADEON_GEN_INT_STATUS 0x0044 |
1000 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) | 1001 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) |
@@ -1006,6 +1007,8 @@ | |||
1006 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) | 1007 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) |
1007 | # define RADEON_FP2_DETECT_STAT (1 << 10) | 1008 | # define RADEON_FP2_DETECT_STAT (1 << 10) |
1008 | # define RADEON_FP2_DETECT_STAT_ACK (1 << 10) | 1009 | # define RADEON_FP2_DETECT_STAT_ACK (1 << 10) |
1010 | # define RADEON_GUI_IDLE_STAT (1 << 19) | ||
1011 | # define RADEON_GUI_IDLE_STAT_ACK (1 << 19) | ||
1009 | # define RADEON_SW_INT_FIRE (1 << 26) | 1012 | # define RADEON_SW_INT_FIRE (1 << 26) |
1010 | # define RADEON_SW_INT_TEST (1 << 25) | 1013 | # define RADEON_SW_INT_TEST (1 << 25) |
1011 | # define RADEON_SW_INT_TEST_ACK (1 << 25) | 1014 | # define RADEON_SW_INT_TEST_ACK (1 << 25) |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 5e3f21861f45..b312b72d76ce 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -382,6 +382,9 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
382 | if (rdev->irq.sw_int) { | 382 | if (rdev->irq.sw_int) { |
383 | tmp |= S_000040_SW_INT_EN(1); | 383 | tmp |= S_000040_SW_INT_EN(1); |
384 | } | 384 | } |
385 | if (rdev->irq.gui_idle) { | ||
386 | tmp |= S_000040_GUI_IDLE(1); | ||
387 | } | ||
385 | if (rdev->irq.crtc_vblank_int[0]) { | 388 | if (rdev->irq.crtc_vblank_int[0]) { |
386 | mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); | 389 | mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); |
387 | } | 390 | } |
@@ -404,9 +407,15 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
404 | static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) | 407 | static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) |
405 | { | 408 | { |
406 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); | 409 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); |
407 | uint32_t irq_mask = ~C_000044_SW_INT; | 410 | uint32_t irq_mask = S_000044_SW_INT(1); |
408 | u32 tmp; | 411 | u32 tmp; |
409 | 412 | ||
413 | /* the interrupt works, but the status bit is permanently asserted */ | ||
414 | if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { | ||
415 | if (!rdev->irq.gui_idle_acked) | ||
416 | irq_mask |= S_000044_GUI_IDLE_STAT(1); | ||
417 | } | ||
418 | |||
410 | if (G_000044_DISPLAY_INT_STAT(irqs)) { | 419 | if (G_000044_DISPLAY_INT_STAT(irqs)) { |
411 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); | 420 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); |
412 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(*r500_disp_int)) { | 421 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(*r500_disp_int)) { |
@@ -454,6 +463,9 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
454 | uint32_t r500_disp_int; | 463 | uint32_t r500_disp_int; |
455 | bool queue_hotplug = false; | 464 | bool queue_hotplug = false; |
456 | 465 | ||
466 | /* reset gui idle ack. the status bit is broken */ | ||
467 | rdev->irq.gui_idle_acked = false; | ||
468 | |||
457 | status = rs600_irq_ack(rdev, &r500_disp_int); | 469 | status = rs600_irq_ack(rdev, &r500_disp_int); |
458 | if (!status && !r500_disp_int) { | 470 | if (!status && !r500_disp_int) { |
459 | return IRQ_NONE; | 471 | return IRQ_NONE; |
@@ -462,6 +474,12 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
462 | /* SW interrupt */ | 474 | /* SW interrupt */ |
463 | if (G_000044_SW_INT(status)) | 475 | if (G_000044_SW_INT(status)) |
464 | radeon_fence_process(rdev); | 476 | radeon_fence_process(rdev); |
477 | /* GUI idle */ | ||
478 | if (G_000040_GUI_IDLE(status)) { | ||
479 | rdev->irq.gui_idle_acked = true; | ||
480 | rdev->pm.gui_idle = true; | ||
481 | wake_up(&rdev->irq.idle_queue); | ||
482 | } | ||
465 | /* Vertical blank interrupts */ | 483 | /* Vertical blank interrupts */ |
466 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) { | 484 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) { |
467 | drm_handle_vblank(rdev->ddev, 0); | 485 | drm_handle_vblank(rdev->ddev, 0); |
@@ -483,6 +501,8 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
483 | } | 501 | } |
484 | status = rs600_irq_ack(rdev, &r500_disp_int); | 502 | status = rs600_irq_ack(rdev, &r500_disp_int); |
485 | } | 503 | } |
504 | /* reset gui idle ack. the status bit is broken */ | ||
505 | rdev->irq.gui_idle_acked = false; | ||
486 | if (queue_hotplug) | 506 | if (queue_hotplug) |
487 | queue_work(rdev->wq, &rdev->hotplug_work); | 507 | queue_work(rdev->wq, &rdev->hotplug_work); |
488 | if (rdev->msi_enabled) { | 508 | if (rdev->msi_enabled) { |