aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c11
-rw-r--r--drivers/gpu/drm/radeon/r100.c20
-rw-r--r--drivers/gpu/drm/radeon/r600.c11
-rw-r--r--drivers/gpu/drm/radeon/radeon.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_reg.h3
-rw-r--r--drivers/gpu/drm/radeon/rs600.c22
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
31static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); 32static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);
32static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); 33static 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)
404static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) 407static 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) {