0001
0002
0003
0004
0005
0006
0007 #include <drm/drm_vblank.h>
0008
0009 #include "omap_drv.h"
0010
0011 struct omap_irq_wait {
0012 struct list_head node;
0013 wait_queue_head_t wq;
0014 u32 irqmask;
0015 int count;
0016 };
0017
0018
0019 static void omap_irq_update(struct drm_device *dev)
0020 {
0021 struct omap_drm_private *priv = dev->dev_private;
0022 struct omap_irq_wait *wait;
0023 u32 irqmask = priv->irq_mask;
0024
0025 assert_spin_locked(&priv->wait_lock);
0026
0027 list_for_each_entry(wait, &priv->wait_list, node)
0028 irqmask |= wait->irqmask;
0029
0030 DBG("irqmask=%08x", irqmask);
0031
0032 dispc_write_irqenable(priv->dispc, irqmask);
0033 }
0034
0035 static void omap_irq_wait_handler(struct omap_irq_wait *wait)
0036 {
0037 wait->count--;
0038 wake_up(&wait->wq);
0039 }
0040
0041 struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev,
0042 u32 irqmask, int count)
0043 {
0044 struct omap_drm_private *priv = dev->dev_private;
0045 struct omap_irq_wait *wait = kzalloc(sizeof(*wait), GFP_KERNEL);
0046 unsigned long flags;
0047
0048 init_waitqueue_head(&wait->wq);
0049 wait->irqmask = irqmask;
0050 wait->count = count;
0051
0052 spin_lock_irqsave(&priv->wait_lock, flags);
0053 list_add(&wait->node, &priv->wait_list);
0054 omap_irq_update(dev);
0055 spin_unlock_irqrestore(&priv->wait_lock, flags);
0056
0057 return wait;
0058 }
0059
0060 int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
0061 unsigned long timeout)
0062 {
0063 struct omap_drm_private *priv = dev->dev_private;
0064 unsigned long flags;
0065 int ret;
0066
0067 ret = wait_event_timeout(wait->wq, (wait->count <= 0), timeout);
0068
0069 spin_lock_irqsave(&priv->wait_lock, flags);
0070 list_del(&wait->node);
0071 omap_irq_update(dev);
0072 spin_unlock_irqrestore(&priv->wait_lock, flags);
0073
0074 kfree(wait);
0075
0076 return ret == 0 ? -1 : 0;
0077 }
0078
0079 int omap_irq_enable_framedone(struct drm_crtc *crtc, bool enable)
0080 {
0081 struct drm_device *dev = crtc->dev;
0082 struct omap_drm_private *priv = dev->dev_private;
0083 unsigned long flags;
0084 enum omap_channel channel = omap_crtc_channel(crtc);
0085 int framedone_irq =
0086 dispc_mgr_get_framedone_irq(priv->dispc, channel);
0087
0088 DBG("dev=%p, crtc=%u, enable=%d", dev, channel, enable);
0089
0090 spin_lock_irqsave(&priv->wait_lock, flags);
0091 if (enable)
0092 priv->irq_mask |= framedone_irq;
0093 else
0094 priv->irq_mask &= ~framedone_irq;
0095 omap_irq_update(dev);
0096 spin_unlock_irqrestore(&priv->wait_lock, flags);
0097
0098 return 0;
0099 }
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 int omap_irq_enable_vblank(struct drm_crtc *crtc)
0114 {
0115 struct drm_device *dev = crtc->dev;
0116 struct omap_drm_private *priv = dev->dev_private;
0117 unsigned long flags;
0118 enum omap_channel channel = omap_crtc_channel(crtc);
0119
0120 DBG("dev=%p, crtc=%u", dev, channel);
0121
0122 spin_lock_irqsave(&priv->wait_lock, flags);
0123 priv->irq_mask |= dispc_mgr_get_vsync_irq(priv->dispc,
0124 channel);
0125 omap_irq_update(dev);
0126 spin_unlock_irqrestore(&priv->wait_lock, flags);
0127
0128 return 0;
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 void omap_irq_disable_vblank(struct drm_crtc *crtc)
0140 {
0141 struct drm_device *dev = crtc->dev;
0142 struct omap_drm_private *priv = dev->dev_private;
0143 unsigned long flags;
0144 enum omap_channel channel = omap_crtc_channel(crtc);
0145
0146 DBG("dev=%p, crtc=%u", dev, channel);
0147
0148 spin_lock_irqsave(&priv->wait_lock, flags);
0149 priv->irq_mask &= ~dispc_mgr_get_vsync_irq(priv->dispc,
0150 channel);
0151 omap_irq_update(dev);
0152 spin_unlock_irqrestore(&priv->wait_lock, flags);
0153 }
0154
0155 static void omap_irq_fifo_underflow(struct omap_drm_private *priv,
0156 u32 irqstatus)
0157 {
0158 static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
0159 DEFAULT_RATELIMIT_BURST);
0160 static const struct {
0161 const char *name;
0162 u32 mask;
0163 } sources[] = {
0164 { "gfx", DISPC_IRQ_GFX_FIFO_UNDERFLOW },
0165 { "vid1", DISPC_IRQ_VID1_FIFO_UNDERFLOW },
0166 { "vid2", DISPC_IRQ_VID2_FIFO_UNDERFLOW },
0167 { "vid3", DISPC_IRQ_VID3_FIFO_UNDERFLOW },
0168 };
0169
0170 const u32 mask = DISPC_IRQ_GFX_FIFO_UNDERFLOW
0171 | DISPC_IRQ_VID1_FIFO_UNDERFLOW
0172 | DISPC_IRQ_VID2_FIFO_UNDERFLOW
0173 | DISPC_IRQ_VID3_FIFO_UNDERFLOW;
0174 unsigned int i;
0175
0176 spin_lock(&priv->wait_lock);
0177 irqstatus &= priv->irq_mask & mask;
0178 spin_unlock(&priv->wait_lock);
0179
0180 if (!irqstatus)
0181 return;
0182
0183 if (!__ratelimit(&_rs))
0184 return;
0185
0186 DRM_ERROR("FIFO underflow on ");
0187
0188 for (i = 0; i < ARRAY_SIZE(sources); ++i) {
0189 if (sources[i].mask & irqstatus)
0190 pr_cont("%s ", sources[i].name);
0191 }
0192
0193 pr_cont("(0x%08x)\n", irqstatus);
0194 }
0195
0196 static void omap_irq_ocp_error_handler(struct drm_device *dev,
0197 u32 irqstatus)
0198 {
0199 if (!(irqstatus & DISPC_IRQ_OCP_ERR))
0200 return;
0201
0202 dev_err_ratelimited(dev->dev, "OCP error\n");
0203 }
0204
0205 static irqreturn_t omap_irq_handler(int irq, void *arg)
0206 {
0207 struct drm_device *dev = (struct drm_device *) arg;
0208 struct omap_drm_private *priv = dev->dev_private;
0209 struct omap_irq_wait *wait, *n;
0210 unsigned long flags;
0211 unsigned int id;
0212 u32 irqstatus;
0213
0214 irqstatus = dispc_read_irqstatus(priv->dispc);
0215 dispc_clear_irqstatus(priv->dispc, irqstatus);
0216 dispc_read_irqstatus(priv->dispc);
0217
0218 VERB("irqs: %08x", irqstatus);
0219
0220 for (id = 0; id < priv->num_pipes; id++) {
0221 struct drm_crtc *crtc = priv->pipes[id].crtc;
0222 enum omap_channel channel = omap_crtc_channel(crtc);
0223
0224 if (irqstatus & dispc_mgr_get_vsync_irq(priv->dispc, channel)) {
0225 drm_handle_vblank(dev, id);
0226 omap_crtc_vblank_irq(crtc);
0227 }
0228
0229 if (irqstatus & dispc_mgr_get_sync_lost_irq(priv->dispc, channel))
0230 omap_crtc_error_irq(crtc, irqstatus);
0231
0232 if (irqstatus & dispc_mgr_get_framedone_irq(priv->dispc, channel))
0233 omap_crtc_framedone_irq(crtc, irqstatus);
0234 }
0235
0236 omap_irq_ocp_error_handler(dev, irqstatus);
0237 omap_irq_fifo_underflow(priv, irqstatus);
0238
0239 spin_lock_irqsave(&priv->wait_lock, flags);
0240 list_for_each_entry_safe(wait, n, &priv->wait_list, node) {
0241 if (wait->irqmask & irqstatus)
0242 omap_irq_wait_handler(wait);
0243 }
0244 spin_unlock_irqrestore(&priv->wait_lock, flags);
0245
0246 return IRQ_HANDLED;
0247 }
0248
0249 static const u32 omap_underflow_irqs[] = {
0250 [OMAP_DSS_GFX] = DISPC_IRQ_GFX_FIFO_UNDERFLOW,
0251 [OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_FIFO_UNDERFLOW,
0252 [OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_FIFO_UNDERFLOW,
0253 [OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_FIFO_UNDERFLOW,
0254 };
0255
0256 int omap_drm_irq_install(struct drm_device *dev)
0257 {
0258 struct omap_drm_private *priv = dev->dev_private;
0259 unsigned int num_mgrs = dispc_get_num_mgrs(priv->dispc);
0260 unsigned int max_planes;
0261 unsigned int i;
0262 int ret;
0263
0264 spin_lock_init(&priv->wait_lock);
0265 INIT_LIST_HEAD(&priv->wait_list);
0266
0267 priv->irq_mask = DISPC_IRQ_OCP_ERR;
0268
0269 max_planes = min(ARRAY_SIZE(priv->planes),
0270 ARRAY_SIZE(omap_underflow_irqs));
0271 for (i = 0; i < max_planes; ++i) {
0272 if (priv->planes[i])
0273 priv->irq_mask |= omap_underflow_irqs[i];
0274 }
0275
0276 for (i = 0; i < num_mgrs; ++i)
0277 priv->irq_mask |= dispc_mgr_get_sync_lost_irq(priv->dispc, i);
0278
0279 dispc_runtime_get(priv->dispc);
0280 dispc_clear_irqstatus(priv->dispc, 0xffffffff);
0281 dispc_runtime_put(priv->dispc);
0282
0283 ret = dispc_request_irq(priv->dispc, omap_irq_handler, dev);
0284 if (ret < 0)
0285 return ret;
0286
0287 priv->irq_enabled = true;
0288
0289 return 0;
0290 }
0291
0292 void omap_drm_irq_uninstall(struct drm_device *dev)
0293 {
0294 struct omap_drm_private *priv = dev->dev_private;
0295
0296 if (!priv->irq_enabled)
0297 return;
0298
0299 priv->irq_enabled = false;
0300
0301 dispc_free_irq(priv->dispc, dev);
0302 }