0001-PATCHv2-1-8-drm-omap-add-framedone-interrupt-support.patch (6259B)
1 From patchwork Thu Feb 8 18:30:28 2018 2 Content-Type: text/plain; charset="utf-8" 3 MIME-Version: 1.0 4 Content-Transfer-Encoding: 7bit 5 Subject: [PATCHv2,1/8] drm/omap: add framedone interrupt support 6 From: Sebastian Reichel <sebastian.reichel@collabora.co.uk> 7 X-Patchwork-Id: 10207753 8 Message-Id: <20180208183035.8461-2-sebastian.reichel@collabora.co.uk> 9 To: Sebastian Reichel <sre@kernel.org>, 10 Tomi Valkeinen <tomi.valkeinen@ti.com>, Tony Lindgren <tony@atomide.com> 11 Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>, 12 Hans de Goede <hdegoede@redhat.com>, Rob Herring <robh+dt@kernel.org>, 13 Mark Rutland <mark.rutland@arm.com>, 14 dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, 15 linux-omap@vger.kernel.org, linux-kernel@vger.kernel.org, 16 kernel@collabora.com, Sebastian Reichel <sebastian.reichel@collabora.co.uk> 17 Date: Thu, 8 Feb 2018 19:30:28 +0100 18 19 This prepares framedone interrupt handling for 20 manual display update support. 21 22 Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk> 23 Tested-by: Tony Lindgren <tony@atomide.com> 24 --- 25 drivers/gpu/drm/omapdrm/omap_crtc.c | 48 +++++++++++++++++++++++++++++++++++++ 26 drivers/gpu/drm/omapdrm/omap_crtc.h | 1 + 27 drivers/gpu/drm/omapdrm/omap_irq.c | 24 +++++++++++++++++++ 28 drivers/gpu/drm/omapdrm/omap_irq.h | 1 + 29 4 files changed, 74 insertions(+) 30 31 diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c 32 index 1b8154e58d18..2278e3433008 100644 33 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c 34 +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c 35 @@ -51,6 +51,9 @@ struct omap_crtc { 36 bool pending; 37 wait_queue_head_t pending_wait; 38 struct drm_pending_vblank_event *event; 39 + 40 + void (*framedone_handler)(void *); 41 + void *framedone_handler_data; 42 }; 43 44 /* ----------------------------------------------------------------------------- 45 @@ -247,6 +250,17 @@ static int omap_crtc_dss_register_framedone( 46 enum omap_channel channel, 47 void (*handler)(void *), void *data) 48 { 49 + struct omap_crtc *omap_crtc = omap_crtcs[channel]; 50 + struct drm_device *dev = omap_crtc->base.dev; 51 + 52 + if (omap_crtc->framedone_handler) 53 + return -EBUSY; 54 + 55 + dev_dbg(dev->dev, "register framedone %s", omap_crtc->name); 56 + 57 + omap_crtc->framedone_handler = handler; 58 + omap_crtc->framedone_handler_data = data; 59 + 60 return 0; 61 } 62 63 @@ -254,6 +268,16 @@ static void omap_crtc_dss_unregister_framedone( 64 enum omap_channel channel, 65 void (*handler)(void *), void *data) 66 { 67 + struct omap_crtc *omap_crtc = omap_crtcs[channel]; 68 + struct drm_device *dev = omap_crtc->base.dev; 69 + 70 + dev_dbg(dev->dev, "unregister framedone %s", omap_crtc->name); 71 + 72 + WARN_ON(omap_crtc->framedone_handler != handler); 73 + WARN_ON(omap_crtc->framedone_handler_data != data); 74 + 75 + omap_crtc->framedone_handler = NULL; 76 + omap_crtc->framedone_handler_data = NULL; 77 } 78 79 static const struct dss_mgr_ops mgr_ops = { 80 @@ -321,6 +345,30 @@ void omap_crtc_vblank_irq(struct drm_crtc *crtc) 81 DBG("%s: apply done", omap_crtc->name); 82 } 83 84 +void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus) 85 +{ 86 + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 87 + 88 + if (!omap_crtc->framedone_handler) { 89 + dev_warn(omap_crtc->base.dev->dev, "no framedone handler?"); 90 + return; 91 + } 92 + 93 + omap_crtc->framedone_handler(omap_crtc->framedone_handler_data); 94 + 95 + spin_lock(&crtc->dev->event_lock); 96 + /* Send the vblank event if one has been requested. */ 97 + if (omap_crtc->event) { 98 + drm_crtc_send_vblank_event(crtc, omap_crtc->event); 99 + omap_crtc->event = NULL; 100 + } 101 + omap_crtc->pending = false; 102 + spin_unlock(&crtc->dev->event_lock); 103 + 104 + /* Wake up omap_atomic_complete. */ 105 + wake_up(&omap_crtc->pending_wait); 106 +} 107 + 108 static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) 109 { 110 struct omap_drm_private *priv = crtc->dev->dev_private; 111 diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.h b/drivers/gpu/drm/omapdrm/omap_crtc.h 112 index ad7b007c6174..bd316bc0b6f4 100644 113 --- a/drivers/gpu/drm/omapdrm/omap_crtc.h 114 +++ b/drivers/gpu/drm/omapdrm/omap_crtc.h 115 @@ -39,5 +39,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, 116 int omap_crtc_wait_pending(struct drm_crtc *crtc); 117 void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus); 118 void omap_crtc_vblank_irq(struct drm_crtc *crtc); 119 +void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus); 120 121 #endif /* __OMAPDRM_CRTC_H__ */ 122 diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c 123 index 53ba424823b2..354df3583229 100644 124 --- a/drivers/gpu/drm/omapdrm/omap_irq.c 125 +++ b/drivers/gpu/drm/omapdrm/omap_irq.c 126 @@ -85,6 +85,27 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait, 127 return ret == 0 ? -1 : 0; 128 } 129 130 +int omap_irq_enable_framedone(struct drm_crtc *crtc, bool enable) 131 +{ 132 + struct drm_device *dev = crtc->dev; 133 + struct omap_drm_private *priv = dev->dev_private; 134 + unsigned long flags; 135 + enum omap_channel channel = omap_crtc_channel(crtc); 136 + int framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(channel); 137 + 138 + DBG("dev=%p, crtc=%u, enable=%d", dev, channel, enable); 139 + 140 + spin_lock_irqsave(&priv->wait_lock, flags); 141 + if (enable) 142 + priv->irq_mask |= framedone_irq; 143 + else 144 + priv->irq_mask &= ~framedone_irq; 145 + omap_irq_update(dev); 146 + spin_unlock_irqrestore(&priv->wait_lock, flags); 147 + 148 + return 0; 149 +} 150 + 151 /** 152 * enable_vblank - enable vblank interrupt events 153 * @dev: DRM device 154 @@ -215,6 +236,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg) 155 156 if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(channel)) 157 omap_crtc_error_irq(crtc, irqstatus); 158 + 159 + if (irqstatus & priv->dispc_ops->mgr_get_framedone_irq(channel)) 160 + omap_crtc_framedone_irq(crtc, irqstatus); 161 } 162 163 omap_irq_ocp_error_handler(dev, irqstatus); 164 diff --git a/drivers/gpu/drm/omapdrm/omap_irq.h b/drivers/gpu/drm/omapdrm/omap_irq.h 165 index 606c09932bc0..69f4ff80a0e4 100644 166 --- a/drivers/gpu/drm/omapdrm/omap_irq.h 167 +++ b/drivers/gpu/drm/omapdrm/omap_irq.h 168 @@ -27,6 +27,7 @@ struct drm_device; 169 struct omap_irq_wait; 170 171 int omap_irq_enable_vblank(struct drm_crtc *crtc); 172 +int omap_irq_enable_framedone(struct drm_crtc *crtc, bool enable); 173 void omap_irq_disable_vblank(struct drm_crtc *crtc); 174 void omap_drm_irq_uninstall(struct drm_device *dev); 175 int omap_drm_irq_install(struct drm_device *dev);