diff options
author | Dave Airlie <airlied@redhat.com> | 2015-02-23 18:23:58 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-03-19 12:26:47 -0400 |
commit | 47f2467fffc4e1a070b141bc9d1319dc2c0acea5 (patch) | |
tree | 51d3b0c26ef8e3403db16ad05e452bbc5573c90e | |
parent | 2bc67b4d9e9f2c8d13782387bbdbb6e1b5e12d30 (diff) |
radeon/si: add support for short HPD irqs
This adds support to process short HPD irqs on SI gpus.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 100 |
1 files changed, 88 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 0d2295fd2844..86e75798320f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -6085,12 +6085,12 @@ int si_irq_set(struct radeon_device *rdev) | |||
6085 | (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | 6085 | (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
6086 | 6086 | ||
6087 | if (!ASIC_IS_NODCE(rdev)) { | 6087 | if (!ASIC_IS_NODCE(rdev)) { |
6088 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; | 6088 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); |
6089 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; | 6089 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); |
6090 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; | 6090 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); |
6091 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; | 6091 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); |
6092 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | 6092 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); |
6093 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | 6093 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); |
6094 | } | 6094 | } |
6095 | 6095 | ||
6096 | dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; | 6096 | dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; |
@@ -6153,27 +6153,27 @@ int si_irq_set(struct radeon_device *rdev) | |||
6153 | } | 6153 | } |
6154 | if (rdev->irq.hpd[0]) { | 6154 | if (rdev->irq.hpd[0]) { |
6155 | DRM_DEBUG("si_irq_set: hpd 1\n"); | 6155 | DRM_DEBUG("si_irq_set: hpd 1\n"); |
6156 | hpd1 |= DC_HPDx_INT_EN; | 6156 | hpd1 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; |
6157 | } | 6157 | } |
6158 | if (rdev->irq.hpd[1]) { | 6158 | if (rdev->irq.hpd[1]) { |
6159 | DRM_DEBUG("si_irq_set: hpd 2\n"); | 6159 | DRM_DEBUG("si_irq_set: hpd 2\n"); |
6160 | hpd2 |= DC_HPDx_INT_EN; | 6160 | hpd2 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; |
6161 | } | 6161 | } |
6162 | if (rdev->irq.hpd[2]) { | 6162 | if (rdev->irq.hpd[2]) { |
6163 | DRM_DEBUG("si_irq_set: hpd 3\n"); | 6163 | DRM_DEBUG("si_irq_set: hpd 3\n"); |
6164 | hpd3 |= DC_HPDx_INT_EN; | 6164 | hpd3 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; |
6165 | } | 6165 | } |
6166 | if (rdev->irq.hpd[3]) { | 6166 | if (rdev->irq.hpd[3]) { |
6167 | DRM_DEBUG("si_irq_set: hpd 4\n"); | 6167 | DRM_DEBUG("si_irq_set: hpd 4\n"); |
6168 | hpd4 |= DC_HPDx_INT_EN; | 6168 | hpd4 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; |
6169 | } | 6169 | } |
6170 | if (rdev->irq.hpd[4]) { | 6170 | if (rdev->irq.hpd[4]) { |
6171 | DRM_DEBUG("si_irq_set: hpd 5\n"); | 6171 | DRM_DEBUG("si_irq_set: hpd 5\n"); |
6172 | hpd5 |= DC_HPDx_INT_EN; | 6172 | hpd5 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; |
6173 | } | 6173 | } |
6174 | if (rdev->irq.hpd[5]) { | 6174 | if (rdev->irq.hpd[5]) { |
6175 | DRM_DEBUG("si_irq_set: hpd 6\n"); | 6175 | DRM_DEBUG("si_irq_set: hpd 6\n"); |
6176 | hpd6 |= DC_HPDx_INT_EN; | 6176 | hpd6 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; |
6177 | } | 6177 | } |
6178 | 6178 | ||
6179 | WREG32(CP_INT_CNTL_RING0, cp_int_cntl); | 6179 | WREG32(CP_INT_CNTL_RING0, cp_int_cntl); |
@@ -6336,6 +6336,37 @@ static inline void si_irq_ack(struct radeon_device *rdev) | |||
6336 | tmp |= DC_HPDx_INT_ACK; | 6336 | tmp |= DC_HPDx_INT_ACK; |
6337 | WREG32(DC_HPD6_INT_CONTROL, tmp); | 6337 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
6338 | } | 6338 | } |
6339 | |||
6340 | if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) { | ||
6341 | tmp = RREG32(DC_HPD1_INT_CONTROL); | ||
6342 | tmp |= DC_HPDx_RX_INT_ACK; | ||
6343 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
6344 | } | ||
6345 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) { | ||
6346 | tmp = RREG32(DC_HPD2_INT_CONTROL); | ||
6347 | tmp |= DC_HPDx_RX_INT_ACK; | ||
6348 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
6349 | } | ||
6350 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) { | ||
6351 | tmp = RREG32(DC_HPD3_INT_CONTROL); | ||
6352 | tmp |= DC_HPDx_RX_INT_ACK; | ||
6353 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
6354 | } | ||
6355 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) { | ||
6356 | tmp = RREG32(DC_HPD4_INT_CONTROL); | ||
6357 | tmp |= DC_HPDx_RX_INT_ACK; | ||
6358 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
6359 | } | ||
6360 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) { | ||
6361 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
6362 | tmp |= DC_HPDx_RX_INT_ACK; | ||
6363 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
6364 | } | ||
6365 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { | ||
6366 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
6367 | tmp |= DC_HPDx_RX_INT_ACK; | ||
6368 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
6369 | } | ||
6339 | } | 6370 | } |
6340 | 6371 | ||
6341 | static void si_irq_disable(struct radeon_device *rdev) | 6372 | static void si_irq_disable(struct radeon_device *rdev) |
@@ -6401,6 +6432,7 @@ int si_irq_process(struct radeon_device *rdev) | |||
6401 | u32 src_id, src_data, ring_id; | 6432 | u32 src_id, src_data, ring_id; |
6402 | u32 ring_index; | 6433 | u32 ring_index; |
6403 | bool queue_hotplug = false; | 6434 | bool queue_hotplug = false; |
6435 | bool queue_dp = false; | ||
6404 | bool queue_thermal = false; | 6436 | bool queue_thermal = false; |
6405 | u32 status, addr; | 6437 | u32 status, addr; |
6406 | 6438 | ||
@@ -6641,6 +6673,48 @@ restart_ih: | |||
6641 | DRM_DEBUG("IH: HPD6\n"); | 6673 | DRM_DEBUG("IH: HPD6\n"); |
6642 | } | 6674 | } |
6643 | break; | 6675 | break; |
6676 | case 6: | ||
6677 | if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) { | ||
6678 | rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT; | ||
6679 | queue_dp = true; | ||
6680 | DRM_DEBUG("IH: HPD_RX 1\n"); | ||
6681 | } | ||
6682 | break; | ||
6683 | case 7: | ||
6684 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) { | ||
6685 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; | ||
6686 | queue_dp = true; | ||
6687 | DRM_DEBUG("IH: HPD_RX 2\n"); | ||
6688 | } | ||
6689 | break; | ||
6690 | case 8: | ||
6691 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) { | ||
6692 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; | ||
6693 | queue_dp = true; | ||
6694 | DRM_DEBUG("IH: HPD_RX 3\n"); | ||
6695 | } | ||
6696 | break; | ||
6697 | case 9: | ||
6698 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) { | ||
6699 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; | ||
6700 | queue_dp = true; | ||
6701 | DRM_DEBUG("IH: HPD_RX 4\n"); | ||
6702 | } | ||
6703 | break; | ||
6704 | case 10: | ||
6705 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) { | ||
6706 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; | ||
6707 | queue_dp = true; | ||
6708 | DRM_DEBUG("IH: HPD_RX 5\n"); | ||
6709 | } | ||
6710 | break; | ||
6711 | case 11: | ||
6712 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { | ||
6713 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; | ||
6714 | queue_dp = true; | ||
6715 | DRM_DEBUG("IH: HPD_RX 6\n"); | ||
6716 | } | ||
6717 | break; | ||
6644 | default: | 6718 | default: |
6645 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | 6719 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
6646 | break; | 6720 | break; |
@@ -6723,6 +6797,8 @@ restart_ih: | |||
6723 | rptr &= rdev->ih.ptr_mask; | 6797 | rptr &= rdev->ih.ptr_mask; |
6724 | WREG32(IH_RB_RPTR, rptr); | 6798 | WREG32(IH_RB_RPTR, rptr); |
6725 | } | 6799 | } |
6800 | if (queue_dp) | ||
6801 | schedule_work(&rdev->dp_work); | ||
6726 | if (queue_hotplug) | 6802 | if (queue_hotplug) |
6727 | schedule_work(&rdev->hotplug_work); | 6803 | schedule_work(&rdev->hotplug_work); |
6728 | if (queue_thermal && rdev->pm.dpm_enabled) | 6804 | if (queue_thermal && rdev->pm.dpm_enabled) |