2 * rcar_du_crtc.c -- R-Car Display Unit CRTCs
4 * Copyright (C) 2013-2015 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_atomic.h>
19 #include <drm/drm_atomic_helper.h>
20 #include <drm/drm_crtc.h>
21 #include <drm/drm_crtc_helper.h>
22 #include <drm/drm_fb_cma_helper.h>
23 #include <drm/drm_gem_cma_helper.h>
24 #include <drm/drm_plane_helper.h>
26 #include "rcar_du_crtc.h"
27 #include "rcar_du_drv.h"
28 #include "rcar_du_kms.h"
29 #include "rcar_du_plane.h"
30 #include "rcar_du_regs.h"
31 #include "rcar_du_vsp.h"
33 static u32
rcar_du_crtc_read(struct rcar_du_crtc
*rcrtc
, u32 reg
)
35 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
37 return rcar_du_read(rcdu
, rcrtc
->mmio_offset
+ reg
);
40 static void rcar_du_crtc_write(struct rcar_du_crtc
*rcrtc
, u32 reg
, u32 data
)
42 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
44 rcar_du_write(rcdu
, rcrtc
->mmio_offset
+ reg
, data
);
47 static void rcar_du_crtc_clr(struct rcar_du_crtc
*rcrtc
, u32 reg
, u32 clr
)
49 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
51 rcar_du_write(rcdu
, rcrtc
->mmio_offset
+ reg
,
52 rcar_du_read(rcdu
, rcrtc
->mmio_offset
+ reg
) & ~clr
);
55 static void rcar_du_crtc_set(struct rcar_du_crtc
*rcrtc
, u32 reg
, u32 set
)
57 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
59 rcar_du_write(rcdu
, rcrtc
->mmio_offset
+ reg
,
60 rcar_du_read(rcdu
, rcrtc
->mmio_offset
+ reg
) | set
);
63 static void rcar_du_crtc_clr_set(struct rcar_du_crtc
*rcrtc
, u32 reg
,
66 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
67 u32 value
= rcar_du_read(rcdu
, rcrtc
->mmio_offset
+ reg
);
69 rcar_du_write(rcdu
, rcrtc
->mmio_offset
+ reg
, (value
& ~clr
) | set
);
72 static int rcar_du_crtc_get(struct rcar_du_crtc
*rcrtc
)
76 ret
= clk_prepare_enable(rcrtc
->clock
);
80 ret
= clk_prepare_enable(rcrtc
->extclock
);
84 ret
= rcar_du_group_get(rcrtc
->group
);
91 clk_disable_unprepare(rcrtc
->extclock
);
93 clk_disable_unprepare(rcrtc
->clock
);
97 static void rcar_du_crtc_put(struct rcar_du_crtc
*rcrtc
)
99 rcar_du_group_put(rcrtc
->group
);
101 clk_disable_unprepare(rcrtc
->extclock
);
102 clk_disable_unprepare(rcrtc
->clock
);
105 /* -----------------------------------------------------------------------------
109 static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc
*rcrtc
)
111 const struct drm_display_mode
*mode
= &rcrtc
->crtc
.state
->adjusted_mode
;
112 unsigned long mode_clock
= mode
->clock
* 1000;
118 /* Compute the clock divisor and select the internal or external dot
119 * clock based on the requested frequency.
121 clk
= clk_get_rate(rcrtc
->clock
);
122 div
= DIV_ROUND_CLOSEST(clk
, mode_clock
);
123 div
= clamp(div
, 1U, 64U) - 1;
124 escr
= div
| ESCR_DCLKSEL_CLKS
;
126 if (rcrtc
->extclock
) {
127 unsigned long extclk
;
128 unsigned long extrate
;
132 extclk
= clk_get_rate(rcrtc
->extclock
);
133 extdiv
= DIV_ROUND_CLOSEST(extclk
, mode_clock
);
134 extdiv
= clamp(extdiv
, 1U, 64U) - 1;
136 rate
= clk
/ (div
+ 1);
137 extrate
= extclk
/ (extdiv
+ 1);
139 if (abs((long)extrate
- (long)mode_clock
) <
140 abs((long)rate
- (long)mode_clock
)) {
141 dev_dbg(rcrtc
->group
->dev
->dev
,
142 "crtc%u: using external clock\n", rcrtc
->index
);
143 escr
= extdiv
| ESCR_DCLKSEL_DCLKIN
;
147 rcar_du_group_write(rcrtc
->group
, rcrtc
->index
% 2 ? ESCR2
: ESCR
,
149 rcar_du_group_write(rcrtc
->group
, rcrtc
->index
% 2 ? OTAR2
: OTAR
, 0);
151 /* Signal polarities */
152 value
= ((mode
->flags
& DRM_MODE_FLAG_PVSYNC
) ? DSMR_VSL
: 0)
153 | ((mode
->flags
& DRM_MODE_FLAG_PHSYNC
) ? DSMR_HSL
: 0)
154 | DSMR_DIPM_DISP
| DSMR_CSPM
;
155 rcar_du_crtc_write(rcrtc
, DSMR
, value
);
157 /* Display timings */
158 rcar_du_crtc_write(rcrtc
, HDSR
, mode
->htotal
- mode
->hsync_start
- 19);
159 rcar_du_crtc_write(rcrtc
, HDER
, mode
->htotal
- mode
->hsync_start
+
160 mode
->hdisplay
- 19);
161 rcar_du_crtc_write(rcrtc
, HSWR
, mode
->hsync_end
-
162 mode
->hsync_start
- 1);
163 rcar_du_crtc_write(rcrtc
, HCR
, mode
->htotal
- 1);
165 rcar_du_crtc_write(rcrtc
, VDSR
, mode
->crtc_vtotal
-
166 mode
->crtc_vsync_end
- 2);
167 rcar_du_crtc_write(rcrtc
, VDER
, mode
->crtc_vtotal
-
168 mode
->crtc_vsync_end
+
169 mode
->crtc_vdisplay
- 2);
170 rcar_du_crtc_write(rcrtc
, VSPR
, mode
->crtc_vtotal
-
171 mode
->crtc_vsync_end
+
172 mode
->crtc_vsync_start
- 1);
173 rcar_du_crtc_write(rcrtc
, VCR
, mode
->crtc_vtotal
- 1);
175 rcar_du_crtc_write(rcrtc
, DESR
, mode
->htotal
- mode
->hsync_start
- 1);
176 rcar_du_crtc_write(rcrtc
, DEWR
, mode
->hdisplay
);
179 void rcar_du_crtc_route_output(struct drm_crtc
*crtc
,
180 enum rcar_du_output output
)
182 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
183 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
185 /* Store the route from the CRTC output to the DU output. The DU will be
186 * configured when starting the CRTC.
188 rcrtc
->outputs
|= BIT(output
);
190 /* Store RGB routing to DPAD0, the hardware will be configured when
193 if (output
== RCAR_DU_OUTPUT_DPAD0
)
194 rcdu
->dpad0_source
= rcrtc
->index
;
197 static unsigned int plane_zpos(struct rcar_du_plane
*plane
)
199 return plane
->plane
.state
->normalized_zpos
;
202 static const struct rcar_du_format_info
*
203 plane_format(struct rcar_du_plane
*plane
)
205 return to_rcar_plane_state(plane
->plane
.state
)->format
;
208 static void rcar_du_crtc_update_planes(struct rcar_du_crtc
*rcrtc
)
210 struct rcar_du_plane
*planes
[RCAR_DU_NUM_HW_PLANES
];
211 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
212 unsigned int num_planes
= 0;
213 unsigned int dptsr_planes
;
214 unsigned int hwplanes
= 0;
215 unsigned int prio
= 0;
219 for (i
= 0; i
< rcrtc
->group
->num_planes
; ++i
) {
220 struct rcar_du_plane
*plane
= &rcrtc
->group
->planes
[i
];
223 if (plane
->plane
.state
->crtc
!= &rcrtc
->crtc
)
226 /* Insert the plane in the sorted planes array. */
227 for (j
= num_planes
++; j
> 0; --j
) {
228 if (plane_zpos(planes
[j
-1]) <= plane_zpos(plane
))
230 planes
[j
] = planes
[j
-1];
234 prio
+= plane_format(plane
)->planes
* 4;
237 for (i
= 0; i
< num_planes
; ++i
) {
238 struct rcar_du_plane
*plane
= planes
[i
];
239 struct drm_plane_state
*state
= plane
->plane
.state
;
240 unsigned int index
= to_rcar_plane_state(state
)->hwindex
;
243 dspr
|= (index
+ 1) << prio
;
244 hwplanes
|= 1 << index
;
246 if (plane_format(plane
)->planes
== 2) {
247 index
= (index
+ 1) % 8;
250 dspr
|= (index
+ 1) << prio
;
251 hwplanes
|= 1 << index
;
255 /* If VSP+DU integration is enabled the plane assignment is fixed. */
256 if (rcar_du_has(rcdu
, RCAR_DU_FEATURE_VSP1_SOURCE
)) {
257 if (rcdu
->info
->gen
< 3) {
258 dspr
= (rcrtc
->index
% 2) + 1;
259 hwplanes
= 1 << (rcrtc
->index
% 2);
261 dspr
= (rcrtc
->index
% 2) ? 3 : 1;
262 hwplanes
= 1 << ((rcrtc
->index
% 2) ? 2 : 0);
266 /* Update the planes to display timing and dot clock generator
269 * Updating the DPTSR register requires restarting the CRTC group,
270 * resulting in visible flicker. To mitigate the issue only update the
271 * association if needed by enabled planes. Planes being disabled will
272 * keep their current association.
274 mutex_lock(&rcrtc
->group
->lock
);
276 dptsr_planes
= rcrtc
->index
% 2 ? rcrtc
->group
->dptsr_planes
| hwplanes
277 : rcrtc
->group
->dptsr_planes
& ~hwplanes
;
279 if (dptsr_planes
!= rcrtc
->group
->dptsr_planes
) {
280 rcar_du_group_write(rcrtc
->group
, DPTSR
,
281 (dptsr_planes
<< 16) | dptsr_planes
);
282 rcrtc
->group
->dptsr_planes
= dptsr_planes
;
284 if (rcrtc
->group
->used_crtcs
)
285 rcar_du_group_restart(rcrtc
->group
);
288 /* Restart the group if plane sources have changed. */
289 if (rcrtc
->group
->need_restart
)
290 rcar_du_group_restart(rcrtc
->group
);
292 mutex_unlock(&rcrtc
->group
->lock
);
294 rcar_du_group_write(rcrtc
->group
, rcrtc
->index
% 2 ? DS2PR
: DS1PR
,
298 /* -----------------------------------------------------------------------------
302 static void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc
*rcrtc
)
304 struct drm_pending_vblank_event
*event
;
305 struct drm_device
*dev
= rcrtc
->crtc
.dev
;
308 spin_lock_irqsave(&dev
->event_lock
, flags
);
309 event
= rcrtc
->event
;
311 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
316 spin_lock_irqsave(&dev
->event_lock
, flags
);
317 drm_crtc_send_vblank_event(&rcrtc
->crtc
, event
);
318 wake_up(&rcrtc
->flip_wait
);
319 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
321 drm_crtc_vblank_put(&rcrtc
->crtc
);
324 static bool rcar_du_crtc_page_flip_pending(struct rcar_du_crtc
*rcrtc
)
326 struct drm_device
*dev
= rcrtc
->crtc
.dev
;
330 spin_lock_irqsave(&dev
->event_lock
, flags
);
331 pending
= rcrtc
->event
!= NULL
;
332 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
337 static void rcar_du_crtc_wait_page_flip(struct rcar_du_crtc
*rcrtc
)
339 struct rcar_du_device
*rcdu
= rcrtc
->group
->dev
;
341 if (wait_event_timeout(rcrtc
->flip_wait
,
342 !rcar_du_crtc_page_flip_pending(rcrtc
),
343 msecs_to_jiffies(50)))
346 dev_warn(rcdu
->dev
, "page flip timeout\n");
348 rcar_du_crtc_finish_page_flip(rcrtc
);
351 /* -----------------------------------------------------------------------------
352 * Start/Stop and Suspend/Resume
355 static void rcar_du_crtc_start(struct rcar_du_crtc
*rcrtc
)
357 struct drm_crtc
*crtc
= &rcrtc
->crtc
;
363 /* Set display off and background to black */
364 rcar_du_crtc_write(rcrtc
, DOOR
, DOOR_RGB(0, 0, 0));
365 rcar_du_crtc_write(rcrtc
, BPOR
, BPOR_RGB(0, 0, 0));
367 /* Configure display timings and output routing */
368 rcar_du_crtc_set_display_timing(rcrtc
);
369 rcar_du_group_set_routing(rcrtc
->group
);
371 /* Start with all planes disabled. */
372 rcar_du_group_write(rcrtc
->group
, rcrtc
->index
% 2 ? DS2PR
: DS1PR
, 0);
374 /* Select master sync mode. This enables display operation in master
375 * sync mode (with the HSYNC and VSYNC signals configured as outputs and
378 interlaced
= rcrtc
->crtc
.mode
.flags
& DRM_MODE_FLAG_INTERLACE
;
379 rcar_du_crtc_clr_set(rcrtc
, DSYSR
, DSYSR_TVM_MASK
| DSYSR_SCM_MASK
,
380 (interlaced
? DSYSR_SCM_INT_VIDEO
: 0) |
383 rcar_du_group_start_stop(rcrtc
->group
, true);
385 /* Enable the VSP compositor. */
386 if (rcar_du_has(rcrtc
->group
->dev
, RCAR_DU_FEATURE_VSP1_SOURCE
))
387 rcar_du_vsp_enable(rcrtc
);
389 /* Turn vertical blanking interrupt reporting back on. */
390 drm_crtc_vblank_on(crtc
);
392 rcrtc
->started
= true;
395 static void rcar_du_crtc_stop(struct rcar_du_crtc
*rcrtc
)
397 struct drm_crtc
*crtc
= &rcrtc
->crtc
;
402 /* Disable all planes and wait for the change to take effect. This is
403 * required as the DSnPR registers are updated on vblank, and no vblank
404 * will occur once the CRTC is stopped. Disabling planes when starting
405 * the CRTC thus wouldn't be enough as it would start scanning out
406 * immediately from old frame buffers until the next vblank.
408 * This increases the CRTC stop delay, especially when multiple CRTCs
409 * are stopped in one operation as we now wait for one vblank per CRTC.
410 * Whether this can be improved needs to be researched.
412 rcar_du_group_write(rcrtc
->group
, rcrtc
->index
% 2 ? DS2PR
: DS1PR
, 0);
413 drm_crtc_wait_one_vblank(crtc
);
415 /* Disable vertical blanking interrupt reporting. We first need to wait
416 * for page flip completion before stopping the CRTC as userspace
417 * expects page flips to eventually complete.
419 rcar_du_crtc_wait_page_flip(rcrtc
);
420 drm_crtc_vblank_off(crtc
);
422 /* Disable the VSP compositor. */
423 if (rcar_du_has(rcrtc
->group
->dev
, RCAR_DU_FEATURE_VSP1_SOURCE
))
424 rcar_du_vsp_disable(rcrtc
);
426 /* Select switch sync mode. This stops display operation and configures
427 * the HSYNC and VSYNC signals as inputs.
429 rcar_du_crtc_clr_set(rcrtc
, DSYSR
, DSYSR_TVM_MASK
, DSYSR_TVM_SWITCH
);
431 rcar_du_group_start_stop(rcrtc
->group
, false);
433 rcrtc
->started
= false;
436 void rcar_du_crtc_suspend(struct rcar_du_crtc
*rcrtc
)
438 if (rcar_du_has(rcrtc
->group
->dev
, RCAR_DU_FEATURE_VSP1_SOURCE
))
439 rcar_du_vsp_disable(rcrtc
);
441 rcar_du_crtc_stop(rcrtc
);
442 rcar_du_crtc_put(rcrtc
);
445 void rcar_du_crtc_resume(struct rcar_du_crtc
*rcrtc
)
449 if (!rcrtc
->crtc
.state
->active
)
452 rcar_du_crtc_get(rcrtc
);
453 rcar_du_crtc_start(rcrtc
);
455 /* Commit the planes state. */
456 if (rcar_du_has(rcrtc
->group
->dev
, RCAR_DU_FEATURE_VSP1_SOURCE
)) {
457 rcar_du_vsp_enable(rcrtc
);
459 for (i
= 0; i
< rcrtc
->group
->num_planes
; ++i
) {
460 struct rcar_du_plane
*plane
= &rcrtc
->group
->planes
[i
];
462 if (plane
->plane
.state
->crtc
!= &rcrtc
->crtc
)
465 rcar_du_plane_setup(plane
);
469 rcar_du_crtc_update_planes(rcrtc
);
472 /* -----------------------------------------------------------------------------
476 static void rcar_du_crtc_enable(struct drm_crtc
*crtc
)
478 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
480 rcar_du_crtc_get(rcrtc
);
481 rcar_du_crtc_start(rcrtc
);
484 static void rcar_du_crtc_disable(struct drm_crtc
*crtc
)
486 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
488 rcar_du_crtc_stop(rcrtc
);
489 rcar_du_crtc_put(rcrtc
);
494 static void rcar_du_crtc_atomic_begin(struct drm_crtc
*crtc
,
495 struct drm_crtc_state
*old_crtc_state
)
497 struct drm_pending_vblank_event
*event
= crtc
->state
->event
;
498 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
499 struct drm_device
*dev
= rcrtc
->crtc
.dev
;
503 WARN_ON(drm_crtc_vblank_get(crtc
) != 0);
505 spin_lock_irqsave(&dev
->event_lock
, flags
);
506 rcrtc
->event
= event
;
507 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
510 if (rcar_du_has(rcrtc
->group
->dev
, RCAR_DU_FEATURE_VSP1_SOURCE
))
511 rcar_du_vsp_atomic_begin(rcrtc
);
514 static void rcar_du_crtc_atomic_flush(struct drm_crtc
*crtc
,
515 struct drm_crtc_state
*old_crtc_state
)
517 struct rcar_du_crtc
*rcrtc
= to_rcar_crtc(crtc
);
519 rcar_du_crtc_update_planes(rcrtc
);
521 if (rcar_du_has(rcrtc
->group
->dev
, RCAR_DU_FEATURE_VSP1_SOURCE
))
522 rcar_du_vsp_atomic_flush(rcrtc
);
525 static const struct drm_crtc_helper_funcs crtc_helper_funcs
= {
526 .disable
= rcar_du_crtc_disable
,
527 .enable
= rcar_du_crtc_enable
,
528 .atomic_begin
= rcar_du_crtc_atomic_begin
,
529 .atomic_flush
= rcar_du_crtc_atomic_flush
,
532 static const struct drm_crtc_funcs crtc_funcs
= {
533 .reset
= drm_atomic_helper_crtc_reset
,
534 .destroy
= drm_crtc_cleanup
,
535 .set_config
= drm_atomic_helper_set_config
,
536 .page_flip
= drm_atomic_helper_page_flip
,
537 .atomic_duplicate_state
= drm_atomic_helper_crtc_duplicate_state
,
538 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
541 /* -----------------------------------------------------------------------------
545 static irqreturn_t
rcar_du_crtc_irq(int irq
, void *arg
)
547 struct rcar_du_crtc
*rcrtc
= arg
;
548 irqreturn_t ret
= IRQ_NONE
;
551 status
= rcar_du_crtc_read(rcrtc
, DSSR
);
552 rcar_du_crtc_write(rcrtc
, DSRCR
, status
& DSRCR_MASK
);
554 if (status
& DSSR_FRM
) {
555 drm_crtc_handle_vblank(&rcrtc
->crtc
);
556 rcar_du_crtc_finish_page_flip(rcrtc
);
563 /* -----------------------------------------------------------------------------
567 int rcar_du_crtc_create(struct rcar_du_group
*rgrp
, unsigned int index
)
569 static const unsigned int mmio_offsets
[] = {
570 DU0_REG_OFFSET
, DU1_REG_OFFSET
, DU2_REG_OFFSET
, DU3_REG_OFFSET
573 struct rcar_du_device
*rcdu
= rgrp
->dev
;
574 struct platform_device
*pdev
= to_platform_device(rcdu
->dev
);
575 struct rcar_du_crtc
*rcrtc
= &rcdu
->crtcs
[index
];
576 struct drm_crtc
*crtc
= &rcrtc
->crtc
;
577 struct drm_plane
*primary
;
578 unsigned int irqflags
;
585 /* Get the CRTC clock and the optional external clock. */
586 if (rcar_du_has(rcdu
, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
)) {
587 sprintf(clk_name
, "du.%u", index
);
593 rcrtc
->clock
= devm_clk_get(rcdu
->dev
, name
);
594 if (IS_ERR(rcrtc
->clock
)) {
595 dev_err(rcdu
->dev
, "no clock for CRTC %u\n", index
);
596 return PTR_ERR(rcrtc
->clock
);
599 sprintf(clk_name
, "dclkin.%u", index
);
600 clk
= devm_clk_get(rcdu
->dev
, clk_name
);
602 rcrtc
->extclock
= clk
;
603 } else if (PTR_ERR(rcrtc
->clock
) == -EPROBE_DEFER
) {
604 dev_info(rcdu
->dev
, "can't get external clock %u\n", index
);
605 return -EPROBE_DEFER
;
608 init_waitqueue_head(&rcrtc
->flip_wait
);
611 rcrtc
->mmio_offset
= mmio_offsets
[index
];
612 rcrtc
->index
= index
;
614 if (rcar_du_has(rcdu
, RCAR_DU_FEATURE_VSP1_SOURCE
))
615 primary
= &rcrtc
->vsp
->planes
[0].plane
;
617 primary
= &rgrp
->planes
[index
% 2].plane
;
619 ret
= drm_crtc_init_with_planes(rcdu
->ddev
, crtc
, primary
,
620 NULL
, &crtc_funcs
, NULL
);
624 drm_crtc_helper_add(crtc
, &crtc_helper_funcs
);
626 /* Start with vertical blanking interrupt reporting disabled. */
627 drm_crtc_vblank_off(crtc
);
629 /* Register the interrupt handler. */
630 if (rcar_du_has(rcdu
, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
)) {
631 irq
= platform_get_irq(pdev
, index
);
634 irq
= platform_get_irq(pdev
, 0);
635 irqflags
= IRQF_SHARED
;
639 dev_err(rcdu
->dev
, "no IRQ for CRTC %u\n", index
);
643 ret
= devm_request_irq(rcdu
->dev
, irq
, rcar_du_crtc_irq
, irqflags
,
644 dev_name(rcdu
->dev
), rcrtc
);
647 "failed to register IRQ for CRTC %u\n", index
);
654 void rcar_du_crtc_enable_vblank(struct rcar_du_crtc
*rcrtc
, bool enable
)
657 rcar_du_crtc_write(rcrtc
, DSRCR
, DSRCR_VBCL
);
658 rcar_du_crtc_set(rcrtc
, DIER
, DIER_VBE
);
660 rcar_du_crtc_clr(rcrtc
, DIER
, DIER_VBE
);