]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/rcar-du/rcar_du_crtc.c
drm: Renesas R-Car Display Unit DRM driver
[karo-tx-linux.git] / drivers / gpu / drm / rcar-du / rcar_du_crtc.c
1 /*
2  * rcar_du_crtc.c  --  R-Car Display Unit CRTCs
3  *
4  * Copyright (C) 2013 Renesas Corporation
5  *
6  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13
14 #include <linux/clk.h>
15 #include <linux/mutex.h>
16
17 #include <drm/drmP.h>
18 #include <drm/drm_crtc.h>
19 #include <drm/drm_crtc_helper.h>
20 #include <drm/drm_fb_cma_helper.h>
21 #include <drm/drm_gem_cma_helper.h>
22
23 #include "rcar_du_crtc.h"
24 #include "rcar_du_drv.h"
25 #include "rcar_du_kms.h"
26 #include "rcar_du_lvds.h"
27 #include "rcar_du_plane.h"
28 #include "rcar_du_regs.h"
29 #include "rcar_du_vga.h"
30
31 #define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc)
32
33 static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
34 {
35         struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
36
37         return rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
38 }
39
40 static void rcar_du_crtc_write(struct rcar_du_crtc *rcrtc, u32 reg, u32 data)
41 {
42         struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
43
44         rcar_du_write(rcdu, rcrtc->mmio_offset + reg, data);
45 }
46
47 static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr)
48 {
49         struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
50
51         rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
52                       rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
53 }
54
55 static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
56 {
57         struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
58
59         rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
60                       rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
61 }
62
63 static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
64                                  u32 clr, u32 set)
65 {
66         struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
67         u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
68
69         rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
70 }
71
72 static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
73 {
74         struct drm_crtc *crtc = &rcrtc->crtc;
75         struct rcar_du_device *rcdu = crtc->dev->dev_private;
76         const struct drm_display_mode *mode = &crtc->mode;
77         unsigned long clk;
78         u32 value;
79         u32 div;
80
81         /* Dot clock */
82         clk = clk_get_rate(rcdu->clock);
83         div = DIV_ROUND_CLOSEST(clk, mode->clock * 1000);
84         div = clamp(div, 1U, 64U) - 1;
85
86         rcar_du_write(rcdu, rcrtc->index ? ESCR2 : ESCR,
87                       ESCR_DCLKSEL_CLKS | div);
88         rcar_du_write(rcdu, rcrtc->index ? OTAR2 : OTAR, 0);
89
90         /* Signal polarities */
91         value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : DSMR_VSL)
92               | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : DSMR_HSL)
93               | DSMR_DIPM_DE;
94         rcar_du_crtc_write(rcrtc, DSMR, value);
95
96         /* Display timings */
97         rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - 19);
98         rcar_du_crtc_write(rcrtc, HDER, mode->htotal - mode->hsync_start +
99                                         mode->hdisplay - 19);
100         rcar_du_crtc_write(rcrtc, HSWR, mode->hsync_end -
101                                         mode->hsync_start - 1);
102         rcar_du_crtc_write(rcrtc, HCR,  mode->htotal - 1);
103
104         rcar_du_crtc_write(rcrtc, VDSR, mode->vtotal - mode->vsync_end - 2);
105         rcar_du_crtc_write(rcrtc, VDER, mode->vtotal - mode->vsync_end +
106                                         mode->vdisplay - 2);
107         rcar_du_crtc_write(rcrtc, VSPR, mode->vtotal - mode->vsync_end +
108                                         mode->vsync_start - 1);
109         rcar_du_crtc_write(rcrtc, VCR,  mode->vtotal - 1);
110
111         rcar_du_crtc_write(rcrtc, DESR,  mode->htotal - mode->hsync_start);
112         rcar_du_crtc_write(rcrtc, DEWR,  mode->hdisplay);
113 }
114
115 static void rcar_du_crtc_set_routing(struct rcar_du_crtc *rcrtc)
116 {
117         struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
118         u32 dorcr = rcar_du_read(rcdu, DORCR);
119
120         dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK);
121
122         /* Set the DU1 pins sources. Select CRTC 0 if explicitly requested and
123          * CRTC 1 in all other cases to avoid cloning CRTC 0 to DU0 and DU1 by
124          * default.
125          */
126         if (rcrtc->outputs & (1 << 1) && rcrtc->index == 0)
127                 dorcr |= DORCR_PG2D_DS1;
128         else
129                 dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2;
130
131         rcar_du_write(rcdu, DORCR, dorcr);
132 }
133
134 static void __rcar_du_start_stop(struct rcar_du_device *rcdu, bool start)
135 {
136         rcar_du_write(rcdu, DSYSR,
137                       (rcar_du_read(rcdu, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) |
138                       (start ? DSYSR_DEN : DSYSR_DRES));
139 }
140
141 static void rcar_du_start_stop(struct rcar_du_device *rcdu, bool start)
142 {
143         /* Many of the configuration bits are only updated when the display
144          * reset (DRES) bit in DSYSR is set to 1, disabling *both* CRTCs. Some
145          * of those bits could be pre-configured, but others (especially the
146          * bits related to plane assignment to display timing controllers) need
147          * to be modified at runtime.
148          *
149          * Restart the display controller if a start is requested. Sorry for the
150          * flicker. It should be possible to move most of the "DRES-update" bits
151          * setup to driver initialization time and minimize the number of cases
152          * when the display controller will have to be restarted.
153          */
154         if (start) {
155                 if (rcdu->used_crtcs++ != 0)
156                         __rcar_du_start_stop(rcdu, false);
157                 __rcar_du_start_stop(rcdu, true);
158         } else {
159                 if (--rcdu->used_crtcs == 0)
160                         __rcar_du_start_stop(rcdu, false);
161         }
162 }
163
164 void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output)
165 {
166         struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
167
168         /* Store the route from the CRTC output to the DU output. The DU will be
169          * configured when starting the CRTC.
170          */
171         rcrtc->outputs |= 1 << output;
172 }
173
174 void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
175 {
176         struct rcar_du_device *rcdu = crtc->dev->dev_private;
177         struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
178         struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
179         unsigned int num_planes = 0;
180         unsigned int prio = 0;
181         unsigned int i;
182         u32 dptsr = 0;
183         u32 dspr = 0;
184
185         for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) {
186                 struct rcar_du_plane *plane = &rcdu->planes.planes[i];
187                 unsigned int j;
188
189                 if (plane->crtc != &rcrtc->crtc || !plane->enabled)
190                         continue;
191
192                 /* Insert the plane in the sorted planes array. */
193                 for (j = num_planes++; j > 0; --j) {
194                         if (planes[j-1]->zpos <= plane->zpos)
195                                 break;
196                         planes[j] = planes[j-1];
197                 }
198
199                 planes[j] = plane;
200                 prio += plane->format->planes * 4;
201         }
202
203         for (i = 0; i < num_planes; ++i) {
204                 struct rcar_du_plane *plane = planes[i];
205                 unsigned int index = plane->hwindex;
206
207                 prio -= 4;
208                 dspr |= (index + 1) << prio;
209                 dptsr |= DPTSR_PnDK(index) |  DPTSR_PnTS(index);
210
211                 if (plane->format->planes == 2) {
212                         index = (index + 1) % 8;
213
214                         prio -= 4;
215                         dspr |= (index + 1) << prio;
216                         dptsr |= DPTSR_PnDK(index) |  DPTSR_PnTS(index);
217                 }
218         }
219
220         /* Select display timing and dot clock generator 2 for planes associated
221          * with superposition controller 2.
222          */
223         if (rcrtc->index) {
224                 u32 value = rcar_du_read(rcdu, DPTSR);
225
226                 /* The DPTSR register is updated when the display controller is
227                  * stopped. We thus need to restart the DU. Once again, sorry
228                  * for the flicker. One way to mitigate the issue would be to
229                  * pre-associate planes with CRTCs (either with a fixed 4/4
230                  * split, or through a module parameter). Flicker would then
231                  * occur only if we need to break the pre-association.
232                  */
233                 if (value != dptsr) {
234                         rcar_du_write(rcdu, DPTSR, dptsr);
235                         if (rcdu->used_crtcs) {
236                                 __rcar_du_start_stop(rcdu, false);
237                                 __rcar_du_start_stop(rcdu, true);
238                         }
239                 }
240         }
241
242         rcar_du_write(rcdu, rcrtc->index ? DS2PR : DS1PR, dspr);
243 }
244
245 static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
246 {
247         struct drm_crtc *crtc = &rcrtc->crtc;
248         struct rcar_du_device *rcdu = crtc->dev->dev_private;
249         unsigned int i;
250
251         if (rcrtc->started)
252                 return;
253
254         if (WARN_ON(rcrtc->plane->format == NULL))
255                 return;
256
257         /* Set display off and background to black */
258         rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
259         rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0));
260
261         /* Configure display timings and output routing */
262         rcar_du_crtc_set_display_timing(rcrtc);
263         rcar_du_crtc_set_routing(rcrtc);
264
265         mutex_lock(&rcdu->planes.lock);
266         rcrtc->plane->enabled = true;
267         rcar_du_crtc_update_planes(crtc);
268         mutex_unlock(&rcdu->planes.lock);
269
270         /* Setup planes. */
271         for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) {
272                 struct rcar_du_plane *plane = &rcdu->planes.planes[i];
273
274                 if (plane->crtc != crtc || !plane->enabled)
275                         continue;
276
277                 rcar_du_plane_setup(plane);
278         }
279
280         /* Select master sync mode. This enables display operation in master
281          * sync mode (with the HSYNC and VSYNC signals configured as outputs and
282          * actively driven).
283          */
284         rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_MASTER);
285
286         rcar_du_start_stop(rcdu, true);
287
288         rcrtc->started = true;
289 }
290
291 static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
292 {
293         struct drm_crtc *crtc = &rcrtc->crtc;
294         struct rcar_du_device *rcdu = crtc->dev->dev_private;
295
296         if (!rcrtc->started)
297                 return;
298
299         mutex_lock(&rcdu->planes.lock);
300         rcrtc->plane->enabled = false;
301         rcar_du_crtc_update_planes(crtc);
302         mutex_unlock(&rcdu->planes.lock);
303
304         /* Select switch sync mode. This stops display operation and configures
305          * the HSYNC and VSYNC signals as inputs.
306          */
307         rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
308
309         rcar_du_start_stop(rcdu, false);
310
311         rcrtc->started = false;
312 }
313
314 void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
315 {
316         struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
317
318         rcar_du_crtc_stop(rcrtc);
319         rcar_du_put(rcdu);
320 }
321
322 void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
323 {
324         struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
325
326         if (rcrtc->dpms != DRM_MODE_DPMS_ON)
327                 return;
328
329         rcar_du_get(rcdu);
330         rcar_du_crtc_start(rcrtc);
331 }
332
333 static void rcar_du_crtc_update_base(struct rcar_du_crtc *rcrtc)
334 {
335         struct drm_crtc *crtc = &rcrtc->crtc;
336
337         rcar_du_plane_compute_base(rcrtc->plane, crtc->fb);
338         rcar_du_plane_update_base(rcrtc->plane);
339 }
340
341 static void rcar_du_crtc_dpms(struct drm_crtc *crtc, int mode)
342 {
343         struct rcar_du_device *rcdu = crtc->dev->dev_private;
344         struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
345
346         if (rcrtc->dpms == mode)
347                 return;
348
349         if (mode == DRM_MODE_DPMS_ON) {
350                 rcar_du_get(rcdu);
351                 rcar_du_crtc_start(rcrtc);
352         } else {
353                 rcar_du_crtc_stop(rcrtc);
354                 rcar_du_put(rcdu);
355         }
356
357         rcrtc->dpms = mode;
358 }
359
360 static bool rcar_du_crtc_mode_fixup(struct drm_crtc *crtc,
361                                     const struct drm_display_mode *mode,
362                                     struct drm_display_mode *adjusted_mode)
363 {
364         /* TODO Fixup modes */
365         return true;
366 }
367
368 static void rcar_du_crtc_mode_prepare(struct drm_crtc *crtc)
369 {
370         struct rcar_du_device *rcdu = crtc->dev->dev_private;
371         struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
372
373         /* We need to access the hardware during mode set, acquire a reference
374          * to the DU.
375          */
376         rcar_du_get(rcdu);
377
378         /* Stop the CRTC and release the plane. Force the DPMS mode to off as a
379          * result.
380          */
381         rcar_du_crtc_stop(rcrtc);
382         rcar_du_plane_release(rcrtc->plane);
383
384         rcrtc->dpms = DRM_MODE_DPMS_OFF;
385 }
386
387 static int rcar_du_crtc_mode_set(struct drm_crtc *crtc,
388                                  struct drm_display_mode *mode,
389                                  struct drm_display_mode *adjusted_mode,
390                                  int x, int y,
391                                  struct drm_framebuffer *old_fb)
392 {
393         struct rcar_du_device *rcdu = crtc->dev->dev_private;
394         struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
395         const struct rcar_du_format_info *format;
396         int ret;
397
398         format = rcar_du_format_info(crtc->fb->pixel_format);
399         if (format == NULL) {
400                 dev_dbg(rcdu->dev, "mode_set: unsupported format %08x\n",
401                         crtc->fb->pixel_format);
402                 ret = -EINVAL;
403                 goto error;
404         }
405
406         ret = rcar_du_plane_reserve(rcrtc->plane, format);
407         if (ret < 0)
408                 goto error;
409
410         rcrtc->plane->format = format;
411         rcrtc->plane->pitch = crtc->fb->pitches[0];
412
413         rcrtc->plane->src_x = x;
414         rcrtc->plane->src_y = y;
415         rcrtc->plane->width = mode->hdisplay;
416         rcrtc->plane->height = mode->vdisplay;
417
418         rcar_du_plane_compute_base(rcrtc->plane, crtc->fb);
419
420         rcrtc->outputs = 0;
421
422         return 0;
423
424 error:
425         /* There's no rollback/abort operation to clean up in case of error. We
426          * thus need to release the reference to the DU acquired in prepare()
427          * here.
428          */
429         rcar_du_put(rcdu);
430         return ret;
431 }
432
433 static void rcar_du_crtc_mode_commit(struct drm_crtc *crtc)
434 {
435         struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
436
437         /* We're done, restart the CRTC and set the DPMS mode to on. The
438          * reference to the DU acquired at prepare() time will thus be released
439          * by the DPMS handler (possibly called by the disable() handler).
440          */
441         rcar_du_crtc_start(rcrtc);
442         rcrtc->dpms = DRM_MODE_DPMS_ON;
443 }
444
445 static int rcar_du_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
446                                       struct drm_framebuffer *old_fb)
447 {
448         struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
449
450         rcrtc->plane->src_x = x;
451         rcrtc->plane->src_y = y;
452
453         rcar_du_crtc_update_base(to_rcar_crtc(crtc));
454
455         return 0;
456 }
457
458 static void rcar_du_crtc_disable(struct drm_crtc *crtc)
459 {
460         struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
461
462         rcar_du_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
463         rcar_du_plane_release(rcrtc->plane);
464 }
465
466 static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
467         .dpms = rcar_du_crtc_dpms,
468         .mode_fixup = rcar_du_crtc_mode_fixup,
469         .prepare = rcar_du_crtc_mode_prepare,
470         .commit = rcar_du_crtc_mode_commit,
471         .mode_set = rcar_du_crtc_mode_set,
472         .mode_set_base = rcar_du_crtc_mode_set_base,
473         .disable = rcar_du_crtc_disable,
474 };
475
476 void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc,
477                                    struct drm_file *file)
478 {
479         struct drm_pending_vblank_event *event;
480         struct drm_device *dev = rcrtc->crtc.dev;
481         unsigned long flags;
482
483         /* Destroy the pending vertical blanking event associated with the
484          * pending page flip, if any, and disable vertical blanking interrupts.
485          */
486         spin_lock_irqsave(&dev->event_lock, flags);
487         event = rcrtc->event;
488         if (event && event->base.file_priv == file) {
489                 rcrtc->event = NULL;
490                 event->base.destroy(&event->base);
491                 drm_vblank_put(dev, rcrtc->index);
492         }
493         spin_unlock_irqrestore(&dev->event_lock, flags);
494 }
495
496 static void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc)
497 {
498         struct drm_pending_vblank_event *event;
499         struct drm_device *dev = rcrtc->crtc.dev;
500         unsigned long flags;
501
502         spin_lock_irqsave(&dev->event_lock, flags);
503         event = rcrtc->event;
504         rcrtc->event = NULL;
505         spin_unlock_irqrestore(&dev->event_lock, flags);
506
507         if (event == NULL)
508                 return;
509
510         spin_lock_irqsave(&dev->event_lock, flags);
511         drm_send_vblank_event(dev, rcrtc->index, event);
512         spin_unlock_irqrestore(&dev->event_lock, flags);
513
514         drm_vblank_put(dev, rcrtc->index);
515 }
516
517 static int rcar_du_crtc_page_flip(struct drm_crtc *crtc,
518                                   struct drm_framebuffer *fb,
519                                   struct drm_pending_vblank_event *event)
520 {
521         struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
522         struct drm_device *dev = rcrtc->crtc.dev;
523         unsigned long flags;
524
525         spin_lock_irqsave(&dev->event_lock, flags);
526         if (rcrtc->event != NULL) {
527                 spin_unlock_irqrestore(&dev->event_lock, flags);
528                 return -EBUSY;
529         }
530         spin_unlock_irqrestore(&dev->event_lock, flags);
531
532         crtc->fb = fb;
533         rcar_du_crtc_update_base(rcrtc);
534
535         if (event) {
536                 event->pipe = rcrtc->index;
537                 drm_vblank_get(dev, rcrtc->index);
538                 spin_lock_irqsave(&dev->event_lock, flags);
539                 rcrtc->event = event;
540                 spin_unlock_irqrestore(&dev->event_lock, flags);
541         }
542
543         return 0;
544 }
545
546 static const struct drm_crtc_funcs crtc_funcs = {
547         .destroy = drm_crtc_cleanup,
548         .set_config = drm_crtc_helper_set_config,
549         .page_flip = rcar_du_crtc_page_flip,
550 };
551
552 int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index)
553 {
554         struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index];
555         struct drm_crtc *crtc = &rcrtc->crtc;
556         int ret;
557
558         rcrtc->mmio_offset = index ? DISP2_REG_OFFSET : 0;
559         rcrtc->index = index;
560         rcrtc->dpms = DRM_MODE_DPMS_OFF;
561         rcrtc->plane = &rcdu->planes.planes[index];
562
563         rcrtc->plane->crtc = crtc;
564
565         ret = drm_crtc_init(rcdu->ddev, crtc, &crtc_funcs);
566         if (ret < 0)
567                 return ret;
568
569         drm_crtc_helper_add(crtc, &crtc_helper_funcs);
570
571         return 0;
572 }
573
574 void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable)
575 {
576         if (enable) {
577                 rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
578                 rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
579         } else {
580                 rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE);
581         }
582 }
583
584 void rcar_du_crtc_irq(struct rcar_du_crtc *rcrtc)
585 {
586         u32 status;
587
588         status = rcar_du_crtc_read(rcrtc, DSSR);
589         rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
590
591         if (status & DSSR_VBK) {
592                 drm_handle_vblank(rcrtc->crtc.dev, rcrtc->index);
593                 rcar_du_crtc_finish_page_flip(rcrtc);
594         }
595 }