---
 drivers/gpu/drm/radeon/evergreen.c |   45 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/r600_hdmi.c |    7 ++++-
 drivers/gpu/drm/radeon/radeon.h    |    2 +-
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index f58254a..8779a75 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2527,12 +2527,22 @@ void evergreen_disable_interrupt_state(struct 
radeon_device *rdev)

 int evergreen_irq_set(struct radeon_device *rdev)
 {
+       u8 i;
        u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
        u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
        u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
        u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
+       u32 hdmi[6];
        u32 grbm_int_cntl = 0;
        u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
+       u16 eg_offsets[] = {
+               EVERGREEN_CRTC0_REGISTER_OFFSET,
+               EVERGREEN_CRTC1_REGISTER_OFFSET,
+               EVERGREEN_CRTC2_REGISTER_OFFSET,
+               EVERGREEN_CRTC3_REGISTER_OFFSET,
+               EVERGREEN_CRTC4_REGISTER_OFFSET,
+               EVERGREEN_CRTC5_REGISTER_OFFSET,
+       };

        if (!rdev->irq.installed) {
                WARN(1, "Can't enable IRQ/MSI because no handler is 
installed\n");
@@ -2553,6 +2563,10 @@ int evergreen_irq_set(struct radeon_device *rdev)
        hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
        hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;

+       for (i = 0; i < ARRAY_SIZE(eg_offsets) && i < rdev->num_crtc; i++)
+               hdmi[i] = RREG32(EVERGREEN_HDMI_BASE + eg_offsets[i] + 0xfc)
+                       & ~0x10000000;
+
        if (rdev->family >= CHIP_CAYMAN) {
                /* enable CP interrupts on all rings */
                if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) {
@@ -2629,6 +2643,12 @@ int evergreen_irq_set(struct radeon_device *rdev)
                DRM_DEBUG("evergreen_irq_set: hpd 6\n");
                hpd6 |= DC_HPDx_INT_EN;
        }
+       for (i = 0; i < ARRAY_SIZE(eg_offsets) && i < rdev->num_crtc; i++) {
+               if (rdev->irq.hdmi[i]) {
+                       DRM_DEBUG("evergreen_irq_set: hdmi %d\n", i);
+                       hdmi[i] |= 0x10000000;
+               }
+       }
        if (rdev->irq.gui_idle) {
                DRM_DEBUG("gui idle\n");
                grbm_int_cntl |= GUI_IDLE_INT_ENABLE;
@@ -2671,12 +2691,24 @@ int evergreen_irq_set(struct radeon_device *rdev)
        WREG32(DC_HPD5_INT_CONTROL, hpd5);
        WREG32(DC_HPD6_INT_CONTROL, hpd6);

+       for (i = 0; i < ARRAY_SIZE(eg_offsets) && i < rdev->num_crtc; i++)
+               WREG32(EVERGREEN_HDMI_BASE + eg_offsets[i] + 0xfc, hdmi[i]);
+
        return 0;
 }

 static void evergreen_irq_ack(struct radeon_device *rdev)
 {
+       u8 i;
        u32 tmp;
+       u16 eg_offsets[] = {
+               EVERGREEN_CRTC0_REGISTER_OFFSET,
+               EVERGREEN_CRTC1_REGISTER_OFFSET,
+               EVERGREEN_CRTC2_REGISTER_OFFSET,
+               EVERGREEN_CRTC3_REGISTER_OFFSET,
+               EVERGREEN_CRTC4_REGISTER_OFFSET,
+               EVERGREEN_CRTC5_REGISTER_OFFSET,
+       };

        rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS);
        rdev->irq.stat_regs.evergreen.disp_int_cont = 
RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
@@ -2768,6 +2800,15 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
                tmp |= DC_HPDx_INT_ACK;
                WREG32(DC_HPD6_INT_CONTROL, tmp);
        }
+
+       for (i = 0; i < ARRAY_SIZE(eg_offsets) && i < rdev->num_crtc; i++) {
+               tmp = RREG32(EVERGREEN_HDMI_BASE + eg_offsets[i] + 0xf8);
+               if (tmp & 0x20000000) {
+                       pr_info("zajec reg 0x%X is: 0x%X\n", 
EVERGREEN_HDMI_BASE + eg_offsets[i] + 0xf8, tmp);
+                       WREG32_P(EVERGREEN_HDMI_BASE + eg_offsets[i] + 0xfc, 
0x20000000, ~0x20000000);
+                       pr_info("zajec ACKed, now: 0x%X\n", 
RREG32(EVERGREEN_HDMI_BASE + eg_offsets[i] + 0xf8));
+               }
+       }
 }

 void evergreen_irq_disable(struct radeon_device *rdev)
@@ -3050,6 +3091,10 @@ restart_ih:
                                break;
                        }
                        break;
+               case 44: /* HDMI */
+                       pr_info("IH: HDMI: 0x%x\n", src_data);
+                       r600_audio_schedule_polling(rdev);
+                       break;
                case 176: /* CP_INT in ring buffer */
                case 177: /* CP_INT in IB1 */
                case 178: /* CP_INT in IB2 */
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c 
b/drivers/gpu/drm/radeon/r600_hdmi.c
index 0b59206..cd00853 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -507,6 +507,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
        uint32_t offset;

        if (ASIC_IS_DCE5(rdev))
@@ -548,7 +549,11 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
                }
        }

-       if (rdev->irq.installed
+       if (rdev->irq.installed && ASIC_IS_DCE4(rdev)) {
+               rdev->irq.hdmi[dig->dig_encoder] = true;
+               radeon_irq_set(rdev);
+               r600_audio_disable_polling(encoder);
+       } else if (rdev->irq.installed
            && rdev->family != CHIP_RS600
            && rdev->family != CHIP_RS690
            && rdev->family != CHIP_RS740
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index d98c55f..88e6d04 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -593,7 +593,7 @@ union radeon_irq_stat_regs {

 #define RADEON_MAX_HPD_PINS 6
 #define RADEON_MAX_CRTCS 6
-#define RADEON_MAX_HDMI_BLOCKS 2
+#define RADEON_MAX_HDMI_BLOCKS 6

 struct radeon_irq {
        bool            installed;
-- 
1.7.7

Reply via email to