mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-27 03:49:57 -04:00
drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2
Let's start to support multiple rings. v2: decode IV is needed as well Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
73c97fa442
commit
8bb9eb480d
@@ -193,14 +193,15 @@ static void tonga_ih_irq_disable(struct amdgpu_device *adev)
|
||||
* Used by cz_irq_process(VI).
|
||||
* Returns the value of the wptr.
|
||||
*/
|
||||
static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
|
||||
static u32 tonga_ih_get_wptr(struct amdgpu_device *adev,
|
||||
struct amdgpu_ih_ring *ih)
|
||||
{
|
||||
u32 wptr, tmp;
|
||||
|
||||
if (adev->irq.ih.use_bus_addr)
|
||||
wptr = le32_to_cpu(adev->irq.ih.ring[adev->irq.ih.wptr_offs]);
|
||||
wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
|
||||
else
|
||||
wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
|
||||
wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
|
||||
|
||||
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
|
||||
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
||||
@@ -209,13 +210,13 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
|
||||
* this should allow us to catchup.
|
||||
*/
|
||||
dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
|
||||
wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
|
||||
adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
|
||||
wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
|
||||
ih->rptr = (wptr + 16) & ih->ptr_mask;
|
||||
tmp = RREG32(mmIH_RB_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32(mmIH_RB_CNTL, tmp);
|
||||
}
|
||||
return (wptr & adev->irq.ih.ptr_mask);
|
||||
return (wptr & ih->ptr_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,16 +228,17 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
|
||||
* position and also advance the position.
|
||||
*/
|
||||
static void tonga_ih_decode_iv(struct amdgpu_device *adev,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
struct amdgpu_ih_ring *ih,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
/* wptr/rptr are in bytes! */
|
||||
u32 ring_index = adev->irq.ih.rptr >> 2;
|
||||
u32 ring_index = ih->rptr >> 2;
|
||||
uint32_t dw[4];
|
||||
|
||||
dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
|
||||
dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
|
||||
dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
|
||||
dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
|
||||
dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
|
||||
dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
|
||||
dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
|
||||
dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
|
||||
|
||||
entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
|
||||
entry->src_id = dw[0] & 0xff;
|
||||
@@ -246,7 +248,7 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
|
||||
entry->pasid = (dw[2] >> 16) & 0xffff;
|
||||
|
||||
/* wptr/rptr are in bytes! */
|
||||
adev->irq.ih.rptr += 16;
|
||||
ih->rptr += 16;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,17 +258,18 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
|
||||
*
|
||||
* Set the IH ring buffer rptr.
|
||||
*/
|
||||
static void tonga_ih_set_rptr(struct amdgpu_device *adev)
|
||||
static void tonga_ih_set_rptr(struct amdgpu_device *adev,
|
||||
struct amdgpu_ih_ring *ih)
|
||||
{
|
||||
if (adev->irq.ih.use_doorbell) {
|
||||
if (ih->use_doorbell) {
|
||||
/* XXX check if swapping is necessary on BE */
|
||||
if (adev->irq.ih.use_bus_addr)
|
||||
adev->irq.ih.ring[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
|
||||
if (ih->use_bus_addr)
|
||||
ih->ring[ih->rptr_offs] = ih->rptr;
|
||||
else
|
||||
adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
|
||||
WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr);
|
||||
adev->wb.wb[ih->rptr_offs] = ih->rptr;
|
||||
WDOORBELL32(ih->doorbell_index, ih->rptr);
|
||||
} else {
|
||||
WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
|
||||
WREG32(mmIH_RB_RPTR, ih->rptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user