diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/rs600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/rs600.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index d25cf869d08d..25f9eef12c42 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -396,7 +396,6 @@ int rs600_asic_reset(struct radeon_device *rdev) | |||
396 | /* Check if GPU is idle */ | 396 | /* Check if GPU is idle */ |
397 | if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { | 397 | if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { |
398 | dev_err(rdev->dev, "failed to reset GPU\n"); | 398 | dev_err(rdev->dev, "failed to reset GPU\n"); |
399 | rdev->gpu_lockup = true; | ||
400 | ret = -1; | 399 | ret = -1; |
401 | } else | 400 | } else |
402 | dev_info(rdev->dev, "GPU reset succeed\n"); | 401 | dev_info(rdev->dev, "GPU reset succeed\n"); |
@@ -553,6 +552,12 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
553 | ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | 552 | ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); |
554 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & | 553 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & |
555 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | 554 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); |
555 | u32 hdmi0; | ||
556 | if (ASIC_IS_DCE2(rdev)) | ||
557 | hdmi0 = RREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL) & | ||
558 | ~S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(1); | ||
559 | else | ||
560 | hdmi0 = 0; | ||
556 | 561 | ||
557 | if (!rdev->irq.installed) { | 562 | if (!rdev->irq.installed) { |
558 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 563 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
@@ -579,10 +584,15 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
579 | if (rdev->irq.hpd[1]) { | 584 | if (rdev->irq.hpd[1]) { |
580 | hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | 585 | hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); |
581 | } | 586 | } |
587 | if (rdev->irq.afmt[0]) { | ||
588 | hdmi0 |= S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(1); | ||
589 | } | ||
582 | WREG32(R_000040_GEN_INT_CNTL, tmp); | 590 | WREG32(R_000040_GEN_INT_CNTL, tmp); |
583 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); | 591 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); |
584 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | 592 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); |
585 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | 593 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); |
594 | if (ASIC_IS_DCE2(rdev)) | ||
595 | WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, hdmi0); | ||
586 | return 0; | 596 | return 0; |
587 | } | 597 | } |
588 | 598 | ||
@@ -622,6 +632,17 @@ static inline u32 rs600_irq_ack(struct radeon_device *rdev) | |||
622 | rdev->irq.stat_regs.r500.disp_int = 0; | 632 | rdev->irq.stat_regs.r500.disp_int = 0; |
623 | } | 633 | } |
624 | 634 | ||
635 | if (ASIC_IS_DCE2(rdev)) { | ||
636 | rdev->irq.stat_regs.r500.hdmi0_status = RREG32(R_007404_HDMI0_STATUS) & | ||
637 | S_007404_HDMI0_AZ_FORMAT_WTRIG(1); | ||
638 | if (G_007404_HDMI0_AZ_FORMAT_WTRIG(rdev->irq.stat_regs.r500.hdmi0_status)) { | ||
639 | tmp = RREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL); | ||
640 | tmp |= S_007408_HDMI0_AZ_FORMAT_WTRIG_ACK(1); | ||
641 | WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, tmp); | ||
642 | } | ||
643 | } else | ||
644 | rdev->irq.stat_regs.r500.hdmi0_status = 0; | ||
645 | |||
625 | if (irqs) { | 646 | if (irqs) { |
626 | WREG32(R_000044_GEN_INT_STATUS, irqs); | 647 | WREG32(R_000044_GEN_INT_STATUS, irqs); |
627 | } | 648 | } |
@@ -630,6 +651,9 @@ static inline u32 rs600_irq_ack(struct radeon_device *rdev) | |||
630 | 651 | ||
631 | void rs600_irq_disable(struct radeon_device *rdev) | 652 | void rs600_irq_disable(struct radeon_device *rdev) |
632 | { | 653 | { |
654 | u32 hdmi0 = RREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL) & | ||
655 | ~S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(1); | ||
656 | WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, hdmi0); | ||
633 | WREG32(R_000040_GEN_INT_CNTL, 0); | 657 | WREG32(R_000040_GEN_INT_CNTL, 0); |
634 | WREG32(R_006540_DxMODE_INT_MASK, 0); | 658 | WREG32(R_006540_DxMODE_INT_MASK, 0); |
635 | /* Wait and acknowledge irq */ | 659 | /* Wait and acknowledge irq */ |
@@ -641,15 +665,20 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
641 | { | 665 | { |
642 | u32 status, msi_rearm; | 666 | u32 status, msi_rearm; |
643 | bool queue_hotplug = false; | 667 | bool queue_hotplug = false; |
668 | bool queue_hdmi = false; | ||
644 | 669 | ||
645 | /* reset gui idle ack. the status bit is broken */ | 670 | /* reset gui idle ack. the status bit is broken */ |
646 | rdev->irq.gui_idle_acked = false; | 671 | rdev->irq.gui_idle_acked = false; |
647 | 672 | ||
648 | status = rs600_irq_ack(rdev); | 673 | status = rs600_irq_ack(rdev); |
649 | if (!status && !rdev->irq.stat_regs.r500.disp_int) { | 674 | if (!status && |
675 | !rdev->irq.stat_regs.r500.disp_int && | ||
676 | !rdev->irq.stat_regs.r500.hdmi0_status) { | ||
650 | return IRQ_NONE; | 677 | return IRQ_NONE; |
651 | } | 678 | } |
652 | while (status || rdev->irq.stat_regs.r500.disp_int) { | 679 | while (status || |
680 | rdev->irq.stat_regs.r500.disp_int || | ||
681 | rdev->irq.stat_regs.r500.hdmi0_status) { | ||
653 | /* SW interrupt */ | 682 | /* SW interrupt */ |
654 | if (G_000044_SW_INT(status)) { | 683 | if (G_000044_SW_INT(status)) { |
655 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | 684 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |
@@ -687,12 +716,18 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
687 | queue_hotplug = true; | 716 | queue_hotplug = true; |
688 | DRM_DEBUG("HPD2\n"); | 717 | DRM_DEBUG("HPD2\n"); |
689 | } | 718 | } |
719 | if (G_007404_HDMI0_AZ_FORMAT_WTRIG(rdev->irq.stat_regs.r500.hdmi0_status)) { | ||
720 | queue_hdmi = true; | ||
721 | DRM_DEBUG("HDMI0\n"); | ||
722 | } | ||
690 | status = rs600_irq_ack(rdev); | 723 | status = rs600_irq_ack(rdev); |
691 | } | 724 | } |
692 | /* reset gui idle ack. the status bit is broken */ | 725 | /* reset gui idle ack. the status bit is broken */ |
693 | rdev->irq.gui_idle_acked = false; | 726 | rdev->irq.gui_idle_acked = false; |
694 | if (queue_hotplug) | 727 | if (queue_hotplug) |
695 | schedule_work(&rdev->hotplug_work); | 728 | schedule_work(&rdev->hotplug_work); |
729 | if (queue_hdmi) | ||
730 | schedule_work(&rdev->audio_work); | ||
696 | if (rdev->msi_enabled) { | 731 | if (rdev->msi_enabled) { |
697 | switch (rdev->family) { | 732 | switch (rdev->family) { |
698 | case CHIP_RS600: | 733 | case CHIP_RS600: |
@@ -883,12 +918,9 @@ static int rs600_startup(struct radeon_device *rdev) | |||
883 | if (r) | 918 | if (r) |
884 | return r; | 919 | return r; |
885 | 920 | ||
886 | r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 921 | r = radeon_ib_ring_tests(rdev); |
887 | if (r) { | 922 | if (r) |
888 | dev_err(rdev->dev, "failed testing IB (%d).\n", r); | ||
889 | rdev->accel_working = false; | ||
890 | return r; | 923 | return r; |
891 | } | ||
892 | 924 | ||
893 | return 0; | 925 | return 0; |
894 | } | 926 | } |