From 26f32a377eeddc5af24821b1ef3a3a8de7a80211 Mon Sep 17 00:00:00 2001 From: Christian König Date: Sat, 31 Oct 2020 18:38:15 +0100 Subject: drm/amdgpu: add infrastructure for soft IH ring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a soft IH ring implementation similar to the hardware IH1/2. This can be used if the hardware delegation of interrupts to IH1/2 doesn't work for some reason. Signed-off-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 300ac73b4738..bea57e8e793f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -206,6 +206,21 @@ static void amdgpu_irq_handle_ih2(struct work_struct *work) amdgpu_ih_process(adev, &adev->irq.ih2); } +/** + * amdgpu_irq_handle_ih_soft - kick of processing for ih_soft + * + * @work: work structure in struct amdgpu_irq + * + * Kick of processing IH soft ring. + */ +static void amdgpu_irq_handle_ih_soft(struct work_struct *work) +{ + struct amdgpu_device *adev = container_of(work, struct amdgpu_device, + irq.ih_soft_work); + + amdgpu_ih_process(adev, &adev->irq.ih_soft); +} + /** * amdgpu_msi_ok - check whether MSI functionality is enabled * @@ -281,6 +296,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev) INIT_WORK(&adev->irq.ih1_work, amdgpu_irq_handle_ih1); INIT_WORK(&adev->irq.ih2_work, amdgpu_irq_handle_ih2); + INIT_WORK(&adev->irq.ih_soft_work, amdgpu_irq_handle_ih_soft); adev->irq.installed = true; /* Use vector 0 for MSI-X */ @@ -413,6 +429,7 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, bool handled = false; int r; + entry.ih = ih; entry.iv_entry = (const uint32_t *)&ih->ring[ring_index]; amdgpu_ih_decode_iv(adev, &entry); @@ -450,6 +467,24 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, amdgpu_amdkfd_interrupt(adev, entry.iv_entry); } +/** + * amdgpu_irq_delegate - delegate IV to soft IH ring + * + * @adev: amdgpu device pointer + * @entry: IV entry + * @num_dw: size of IV + * + * Delegate the IV to the soft IH ring and schedule processing of it. Used + * if the hardware delegation to IH1 or IH2 doesn't work for some reason. + */ +void amdgpu_irq_delegate(struct amdgpu_device *adev, + struct amdgpu_iv_entry *entry, + unsigned int num_dw) +{ + amdgpu_ih_ring_write(&adev->irq.ih_soft, entry->iv_entry, num_dw); + schedule_work(&adev->irq.ih_soft_work); +} + /** * amdgpu_irq_update - update hardware interrupt state * -- cgit v1.2.3-70-g09d2