2 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
3 * Author: Rob Clark <rob.clark@linaro.org>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
20 struct omap_irq_wait
{
21 struct list_head node
;
27 /* call with wait_lock and dispc runtime held */
28 static void omap_irq_update(struct drm_device
*dev
)
30 struct omap_drm_private
*priv
= dev
->dev_private
;
31 struct omap_irq_wait
*wait
;
32 uint32_t irqmask
= priv
->irq_mask
;
34 assert_spin_locked(&priv
->wait_lock
);
36 list_for_each_entry(wait
, &priv
->wait_list
, node
)
37 irqmask
|= wait
->irqmask
;
39 DBG("irqmask=%08x", irqmask
);
41 priv
->dispc_ops
->write_irqenable(irqmask
);
44 static void omap_irq_wait_handler(struct omap_irq_wait
*wait
)
50 struct omap_irq_wait
* omap_irq_wait_init(struct drm_device
*dev
,
51 uint32_t irqmask
, int count
)
53 struct omap_drm_private
*priv
= dev
->dev_private
;
54 struct omap_irq_wait
*wait
= kzalloc(sizeof(*wait
), GFP_KERNEL
);
57 init_waitqueue_head(&wait
->wq
);
58 wait
->irqmask
= irqmask
;
61 spin_lock_irqsave(&priv
->wait_lock
, flags
);
62 list_add(&wait
->node
, &priv
->wait_list
);
64 spin_unlock_irqrestore(&priv
->wait_lock
, flags
);
69 int omap_irq_wait(struct drm_device
*dev
, struct omap_irq_wait
*wait
,
70 unsigned long timeout
)
72 struct omap_drm_private
*priv
= dev
->dev_private
;
76 ret
= wait_event_timeout(wait
->wq
, (wait
->count
<= 0), timeout
);
78 spin_lock_irqsave(&priv
->wait_lock
, flags
);
79 list_del(&wait
->node
);
81 spin_unlock_irqrestore(&priv
->wait_lock
, flags
);
85 return ret
== 0 ? -1 : 0;
89 * enable_vblank - enable vblank interrupt events
91 * @pipe: which irq to enable
93 * Enable vblank interrupts for @crtc. If the device doesn't have
94 * a hardware vblank counter, this routine should be a no-op, since
95 * interrupts will have to stay on to keep the count accurate.
98 * Zero on success, appropriate errno if the given @crtc's vblank
99 * interrupt cannot be enabled.
101 int omap_irq_enable_vblank(struct drm_crtc
*crtc
)
103 struct drm_device
*dev
= crtc
->dev
;
104 struct omap_drm_private
*priv
= dev
->dev_private
;
106 enum omap_channel channel
= omap_crtc_channel(crtc
);
108 DBG("dev=%p, crtc=%u", dev
, channel
);
110 spin_lock_irqsave(&priv
->wait_lock
, flags
);
111 priv
->irq_mask
|= priv
->dispc_ops
->mgr_get_vsync_irq(channel
);
112 omap_irq_update(dev
);
113 spin_unlock_irqrestore(&priv
->wait_lock
, flags
);
119 * disable_vblank - disable vblank interrupt events
121 * @pipe: which irq to enable
123 * Disable vblank interrupts for @crtc. If the device doesn't have
124 * a hardware vblank counter, this routine should be a no-op, since
125 * interrupts will have to stay on to keep the count accurate.
127 void omap_irq_disable_vblank(struct drm_crtc
*crtc
)
129 struct drm_device
*dev
= crtc
->dev
;
130 struct omap_drm_private
*priv
= dev
->dev_private
;
132 enum omap_channel channel
= omap_crtc_channel(crtc
);
134 DBG("dev=%p, crtc=%u", dev
, channel
);
136 spin_lock_irqsave(&priv
->wait_lock
, flags
);
137 priv
->irq_mask
&= ~priv
->dispc_ops
->mgr_get_vsync_irq(channel
);
138 omap_irq_update(dev
);
139 spin_unlock_irqrestore(&priv
->wait_lock
, flags
);
142 static void omap_irq_fifo_underflow(struct omap_drm_private
*priv
,
145 static DEFINE_RATELIMIT_STATE(_rs
, DEFAULT_RATELIMIT_INTERVAL
,
146 DEFAULT_RATELIMIT_BURST
);
147 static const struct {
151 { "gfx", DISPC_IRQ_GFX_FIFO_UNDERFLOW
},
152 { "vid1", DISPC_IRQ_VID1_FIFO_UNDERFLOW
},
153 { "vid2", DISPC_IRQ_VID2_FIFO_UNDERFLOW
},
154 { "vid3", DISPC_IRQ_VID3_FIFO_UNDERFLOW
},
157 const u32 mask
= DISPC_IRQ_GFX_FIFO_UNDERFLOW
158 | DISPC_IRQ_VID1_FIFO_UNDERFLOW
159 | DISPC_IRQ_VID2_FIFO_UNDERFLOW
160 | DISPC_IRQ_VID3_FIFO_UNDERFLOW
;
163 spin_lock(&priv
->wait_lock
);
164 irqstatus
&= priv
->irq_mask
& mask
;
165 spin_unlock(&priv
->wait_lock
);
170 if (!__ratelimit(&_rs
))
173 DRM_ERROR("FIFO underflow on ");
175 for (i
= 0; i
< ARRAY_SIZE(sources
); ++i
) {
176 if (sources
[i
].mask
& irqstatus
)
177 pr_cont("%s ", sources
[i
].name
);
180 pr_cont("(0x%08x)\n", irqstatus
);
183 static void omap_irq_ocp_error_handler(struct drm_device
*dev
,
186 if (!(irqstatus
& DISPC_IRQ_OCP_ERR
))
189 dev_err_ratelimited(dev
->dev
, "OCP error\n");
192 static irqreturn_t
omap_irq_handler(int irq
, void *arg
)
194 struct drm_device
*dev
= (struct drm_device
*) arg
;
195 struct omap_drm_private
*priv
= dev
->dev_private
;
196 struct omap_irq_wait
*wait
, *n
;
201 irqstatus
= priv
->dispc_ops
->read_irqstatus();
202 priv
->dispc_ops
->clear_irqstatus(irqstatus
);
203 priv
->dispc_ops
->read_irqstatus(); /* flush posted write */
205 VERB("irqs: %08x", irqstatus
);
207 for (id
= 0; id
< priv
->num_crtcs
; id
++) {
208 struct drm_crtc
*crtc
= priv
->crtcs
[id
];
209 enum omap_channel channel
= omap_crtc_channel(crtc
);
211 if (irqstatus
& priv
->dispc_ops
->mgr_get_vsync_irq(channel
)) {
212 drm_handle_vblank(dev
, id
);
213 omap_crtc_vblank_irq(crtc
);
216 if (irqstatus
& priv
->dispc_ops
->mgr_get_sync_lost_irq(channel
))
217 omap_crtc_error_irq(crtc
, irqstatus
);
220 omap_irq_ocp_error_handler(dev
, irqstatus
);
221 omap_irq_fifo_underflow(priv
, irqstatus
);
223 spin_lock_irqsave(&priv
->wait_lock
, flags
);
224 list_for_each_entry_safe(wait
, n
, &priv
->wait_list
, node
) {
225 if (wait
->irqmask
& irqstatus
)
226 omap_irq_wait_handler(wait
);
228 spin_unlock_irqrestore(&priv
->wait_lock
, flags
);
233 static const u32 omap_underflow_irqs
[] = {
234 [OMAP_DSS_GFX
] = DISPC_IRQ_GFX_FIFO_UNDERFLOW
,
235 [OMAP_DSS_VIDEO1
] = DISPC_IRQ_VID1_FIFO_UNDERFLOW
,
236 [OMAP_DSS_VIDEO2
] = DISPC_IRQ_VID2_FIFO_UNDERFLOW
,
237 [OMAP_DSS_VIDEO3
] = DISPC_IRQ_VID3_FIFO_UNDERFLOW
,
241 * We need a special version, instead of just using drm_irq_install(),
242 * because we need to register the irq via omapdss. Once omapdss and
243 * omapdrm are merged together we can assign the dispc hwmod data to
244 * ourselves and drop these and just use drm_irq_{install,uninstall}()
247 int omap_drm_irq_install(struct drm_device
*dev
)
249 struct omap_drm_private
*priv
= dev
->dev_private
;
250 unsigned int num_mgrs
= priv
->dispc_ops
->get_num_mgrs();
251 unsigned int max_planes
;
255 spin_lock_init(&priv
->wait_lock
);
256 INIT_LIST_HEAD(&priv
->wait_list
);
258 priv
->irq_mask
= DISPC_IRQ_OCP_ERR
;
260 max_planes
= min(ARRAY_SIZE(priv
->planes
),
261 ARRAY_SIZE(omap_underflow_irqs
));
262 for (i
= 0; i
< max_planes
; ++i
) {
264 priv
->irq_mask
|= omap_underflow_irqs
[i
];
267 for (i
= 0; i
< num_mgrs
; ++i
)
268 priv
->irq_mask
|= priv
->dispc_ops
->mgr_get_sync_lost_irq(i
);
270 priv
->dispc_ops
->runtime_get();
271 priv
->dispc_ops
->clear_irqstatus(0xffffffff);
272 priv
->dispc_ops
->runtime_put();
274 ret
= priv
->dispc_ops
->request_irq(omap_irq_handler
, dev
);
278 dev
->irq_enabled
= true;
283 void omap_drm_irq_uninstall(struct drm_device
*dev
)
285 struct omap_drm_private
*priv
= dev
->dev_private
;
287 if (!dev
->irq_enabled
)
290 dev
->irq_enabled
= false;
292 priv
->dispc_ops
->free_irq(dev
);