From: Sebastian Reichel <sebastian.reichel@collabora.com>
To: Sebastian Reichel <sre@kernel.org>,
Tomi Valkeinen <tomi.valkeinen@ti.com>,
Tony Lindgren <tony@atomide.com>, Pavel Machek <pavel@ucw.cz>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: "H. Nikolaus Schaller" <hns@goldelico.com>,
dri-devel@lists.freedesktop.org, linux-omap@vger.kernel.org,
linux-kernel@vger.kernel.org, kernel@collabora.com,
Sebastian Reichel <sebastian.reichel@collabora.com>
Subject: [PATCHv6 3/4] drm/omap: add framedone interrupt support
Date: Wed, 3 Apr 2019 22:13:25 +0200 [thread overview]
Message-ID: <20190403201326.3127-4-sebastian.reichel@collabora.com> (raw)
In-Reply-To: <20190403201326.3127-1-sebastian.reichel@collabora.com>
This prepares framedone interrupt handling for
manual display update support.
Acked-by: Pavel Machek <pavel@ucw.cz>
Tested-by: Tony Lindgren <tony@atomide.com>
Tested-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/gpu/drm/omapdrm/omap_crtc.c | 50 +++++++++++++++++++++++++++++
drivers/gpu/drm/omapdrm/omap_crtc.h | 1 +
drivers/gpu/drm/omapdrm/omap_irq.c | 25 +++++++++++++++
drivers/gpu/drm/omapdrm/omap_irq.h | 1 +
4 files changed, 77 insertions(+)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 86827a061b0b..68697820d189 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;
};
/* -----------------------------------------------------------------------------
@@ -230,6 +233,18 @@ static int omap_crtc_dss_register_framedone(
struct omap_drm_private *priv, enum omap_channel channel,
void (*handler)(void *), void *data)
{
+ struct drm_crtc *crtc = priv->channels[channel]->crtc;
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+ 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;
}
@@ -237,6 +252,17 @@ static void omap_crtc_dss_unregister_framedone(
struct omap_drm_private *priv, enum omap_channel channel,
void (*handler)(void *), void *data)
{
+ struct drm_crtc *crtc = priv->channels[channel]->crtc;
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+ 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 = {
@@ -302,6 +328,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 d9de437ba9dd..d33bbb7a4f90 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.h
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.h
@@ -41,5 +41,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, u32 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 329ad26d6d50..01dda84ca2ee 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -85,6 +85,28 @@ 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(priv->dispc, 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
@@ -217,6 +239,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, channel))
omap_crtc_error_irq(crtc, irqstatus);
+
+ if (irqstatus & priv->dispc_ops->mgr_get_framedone_irq(priv->dispc, 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 9d5441468eca..02abb4ed9813 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);
--
2.20.1
next prev parent reply other threads:[~2019-04-03 20:13 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-21 16:09 [PATCHv5 0/6] omapdrm: DSI command mode panel support Sebastian Reichel
2018-11-21 16:09 ` [PATCHv5 1/6] drm/omap: use DRM_DEBUG_DRIVER instead of CORE Sebastian Reichel
2018-11-26 9:25 ` Tomi Valkeinen
2018-11-21 16:09 ` [PATCHv5 2/6] drm/omap: populate DSI platform bus earlier Sebastian Reichel
2018-11-26 9:27 ` Tomi Valkeinen
2018-11-21 16:09 ` [PATCHv5 3/6] drm/omap: don't check dispc timings for DSI Sebastian Reichel
2018-11-21 16:09 ` [PATCHv5 4/6] drm/omap: fix incorrect union usage Sebastian Reichel
2018-11-23 17:33 ` Tony Lindgren
2018-11-26 9:32 ` Tomi Valkeinen
2018-11-21 16:09 ` [PATCHv5 5/6] drm/omap: add framedone interrupt support Sebastian Reichel
2018-11-21 16:09 ` [PATCHv5 6/6] drm/omap: add support for manually updated displays Sebastian Reichel
2018-11-26 9:34 ` [PATCHv5 0/6] omapdrm: DSI command mode panel support Tomi Valkeinen
2018-11-26 22:45 ` Sebastian Reichel
2019-04-02 15:36 ` Tomi Valkeinen
2019-04-02 15:55 ` Laurent Pinchart
2019-04-03 19:54 ` Sebastian Reichel
2019-04-03 20:13 ` [PATCHv6 0/4] " Sebastian Reichel
2019-04-03 20:13 ` [PATCHv6 1/4] drm/omap: use DRM_DEBUG_DRIVER instead of CORE Sebastian Reichel
2019-04-03 20:13 ` [PATCHv6 2/4] drm/omap: don't check dispc timings for DSI Sebastian Reichel
2019-04-03 20:13 ` Sebastian Reichel [this message]
2019-04-03 20:13 ` [PATCHv6 4/4] drm/omap: add support for manually updated displays Sebastian Reichel
2019-04-04 0:11 ` Tony Lindgren
2019-05-22 18:21 ` Pavel Machek
2019-05-23 20:07 [PATCHv6 0/4] omapdrm: DSI command mode panel support Sebastian Reichel
2019-05-23 20:07 ` [PATCHv6 3/4] drm/omap: add framedone interrupt support Sebastian Reichel
2019-05-28 10:19 ` Tomi Valkeinen
2019-05-29 21:55 ` Sebastian Reichel
2019-05-31 12:23 ` Tomi Valkeinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190403201326.3127-4-sebastian.reichel@collabora.com \
--to=sebastian.reichel@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=hns@goldelico.com \
--cc=kernel@collabora.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
--cc=pavel@ucw.cz \
--cc=sre@kernel.org \
--cc=tomi.valkeinen@ti.com \
--cc=tony@atomide.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).