aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2013-01-08 16:04:28 -0500
committerRob Clark <robdclark@gmail.com>2013-02-19 17:57:44 -0500
commit16ea975eac671fa40a78594a116a44fef8e3f4a9 (patch)
tree4e83f07ea5856e0b33e8fd0918f11aff4b25547b /drivers/gpu/drm/tilcdc/tilcdc_crtc.c
parentb3d3de80133d32723224329f87edecaff230fefc (diff)
drm/tilcdc: add TI LCD Controller DRM driver (v4)
A simple DRM/KMS driver for the TI LCD Controller found in various smaller TI parts (AM33xx, OMAPL138, etc). This driver uses the CMA helpers. Currently only the TFP410 DVI encoder is supported (tested with beaglebone + DVI cape). There are also various LCD displays, for which support can be added (as I get hw to test on), and an external i2c HDMI encoder found on some boards. The display controller supports a single CRTC. And the encoder+ connector are split out into sub-devices. Depending on which LCD or external encoder is actually present, the appropriate output module(s) will be loaded. v1: original v2: fix fb refcnting and few other cleanups v3: get +/- vsync/hsync from timings rather than panel-info, add option DT max-bandwidth field so driver doesn't attempt to pick a display mode with too high memory bandwidth, and other small cleanups v4: remove some unneeded stuff from panel-info struct, properly set high bits for hfp/hsw/hbp for rev 2, add DT bindings docs Signed-off-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Tested-by: Koen Kooi <koen@dominion.thruhere.net>
Diffstat (limited to 'drivers/gpu/drm/tilcdc/tilcdc_crtc.c')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c602
1 files changed, 602 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
new file mode 100644
index 000000000000..5dd3c7d031d5
--- /dev/null
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -0,0 +1,602 @@
1/*
2 * Copyright (C) 2012 Texas Instruments
3 * Author: Rob Clark <robdclark@gmail.com>
4 *
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.
8 *
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
12 * more details.
13 *
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/>.
16 */
17
18#include <linux/kfifo.h>
19
20#include "tilcdc_drv.h"
21#include "tilcdc_regs.h"
22
23struct tilcdc_crtc {
24 struct drm_crtc base;
25
26 const struct tilcdc_panel_info *info;
27 uint32_t dirty;
28 dma_addr_t start, end;
29 struct drm_pending_vblank_event *event;
30 int dpms;
31 wait_queue_head_t frame_done_wq;
32 bool frame_done;
33
34 /* fb currently set to scanout 0/1: */
35 struct drm_framebuffer *scanout[2];
36
37 /* for deferred fb unref's: */
38 DECLARE_KFIFO_PTR(unref_fifo, struct drm_framebuffer *);
39 struct work_struct work;
40};
41#define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
42
43static void unref_worker(struct work_struct *work)
44{
45 struct tilcdc_crtc *tilcdc_crtc = container_of(work, struct tilcdc_crtc, work);
46 struct drm_device *dev = tilcdc_crtc->base.dev;
47 struct drm_framebuffer *fb;
48
49 mutex_lock(&dev->mode_config.mutex);
50 while (kfifo_get(&tilcdc_crtc->unref_fifo, &fb))
51 drm_framebuffer_unreference(fb);
52 mutex_unlock(&dev->mode_config.mutex);
53}
54
55static void set_scanout(struct drm_crtc *crtc, int n)
56{
57 static const uint32_t base_reg[] = {
58 LCDC_DMA_FB_BASE_ADDR_0_REG, LCDC_DMA_FB_BASE_ADDR_1_REG,
59 };
60 static const uint32_t ceil_reg[] = {
61 LCDC_DMA_FB_CEILING_ADDR_0_REG, LCDC_DMA_FB_CEILING_ADDR_1_REG,
62 };
63 static const uint32_t stat[] = {
64 LCDC_END_OF_FRAME0, LCDC_END_OF_FRAME1,
65 };
66 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
67 struct drm_device *dev = crtc->dev;
68
69 pm_runtime_get_sync(dev->dev);
70 tilcdc_write(dev, base_reg[n], tilcdc_crtc->start);
71 tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end);
72 if (tilcdc_crtc->scanout[n]) {
73 if (kfifo_put(&tilcdc_crtc->unref_fifo,
74 (const struct drm_framebuffer **)&tilcdc_crtc->scanout[n])) {
75 struct tilcdc_drm_private *priv = dev->dev_private;
76 queue_work(priv->wq, &tilcdc_crtc->work);
77 } else {
78 dev_err(dev->dev, "unref fifo full!\n");
79 drm_framebuffer_unreference(tilcdc_crtc->scanout[n]);
80 }
81 }
82 tilcdc_crtc->scanout[n] = crtc->fb;
83 drm_framebuffer_reference(tilcdc_crtc->scanout[n]);
84 tilcdc_crtc->dirty &= ~stat[n];
85 pm_runtime_put_sync(dev->dev);
86}
87
88static void update_scanout(struct drm_crtc *crtc)
89{
90 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
91 struct drm_device *dev = crtc->dev;
92 struct drm_framebuffer *fb = crtc->fb;
93 struct drm_gem_cma_object *gem;
94 unsigned int depth, bpp;
95
96 drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
97 gem = drm_fb_cma_get_gem_obj(fb, 0);
98
99 tilcdc_crtc->start = gem->paddr + fb->offsets[0] +
100 (crtc->y * fb->pitches[0]) + (crtc->x * bpp/8);
101
102 tilcdc_crtc->end = tilcdc_crtc->start +
103 (crtc->mode.vdisplay * fb->pitches[0]);
104
105 if (tilcdc_crtc->dpms == DRM_MODE_DPMS_ON) {
106 /* already enabled, so just mark the frames that need
107 * updating and they will be updated on vblank:
108 */
109 tilcdc_crtc->dirty |= LCDC_END_OF_FRAME0 | LCDC_END_OF_FRAME1;
110 drm_vblank_get(dev, 0);
111 } else {
112 /* not enabled yet, so update registers immediately: */
113 set_scanout(crtc, 0);
114 set_scanout(crtc, 1);
115 }
116}
117
118static void start(struct drm_crtc *crtc)
119{
120 struct drm_device *dev = crtc->dev;
121 struct tilcdc_drm_private *priv = dev->dev_private;
122
123 if (priv->rev == 2) {
124 tilcdc_set(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET);
125 msleep(1);
126 tilcdc_clear(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET);
127 msleep(1);
128 }
129
130 tilcdc_set(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE);
131 tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_PALETTE_LOAD_MODE(DATA_ONLY));
132 tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
133}
134
135static void stop(struct drm_crtc *crtc)
136{
137 struct drm_device *dev = crtc->dev;
138
139 tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
140}
141
142static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
143{
144 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
145
146 WARN_ON(tilcdc_crtc->dpms == DRM_MODE_DPMS_ON);
147
148 drm_crtc_cleanup(crtc);
149 WARN_ON(!kfifo_is_empty(&tilcdc_crtc->unref_fifo));
150 kfifo_free(&tilcdc_crtc->unref_fifo);
151 kfree(tilcdc_crtc);
152}
153
154static int tilcdc_crtc_page_flip(struct drm_crtc *crtc,
155 struct drm_framebuffer *fb,
156 struct drm_pending_vblank_event *event)
157{
158 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
159 struct drm_device *dev = crtc->dev;
160
161 if (tilcdc_crtc->event) {
162 dev_err(dev->dev, "already pending page flip!\n");
163 return -EBUSY;
164 }
165
166 crtc->fb = fb;
167 tilcdc_crtc->event = event;
168 update_scanout(crtc);
169
170 return 0;
171}
172
173static void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode)
174{
175 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
176 struct drm_device *dev = crtc->dev;
177 struct tilcdc_drm_private *priv = dev->dev_private;
178
179 /* we really only care about on or off: */
180 if (mode != DRM_MODE_DPMS_ON)
181 mode = DRM_MODE_DPMS_OFF;
182
183 if (tilcdc_crtc->dpms == mode)
184 return;
185
186 tilcdc_crtc->dpms = mode;
187
188 pm_runtime_get_sync(dev->dev);
189
190 if (mode == DRM_MODE_DPMS_ON) {
191 pm_runtime_forbid(dev->dev);
192 start(crtc);
193 } else {
194 tilcdc_crtc->frame_done = false;
195 stop(crtc);
196
197 /* if necessary wait for framedone irq which will still come
198 * before putting things to sleep..
199 */
200 if (priv->rev == 2) {
201 int ret = wait_event_timeout(
202 tilcdc_crtc->frame_done_wq,
203 tilcdc_crtc->frame_done,
204 msecs_to_jiffies(50));
205 if (ret == 0)
206 dev_err(dev->dev, "timeout waiting for framedone\n");
207 }
208 pm_runtime_allow(dev->dev);
209 }
210
211 pm_runtime_put_sync(dev->dev);
212}
213
214static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc,
215 const struct drm_display_mode *mode,
216 struct drm_display_mode *adjusted_mode)
217{
218 return true;
219}
220
221static void tilcdc_crtc_prepare(struct drm_crtc *crtc)
222{
223 tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
224}
225
226static void tilcdc_crtc_commit(struct drm_crtc *crtc)
227{
228 tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
229}
230
231static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
232 struct drm_display_mode *mode,
233 struct drm_display_mode *adjusted_mode,
234 int x, int y,
235 struct drm_framebuffer *old_fb)
236{
237 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
238 struct drm_device *dev = crtc->dev;
239 struct tilcdc_drm_private *priv = dev->dev_private;
240 const struct tilcdc_panel_info *info = tilcdc_crtc->info;
241 uint32_t reg, hbp, hfp, hsw, vbp, vfp, vsw;
242 int ret;
243
244 ret = tilcdc_crtc_mode_valid(crtc, mode);
245 if (WARN_ON(ret))
246 return ret;
247
248 if (WARN_ON(!info))
249 return -EINVAL;
250
251 pm_runtime_get_sync(dev->dev);
252
253 /* Configure the Burst Size and fifo threshold of DMA: */
254 reg = tilcdc_read(dev, LCDC_DMA_CTRL_REG) & ~0x00000770;
255 switch (info->dma_burst_sz) {
256 case 1:
257 reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_1);
258 break;
259 case 2:
260 reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_2);
261 break;
262 case 4:
263 reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_4);
264 break;
265 case 8:
266 reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_8);
267 break;
268 case 16:
269 reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_16);
270 break;
271 default:
272 return -EINVAL;
273 }
274 reg |= (info->fifo_th << 8);
275 tilcdc_write(dev, LCDC_DMA_CTRL_REG, reg);
276
277 /* Configure timings: */
278 hbp = mode->htotal - mode->hsync_end;
279 hfp = mode->hsync_start - mode->hdisplay;
280 hsw = mode->hsync_end - mode->hsync_start;
281 vbp = mode->vtotal - mode->vsync_end;
282 vfp = mode->vsync_start - mode->vdisplay;
283 vsw = mode->vsync_end - mode->vsync_start;
284
285 DBG("%dx%d, hbp=%u, hfp=%u, hsw=%u, vbp=%u, vfp=%u, vsw=%u",
286 mode->hdisplay, mode->vdisplay, hbp, hfp, hsw, vbp, vfp, vsw);
287
288 /* Configure the AC Bias Period and Number of Transitions per Interrupt: */
289 reg = tilcdc_read(dev, LCDC_RASTER_TIMING_2_REG) & ~0x000fff00;
290 reg |= LCDC_AC_BIAS_FREQUENCY(info->ac_bias) |
291 LCDC_AC_BIAS_TRANSITIONS_PER_INT(info->ac_bias_intrpt);
292 if (priv->rev == 2) {
293 reg |= (hfp & 0x300) >> 8;
294 reg |= (hbp & 0x300) >> 4;
295 reg |= (hsw & 0x3c0) << 21;
296 }
297 tilcdc_write(dev, LCDC_RASTER_TIMING_2_REG, reg);
298
299 reg = (((mode->hdisplay >> 4) - 1) << 4) |
300 ((hbp & 0xff) << 24) |
301 ((hfp & 0xff) << 16) |
302 ((hsw & 0x3f) << 10);
303 if (priv->rev == 2)
304 reg |= (((mode->hdisplay >> 4) - 1) & 0x40) >> 3;
305 tilcdc_write(dev, LCDC_RASTER_TIMING_0_REG, reg);
306
307 reg = ((mode->vdisplay - 1) & 0x3ff) |
308 ((vbp & 0xff) << 24) |
309 ((vfp & 0xff) << 16) |
310 ((vsw & 0x3f) << 10);
311 tilcdc_write(dev, LCDC_RASTER_TIMING_1_REG, reg);
312
313 /* Configure display type: */
314 reg = tilcdc_read(dev, LCDC_RASTER_CTRL_REG) &
315 ~(LCDC_TFT_MODE | LCDC_MONO_8BIT_MODE | LCDC_MONOCHROME_MODE |
316 LCDC_V2_TFT_24BPP_MODE | LCDC_V2_TFT_24BPP_UNPACK | 0x000ff000);
317 reg |= LCDC_TFT_MODE; /* no monochrome/passive support */
318 if (info->tft_alt_mode)
319 reg |= LCDC_TFT_ALT_ENABLE;
320 if (priv->rev == 2) {
321 unsigned int depth, bpp;
322
323 drm_fb_get_bpp_depth(crtc->fb->pixel_format, &depth, &bpp);
324 switch (bpp) {
325 case 16:
326 break;
327 case 32:
328 reg |= LCDC_V2_TFT_24BPP_UNPACK;
329 /* fallthrough */
330 case 24:
331 reg |= LCDC_V2_TFT_24BPP_MODE;
332 break;
333 default:
334 dev_err(dev->dev, "invalid pixel format\n");
335 return -EINVAL;
336 }
337 }
338 reg |= info->fdd < 12;
339 tilcdc_write(dev, LCDC_RASTER_CTRL_REG, reg);
340
341 if (info->invert_pxl_clk)
342 tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_PIXEL_CLOCK);
343 else
344 tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_PIXEL_CLOCK);
345
346 if (info->sync_ctrl)
347 tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL);
348 else
349 tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL);
350
351 if (info->sync_edge)
352 tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);
353 else
354 tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);
355
356 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
357 tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC);
358 else
359 tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC);
360
361 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
362 tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_VSYNC);
363 else
364 tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_VSYNC);
365
366 if (info->raster_order)
367 tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ORDER);
368 else
369 tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ORDER);
370
371
372 update_scanout(crtc);
373 tilcdc_crtc_update_clk(crtc);
374
375 pm_runtime_put_sync(dev->dev);
376
377 return 0;
378}
379
380static int tilcdc_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
381 struct drm_framebuffer *old_fb)
382{
383 update_scanout(crtc);
384 return 0;
385}
386
387static void tilcdc_crtc_load_lut(struct drm_crtc *crtc)
388{
389}
390
391static const struct drm_crtc_funcs tilcdc_crtc_funcs = {
392 .destroy = tilcdc_crtc_destroy,
393 .set_config = drm_crtc_helper_set_config,
394 .page_flip = tilcdc_crtc_page_flip,
395};
396
397static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = {
398 .dpms = tilcdc_crtc_dpms,
399 .mode_fixup = tilcdc_crtc_mode_fixup,
400 .prepare = tilcdc_crtc_prepare,
401 .commit = tilcdc_crtc_commit,
402 .mode_set = tilcdc_crtc_mode_set,
403 .mode_set_base = tilcdc_crtc_mode_set_base,
404 .load_lut = tilcdc_crtc_load_lut,
405};
406
407int tilcdc_crtc_max_width(struct drm_crtc *crtc)
408{
409 struct drm_device *dev = crtc->dev;
410 struct tilcdc_drm_private *priv = dev->dev_private;
411 int max_width = 0;
412
413 if (priv->rev == 1)
414 max_width = 1024;
415 else if (priv->rev == 2)
416 max_width = 2048;
417
418 return max_width;
419}
420
421int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
422{
423 struct tilcdc_drm_private *priv = crtc->dev->dev_private;
424 unsigned int bandwidth;
425
426 if (mode->hdisplay > tilcdc_crtc_max_width(crtc))
427 return MODE_VIRTUAL_X;
428
429 /* width must be multiple of 16 */
430 if (mode->hdisplay & 0xf)
431 return MODE_VIRTUAL_X;
432
433 if (mode->vdisplay > 2048)
434 return MODE_VIRTUAL_Y;
435
436 /* filter out modes that would require too much memory bandwidth: */
437 bandwidth = mode->hdisplay * mode->vdisplay * drm_mode_vrefresh(mode);
438 if (bandwidth > priv->max_bandwidth)
439 return MODE_BAD;
440
441 return MODE_OK;
442}
443
444void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
445 const struct tilcdc_panel_info *info)
446{
447 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
448 tilcdc_crtc->info = info;
449}
450
451void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
452{
453 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
454 struct drm_device *dev = crtc->dev;
455 struct tilcdc_drm_private *priv = dev->dev_private;
456 int dpms = tilcdc_crtc->dpms;
457 unsigned int lcd_clk, div;
458 int ret;
459
460 pm_runtime_get_sync(dev->dev);
461
462 if (dpms == DRM_MODE_DPMS_ON)
463 tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
464
465 /* in raster mode, minimum divisor is 2: */
466 ret = clk_set_rate(priv->disp_clk, crtc->mode.clock * 1000 * 2);
467 if (ret) {
468 dev_err(dev->dev, "failed to set display clock rate to: %d\n",
469 crtc->mode.clock);
470 goto out;
471 }
472
473 lcd_clk = clk_get_rate(priv->clk);
474 div = lcd_clk / (crtc->mode.clock * 1000);
475
476 DBG("lcd_clk=%u, mode clock=%d, div=%u", lcd_clk, crtc->mode.clock, div);
477 DBG("fck=%lu, dpll_disp_ck=%lu", clk_get_rate(priv->clk), clk_get_rate(priv->disp_clk));
478
479 /* Configure the LCD clock divisor. */
480 tilcdc_write(dev, LCDC_CTRL_REG, LCDC_CLK_DIVISOR(div) |
481 LCDC_RASTER_MODE);
482
483 if (priv->rev == 2)
484 tilcdc_set(dev, LCDC_CLK_ENABLE_REG,
485 LCDC_V2_DMA_CLK_EN | LCDC_V2_LIDD_CLK_EN |
486 LCDC_V2_CORE_CLK_EN);
487
488 if (dpms == DRM_MODE_DPMS_ON)
489 tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
490
491out:
492 pm_runtime_put_sync(dev->dev);
493}
494
495irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
496{
497 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
498 struct drm_device *dev = crtc->dev;
499 struct tilcdc_drm_private *priv = dev->dev_private;
500 uint32_t stat = tilcdc_read_irqstatus(dev);
501
502 if ((stat & LCDC_SYNC_LOST) && (stat & LCDC_FIFO_UNDERFLOW)) {
503 stop(crtc);
504 dev_err(dev->dev, "error: %08x\n", stat);
505 tilcdc_clear_irqstatus(dev, stat);
506 start(crtc);
507 } else if (stat & LCDC_PL_LOAD_DONE) {
508 tilcdc_clear_irqstatus(dev, stat);
509 } else {
510 struct drm_pending_vblank_event *event;
511 unsigned long flags;
512 uint32_t dirty = tilcdc_crtc->dirty & stat;
513
514 tilcdc_clear_irqstatus(dev, stat);
515
516 if (dirty & LCDC_END_OF_FRAME0)
517 set_scanout(crtc, 0);
518
519 if (dirty & LCDC_END_OF_FRAME1)
520 set_scanout(crtc, 1);
521
522 drm_handle_vblank(dev, 0);
523
524 spin_lock_irqsave(&dev->event_lock, flags);
525 event = tilcdc_crtc->event;
526 tilcdc_crtc->event = NULL;
527 if (event)
528 drm_send_vblank_event(dev, 0, event);
529 spin_unlock_irqrestore(&dev->event_lock, flags);
530
531 if (dirty && !tilcdc_crtc->dirty)
532 drm_vblank_put(dev, 0);
533 }
534
535 if (priv->rev == 2) {
536 if (stat & LCDC_FRAME_DONE) {
537 tilcdc_crtc->frame_done = true;
538 wake_up(&tilcdc_crtc->frame_done_wq);
539 }
540 tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
541 }
542
543 return IRQ_HANDLED;
544}
545
546void tilcdc_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
547{
548 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
549 struct drm_pending_vblank_event *event;
550 struct drm_device *dev = crtc->dev;
551 unsigned long flags;
552
553 /* Destroy the pending vertical blanking event associated with the
554 * pending page flip, if any, and disable vertical blanking interrupts.
555 */
556 spin_lock_irqsave(&dev->event_lock, flags);
557 event = tilcdc_crtc->event;
558 if (event && event->base.file_priv == file) {
559 tilcdc_crtc->event = NULL;
560 event->base.destroy(&event->base);
561 drm_vblank_put(dev, 0);
562 }
563 spin_unlock_irqrestore(&dev->event_lock, flags);
564}
565
566struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
567{
568 struct tilcdc_crtc *tilcdc_crtc;
569 struct drm_crtc *crtc;
570 int ret;
571
572 tilcdc_crtc = kzalloc(sizeof(*tilcdc_crtc), GFP_KERNEL);
573 if (!tilcdc_crtc) {
574 dev_err(dev->dev, "allocation failed\n");
575 return NULL;
576 }
577
578 crtc = &tilcdc_crtc->base;
579
580 tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF;
581 init_waitqueue_head(&tilcdc_crtc->frame_done_wq);
582
583 ret = kfifo_alloc(&tilcdc_crtc->unref_fifo, 16, GFP_KERNEL);
584 if (ret) {
585 dev_err(dev->dev, "could not allocate unref FIFO\n");
586 goto fail;
587 }
588
589 INIT_WORK(&tilcdc_crtc->work, unref_worker);
590
591 ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs);
592 if (ret < 0)
593 goto fail;
594
595 drm_crtc_helper_add(crtc, &tilcdc_crtc_helper_funcs);
596
597 return crtc;
598
599fail:
600 tilcdc_crtc_destroy(crtc);
601 return NULL;
602}