aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/evergreen.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-03-30 08:59:57 -0400
committerDave Airlie <airlied@redhat.com>2012-04-24 04:50:14 -0400
commitf122c6109b1a79153cfb1e188c665ce3f312a886 (patch)
tree9b8d9211c0be59a0a96a906373bd85d187d23ab4 /drivers/gpu/drm/radeon/evergreen.c
parent3a2a67aa28725bb500505087067e7830cfa9c137 (diff)
drm/radeon/kms: fix up audio interrupt handling
- add support for rs6xx - add support for DCE4/5 - fixup 6xx/7xx Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen.c')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index cfa372cb1cb..eed7acefb49 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2594,6 +2594,7 @@ int evergreen_irq_set(struct radeon_device *rdev)
2594 u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; 2594 u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
2595 u32 grbm_int_cntl = 0; 2595 u32 grbm_int_cntl = 0;
2596 u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; 2596 u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
2597 u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0;
2597 2598
2598 if (!rdev->irq.installed) { 2599 if (!rdev->irq.installed) {
2599 WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); 2600 WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
@@ -2614,6 +2615,13 @@ int evergreen_irq_set(struct radeon_device *rdev)
2614 hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; 2615 hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
2615 hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; 2616 hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
2616 2617
2618 afmt1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
2619 afmt2 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
2620 afmt3 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
2621 afmt4 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
2622 afmt5 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
2623 afmt6 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
2624
2617 if (rdev->family >= CHIP_CAYMAN) { 2625 if (rdev->family >= CHIP_CAYMAN) {
2618 /* enable CP interrupts on all rings */ 2626 /* enable CP interrupts on all rings */
2619 if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { 2627 if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) {
@@ -2690,6 +2698,30 @@ int evergreen_irq_set(struct radeon_device *rdev)
2690 DRM_DEBUG("evergreen_irq_set: hpd 6\n"); 2698 DRM_DEBUG("evergreen_irq_set: hpd 6\n");
2691 hpd6 |= DC_HPDx_INT_EN; 2699 hpd6 |= DC_HPDx_INT_EN;
2692 } 2700 }
2701 if (rdev->irq.afmt[0]) {
2702 DRM_DEBUG("evergreen_irq_set: hdmi 0\n");
2703 afmt1 |= AFMT_AZ_FORMAT_WTRIG_MASK;
2704 }
2705 if (rdev->irq.afmt[1]) {
2706 DRM_DEBUG("evergreen_irq_set: hdmi 1\n");
2707 afmt2 |= AFMT_AZ_FORMAT_WTRIG_MASK;
2708 }
2709 if (rdev->irq.afmt[2]) {
2710 DRM_DEBUG("evergreen_irq_set: hdmi 2\n");
2711 afmt3 |= AFMT_AZ_FORMAT_WTRIG_MASK;
2712 }
2713 if (rdev->irq.afmt[3]) {
2714 DRM_DEBUG("evergreen_irq_set: hdmi 3\n");
2715 afmt4 |= AFMT_AZ_FORMAT_WTRIG_MASK;
2716 }
2717 if (rdev->irq.afmt[4]) {
2718 DRM_DEBUG("evergreen_irq_set: hdmi 4\n");
2719 afmt5 |= AFMT_AZ_FORMAT_WTRIG_MASK;
2720 }
2721 if (rdev->irq.afmt[5]) {
2722 DRM_DEBUG("evergreen_irq_set: hdmi 5\n");
2723 afmt6 |= AFMT_AZ_FORMAT_WTRIG_MASK;
2724 }
2693 if (rdev->irq.gui_idle) { 2725 if (rdev->irq.gui_idle) {
2694 DRM_DEBUG("gui idle\n"); 2726 DRM_DEBUG("gui idle\n");
2695 grbm_int_cntl |= GUI_IDLE_INT_ENABLE; 2727 grbm_int_cntl |= GUI_IDLE_INT_ENABLE;
@@ -2732,6 +2764,13 @@ int evergreen_irq_set(struct radeon_device *rdev)
2732 WREG32(DC_HPD5_INT_CONTROL, hpd5); 2764 WREG32(DC_HPD5_INT_CONTROL, hpd5);
2733 WREG32(DC_HPD6_INT_CONTROL, hpd6); 2765 WREG32(DC_HPD6_INT_CONTROL, hpd6);
2734 2766
2767 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, afmt1);
2768 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, afmt2);
2769 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, afmt3);
2770 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, afmt4);
2771 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, afmt5);
2772 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, afmt6);
2773
2735 return 0; 2774 return 0;
2736} 2775}
2737 2776
@@ -2756,6 +2795,13 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
2756 rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); 2795 rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
2757 } 2796 }
2758 2797
2798 rdev->irq.stat_regs.evergreen.afmt_status1 = RREG32(AFMT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
2799 rdev->irq.stat_regs.evergreen.afmt_status2 = RREG32(AFMT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
2800 rdev->irq.stat_regs.evergreen.afmt_status3 = RREG32(AFMT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
2801 rdev->irq.stat_regs.evergreen.afmt_status4 = RREG32(AFMT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
2802 rdev->irq.stat_regs.evergreen.afmt_status5 = RREG32(AFMT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
2803 rdev->irq.stat_regs.evergreen.afmt_status6 = RREG32(AFMT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
2804
2759 if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) 2805 if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
2760 WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); 2806 WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
2761 if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) 2807 if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
@@ -2829,6 +2875,36 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
2829 tmp |= DC_HPDx_INT_ACK; 2875 tmp |= DC_HPDx_INT_ACK;
2830 WREG32(DC_HPD6_INT_CONTROL, tmp); 2876 WREG32(DC_HPD6_INT_CONTROL, tmp);
2831 } 2877 }
2878 if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) {
2879 tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
2880 tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
2881 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, tmp);
2882 }
2883 if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) {
2884 tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
2885 tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
2886 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, tmp);
2887 }
2888 if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) {
2889 tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
2890 tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
2891 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, tmp);
2892 }
2893 if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) {
2894 tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
2895 tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
2896 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, tmp);
2897 }
2898 if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) {
2899 tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
2900 tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
2901 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, tmp);
2902 }
2903 if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) {
2904 tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
2905 tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
2906 WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, tmp);
2907 }
2832} 2908}
2833 2909
2834void evergreen_irq_disable(struct radeon_device *rdev) 2910void evergreen_irq_disable(struct radeon_device *rdev)
@@ -2878,6 +2954,7 @@ int evergreen_irq_process(struct radeon_device *rdev)
2878 u32 ring_index; 2954 u32 ring_index;
2879 unsigned long flags; 2955 unsigned long flags;
2880 bool queue_hotplug = false; 2956 bool queue_hotplug = false;
2957 bool queue_hdmi = false;
2881 2958
2882 if (!rdev->ih.enabled || rdev->shutdown) 2959 if (!rdev->ih.enabled || rdev->shutdown)
2883 return IRQ_NONE; 2960 return IRQ_NONE;
@@ -3111,6 +3188,55 @@ restart_ih:
3111 break; 3188 break;
3112 } 3189 }
3113 break; 3190 break;
3191 case 44: /* hdmi */
3192 switch (src_data) {
3193 case 0:
3194 if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) {
3195 rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG;
3196 queue_hdmi = true;
3197 DRM_DEBUG("IH: HDMI0\n");
3198 }
3199 break;
3200 case 1:
3201 if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) {
3202 rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG;
3203 queue_hdmi = true;
3204 DRM_DEBUG("IH: HDMI1\n");
3205 }
3206 break;
3207 case 2:
3208 if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) {
3209 rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG;
3210 queue_hdmi = true;
3211 DRM_DEBUG("IH: HDMI2\n");
3212 }
3213 break;
3214 case 3:
3215 if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) {
3216 rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG;
3217 queue_hdmi = true;
3218 DRM_DEBUG("IH: HDMI3\n");
3219 }
3220 break;
3221 case 4:
3222 if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) {
3223 rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG;
3224 queue_hdmi = true;
3225 DRM_DEBUG("IH: HDMI4\n");
3226 }
3227 break;
3228 case 5:
3229 if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) {
3230 rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG;
3231 queue_hdmi = true;
3232 DRM_DEBUG("IH: HDMI5\n");
3233 }
3234 break;
3235 default:
3236 DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
3237 break;
3238 }
3239 break;
3114 case 176: /* CP_INT in ring buffer */ 3240 case 176: /* CP_INT in ring buffer */
3115 case 177: /* CP_INT in IB1 */ 3241 case 177: /* CP_INT in IB1 */
3116 case 178: /* CP_INT in IB2 */ 3242 case 178: /* CP_INT in IB2 */
@@ -3154,6 +3280,8 @@ restart_ih:
3154 goto restart_ih; 3280 goto restart_ih;
3155 if (queue_hotplug) 3281 if (queue_hotplug)
3156 schedule_work(&rdev->hotplug_work); 3282 schedule_work(&rdev->hotplug_work);
3283 if (queue_hdmi)
3284 schedule_work(&rdev->audio_work);
3157 rdev->ih.rptr = rptr; 3285 rdev->ih.rptr = rptr;
3158 WREG32(IH_RB_RPTR, rdev->ih.rptr); 3286 WREG32(IH_RB_RPTR, rdev->ih.rptr);
3159 spin_unlock_irqrestore(&rdev->ih.lock, flags); 3287 spin_unlock_irqrestore(&rdev->ih.lock, flags);