drm/omap: add framedone interrupt support

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>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
Sebastian Reichel
2019-05-23 22:07:55 +02:00
committed by Tomi Valkeinen
parent ad9df7d91b
commit 47103a80f5
4 changed files with 75 additions and 0 deletions

View File

@@ -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,28 @@ 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)
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;