2 * rcar_du_crtc.c -- R-Car Display Unit CRTCs
4 * Copyright (C) 2013-2014 Renesas Electronics Corporation
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
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.
14 #include <linux/clk.h>
15 #include <linux/mutex.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 #include <drm/drm_plane_helper.h>
24 #include "rcar_du_crtc.h"
25 #include "rcar_du_drv.h"
26 #include "rcar_du_kms.h"
27 #include "rcar_du_plane.h"
28 #include "rcar_du_regs.h"
30 static u32
rcar_du_crtc_read(struct rcar_du_crtc
*rcrtc
, u32 reg
)
32 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
34 return rcar_du_read(rcdu
, rcrtc
->mmio_offset
+ reg
);
37 static void rcar_du_crtc_write(struct rcar_du_crtc
*rcrtc
, u32 reg
, u32 data
)
39 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
41 rcar_du_write(rcdu
, rcrtc
->mmio_offset
+ reg
, data
);
44 static void rcar_du_crtc_clr(struct rcar_du_crtc
*rcrtc
, u32 reg
, u32 clr
)
46 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
48 rcar_du_write(rcdu
, rcrtc
->mmio_offset
+ reg
,
49 rcar_du_read(rcdu
, rcrtc
->mmio_offset
+ reg
) & ~clr
);
52 static void rcar_du_crtc_set(struct rcar_du_crtc
*rcrtc
, u32 reg
, u32 set
)
54 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
56 rcar_du_write(rcdu
, rcrtc
->mmio_offset
+ reg
,
57 rcar_du_read(rcdu
, rcrtc
->mmio_offset
+ reg
) | set
);
60 static void rcar_du_crtc_clr_set(struct rcar_du_crtc
*rcrtc
, u32 reg
,
63 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
64 u32 value
= rcar_du_read(rcdu
, rcrtc
->mmio_offset
+ reg
);
66 rcar_du_write(rcdu
, rcrtc
->mmio_offset
+ reg
, (value
& ~clr
) | set
);
69 static int rcar_du_crtc_get(struct rcar_du_crtc
*rcrtc
)
73 ret
= clk_prepare_enable(rcrtc
->clock
);
77 ret
= clk_prepare_enable(rcrtc
->extclock
);
81 ret
= rcar_du_group_get(rcrtc
->group
);
88 clk_disable_unprepare(rcrtc
->extclock
);
90 clk_disable_unprepare(rcrtc
->clock
);
94 static void rcar_du_crtc_put(struct rcar_du_crtc
*rcrtc
)
96 rcar_du_group_put(rcrtc
->group
);
98 clk_disable_unprepare(rcrtc
->extclock
);
99 clk_disable_unprepare(rcrtc
->clock
);
102 static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc
*rcrtc
)
104 const struct drm_display_mode
*mode
= &rcrtc
->crtc
.mode
;
105 unsigned long mode_clock
= mode
->clock
* 1000;
111 /* Compute the clock divisor and select the internal or external dot
112 * clock based on the requested frequency.
114 clk
= clk_get_rate(rcrtc
->clock
);
115 div
= DIV_ROUND_CLOSEST(clk
, mode_clock
);
116 div
= clamp(div
, 1U, 64U) - 1;
117 escr
= div
| ESCR_DCLKSEL_CLKS
;
119 if (rcrtc
->extclock
) {
120 unsigned long extclk
;
121 unsigned long extrate
;
125 extclk
= clk_get_rate(rcrtc
->extclock
);
126 extdiv
= DIV_ROUND_CLOSEST(extclk
, mode_clock
);
127 extdiv
= clamp(extdiv
, 1U, 64U) - 1;
129 rate
= clk
/ (div
+ 1);
130 extrate
= extclk
/ (extdiv
+ 1);
132 if (abs((long)extrate
- (long)mode_clock
) <
133 abs((long)rate
- (long)mode_clock
)) {
134 dev_dbg(rcrtc
->group
->dev
->dev
,
135 "crtc%u: using external clock\n", rcrtc
->index
);
136 escr
= extdiv
| ESCR_DCLKSEL_DCLKIN
;
140 rcar_du_group_write(rcrtc
->group
, rcrtc
->index
% 2 ? ESCR2
: ESCR
,
142 rcar_du_group_write(rcrtc
->group
, rcrtc
->index
% 2 ? OTAR2
: OTAR
, 0);
144 /* Signal polarities */
145 value
= ((mode
->flags
& DRM_MODE_FLAG_PVSYNC
) ? 0 : DSMR_VSL
)
146 | ((mode
->flags
& DRM_MODE_FLAG_PHSYNC
) ? 0 : DSMR_HSL
)
147 | DSMR_DIPM_DE
| DSMR_CSPM
;
148 rcar_du_crtc_write(rcrtc
, DSMR
, value
);
150 /* Display timings */
151 rcar_du_crtc_write(rcrtc
, HDSR
, mode
->htotal
- mode
->hsync_start
- 19);
152 rcar_du_crtc_write(rcrtc
, HDER
, mode
->htotal
- mode
->hsync_start
+
153 mode
->hdisplay
- 19);
154 rcar_du_crtc_write(rcrtc
, HSWR
, mode
->hsync_end
-
155 mode
->hsync_start
- 1);
156 rcar_du_crtc_write(rcrtc
, HCR
, mode
->htotal
- 1);
158 rcar_du_crtc_write(rcrtc
, VDSR
, mode
->crtc_vtotal
-
159 mode
->crtc_vsync_end
- 2);
160 rcar_du_crtc_write(rcrtc
, VDER
, mode
->crtc_vtotal
-
161 mode
->crtc_vsync_end
+
162 mode
->crtc_vdisplay
- 2);
163 rcar_du_crtc_write(rcrtc
, VSPR
, mode
->crtc_vtotal
-
164 mode
->crtc_vsync_end
+
165 mode
->crtc_vsync_start
- 1);
166 rcar_du_crtc_write(rcrtc
, VCR
, mode
->crtc_vtotal
- 1);
168 rcar_du_crtc_write(rcrtc
, DESR
, mode
->htotal
- mode
->hsync_start
);
169 rcar_du_crtc_write(rcrtc
, DEWR
, mode
->hdisplay
);
172 void rcar_du_crtc_route_output(struct drm_crtc
*crtc
,
173 enum rcar_du_output output
)
175 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
176 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
178 /* Store the route from the CRTC output to the DU output. The DU will be
179 * configured when starting the CRTC.
181 rcrtc
->outputs
|= BIT(output
);
183 /* Store RGB routing to DPAD0, the hardware will be configured when
186 if (output
== RCAR_DU_OUTPUT_DPAD0
)
187 rcdu
->dpad0_source
= rcrtc
->index
;
190 void rcar_du_crtc_update_planes(struct drm_crtc
*crtc
)
192 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
193 struct rcar_du_plane
*planes
[RCAR_DU_NUM_HW_PLANES
];
194 unsigned int num_planes
= 0;
195 unsigned int prio
= 0;
200 for (i
= 0; i
< ARRAY_SIZE(rcrtc
->group
->planes
.planes
); ++i
) {
201 struct rcar_du_plane
*plane
= &rcrtc
->group
->planes
.planes
[i
];
204 if (plane
->crtc
!= &rcrtc
->crtc
|| !plane
->enabled
)
207 /* Insert the plane in the sorted planes array. */
208 for (j
= num_planes
++; j
> 0; --j
) {
209 if (planes
[j
-1]->zpos
<= plane
->zpos
)
211 planes
[j
] = planes
[j
-1];
215 prio
+= plane
->format
->planes
* 4;
218 for (i
= 0; i
< num_planes
; ++i
) {
219 struct rcar_du_plane
*plane
= planes
[i
];
220 unsigned int index
= plane
->hwindex
;
223 dspr
|= (index
+ 1) << prio
;
224 dptsr
|= DPTSR_PnDK(index
) | DPTSR_PnTS(index
);
226 if (plane
->format
->planes
== 2) {
227 index
= (index
+ 1) % 8;
230 dspr
|= (index
+ 1) << prio
;
231 dptsr
|= DPTSR_PnDK(index
) | DPTSR_PnTS(index
);
235 /* Select display timing and dot clock generator 2 for planes associated
236 * with superposition controller 2.
238 if (rcrtc
->index
% 2) {
239 u32 value
= rcar_du_group_read(rcrtc
->group
, DPTSR
);
241 /* The DPTSR register is updated when the display controller is
242 * stopped. We thus need to restart the DU. Once again, sorry
243 * for the flicker. One way to mitigate the issue would be to
244 * pre-associate planes with CRTCs (either with a fixed 4/4
245 * split, or through a module parameter). Flicker would then
246 * occur only if we need to break the pre-association.
248 if (value
!= dptsr
) {
249 rcar_du_group_write(rcrtc
->group
, DPTSR
, dptsr
);
250 if (rcrtc
->group
->used_crtcs
)
251 rcar_du_group_restart(rcrtc
->group
);
255 rcar_du_group_write(rcrtc
->group
, rcrtc
->index
% 2 ? DS2PR
: DS1PR
,
259 static void rcar_du_crtc_start(struct rcar_du_crtc
*rcrtc
)
261 struct drm_crtc
*crtc
= &rcrtc
->crtc
;
268 if (WARN_ON(rcrtc
->plane
->format
== NULL
))
271 /* Set display off and background to black */
272 rcar_du_crtc_write(rcrtc
, DOOR
, DOOR_RGB(0, 0, 0));
273 rcar_du_crtc_write(rcrtc
, BPOR
, BPOR_RGB(0, 0, 0));
275 /* Configure display timings and output routing */
276 rcar_du_crtc_set_display_timing(rcrtc
);
277 rcar_du_group_set_routing(rcrtc
->group
);
279 mutex_lock(&rcrtc
->group
->planes
.lock
);
280 rcrtc
->plane
->enabled
= true;
281 rcar_du_crtc_update_planes(crtc
);
282 mutex_unlock(&rcrtc
->group
->planes
.lock
);
285 for (i
= 0; i
< ARRAY_SIZE(rcrtc
->group
->planes
.planes
); ++i
) {
286 struct rcar_du_plane
*plane
= &rcrtc
->group
->planes
.planes
[i
];
288 if (plane
->crtc
!= crtc
|| !plane
->enabled
)
291 rcar_du_plane_setup(plane
);
294 /* Select master sync mode. This enables display operation in master
295 * sync mode (with the HSYNC and VSYNC signals configured as outputs and
298 interlaced
= rcrtc
->crtc
.mode
.flags
& DRM_MODE_FLAG_INTERLACE
;
299 rcar_du_crtc_clr_set(rcrtc
, DSYSR
, DSYSR_TVM_MASK
| DSYSR_SCM_MASK
,
300 (interlaced
? DSYSR_SCM_INT_VIDEO
: 0) |
303 rcar_du_group_start_stop(rcrtc
->group
, true);
305 rcrtc
->started
= true;
308 static void rcar_du_crtc_stop(struct rcar_du_crtc
*rcrtc
)
310 struct drm_crtc
*crtc
= &rcrtc
->crtc
;
315 mutex_lock(&rcrtc
->group
->planes
.lock
);
316 rcrtc
->plane
->enabled
= false;
317 rcar_du_crtc_update_planes(crtc
);
318 mutex_unlock(&rcrtc
->group
->planes
.lock
);
320 /* Select switch sync mode. This stops display operation and configures
321 * the HSYNC and VSYNC signals as inputs.
323 rcar_du_crtc_clr_set(rcrtc
, DSYSR
, DSYSR_TVM_MASK
, DSYSR_TVM_SWITCH
);
325 rcar_du_group_start_stop(rcrtc
->group
, false);
327 rcrtc
->started
= false;
330 void rcar_du_crtc_suspend(struct rcar_du_crtc
*rcrtc
)
332 rcar_du_crtc_stop(rcrtc
);
333 rcar_du_crtc_put(rcrtc
);
336 void rcar_du_crtc_resume(struct rcar_du_crtc
*rcrtc
)
338 if (rcrtc
->dpms
!= DRM_MODE_DPMS_ON
)
341 rcar_du_crtc_get(rcrtc
);
342 rcar_du_crtc_start(rcrtc
);
345 static void rcar_du_crtc_update_base(struct rcar_du_crtc
*rcrtc
)
347 struct drm_crtc
*crtc
= &rcrtc
->crtc
;
349 rcar_du_plane_compute_base(rcrtc
->plane
, crtc
->primary
->fb
);
350 rcar_du_plane_update_base(rcrtc
->plane
);
353 static void rcar_du_crtc_dpms(struct drm_crtc
*crtc
, int mode
)
355 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
357 if (mode
!= DRM_MODE_DPMS_ON
)
358 mode
= DRM_MODE_DPMS_OFF
;
360 if (rcrtc
->dpms
== mode
)
363 if (mode
== DRM_MODE_DPMS_ON
) {
364 rcar_du_crtc_get(rcrtc
);
365 rcar_du_crtc_start(rcrtc
);
367 rcar_du_crtc_stop(rcrtc
);
368 rcar_du_crtc_put(rcrtc
);
374 static bool rcar_du_crtc_mode_fixup(struct drm_crtc
*crtc
,
375 const struct drm_display_mode
*mode
,
376 struct drm_display_mode
*adjusted_mode
)
378 /* TODO Fixup modes */
382 static void rcar_du_crtc_mode_prepare(struct drm_crtc
*crtc
)
384 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
386 /* We need to access the hardware during mode set, acquire a reference
389 rcar_du_crtc_get(rcrtc
);
391 /* Stop the CRTC and release the plane. Force the DPMS mode to off as a
394 rcar_du_crtc_stop(rcrtc
);
395 rcar_du_plane_release(rcrtc
->plane
);
397 rcrtc
->dpms
= DRM_MODE_DPMS_OFF
;
400 static int rcar_du_crtc_mode_set(struct drm_crtc
*crtc
,
401 struct drm_display_mode
*mode
,
402 struct drm_display_mode
*adjusted_mode
,
404 struct drm_framebuffer
*old_fb
)
406 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
407 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
408 const struct rcar_du_format_info
*format
;
411 format
= rcar_du_format_info(crtc
->primary
->fb
->pixel_format
);
412 if (format
== NULL
) {
413 dev_dbg(rcdu
->dev
, "mode_set: unsupported format %08x\n",
414 crtc
->primary
->fb
->pixel_format
);
419 ret
= rcar_du_plane_reserve(rcrtc
->plane
, format
);
423 rcrtc
->plane
->format
= format
;
425 rcrtc
->plane
->src_x
= x
;
426 rcrtc
->plane
->src_y
= y
;
427 rcrtc
->plane
->width
= mode
->hdisplay
;
428 rcrtc
->plane
->height
= mode
->vdisplay
;
430 rcar_du_plane_compute_base(rcrtc
->plane
, crtc
->primary
->fb
);
437 /* There's no rollback/abort operation to clean up in case of error. We
438 * thus need to release the reference to the CRTC acquired in prepare()
441 rcar_du_crtc_put(rcrtc
);
445 static void rcar_du_crtc_mode_commit(struct drm_crtc
*crtc
)
447 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
449 /* We're done, restart the CRTC and set the DPMS mode to on. The
450 * reference to the DU acquired at prepare() time will thus be released
451 * by the DPMS handler (possibly called by the disable() handler).
453 rcar_du_crtc_start(rcrtc
);
454 rcrtc
->dpms
= DRM_MODE_DPMS_ON
;
457 static int rcar_du_crtc_mode_set_base(struct drm_crtc
*crtc
, int x
, int y
,
458 struct drm_framebuffer
*old_fb
)
460 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
462 rcrtc
->plane
->src_x
= x
;
463 rcrtc
->plane
->src_y
= y
;
465 rcar_du_crtc_update_base(rcrtc
);
470 static void rcar_du_crtc_disable(struct drm_crtc
*crtc
)
472 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
474 rcar_du_crtc_dpms(crtc
, DRM_MODE_DPMS_OFF
);
475 rcar_du_plane_release(rcrtc
->plane
);
478 static const struct drm_crtc_helper_funcs crtc_helper_funcs
= {
479 .dpms
= rcar_du_crtc_dpms
,
480 .mode_fixup
= rcar_du_crtc_mode_fixup
,
481 .prepare
= rcar_du_crtc_mode_prepare
,
482 .commit
= rcar_du_crtc_mode_commit
,
483 .mode_set
= rcar_du_crtc_mode_set
,
484 .mode_set_base
= rcar_du_crtc_mode_set_base
,
485 .disable
= rcar_du_crtc_disable
,
488 void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc
*rcrtc
,
489 struct drm_file
*file
)
491 struct drm_pending_vblank_event
*event
;
492 struct drm_device
*dev
= rcrtc
->crtc
.dev
;
495 /* Destroy the pending vertical blanking event associated with the
496 * pending page flip, if any, and disable vertical blanking interrupts.
498 spin_lock_irqsave(&dev
->event_lock
, flags
);
499 event
= rcrtc
->event
;
500 if (event
&& event
->base
.file_priv
== file
) {
502 event
->base
.destroy(&event
->base
);
503 drm_vblank_put(dev
, rcrtc
->index
);
505 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
508 static void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc
*rcrtc
)
510 struct drm_pending_vblank_event
*event
;
511 struct drm_device
*dev
= rcrtc
->crtc
.dev
;
514 spin_lock_irqsave(&dev
->event_lock
, flags
);
515 event
= rcrtc
->event
;
517 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
522 spin_lock_irqsave(&dev
->event_lock
, flags
);
523 drm_send_vblank_event(dev
, rcrtc
->index
, event
);
524 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
526 drm_vblank_put(dev
, rcrtc
->index
);
529 static irqreturn_t
rcar_du_crtc_irq(int irq
, void *arg
)
531 struct rcar_du_crtc
*rcrtc
= arg
;
532 irqreturn_t ret
= IRQ_NONE
;
535 status
= rcar_du_crtc_read(rcrtc
, DSSR
);
536 rcar_du_crtc_write(rcrtc
, DSRCR
, status
& DSRCR_MASK
);
538 if (status
& DSSR_FRM
) {
539 drm_handle_vblank(rcrtc
->crtc
.dev
, rcrtc
->index
);
540 rcar_du_crtc_finish_page_flip(rcrtc
);
547 static int rcar_du_crtc_page_flip(struct drm_crtc
*crtc
,
548 struct drm_framebuffer
*fb
,
549 struct drm_pending_vblank_event
*event
,
550 uint32_t page_flip_flags
)
552 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
553 struct drm_device
*dev
= rcrtc
->crtc
.dev
;
556 spin_lock_irqsave(&dev
->event_lock
, flags
);
557 if (rcrtc
->event
!= NULL
) {
558 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
561 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
563 crtc
->primary
->fb
= fb
;
564 rcar_du_crtc_update_base(rcrtc
);
567 event
->pipe
= rcrtc
->index
;
568 drm_vblank_get(dev
, rcrtc
->index
);
569 spin_lock_irqsave(&dev
->event_lock
, flags
);
570 rcrtc
->event
= event
;
571 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
577 static const struct drm_crtc_funcs crtc_funcs
= {
578 .destroy
= drm_crtc_cleanup
,
579 .set_config
= drm_crtc_helper_set_config
,
580 .page_flip
= rcar_du_crtc_page_flip
,
583 int rcar_du_crtc_create(struct rcar_du_group
*rgrp
, unsigned int index
)
585 static const unsigned int mmio_offsets
[] = {
586 DU0_REG_OFFSET
, DU1_REG_OFFSET
, DU2_REG_OFFSET
589 struct rcar_du_device
*rcdu
= rgrp
->dev
;
590 struct platform_device
*pdev
= to_platform_device(rcdu
->dev
);
591 struct rcar_du_crtc
*rcrtc
= &rcdu
->crtcs
[index
];
592 struct drm_crtc
*crtc
= &rcrtc
->crtc
;
593 unsigned int irqflags
;
600 /* Get the CRTC clock and the optional external clock. */
601 if (rcar_du_has(rcdu
, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
)) {
602 sprintf(clk_name
, "du.%u", index
);
608 rcrtc
->clock
= devm_clk_get(rcdu
->dev
, name
);
609 if (IS_ERR(rcrtc
->clock
)) {
610 dev_err(rcdu
->dev
, "no clock for CRTC %u\n", index
);
611 return PTR_ERR(rcrtc
->clock
);
614 sprintf(clk_name
, "dclkin.%u", index
);
615 clk
= devm_clk_get(rcdu
->dev
, clk_name
);
617 rcrtc
->extclock
= clk
;
618 } else if (PTR_ERR(rcrtc
->clock
) == -EPROBE_DEFER
) {
619 dev_info(rcdu
->dev
, "can't get external clock %u\n", index
);
620 return -EPROBE_DEFER
;
624 rcrtc
->mmio_offset
= mmio_offsets
[index
];
625 rcrtc
->index
= index
;
626 rcrtc
->dpms
= DRM_MODE_DPMS_OFF
;
627 rcrtc
->plane
= &rgrp
->planes
.planes
[index
% 2];
629 rcrtc
->plane
->crtc
= crtc
;
631 ret
= drm_crtc_init(rcdu
->ddev
, crtc
, &crtc_funcs
);
635 drm_crtc_helper_add(crtc
, &crtc_helper_funcs
);
637 /* Register the interrupt handler. */
638 if (rcar_du_has(rcdu
, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
)) {
639 irq
= platform_get_irq(pdev
, index
);
642 irq
= platform_get_irq(pdev
, 0);
643 irqflags
= IRQF_SHARED
;
647 dev_err(rcdu
->dev
, "no IRQ for CRTC %u\n", index
);
651 ret
= devm_request_irq(rcdu
->dev
, irq
, rcar_du_crtc_irq
, irqflags
,
652 dev_name(rcdu
->dev
), rcrtc
);
655 "failed to register IRQ for CRTC %u\n", index
);
662 void rcar_du_crtc_enable_vblank(struct rcar_du_crtc
*rcrtc
, bool enable
)
665 rcar_du_crtc_write(rcrtc
, DSRCR
, DSRCR_VBCL
);
666 rcar_du_crtc_set(rcrtc
, DIER
, DIER_VBE
);
668 rcar_du_crtc_clr(rcrtc
, DIER
, DIER_VBE
);