aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/rs600.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/rs600.c')
-rw-r--r--drivers/gpu/drm/radeon/rs600.c22
1 files changed, 21 insertions, 1 deletions
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) {