]> Pileus Git - ~andy/linux/blob - drivers/gpu/drm/msm/mdp4/mdp4_crtc.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[~andy/linux] / drivers / gpu / drm / msm / mdp4 / mdp4_crtc.c
1 /*
2  * Copyright (C) 2013 Red Hat
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 "mdp4_kms.h"
19
20 #include <drm/drm_mode.h>
21 #include "drm_crtc.h"
22 #include "drm_crtc_helper.h"
23 #include "drm_flip_work.h"
24
25 struct mdp4_crtc {
26         struct drm_crtc base;
27         char name[8];
28         struct drm_plane *plane;
29         int id;
30         int ovlp;
31         enum mdp4_dma dma;
32         bool enabled;
33
34         /* which mixer/encoder we route output to: */
35         int mixer;
36
37         struct {
38                 spinlock_t lock;
39                 bool stale;
40                 uint32_t width, height;
41
42                 /* next cursor to scan-out: */
43                 uint32_t next_iova;
44                 struct drm_gem_object *next_bo;
45
46                 /* current cursor being scanned out: */
47                 struct drm_gem_object *scanout_bo;
48         } cursor;
49
50
51         /* if there is a pending flip, these will be non-null: */
52         struct drm_pending_vblank_event *event;
53         struct work_struct pageflip_work;
54
55         /* the fb that we currently hold a scanout ref to: */
56         struct drm_framebuffer *fb;
57
58         /* for unref'ing framebuffers after scanout completes: */
59         struct drm_flip_work unref_fb_work;
60
61         /* for unref'ing cursor bo's after scanout completes: */
62         struct drm_flip_work unref_cursor_work;
63
64         struct mdp4_irq vblank;
65         struct mdp4_irq err;
66 };
67 #define to_mdp4_crtc(x) container_of(x, struct mdp4_crtc, base)
68
69 static struct mdp4_kms *get_kms(struct drm_crtc *crtc)
70 {
71         struct msm_drm_private *priv = crtc->dev->dev_private;
72         return to_mdp4_kms(priv->kms);
73 }
74
75 static void update_fb(struct drm_crtc *crtc, bool async,
76                 struct drm_framebuffer *new_fb)
77 {
78         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
79         struct drm_framebuffer *old_fb = mdp4_crtc->fb;
80
81         if (old_fb)
82                 drm_flip_work_queue(&mdp4_crtc->unref_fb_work, old_fb);
83
84         /* grab reference to incoming scanout fb: */
85         drm_framebuffer_reference(new_fb);
86         mdp4_crtc->base.fb = new_fb;
87         mdp4_crtc->fb = new_fb;
88
89         if (!async) {
90                 /* enable vblank to pick up the old_fb */
91                 mdp4_irq_register(get_kms(crtc), &mdp4_crtc->vblank);
92         }
93 }
94
95 static void complete_flip(struct drm_crtc *crtc, bool canceled)
96 {
97         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
98         struct drm_device *dev = crtc->dev;
99         struct drm_pending_vblank_event *event;
100         unsigned long flags;
101
102         spin_lock_irqsave(&dev->event_lock, flags);
103         event = mdp4_crtc->event;
104         if (event) {
105                 mdp4_crtc->event = NULL;
106                 if (canceled)
107                         event->base.destroy(&event->base);
108                 else
109                         drm_send_vblank_event(dev, mdp4_crtc->id, event);
110         }
111         spin_unlock_irqrestore(&dev->event_lock, flags);
112 }
113
114 static void crtc_flush(struct drm_crtc *crtc)
115 {
116         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
117         struct mdp4_kms *mdp4_kms = get_kms(crtc);
118         uint32_t flush = 0;
119
120         flush |= pipe2flush(mdp4_plane_pipe(mdp4_crtc->plane));
121         flush |= ovlp2flush(mdp4_crtc->ovlp);
122
123         DBG("%s: flush=%08x", mdp4_crtc->name, flush);
124
125         mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush);
126 }
127
128 static void pageflip_worker(struct work_struct *work)
129 {
130         struct mdp4_crtc *mdp4_crtc =
131                 container_of(work, struct mdp4_crtc, pageflip_work);
132         struct drm_crtc *crtc = &mdp4_crtc->base;
133
134         mdp4_plane_set_scanout(mdp4_crtc->plane, crtc->fb);
135         crtc_flush(crtc);
136
137         /* enable vblank to complete flip: */
138         mdp4_irq_register(get_kms(crtc), &mdp4_crtc->vblank);
139 }
140
141 static void unref_fb_worker(struct drm_flip_work *work, void *val)
142 {
143         struct mdp4_crtc *mdp4_crtc =
144                 container_of(work, struct mdp4_crtc, unref_fb_work);
145         struct drm_device *dev = mdp4_crtc->base.dev;
146
147         mutex_lock(&dev->mode_config.mutex);
148         drm_framebuffer_unreference(val);
149         mutex_unlock(&dev->mode_config.mutex);
150 }
151
152 static void unref_cursor_worker(struct drm_flip_work *work, void *val)
153 {
154         struct mdp4_crtc *mdp4_crtc =
155                 container_of(work, struct mdp4_crtc, unref_cursor_work);
156         struct mdp4_kms *mdp4_kms = get_kms(&mdp4_crtc->base);
157
158         msm_gem_put_iova(val, mdp4_kms->id);
159         drm_gem_object_unreference_unlocked(val);
160 }
161
162 static void mdp4_crtc_destroy(struct drm_crtc *crtc)
163 {
164         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
165
166         mdp4_crtc->plane->funcs->destroy(mdp4_crtc->plane);
167
168         drm_crtc_cleanup(crtc);
169         drm_flip_work_cleanup(&mdp4_crtc->unref_fb_work);
170         drm_flip_work_cleanup(&mdp4_crtc->unref_cursor_work);
171
172         kfree(mdp4_crtc);
173 }
174
175 static void mdp4_crtc_dpms(struct drm_crtc *crtc, int mode)
176 {
177         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
178         struct mdp4_kms *mdp4_kms = get_kms(crtc);
179         bool enabled = (mode == DRM_MODE_DPMS_ON);
180
181         DBG("%s: mode=%d", mdp4_crtc->name, mode);
182
183         if (enabled != mdp4_crtc->enabled) {
184                 if (enabled) {
185                         mdp4_enable(mdp4_kms);
186                         mdp4_irq_register(mdp4_kms, &mdp4_crtc->err);
187                 } else {
188                         mdp4_irq_unregister(mdp4_kms, &mdp4_crtc->err);
189                         mdp4_disable(mdp4_kms);
190                 }
191                 mdp4_crtc->enabled = enabled;
192         }
193 }
194
195 static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc,
196                 const struct drm_display_mode *mode,
197                 struct drm_display_mode *adjusted_mode)
198 {
199         return true;
200 }
201
202 static void blend_setup(struct drm_crtc *crtc)
203 {
204         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
205         struct mdp4_kms *mdp4_kms = get_kms(crtc);
206         int i, ovlp = mdp4_crtc->ovlp;
207         uint32_t mixer_cfg = 0;
208
209         /*
210          * This probably would also need to be triggered by any attached
211          * plane when it changes.. for now since we are only using a single
212          * private plane, the configuration is hard-coded:
213          */
214
215         mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0);
216         mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0);
217         mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0);
218         mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0);
219
220         for (i = 0; i < 4; i++) {
221                 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0);
222                 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0);
223                 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i),
224                                 MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |
225                                 MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST));
226                 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 0);
227                 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW0(ovlp, i), 0);
228                 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW1(ovlp, i), 0);
229                 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(ovlp, i), 0);
230                 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0);
231         }
232
233         /* TODO single register for all CRTCs, so this won't work properly
234          * when multiple CRTCs are active..
235          */
236         switch (mdp4_plane_pipe(mdp4_crtc->plane)) {
237         case VG1:
238                 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(STAGE_BASE) |
239                         COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
240                 break;
241         case VG2:
242                 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(STAGE_BASE) |
243                         COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
244                 break;
245         case RGB1:
246                 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(STAGE_BASE) |
247                         COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
248                 break;
249         case RGB2:
250                 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(STAGE_BASE) |
251                         COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
252                 break;
253         case RGB3:
254                 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(STAGE_BASE) |
255                         COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
256                 break;
257         case VG3:
258                 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(STAGE_BASE) |
259                         COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
260                 break;
261         case VG4:
262                 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(STAGE_BASE) |
263                         COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
264                 break;
265         default:
266                 WARN_ON("invalid pipe");
267                 break;
268         }
269         mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg);
270 }
271
272 static int mdp4_crtc_mode_set(struct drm_crtc *crtc,
273                 struct drm_display_mode *mode,
274                 struct drm_display_mode *adjusted_mode,
275                 int x, int y,
276                 struct drm_framebuffer *old_fb)
277 {
278         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
279         struct mdp4_kms *mdp4_kms = get_kms(crtc);
280         enum mdp4_dma dma = mdp4_crtc->dma;
281         int ret, ovlp = mdp4_crtc->ovlp;
282
283         mode = adjusted_mode;
284
285         DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
286                         mdp4_crtc->name, mode->base.id, mode->name,
287                         mode->vrefresh, mode->clock,
288                         mode->hdisplay, mode->hsync_start,
289                         mode->hsync_end, mode->htotal,
290                         mode->vdisplay, mode->vsync_start,
291                         mode->vsync_end, mode->vtotal,
292                         mode->type, mode->flags);
293
294         mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma),
295                         MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) |
296                         MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay));
297
298         /* take data from pipe: */
299         mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_BASE(dma), 0);
300         mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_STRIDE(dma),
301                         crtc->fb->pitches[0]);
302         mdp4_write(mdp4_kms, REG_MDP4_DMA_DST_SIZE(dma),
303                         MDP4_DMA_DST_SIZE_WIDTH(0) |
304                         MDP4_DMA_DST_SIZE_HEIGHT(0));
305
306         mdp4_write(mdp4_kms, REG_MDP4_OVLP_BASE(ovlp), 0);
307         mdp4_write(mdp4_kms, REG_MDP4_OVLP_SIZE(ovlp),
308                         MDP4_OVLP_SIZE_WIDTH(mode->hdisplay) |
309                         MDP4_OVLP_SIZE_HEIGHT(mode->vdisplay));
310         mdp4_write(mdp4_kms, REG_MDP4_OVLP_STRIDE(ovlp),
311                         crtc->fb->pitches[0]);
312
313         mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1);
314
315         update_fb(crtc, false, crtc->fb);
316
317         ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb,
318                         0, 0, mode->hdisplay, mode->vdisplay,
319                         x << 16, y << 16,
320                         mode->hdisplay << 16, mode->vdisplay << 16);
321         if (ret) {
322                 dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n",
323                                 mdp4_crtc->name, ret);
324                 return ret;
325         }
326
327         if (dma == DMA_E) {
328                 mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000);
329                 mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000);
330                 mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000);
331         }
332
333         return 0;
334 }
335
336 static void mdp4_crtc_prepare(struct drm_crtc *crtc)
337 {
338         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
339         DBG("%s", mdp4_crtc->name);
340         /* make sure we hold a ref to mdp clks while setting up mode: */
341         mdp4_enable(get_kms(crtc));
342         mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
343 }
344
345 static void mdp4_crtc_commit(struct drm_crtc *crtc)
346 {
347         mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
348         crtc_flush(crtc);
349         /* drop the ref to mdp clk's that we got in prepare: */
350         mdp4_disable(get_kms(crtc));
351 }
352
353 static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
354                 struct drm_framebuffer *old_fb)
355 {
356         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
357         struct drm_plane *plane = mdp4_crtc->plane;
358         struct drm_display_mode *mode = &crtc->mode;
359
360         update_fb(crtc, false, crtc->fb);
361
362         return mdp4_plane_mode_set(plane, crtc, crtc->fb,
363                         0, 0, mode->hdisplay, mode->vdisplay,
364                         x << 16, y << 16,
365                         mode->hdisplay << 16, mode->vdisplay << 16);
366 }
367
368 static void mdp4_crtc_load_lut(struct drm_crtc *crtc)
369 {
370 }
371
372 static int mdp4_crtc_page_flip(struct drm_crtc *crtc,
373                 struct drm_framebuffer *new_fb,
374                 struct drm_pending_vblank_event *event,
375                 uint32_t page_flip_flags)
376 {
377         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
378         struct drm_device *dev = crtc->dev;
379         struct drm_gem_object *obj;
380
381         if (mdp4_crtc->event) {
382                 dev_err(dev->dev, "already pending flip!\n");
383                 return -EBUSY;
384         }
385
386         obj = msm_framebuffer_bo(new_fb, 0);
387
388         mdp4_crtc->event = event;
389         update_fb(crtc, true, new_fb);
390
391         return msm_gem_queue_inactive_work(obj,
392                         &mdp4_crtc->pageflip_work);
393 }
394
395 static int mdp4_crtc_set_property(struct drm_crtc *crtc,
396                 struct drm_property *property, uint64_t val)
397 {
398         // XXX
399         return -EINVAL;
400 }
401
402 #define CURSOR_WIDTH 64
403 #define CURSOR_HEIGHT 64
404
405 /* called from IRQ to update cursor related registers (if needed).  The
406  * cursor registers, other than x/y position, appear not to be double
407  * buffered, and changing them other than from vblank seems to trigger
408  * underflow.
409  */
410 static void update_cursor(struct drm_crtc *crtc)
411 {
412         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
413         enum mdp4_dma dma = mdp4_crtc->dma;
414         unsigned long flags;
415
416         spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
417         if (mdp4_crtc->cursor.stale) {
418                 struct mdp4_kms *mdp4_kms = get_kms(crtc);
419                 struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo;
420                 struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo;
421                 uint32_t iova = mdp4_crtc->cursor.next_iova;
422
423                 if (next_bo) {
424                         /* take a obj ref + iova ref when we start scanning out: */
425                         drm_gem_object_reference(next_bo);
426                         msm_gem_get_iova_locked(next_bo, mdp4_kms->id, &iova);
427
428                         /* enable cursor: */
429                         mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma),
430                                         MDP4_DMA_CURSOR_SIZE_WIDTH(mdp4_crtc->cursor.width) |
431                                         MDP4_DMA_CURSOR_SIZE_HEIGHT(mdp4_crtc->cursor.height));
432                         mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), iova);
433                         mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BLEND_CONFIG(dma),
434                                         MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(CURSOR_ARGB) |
435                                         MDP4_DMA_CURSOR_BLEND_CONFIG_CURSOR_EN);
436                 } else {
437                         /* disable cursor: */
438                         mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), 0);
439                         mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BLEND_CONFIG(dma),
440                                         MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(CURSOR_ARGB));
441                 }
442
443                 /* and drop the iova ref + obj rev when done scanning out: */
444                 if (prev_bo)
445                         drm_flip_work_queue(&mdp4_crtc->unref_cursor_work, prev_bo);
446
447                 mdp4_crtc->cursor.scanout_bo = next_bo;
448                 mdp4_crtc->cursor.stale = false;
449         }
450         spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
451 }
452
453 static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
454                 struct drm_file *file_priv, uint32_t handle,
455                 uint32_t width, uint32_t height)
456 {
457         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
458         struct mdp4_kms *mdp4_kms = get_kms(crtc);
459         struct drm_device *dev = crtc->dev;
460         struct drm_gem_object *cursor_bo, *old_bo;
461         unsigned long flags;
462         uint32_t iova;
463         int ret;
464
465         if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
466                 dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height);
467                 return -EINVAL;
468         }
469
470         if (handle) {
471                 cursor_bo = drm_gem_object_lookup(dev, file_priv, handle);
472                 if (!cursor_bo)
473                         return -ENOENT;
474         } else {
475                 cursor_bo = NULL;
476         }
477
478         if (cursor_bo) {
479                 ret = msm_gem_get_iova(cursor_bo, mdp4_kms->id, &iova);
480                 if (ret)
481                         goto fail;
482         } else {
483                 iova = 0;
484         }
485
486         spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
487         old_bo = mdp4_crtc->cursor.next_bo;
488         mdp4_crtc->cursor.next_bo   = cursor_bo;
489         mdp4_crtc->cursor.next_iova = iova;
490         mdp4_crtc->cursor.width     = width;
491         mdp4_crtc->cursor.height    = height;
492         mdp4_crtc->cursor.stale     = true;
493         spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
494
495         if (old_bo) {
496                 /* drop our previous reference: */
497                 msm_gem_put_iova(old_bo, mdp4_kms->id);
498                 drm_gem_object_unreference_unlocked(old_bo);
499         }
500
501         return 0;
502
503 fail:
504         drm_gem_object_unreference_unlocked(cursor_bo);
505         return ret;
506 }
507
508 static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
509 {
510         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
511         struct mdp4_kms *mdp4_kms = get_kms(crtc);
512         enum mdp4_dma dma = mdp4_crtc->dma;
513
514         mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma),
515                         MDP4_DMA_CURSOR_POS_X(x) |
516                         MDP4_DMA_CURSOR_POS_Y(y));
517
518         return 0;
519 }
520
521 static const struct drm_crtc_funcs mdp4_crtc_funcs = {
522         .set_config = drm_crtc_helper_set_config,
523         .destroy = mdp4_crtc_destroy,
524         .page_flip = mdp4_crtc_page_flip,
525         .set_property = mdp4_crtc_set_property,
526         .cursor_set = mdp4_crtc_cursor_set,
527         .cursor_move = mdp4_crtc_cursor_move,
528 };
529
530 static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = {
531         .dpms = mdp4_crtc_dpms,
532         .mode_fixup = mdp4_crtc_mode_fixup,
533         .mode_set = mdp4_crtc_mode_set,
534         .prepare = mdp4_crtc_prepare,
535         .commit = mdp4_crtc_commit,
536         .mode_set_base = mdp4_crtc_mode_set_base,
537         .load_lut = mdp4_crtc_load_lut,
538 };
539
540 static void mdp4_crtc_vblank_irq(struct mdp4_irq *irq, uint32_t irqstatus)
541 {
542         struct mdp4_crtc *mdp4_crtc = container_of(irq, struct mdp4_crtc, vblank);
543         struct drm_crtc *crtc = &mdp4_crtc->base;
544         struct msm_drm_private *priv = crtc->dev->dev_private;
545
546         update_cursor(crtc);
547         complete_flip(crtc, false);
548         mdp4_irq_unregister(get_kms(crtc), &mdp4_crtc->vblank);
549
550         drm_flip_work_commit(&mdp4_crtc->unref_fb_work, priv->wq);
551         drm_flip_work_commit(&mdp4_crtc->unref_cursor_work, priv->wq);
552 }
553
554 static void mdp4_crtc_err_irq(struct mdp4_irq *irq, uint32_t irqstatus)
555 {
556         struct mdp4_crtc *mdp4_crtc = container_of(irq, struct mdp4_crtc, err);
557         struct drm_crtc *crtc = &mdp4_crtc->base;
558         DBG("%s: error: %08x", mdp4_crtc->name, irqstatus);
559         crtc_flush(crtc);
560 }
561
562 uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc)
563 {
564         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
565         return mdp4_crtc->vblank.irqmask;
566 }
567
568 void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc)
569 {
570         complete_flip(crtc, true);
571 }
572
573 /* set dma config, ie. the format the encoder wants. */
574 void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config)
575 {
576         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
577         struct mdp4_kms *mdp4_kms = get_kms(crtc);
578
579         mdp4_write(mdp4_kms, REG_MDP4_DMA_CONFIG(mdp4_crtc->dma), config);
580 }
581
582 /* set interface for routing crtc->encoder: */
583 void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf)
584 {
585         struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
586         struct mdp4_kms *mdp4_kms = get_kms(crtc);
587         uint32_t intf_sel;
588
589         intf_sel = mdp4_read(mdp4_kms, REG_MDP4_DISP_INTF_SEL);
590
591         switch (mdp4_crtc->dma) {
592         case DMA_P:
593                 intf_sel &= ~MDP4_DISP_INTF_SEL_PRIM__MASK;
594                 intf_sel |= MDP4_DISP_INTF_SEL_PRIM(intf);
595                 break;
596         case DMA_S:
597                 intf_sel &= ~MDP4_DISP_INTF_SEL_SEC__MASK;
598                 intf_sel |= MDP4_DISP_INTF_SEL_SEC(intf);
599                 break;
600         case DMA_E:
601                 intf_sel &= ~MDP4_DISP_INTF_SEL_EXT__MASK;
602                 intf_sel |= MDP4_DISP_INTF_SEL_EXT(intf);
603                 break;
604         }
605
606         if (intf == INTF_DSI_VIDEO) {
607                 intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_CMD;
608                 intf_sel |= MDP4_DISP_INTF_SEL_DSI_VIDEO;
609                 mdp4_crtc->mixer = 0;
610         } else if (intf == INTF_DSI_CMD) {
611                 intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_VIDEO;
612                 intf_sel |= MDP4_DISP_INTF_SEL_DSI_CMD;
613                 mdp4_crtc->mixer = 0;
614         } else if (intf == INTF_LCDC_DTV){
615                 mdp4_crtc->mixer = 1;
616         }
617
618         blend_setup(crtc);
619
620         DBG("%s: intf_sel=%08x", mdp4_crtc->name, intf_sel);
621
622         mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel);
623 }
624
625 static const char *dma_names[] = {
626                 "DMA_P", "DMA_S", "DMA_E",
627 };
628
629 /* initialize crtc */
630 struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
631                 struct drm_plane *plane, int id, int ovlp_id,
632                 enum mdp4_dma dma_id)
633 {
634         struct drm_crtc *crtc = NULL;
635         struct mdp4_crtc *mdp4_crtc;
636         int ret;
637
638         mdp4_crtc = kzalloc(sizeof(*mdp4_crtc), GFP_KERNEL);
639         if (!mdp4_crtc) {
640                 ret = -ENOMEM;
641                 goto fail;
642         }
643
644         crtc = &mdp4_crtc->base;
645
646         mdp4_crtc->plane = plane;
647         mdp4_crtc->plane->crtc = crtc;
648
649         mdp4_crtc->ovlp = ovlp_id;
650         mdp4_crtc->dma = dma_id;
651
652         mdp4_crtc->vblank.irqmask = dma2irq(mdp4_crtc->dma);
653         mdp4_crtc->vblank.irq = mdp4_crtc_vblank_irq;
654
655         mdp4_crtc->err.irqmask = dma2err(mdp4_crtc->dma);
656         mdp4_crtc->err.irq = mdp4_crtc_err_irq;
657
658         snprintf(mdp4_crtc->name, sizeof(mdp4_crtc->name), "%s:%d",
659                         dma_names[dma_id], ovlp_id);
660
661         spin_lock_init(&mdp4_crtc->cursor.lock);
662
663         ret = drm_flip_work_init(&mdp4_crtc->unref_fb_work, 16,
664                         "unref fb", unref_fb_worker);
665         if (ret)
666                 goto fail;
667
668         ret = drm_flip_work_init(&mdp4_crtc->unref_cursor_work, 64,
669                         "unref cursor", unref_cursor_worker);
670
671         INIT_WORK(&mdp4_crtc->pageflip_work, pageflip_worker);
672
673         drm_crtc_init(dev, crtc, &mdp4_crtc_funcs);
674         drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs);
675
676         mdp4_plane_install_properties(mdp4_crtc->plane, &crtc->base);
677
678         return crtc;
679
680 fail:
681         if (crtc)
682                 mdp4_crtc_destroy(crtc);
683
684         return ERR_PTR(ret);
685 }