summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/v3d/v3d_irq.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2019-03-25 13:05:11 +0300
committerDaniel Vetter <daniel.vetter@ffwll.ch>2019-03-25 13:05:12 +0300
commit0bec6219e5a0cf2dd17716949a7592807e10f3d7 (patch)
tree3eabbc70c5d9c053fbdc269bc09bf622b6ad1400 /drivers/gpu/drm/v3d/v3d_irq.c
parent535f6f5d7b7f7b3127c1c8172ff0504260d14f45 (diff)
parentff01e6971ecd9ba6a9c0538c46d713f38a751f11 (diff)
downloadlinux-0bec6219e5a0cf2dd17716949a7592807e10f3d7.tar.xz
Merge tag 'drm-misc-next-2019-03-21' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.2: UAPI Changes: - Add Colorspace connector property (Uma) - fourcc: Several new YUV formats from ARM (Brian & Ayan) - fourcc: Fix merge conflicts between new formats above and Swati's that went in via topic/hdr-formats-2019-03-07 branch (Maarten) Cross-subsystem Changes: - Typed component support via topic/component-typed-2019-02-11 (Maxime/Daniel) Core Changes: - Improve component helper documentation (Daniel) - Avoid calling drm_dev_unregister() twice on unplugged devices (Noralf) - Add device managed (devm) drm_device init function (Noralf) - Graduate TINYDRM_MODE to DRM_SIMPLE_MODE in core (Noralf) - Move MIPI/DSI rate control params computation into core from i915 (David) - Add support for shmem backed gem objects (Noralf) Driver Changes: - various: Use of_node_name_eq for node name comparisons (Rob Herring) - sun4i: Add DSI burst mode support (Konstantin) - panel: Add Ronbo RB070D30 MIPI/DSI panel support (Konstantin) - virtio: A few prime improvements (Gerd) - tinydrm: Remove tinydrm_device (Noralf) - vc4: Add load tracker to driver to detect underflow in atomic check (Boris) - vboxvideo: Move it out of staging \o/ (Hans) - v3d: Add support for V3D v4.2 (Eric) Cc: Konstantin Sudakov <k.sudakov@integrasources.com> Cc: Rob Herring <robh@kernel.org> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Maxime Ripard <maxime.ripard@bootlin.com> Cc: Uma Shankar <uma.shankar@intel.com> Cc: Noralf Trønnes <noralf@tronnes.org> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: David Francis <David.Francis@amd.com> Cc: Boris Brezillon <boris.brezillon@bootlin.com> Cc: Eric Anholt <eric@anholt.net> Cc: Hans de Goede <hdegoede@redhat.com> Cc: Brian Starkey <brian.starkey@arm.com> Cc: Ayan Kumar Halder <ayan.halder@arm.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Sean Paul <sean@poorly.run> Link: https://patchwork.freedesktop.org/patch/msgid/20190321170805.GA50145@art_vandelay
Diffstat (limited to 'drivers/gpu/drm/v3d/v3d_irq.c')
-rw-r--r--drivers/gpu/drm/v3d/v3d_irq.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
index 69338da70ddc..b4d6ae81186d 100644
--- a/drivers/gpu/drm/v3d/v3d_irq.c
+++ b/drivers/gpu/drm/v3d/v3d_irq.c
@@ -27,6 +27,9 @@
V3D_HUB_INT_MMU_CAP | \
V3D_HUB_INT_TFUC))
+static irqreturn_t
+v3d_hub_irq(int irq, void *arg);
+
static void
v3d_overflow_mem_work(struct work_struct *work)
{
@@ -34,12 +37,14 @@ v3d_overflow_mem_work(struct work_struct *work)
container_of(work, struct v3d_dev, overflow_mem_work);
struct drm_device *dev = &v3d->drm;
struct v3d_bo *bo = v3d_bo_create(dev, NULL /* XXX: GMP */, 256 * 1024);
+ struct drm_gem_object *obj;
unsigned long irqflags;
if (IS_ERR(bo)) {
DRM_ERROR("Couldn't allocate binner overflow mem\n");
return;
}
+ obj = &bo->base.base;
/* We lost a race, and our work task came in after the bin job
* completed and exited. This can happen because the HW
@@ -56,15 +61,15 @@ v3d_overflow_mem_work(struct work_struct *work)
goto out;
}
- drm_gem_object_get(&bo->base);
+ drm_gem_object_get(obj);
list_add_tail(&bo->unref_head, &v3d->bin_job->unref_list);
spin_unlock_irqrestore(&v3d->job_lock, irqflags);
V3D_CORE_WRITE(0, V3D_PTB_BPOA, bo->node.start << PAGE_SHIFT);
- V3D_CORE_WRITE(0, V3D_PTB_BPOS, bo->base.size);
+ V3D_CORE_WRITE(0, V3D_PTB_BPOS, obj->size);
out:
- drm_gem_object_put_unlocked(&bo->base);
+ drm_gem_object_put_unlocked(obj);
}
static irqreturn_t
@@ -112,6 +117,12 @@ v3d_irq(int irq, void *arg)
if (intsts & V3D_INT_GMPV)
dev_err(v3d->dev, "GMP violation\n");
+ /* V3D 4.2 wires the hub and core IRQs together, so if we &
+ * didn't see the common one then check hub for MMU IRQs.
+ */
+ if (v3d->single_irq_line && status == IRQ_NONE)
+ return v3d_hub_irq(irq, arg);
+
return status;
}
@@ -156,10 +167,10 @@ v3d_hub_irq(int irq, void *arg)
return status;
}
-void
+int
v3d_irq_init(struct v3d_dev *v3d)
{
- int ret, core;
+ int irq1, ret, core;
INIT_WORK(&v3d->overflow_mem_work, v3d_overflow_mem_work);
@@ -170,16 +181,37 @@ v3d_irq_init(struct v3d_dev *v3d)
V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS);
V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS);
- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0),
- v3d_hub_irq, IRQF_SHARED,
- "v3d_hub", v3d);
- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1),
- v3d_irq, IRQF_SHARED,
- "v3d_core0", v3d);
- if (ret)
- dev_err(v3d->dev, "IRQ setup failed: %d\n", ret);
+ irq1 = platform_get_irq(v3d->pdev, 1);
+ if (irq1 == -EPROBE_DEFER)
+ return irq1;
+ if (irq1 > 0) {
+ ret = devm_request_irq(v3d->dev, irq1,
+ v3d_irq, IRQF_SHARED,
+ "v3d_core0", v3d);
+ if (ret)
+ goto fail;
+ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0),
+ v3d_hub_irq, IRQF_SHARED,
+ "v3d_hub", v3d);
+ if (ret)
+ goto fail;
+ } else {
+ v3d->single_irq_line = true;
+
+ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0),
+ v3d_irq, IRQF_SHARED,
+ "v3d", v3d);
+ if (ret)
+ goto fail;
+ }
v3d_irq_enable(v3d);
+ return 0;
+
+fail:
+ if (ret != -EPROBE_DEFER)
+ dev_err(v3d->dev, "IRQ setup failed: %d\n", ret);
+ return ret;
}
void