summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/vc4/vc4_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_irq.c')
-rw-r--r--drivers/gpu/drm/vc4/vc4_irq.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index 20fa8e34c20b..63e88f90eef7 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -48,16 +48,16 @@
#include <linux/platform_device.h>
#include <drm/drm_drv.h>
+#include <drm/drm_print.h>
#include "vc4_drv.h"
#include "vc4_regs.h"
+#include "vc4_trace.h"
#define V3D_DRIVER_IRQS (V3D_INT_OUTOMEM | \
V3D_INT_FLDONE | \
V3D_INT_FRDONE)
-DECLARE_WAIT_QUEUE_HEAD(render_wait);
-
static void
vc4_overflow_mem_work(struct work_struct *work)
{
@@ -77,7 +77,7 @@ vc4_overflow_mem_work(struct work_struct *work)
bin_bo_slot = vc4_v3d_get_bin_slot(vc4);
if (bin_bo_slot < 0) {
- DRM_ERROR("Couldn't allocate binner overflow mem\n");
+ drm_err(&vc4->base, "Couldn't allocate binner overflow mem\n");
goto complete;
}
@@ -104,7 +104,7 @@ vc4_overflow_mem_work(struct work_struct *work)
}
vc4->bin_alloc_overflow = BIT(bin_bo_slot);
- V3D_WRITE(V3D_BPOA, bo->base.paddr + bin_bo_slot * vc4->bin_alloc_size);
+ V3D_WRITE(V3D_BPOA, bo->base.dma_addr + bin_bo_slot * vc4->bin_alloc_size);
V3D_WRITE(V3D_BPOS, bo->base.base.size);
V3D_WRITE(V3D_INTCTL, V3D_INT_OUTOMEM);
V3D_WRITE(V3D_INTENA, V3D_INT_OUTOMEM);
@@ -123,6 +123,8 @@ vc4_irq_finish_bin_job(struct drm_device *dev)
if (!exec)
return;
+ trace_vc4_bcl_end_irq(dev, exec->seqno);
+
vc4_move_job_to_render(dev, exec);
next = vc4_first_bin_job(vc4);
@@ -161,6 +163,8 @@ vc4_irq_finish_render_job(struct drm_device *dev)
if (!exec)
return;
+ trace_vc4_rcl_end_irq(dev, exec->seqno);
+
vc4->finished_seqno++;
list_move_tail(&exec->head, &vc4->job_done_list);
@@ -260,6 +264,9 @@ vc4_irq_enable(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
+ return;
+
if (!vc4->v3d)
return;
@@ -274,6 +281,9 @@ vc4_irq_disable(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
+ return;
+
if (!vc4->v3d)
return;
@@ -284,15 +294,19 @@ vc4_irq_disable(struct drm_device *dev)
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
/* Finish any interrupt handler still in flight. */
- disable_irq(vc4->irq);
+ synchronize_irq(vc4->irq);
cancel_work_sync(&vc4->overflow_mem_work);
}
int vc4_irq_install(struct drm_device *dev, int irq)
{
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
int ret;
+ if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
+ return -ENODEV;
+
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
@@ -311,6 +325,9 @@ void vc4_irq_uninstall(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
+ return;
+
vc4_irq_disable(dev);
free_irq(vc4->irq, dev);
}
@@ -321,6 +338,9 @@ void vc4_irq_reset(struct drm_device *dev)
struct vc4_dev *vc4 = to_vc4_dev(dev);
unsigned long irqflags;
+ if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
+ return;
+
/* Acknowledge any stale IRQs. */
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);