Commit 47f2467f authored by Dave Airlie's avatar Dave Airlie Committed by Alex Deucher

radeon/si: add support for short HPD irqs

This adds support to process short HPD irqs on SI gpus.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2bc67b4d
...@@ -6085,12 +6085,12 @@ int si_irq_set(struct radeon_device *rdev) ...@@ -6085,12 +6085,12 @@ int si_irq_set(struct radeon_device *rdev)
(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
if (!ASIC_IS_NODCE(rdev)) { if (!ASIC_IS_NODCE(rdev)) {
hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
} }
dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
...@@ -6153,27 +6153,27 @@ int si_irq_set(struct radeon_device *rdev) ...@@ -6153,27 +6153,27 @@ int si_irq_set(struct radeon_device *rdev)
} }
if (rdev->irq.hpd[0]) { if (rdev->irq.hpd[0]) {
DRM_DEBUG("si_irq_set: hpd 1\n"); DRM_DEBUG("si_irq_set: hpd 1\n");
hpd1 |= DC_HPDx_INT_EN; hpd1 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
} }
if (rdev->irq.hpd[1]) { if (rdev->irq.hpd[1]) {
DRM_DEBUG("si_irq_set: hpd 2\n"); DRM_DEBUG("si_irq_set: hpd 2\n");
hpd2 |= DC_HPDx_INT_EN; hpd2 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
} }
if (rdev->irq.hpd[2]) { if (rdev->irq.hpd[2]) {
DRM_DEBUG("si_irq_set: hpd 3\n"); DRM_DEBUG("si_irq_set: hpd 3\n");
hpd3 |= DC_HPDx_INT_EN; hpd3 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
} }
if (rdev->irq.hpd[3]) { if (rdev->irq.hpd[3]) {
DRM_DEBUG("si_irq_set: hpd 4\n"); DRM_DEBUG("si_irq_set: hpd 4\n");
hpd4 |= DC_HPDx_INT_EN; hpd4 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
} }
if (rdev->irq.hpd[4]) { if (rdev->irq.hpd[4]) {
DRM_DEBUG("si_irq_set: hpd 5\n"); DRM_DEBUG("si_irq_set: hpd 5\n");
hpd5 |= DC_HPDx_INT_EN; hpd5 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
} }
if (rdev->irq.hpd[5]) { if (rdev->irq.hpd[5]) {
DRM_DEBUG("si_irq_set: hpd 6\n"); DRM_DEBUG("si_irq_set: hpd 6\n");
hpd6 |= DC_HPDx_INT_EN; hpd6 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
} }
WREG32(CP_INT_CNTL_RING0, cp_int_cntl); WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
...@@ -6336,6 +6336,37 @@ static inline void si_irq_ack(struct radeon_device *rdev) ...@@ -6336,6 +6336,37 @@ static inline void si_irq_ack(struct radeon_device *rdev)
tmp |= DC_HPDx_INT_ACK; tmp |= DC_HPDx_INT_ACK;
WREG32(DC_HPD6_INT_CONTROL, tmp); WREG32(DC_HPD6_INT_CONTROL, tmp);
} }
if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) {
tmp = RREG32(DC_HPD1_INT_CONTROL);
tmp |= DC_HPDx_RX_INT_ACK;
WREG32(DC_HPD1_INT_CONTROL, tmp);
}
if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) {
tmp = RREG32(DC_HPD2_INT_CONTROL);
tmp |= DC_HPDx_RX_INT_ACK;
WREG32(DC_HPD2_INT_CONTROL, tmp);
}
if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) {
tmp = RREG32(DC_HPD3_INT_CONTROL);
tmp |= DC_HPDx_RX_INT_ACK;
WREG32(DC_HPD3_INT_CONTROL, tmp);
}
if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) {
tmp = RREG32(DC_HPD4_INT_CONTROL);
tmp |= DC_HPDx_RX_INT_ACK;
WREG32(DC_HPD4_INT_CONTROL, tmp);
}
if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) {
tmp = RREG32(DC_HPD5_INT_CONTROL);
tmp |= DC_HPDx_RX_INT_ACK;
WREG32(DC_HPD5_INT_CONTROL, tmp);
}
if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) {
tmp = RREG32(DC_HPD5_INT_CONTROL);
tmp |= DC_HPDx_RX_INT_ACK;
WREG32(DC_HPD6_INT_CONTROL, tmp);
}
} }
static void si_irq_disable(struct radeon_device *rdev) static void si_irq_disable(struct radeon_device *rdev)
...@@ -6401,6 +6432,7 @@ int si_irq_process(struct radeon_device *rdev) ...@@ -6401,6 +6432,7 @@ int si_irq_process(struct radeon_device *rdev)
u32 src_id, src_data, ring_id; u32 src_id, src_data, ring_id;
u32 ring_index; u32 ring_index;
bool queue_hotplug = false; bool queue_hotplug = false;
bool queue_dp = false;
bool queue_thermal = false; bool queue_thermal = false;
u32 status, addr; u32 status, addr;
...@@ -6641,6 +6673,48 @@ int si_irq_process(struct radeon_device *rdev) ...@@ -6641,6 +6673,48 @@ int si_irq_process(struct radeon_device *rdev)
DRM_DEBUG("IH: HPD6\n"); DRM_DEBUG("IH: HPD6\n");
} }
break; break;
case 6:
if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) {
rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT;
queue_dp = true;
DRM_DEBUG("IH: HPD_RX 1\n");
}
break;
case 7:
if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) {
rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
queue_dp = true;
DRM_DEBUG("IH: HPD_RX 2\n");
}
break;
case 8:
if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) {
rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
queue_dp = true;
DRM_DEBUG("IH: HPD_RX 3\n");
}
break;
case 9:
if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) {
rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
queue_dp = true;
DRM_DEBUG("IH: HPD_RX 4\n");
}
break;
case 10:
if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) {
rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
queue_dp = true;
DRM_DEBUG("IH: HPD_RX 5\n");
}
break;
case 11:
if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) {
rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
queue_dp = true;
DRM_DEBUG("IH: HPD_RX 6\n");
}
break;
default: default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
break; break;
...@@ -6723,6 +6797,8 @@ int si_irq_process(struct radeon_device *rdev) ...@@ -6723,6 +6797,8 @@ int si_irq_process(struct radeon_device *rdev)
rptr &= rdev->ih.ptr_mask; rptr &= rdev->ih.ptr_mask;
WREG32(IH_RB_RPTR, rptr); WREG32(IH_RB_RPTR, rptr);
} }
if (queue_dp)
schedule_work(&rdev->dp_work);
if (queue_hotplug) if (queue_hotplug)
schedule_work(&rdev->hotplug_work); schedule_work(&rdev->hotplug_work);
if (queue_thermal && rdev->pm.dpm_enabled) if (queue_thermal && rdev->pm.dpm_enabled)
......
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