mirror of https://github.com/parazyd/arm-sdk.git
176 lines
6.1 KiB
Diff
176 lines
6.1 KiB
Diff
From patchwork Thu Feb 8 18:30:28 2018
|
|
Content-Type: text/plain; charset="utf-8"
|
|
MIME-Version: 1.0
|
|
Content-Transfer-Encoding: 7bit
|
|
Subject: [PATCHv2,1/8] drm/omap: add framedone interrupt support
|
|
From: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
|
|
X-Patchwork-Id: 10207753
|
|
Message-Id: <20180208183035.8461-2-sebastian.reichel@collabora.co.uk>
|
|
To: Sebastian Reichel <sre@kernel.org>,
|
|
Tomi Valkeinen <tomi.valkeinen@ti.com>, Tony Lindgren <tony@atomide.com>
|
|
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
|
|
Hans de Goede <hdegoede@redhat.com>, Rob Herring <robh+dt@kernel.org>,
|
|
Mark Rutland <mark.rutland@arm.com>,
|
|
dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
|
|
linux-omap@vger.kernel.org, linux-kernel@vger.kernel.org,
|
|
kernel@collabora.com, Sebastian Reichel <sebastian.reichel@collabora.co.uk>
|
|
Date: Thu, 8 Feb 2018 19:30:28 +0100
|
|
|
|
This prepares framedone interrupt handling for
|
|
manual display update support.
|
|
|
|
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
|
|
Tested-by: Tony Lindgren <tony@atomide.com>
|
|
---
|
|
drivers/gpu/drm/omapdrm/omap_crtc.c | 48 +++++++++++++++++++++++++++++++++++++
|
|
drivers/gpu/drm/omapdrm/omap_crtc.h | 1 +
|
|
drivers/gpu/drm/omapdrm/omap_irq.c | 24 +++++++++++++++++++
|
|
drivers/gpu/drm/omapdrm/omap_irq.h | 1 +
|
|
4 files changed, 74 insertions(+)
|
|
|
|
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
|
|
index 1b8154e58d18..2278e3433008 100644
|
|
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
|
|
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
|
|
@@ -51,6 +51,9 @@ struct omap_crtc {
|
|
bool pending;
|
|
wait_queue_head_t pending_wait;
|
|
struct drm_pending_vblank_event *event;
|
|
+
|
|
+ void (*framedone_handler)(void *);
|
|
+ void *framedone_handler_data;
|
|
};
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
@@ -247,6 +250,17 @@ static int omap_crtc_dss_register_framedone(
|
|
enum omap_channel channel,
|
|
void (*handler)(void *), void *data)
|
|
{
|
|
+ struct omap_crtc *omap_crtc = omap_crtcs[channel];
|
|
+ struct drm_device *dev = omap_crtc->base.dev;
|
|
+
|
|
+ if (omap_crtc->framedone_handler)
|
|
+ return -EBUSY;
|
|
+
|
|
+ dev_dbg(dev->dev, "register framedone %s", omap_crtc->name);
|
|
+
|
|
+ omap_crtc->framedone_handler = handler;
|
|
+ omap_crtc->framedone_handler_data = data;
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -254,6 +268,16 @@ static void omap_crtc_dss_unregister_framedone(
|
|
enum omap_channel channel,
|
|
void (*handler)(void *), void *data)
|
|
{
|
|
+ struct omap_crtc *omap_crtc = omap_crtcs[channel];
|
|
+ struct drm_device *dev = omap_crtc->base.dev;
|
|
+
|
|
+ dev_dbg(dev->dev, "unregister framedone %s", omap_crtc->name);
|
|
+
|
|
+ WARN_ON(omap_crtc->framedone_handler != handler);
|
|
+ WARN_ON(omap_crtc->framedone_handler_data != data);
|
|
+
|
|
+ omap_crtc->framedone_handler = NULL;
|
|
+ omap_crtc->framedone_handler_data = NULL;
|
|
}
|
|
|
|
static const struct dss_mgr_ops mgr_ops = {
|
|
@@ -321,6 +345,30 @@ void omap_crtc_vblank_irq(struct drm_crtc *crtc)
|
|
DBG("%s: apply done", omap_crtc->name);
|
|
}
|
|
|
|
+void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus)
|
|
+{
|
|
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
|
|
+
|
|
+ if (!omap_crtc->framedone_handler) {
|
|
+ dev_warn(omap_crtc->base.dev->dev, "no framedone handler?");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ omap_crtc->framedone_handler(omap_crtc->framedone_handler_data);
|
|
+
|
|
+ spin_lock(&crtc->dev->event_lock);
|
|
+ /* Send the vblank event if one has been requested. */
|
|
+ if (omap_crtc->event) {
|
|
+ drm_crtc_send_vblank_event(crtc, omap_crtc->event);
|
|
+ omap_crtc->event = NULL;
|
|
+ }
|
|
+ omap_crtc->pending = false;
|
|
+ spin_unlock(&crtc->dev->event_lock);
|
|
+
|
|
+ /* Wake up omap_atomic_complete. */
|
|
+ wake_up(&omap_crtc->pending_wait);
|
|
+}
|
|
+
|
|
static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc)
|
|
{
|
|
struct omap_drm_private *priv = crtc->dev->dev_private;
|
|
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.h b/drivers/gpu/drm/omapdrm/omap_crtc.h
|
|
index ad7b007c6174..bd316bc0b6f4 100644
|
|
--- a/drivers/gpu/drm/omapdrm/omap_crtc.h
|
|
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.h
|
|
@@ -39,5 +39,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
|
int omap_crtc_wait_pending(struct drm_crtc *crtc);
|
|
void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus);
|
|
void omap_crtc_vblank_irq(struct drm_crtc *crtc);
|
|
+void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus);
|
|
|
|
#endif /* __OMAPDRM_CRTC_H__ */
|
|
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
|
|
index 53ba424823b2..354df3583229 100644
|
|
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
|
|
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
|
|
@@ -85,6 +85,27 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
|
|
return ret == 0 ? -1 : 0;
|
|
}
|
|
|
|
+int omap_irq_enable_framedone(struct drm_crtc *crtc, bool enable)
|
|
+{
|
|
+ struct drm_device *dev = crtc->dev;
|
|
+ struct omap_drm_private *priv = dev->dev_private;
|
|
+ unsigned long flags;
|
|
+ enum omap_channel channel = omap_crtc_channel(crtc);
|
|
+ int framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(channel);
|
|
+
|
|
+ DBG("dev=%p, crtc=%u, enable=%d", dev, channel, enable);
|
|
+
|
|
+ spin_lock_irqsave(&priv->wait_lock, flags);
|
|
+ if (enable)
|
|
+ priv->irq_mask |= framedone_irq;
|
|
+ else
|
|
+ priv->irq_mask &= ~framedone_irq;
|
|
+ omap_irq_update(dev);
|
|
+ spin_unlock_irqrestore(&priv->wait_lock, flags);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/**
|
|
* enable_vblank - enable vblank interrupt events
|
|
* @dev: DRM device
|
|
@@ -215,6 +236,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
|
|
|
|
if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(channel))
|
|
omap_crtc_error_irq(crtc, irqstatus);
|
|
+
|
|
+ if (irqstatus & priv->dispc_ops->mgr_get_framedone_irq(channel))
|
|
+ omap_crtc_framedone_irq(crtc, irqstatus);
|
|
}
|
|
|
|
omap_irq_ocp_error_handler(dev, irqstatus);
|
|
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.h b/drivers/gpu/drm/omapdrm/omap_irq.h
|
|
index 606c09932bc0..69f4ff80a0e4 100644
|
|
--- a/drivers/gpu/drm/omapdrm/omap_irq.h
|
|
+++ b/drivers/gpu/drm/omapdrm/omap_irq.h
|
|
@@ -27,6 +27,7 @@ struct drm_device;
|
|
struct omap_irq_wait;
|
|
|
|
int omap_irq_enable_vblank(struct drm_crtc *crtc);
|
|
+int omap_irq_enable_framedone(struct drm_crtc *crtc, bool enable);
|
|
void omap_irq_disable_vblank(struct drm_crtc *crtc);
|
|
void omap_drm_irq_uninstall(struct drm_device *dev);
|
|
int omap_drm_irq_install(struct drm_device *dev);
|