Commit 5cc4e5fc authored by Lyude's avatar Lyude Committed by Alex Deucher

drm/radeon: Cleanup HDMI audio interrupt handling for evergreen

Same as the previous patch, but now for handling HDMI audio interrupts.

Changes since v1:
- Preserve the order we write back all registers
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarLyude <lyude@redhat.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4cd096dd
...@@ -4495,7 +4495,6 @@ int evergreen_irq_set(struct radeon_device *rdev) ...@@ -4495,7 +4495,6 @@ int evergreen_irq_set(struct radeon_device *rdev)
u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
u32 grbm_int_cntl = 0; u32 grbm_int_cntl = 0;
u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0;
u32 dma_cntl, dma_cntl1 = 0; u32 dma_cntl, dma_cntl1 = 0;
u32 thermal_int = 0; u32 thermal_int = 0;
...@@ -4518,13 +4517,6 @@ int evergreen_irq_set(struct radeon_device *rdev) ...@@ -4518,13 +4517,6 @@ int evergreen_irq_set(struct radeon_device *rdev)
thermal_int = RREG32(CG_THERMAL_INT) & thermal_int = RREG32(CG_THERMAL_INT) &
~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
afmt1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
afmt2 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
afmt3 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
afmt4 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
afmt5 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
afmt6 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE; dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
if (rdev->family >= CHIP_CAYMAN) { if (rdev->family >= CHIP_CAYMAN) {
...@@ -4567,31 +4559,6 @@ int evergreen_irq_set(struct radeon_device *rdev) ...@@ -4567,31 +4559,6 @@ int evergreen_irq_set(struct radeon_device *rdev)
thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
} }
if (rdev->irq.afmt[0]) {
DRM_DEBUG("evergreen_irq_set: hdmi 0\n");
afmt1 |= AFMT_AZ_FORMAT_WTRIG_MASK;
}
if (rdev->irq.afmt[1]) {
DRM_DEBUG("evergreen_irq_set: hdmi 1\n");
afmt2 |= AFMT_AZ_FORMAT_WTRIG_MASK;
}
if (rdev->irq.afmt[2]) {
DRM_DEBUG("evergreen_irq_set: hdmi 2\n");
afmt3 |= AFMT_AZ_FORMAT_WTRIG_MASK;
}
if (rdev->irq.afmt[3]) {
DRM_DEBUG("evergreen_irq_set: hdmi 3\n");
afmt4 |= AFMT_AZ_FORMAT_WTRIG_MASK;
}
if (rdev->irq.afmt[4]) {
DRM_DEBUG("evergreen_irq_set: hdmi 4\n");
afmt5 |= AFMT_AZ_FORMAT_WTRIG_MASK;
}
if (rdev->irq.afmt[5]) {
DRM_DEBUG("evergreen_irq_set: hdmi 5\n");
afmt6 |= AFMT_AZ_FORMAT_WTRIG_MASK;
}
if (rdev->family >= CHIP_CAYMAN) { if (rdev->family >= CHIP_CAYMAN) {
cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl); cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl);
cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1); cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1);
...@@ -4643,12 +4610,12 @@ int evergreen_irq_set(struct radeon_device *rdev) ...@@ -4643,12 +4610,12 @@ int evergreen_irq_set(struct radeon_device *rdev)
else else
WREG32(CG_THERMAL_INT, thermal_int); WREG32(CG_THERMAL_INT, thermal_int);
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, afmt1); for (i = 0; i < 6; i++) {
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, afmt2); radeon_irq_kms_set_irq_n_enabled(
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, afmt3); rdev, AFMT_AUDIO_PACKET_CONTROL + crtc_offsets[i],
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, afmt4); AFMT_AZ_FORMAT_WTRIG_MASK,
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, afmt5); rdev->irq.afmt[i], "HDMI", i);
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, afmt6); }
/* posting read */ /* posting read */
RREG32(SRBM_STATUS); RREG32(SRBM_STATUS);
...@@ -4661,10 +4628,12 @@ static void evergreen_irq_ack(struct radeon_device *rdev) ...@@ -4661,10 +4628,12 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
{ {
int i; int i;
u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int; u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
u32 tmp; u32 *afmt_status = rdev->irq.stat_regs.evergreen.afmt_status;
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++) {
disp_int[i] = RREG32(evergreen_disp_int_status[i]); disp_int[i] = RREG32(evergreen_disp_int_status[i]);
afmt_status[i] = RREG32(AFMT_STATUS + crtc_offsets[i]);
}
rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
...@@ -4677,12 +4646,6 @@ static void evergreen_irq_ack(struct radeon_device *rdev) ...@@ -4677,12 +4646,6 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
} }
rdev->irq.stat_regs.evergreen.afmt_status1 = RREG32(AFMT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
rdev->irq.stat_regs.evergreen.afmt_status2 = RREG32(AFMT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
rdev->irq.stat_regs.evergreen.afmt_status3 = RREG32(AFMT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
rdev->irq.stat_regs.evergreen.afmt_status4 = RREG32(AFMT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
rdev->irq.stat_regs.evergreen.afmt_status5 = RREG32(AFMT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
rdev->irq.stat_regs.evergreen.afmt_status6 = RREG32(AFMT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
...@@ -4737,35 +4700,10 @@ static void evergreen_irq_ack(struct radeon_device *rdev) ...@@ -4737,35 +4700,10 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK); WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK);
} }
if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) { for (i = 0; i < 6; i++) {
tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); if (afmt_status[i] & AFMT_AZ_FORMAT_WTRIG)
tmp |= AFMT_AZ_FORMAT_WTRIG_ACK; WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + crtc_offsets[i],
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, tmp); AFMT_AZ_FORMAT_WTRIG_ACK);
}
if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) {
tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, tmp);
}
if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) {
tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, tmp);
}
if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) {
tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, tmp);
}
if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) {
tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, tmp);
}
if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) {
tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, tmp);
} }
} }
...@@ -4812,7 +4750,8 @@ static u32 evergreen_get_ih_wptr(struct radeon_device *rdev) ...@@ -4812,7 +4750,8 @@ static u32 evergreen_get_ih_wptr(struct radeon_device *rdev)
int evergreen_irq_process(struct radeon_device *rdev) int evergreen_irq_process(struct radeon_device *rdev)
{ {
u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int; u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
u32 crtc_idx, hpd_idx; u32 *afmt_status = rdev->irq.stat_regs.evergreen.afmt_status;
u32 crtc_idx, hpd_idx, afmt_idx;
u32 mask; u32 mask;
u32 wptr; u32 wptr;
u32 rptr; u32 rptr;
...@@ -4928,59 +4867,19 @@ int evergreen_irq_process(struct radeon_device *rdev) ...@@ -4928,59 +4867,19 @@ int evergreen_irq_process(struct radeon_device *rdev)
break; break;
case 44: /* hdmi */ case 44: /* hdmi */
switch (src_data) { afmt_idx = src_data;
case 0: if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG))
if (!(rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG))
DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG;
queue_hdmi = true;
DRM_DEBUG("IH: HDMI0\n");
break;
case 1:
if (!(rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG))
DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG;
queue_hdmi = true;
DRM_DEBUG("IH: HDMI1\n");
break;
case 2:
if (!(rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG))
DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG;
queue_hdmi = true;
DRM_DEBUG("IH: HDMI2\n");
break;
case 3:
if (!(rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG))
DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG;
queue_hdmi = true;
DRM_DEBUG("IH: HDMI3\n");
break;
case 4:
if (!(rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG))
DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG; if (afmt_idx > 5) {
queue_hdmi = true; DRM_ERROR("Unhandled interrupt: %d %d\n",
DRM_DEBUG("IH: HDMI4\n"); src_id, src_data);
break; break;
case 5: }
if (!(rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG)) afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG;
DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG;
queue_hdmi = true; queue_hdmi = true;
DRM_DEBUG("IH: HDMI5\n"); DRM_DEBUG("IH: HDMI%d\n", afmt_idx + 1);
break; break;
default:
DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
break;
}
case 96: case 96:
DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR)); DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR));
WREG32(SRBM_INT_ACK, 0x1); WREG32(SRBM_INT_ACK, 0x1);
......
...@@ -778,12 +778,7 @@ struct evergreen_irq_stat_regs { ...@@ -778,12 +778,7 @@ struct evergreen_irq_stat_regs {
u32 d4grph_int; u32 d4grph_int;
u32 d5grph_int; u32 d5grph_int;
u32 d6grph_int; u32 d6grph_int;
u32 afmt_status1; u32 afmt_status[6];
u32 afmt_status2;
u32 afmt_status3;
u32 afmt_status4;
u32 afmt_status5;
u32 afmt_status6;
}; };
struct cik_irq_stat_regs { struct cik_irq_stat_regs {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment