• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * rcar_du_crtc.c  --  R-Car Display Unit CRTCs
3  *
4  * Copyright (C) 2013-2015 Renesas Electronics 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_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>
25 
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"
32 
rcar_du_crtc_read(struct rcar_du_crtc * rcrtc,u32 reg)33 static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
34 {
35 	struct rcar_du_device *rcdu = rcrtc->group->dev;
36 
37 	return rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
38 }
39 
rcar_du_crtc_write(struct rcar_du_crtc * rcrtc,u32 reg,u32 data)40 static void rcar_du_crtc_write(struct rcar_du_crtc *rcrtc, u32 reg, u32 data)
41 {
42 	struct rcar_du_device *rcdu = rcrtc->group->dev;
43 
44 	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, data);
45 }
46 
rcar_du_crtc_clr(struct rcar_du_crtc * rcrtc,u32 reg,u32 clr)47 static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr)
48 {
49 	struct rcar_du_device *rcdu = rcrtc->group->dev;
50 
51 	rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
52 		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
53 }
54 
rcar_du_crtc_set(struct rcar_du_crtc * rcrtc,u32 reg,u32 set)55 static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
56 {
57 	struct rcar_du_device *rcdu = rcrtc->group->dev;
58 
59 	rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
60 		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
61 }
62 
rcar_du_crtc_clr_set(struct rcar_du_crtc * rcrtc,u32 reg,u32 clr,u32 set)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->group->dev;
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 
rcar_du_crtc_get(struct rcar_du_crtc * rcrtc)72 static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
73 {
74 	int ret;
75 
76 	ret = clk_prepare_enable(rcrtc->clock);
77 	if (ret < 0)
78 		return ret;
79 
80 	ret = clk_prepare_enable(rcrtc->extclock);
81 	if (ret < 0)
82 		goto error_clock;
83 
84 	ret = rcar_du_group_get(rcrtc->group);
85 	if (ret < 0)
86 		goto error_group;
87 
88 	return 0;
89 
90 error_group:
91 	clk_disable_unprepare(rcrtc->extclock);
92 error_clock:
93 	clk_disable_unprepare(rcrtc->clock);
94 	return ret;
95 }
96 
rcar_du_crtc_put(struct rcar_du_crtc * rcrtc)97 static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
98 {
99 	rcar_du_group_put(rcrtc->group);
100 
101 	clk_disable_unprepare(rcrtc->extclock);
102 	clk_disable_unprepare(rcrtc->clock);
103 }
104 
105 /* -----------------------------------------------------------------------------
106  * Hardware Setup
107  */
108 
rcar_du_crtc_set_display_timing(struct rcar_du_crtc * rcrtc)109 static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
110 {
111 	const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
112 	unsigned long mode_clock = mode->clock * 1000;
113 	unsigned long clk;
114 	u32 value;
115 	u32 escr;
116 	u32 div;
117 
118 	/* Compute the clock divisor and select the internal or external dot
119 	 * clock based on the requested frequency.
120 	 */
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;
125 
126 	if (rcrtc->extclock) {
127 		unsigned long extclk;
128 		unsigned long extrate;
129 		unsigned long rate;
130 		u32 extdiv;
131 
132 		extclk = clk_get_rate(rcrtc->extclock);
133 		extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock);
134 		extdiv = clamp(extdiv, 1U, 64U) - 1;
135 
136 		rate = clk / (div + 1);
137 		extrate = extclk / (extdiv + 1);
138 
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;
144 		}
145 	}
146 
147 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
148 			    escr);
149 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
150 
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);
156 
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);
164 
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);
174 
175 	rcar_du_crtc_write(rcrtc, DESR,  mode->htotal - mode->hsync_start - 1);
176 	rcar_du_crtc_write(rcrtc, DEWR,  mode->hdisplay);
177 }
178 
rcar_du_crtc_route_output(struct drm_crtc * crtc,enum rcar_du_output output)179 void rcar_du_crtc_route_output(struct drm_crtc *crtc,
180 			       enum rcar_du_output output)
181 {
182 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
183 	struct rcar_du_device *rcdu = rcrtc->group->dev;
184 
185 	/* Store the route from the CRTC output to the DU output. The DU will be
186 	 * configured when starting the CRTC.
187 	 */
188 	rcrtc->outputs |= BIT(output);
189 
190 	/* Store RGB routing to DPAD0, the hardware will be configured when
191 	 * starting the CRTC.
192 	 */
193 	if (output == RCAR_DU_OUTPUT_DPAD0)
194 		rcdu->dpad0_source = rcrtc->index;
195 }
196 
plane_zpos(struct rcar_du_plane * plane)197 static unsigned int plane_zpos(struct rcar_du_plane *plane)
198 {
199 	return plane->plane.state->normalized_zpos;
200 }
201 
202 static const struct rcar_du_format_info *
plane_format(struct rcar_du_plane * plane)203 plane_format(struct rcar_du_plane *plane)
204 {
205 	return to_rcar_plane_state(plane->plane.state)->format;
206 }
207 
rcar_du_crtc_update_planes(struct rcar_du_crtc * rcrtc)208 static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
209 {
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;
216 	unsigned int i;
217 	u32 dspr = 0;
218 
219 	for (i = 0; i < rcrtc->group->num_planes; ++i) {
220 		struct rcar_du_plane *plane = &rcrtc->group->planes[i];
221 		unsigned int j;
222 
223 		if (plane->plane.state->crtc != &rcrtc->crtc)
224 			continue;
225 
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))
229 				break;
230 			planes[j] = planes[j-1];
231 		}
232 
233 		planes[j] = plane;
234 		prio += plane_format(plane)->planes * 4;
235 	}
236 
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;
241 
242 		prio -= 4;
243 		dspr |= (index + 1) << prio;
244 		hwplanes |= 1 << index;
245 
246 		if (plane_format(plane)->planes == 2) {
247 			index = (index + 1) % 8;
248 
249 			prio -= 4;
250 			dspr |= (index + 1) << prio;
251 			hwplanes |= 1 << index;
252 		}
253 	}
254 
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);
260 		} else {
261 			dspr = (rcrtc->index % 2) ? 3 : 1;
262 			hwplanes = 1 << ((rcrtc->index % 2) ? 2 : 0);
263 		}
264 	}
265 
266 	/* Update the planes to display timing and dot clock generator
267 	 * associations.
268 	 *
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.
273 	 */
274 	mutex_lock(&rcrtc->group->lock);
275 
276 	dptsr_planes = rcrtc->index % 2 ? rcrtc->group->dptsr_planes | hwplanes
277 		     : rcrtc->group->dptsr_planes & ~hwplanes;
278 
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;
283 
284 		if (rcrtc->group->used_crtcs)
285 			rcar_du_group_restart(rcrtc->group);
286 	}
287 
288 	/* Restart the group if plane sources have changed. */
289 	if (rcrtc->group->need_restart)
290 		rcar_du_group_restart(rcrtc->group);
291 
292 	mutex_unlock(&rcrtc->group->lock);
293 
294 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
295 			    dspr);
296 }
297 
298 /* -----------------------------------------------------------------------------
299  * Page Flip
300  */
301 
rcar_du_crtc_finish_page_flip(struct rcar_du_crtc * rcrtc)302 static void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc)
303 {
304 	struct drm_pending_vblank_event *event;
305 	struct drm_device *dev = rcrtc->crtc.dev;
306 	unsigned long flags;
307 
308 	spin_lock_irqsave(&dev->event_lock, flags);
309 	event = rcrtc->event;
310 	rcrtc->event = NULL;
311 	spin_unlock_irqrestore(&dev->event_lock, flags);
312 
313 	if (event == NULL)
314 		return;
315 
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);
320 
321 	drm_crtc_vblank_put(&rcrtc->crtc);
322 }
323 
rcar_du_crtc_page_flip_pending(struct rcar_du_crtc * rcrtc)324 static bool rcar_du_crtc_page_flip_pending(struct rcar_du_crtc *rcrtc)
325 {
326 	struct drm_device *dev = rcrtc->crtc.dev;
327 	unsigned long flags;
328 	bool pending;
329 
330 	spin_lock_irqsave(&dev->event_lock, flags);
331 	pending = rcrtc->event != NULL;
332 	spin_unlock_irqrestore(&dev->event_lock, flags);
333 
334 	return pending;
335 }
336 
rcar_du_crtc_wait_page_flip(struct rcar_du_crtc * rcrtc)337 static void rcar_du_crtc_wait_page_flip(struct rcar_du_crtc *rcrtc)
338 {
339 	struct rcar_du_device *rcdu = rcrtc->group->dev;
340 
341 	if (wait_event_timeout(rcrtc->flip_wait,
342 			       !rcar_du_crtc_page_flip_pending(rcrtc),
343 			       msecs_to_jiffies(50)))
344 		return;
345 
346 	dev_warn(rcdu->dev, "page flip timeout\n");
347 
348 	rcar_du_crtc_finish_page_flip(rcrtc);
349 }
350 
351 /* -----------------------------------------------------------------------------
352  * Start/Stop and Suspend/Resume
353  */
354 
rcar_du_crtc_start(struct rcar_du_crtc * rcrtc)355 static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
356 {
357 	struct drm_crtc *crtc = &rcrtc->crtc;
358 	bool interlaced;
359 
360 	if (rcrtc->started)
361 		return;
362 
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));
366 
367 	/* Configure display timings and output routing */
368 	rcar_du_crtc_set_display_timing(rcrtc);
369 	rcar_du_group_set_routing(rcrtc->group);
370 
371 	/* Start with all planes disabled. */
372 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
373 
374 	/* Select master sync mode. This enables display operation in master
375 	 * sync mode (with the HSYNC and VSYNC signals configured as outputs and
376 	 * actively driven).
377 	 */
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) |
381 			     DSYSR_TVM_MASTER);
382 
383 	rcar_du_group_start_stop(rcrtc->group, true);
384 
385 	/* Enable the VSP compositor. */
386 	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
387 		rcar_du_vsp_enable(rcrtc);
388 
389 	/* Turn vertical blanking interrupt reporting back on. */
390 	drm_crtc_vblank_on(crtc);
391 
392 	rcrtc->started = true;
393 }
394 
rcar_du_crtc_disable_planes(struct rcar_du_crtc * rcrtc)395 static void rcar_du_crtc_disable_planes(struct rcar_du_crtc *rcrtc)
396 {
397 	struct rcar_du_device *rcdu = rcrtc->group->dev;
398 	struct drm_crtc *crtc = &rcrtc->crtc;
399 	u32 status;
400 	/* Make sure vblank interrupts are enabled. */
401 	drm_crtc_vblank_get(crtc);
402 	/*
403 	 * Disable planes and calculate how many vertical blanking interrupts we
404 	 * have to wait for. If a vertical blanking interrupt has been triggered
405 	 * but not processed yet, we don't know whether it occurred before or
406 	 * after the planes got disabled. We thus have to wait for two vblank
407 	 * interrupts in that case.
408 	 */
409 	spin_lock_irq(&rcrtc->vblank_lock);
410 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
411 	status = rcar_du_crtc_read(rcrtc, DSSR);
412 	rcrtc->vblank_count = status & DSSR_VBK ? 2 : 1;
413 	spin_unlock_irq(&rcrtc->vblank_lock);
414 	if (!wait_event_timeout(rcrtc->vblank_wait, rcrtc->vblank_count == 0,
415 				msecs_to_jiffies(100)))
416 		dev_warn(rcdu->dev, "vertical blanking timeout\n");
417 	drm_crtc_vblank_put(crtc);
418 }
419 
rcar_du_crtc_stop(struct rcar_du_crtc * rcrtc)420 static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
421 {
422 	struct drm_crtc *crtc = &rcrtc->crtc;
423 
424 	if (!rcrtc->started)
425 		return;
426 
427 	/* Disable all planes and wait for the change to take effect. This is
428          * required as the plane enable registers are updated on vblank, and no
429          * vblank will occur once the CRTC is stopped. Disabling planes when
430          * starting the CRTC thus wouldn't be enough as it would start scanning
431          * out immediately from old frame buffers until the next vblank.
432 	 *
433 	 * This increases the CRTC stop delay, especially when multiple CRTCs
434 	 * are stopped in one operation as we now wait for one vblank per CRTC.
435 	 * Whether this can be improved needs to be researched.
436 	 */
437 	rcar_du_crtc_disable_planes(rcrtc);
438 
439 	/* Disable vertical blanking interrupt reporting. We first need to wait
440 	 * for page flip completion before stopping the CRTC as userspace
441 	 * expects page flips to eventually complete.
442 	 */
443 	rcar_du_crtc_wait_page_flip(rcrtc);
444 	drm_crtc_vblank_off(crtc);
445 
446 	/* Disable the VSP compositor. */
447 	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
448 		rcar_du_vsp_disable(rcrtc);
449 
450 	/* Select switch sync mode. This stops display operation and configures
451 	 * the HSYNC and VSYNC signals as inputs.
452 	 */
453 	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
454 
455 	rcar_du_group_start_stop(rcrtc->group, false);
456 
457 	rcrtc->started = false;
458 }
459 
rcar_du_crtc_suspend(struct rcar_du_crtc * rcrtc)460 void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
461 {
462 	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
463 		rcar_du_vsp_disable(rcrtc);
464 
465 	rcar_du_crtc_stop(rcrtc);
466 	rcar_du_crtc_put(rcrtc);
467 }
468 
rcar_du_crtc_resume(struct rcar_du_crtc * rcrtc)469 void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
470 {
471 	unsigned int i;
472 
473 	if (!rcrtc->crtc.state->active)
474 		return;
475 
476 	rcar_du_crtc_get(rcrtc);
477 	rcar_du_crtc_start(rcrtc);
478 
479 	/* Commit the planes state. */
480 	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE)) {
481 		rcar_du_vsp_enable(rcrtc);
482 	} else {
483 		for (i = 0; i < rcrtc->group->num_planes; ++i) {
484 			struct rcar_du_plane *plane = &rcrtc->group->planes[i];
485 
486 			if (plane->plane.state->crtc != &rcrtc->crtc)
487 				continue;
488 
489 			rcar_du_plane_setup(plane);
490 		}
491 	}
492 
493 	rcar_du_crtc_update_planes(rcrtc);
494 }
495 
496 /* -----------------------------------------------------------------------------
497  * CRTC Functions
498  */
499 
rcar_du_crtc_enable(struct drm_crtc * crtc)500 static void rcar_du_crtc_enable(struct drm_crtc *crtc)
501 {
502 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
503 
504 	rcar_du_crtc_get(rcrtc);
505 	rcar_du_crtc_start(rcrtc);
506 }
507 
rcar_du_crtc_disable(struct drm_crtc * crtc)508 static void rcar_du_crtc_disable(struct drm_crtc *crtc)
509 {
510 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
511 
512 	rcar_du_crtc_stop(rcrtc);
513 	rcar_du_crtc_put(rcrtc);
514 
515 	spin_lock_irq(&crtc->dev->event_lock);
516 	if (crtc->state->event) {
517 		drm_crtc_send_vblank_event(crtc, crtc->state->event);
518 		crtc->state->event = NULL;
519 	}
520 	spin_unlock_irq(&crtc->dev->event_lock);
521 
522 	rcrtc->outputs = 0;
523 }
524 
rcar_du_crtc_atomic_begin(struct drm_crtc * crtc,struct drm_crtc_state * old_crtc_state)525 static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
526 				      struct drm_crtc_state *old_crtc_state)
527 {
528 	struct drm_pending_vblank_event *event = crtc->state->event;
529 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
530 	struct drm_device *dev = rcrtc->crtc.dev;
531 	unsigned long flags;
532 
533 	if (event) {
534 		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
535 
536 		spin_lock_irqsave(&dev->event_lock, flags);
537 		rcrtc->event = event;
538 		spin_unlock_irqrestore(&dev->event_lock, flags);
539 	}
540 
541 	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
542 		rcar_du_vsp_atomic_begin(rcrtc);
543 }
544 
rcar_du_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_crtc_state * old_crtc_state)545 static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
546 				      struct drm_crtc_state *old_crtc_state)
547 {
548 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
549 
550 	rcar_du_crtc_update_planes(rcrtc);
551 
552 	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
553 		rcar_du_vsp_atomic_flush(rcrtc);
554 }
555 
556 static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
557 	.disable = rcar_du_crtc_disable,
558 	.enable = rcar_du_crtc_enable,
559 	.atomic_begin = rcar_du_crtc_atomic_begin,
560 	.atomic_flush = rcar_du_crtc_atomic_flush,
561 };
562 
563 static const struct drm_crtc_funcs crtc_funcs = {
564 	.reset = drm_atomic_helper_crtc_reset,
565 	.destroy = drm_crtc_cleanup,
566 	.set_config = drm_atomic_helper_set_config,
567 	.page_flip = drm_atomic_helper_page_flip,
568 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
569 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
570 };
571 
572 /* -----------------------------------------------------------------------------
573  * Interrupt Handling
574  */
575 
rcar_du_crtc_irq(int irq,void * arg)576 static irqreturn_t rcar_du_crtc_irq(int irq, void *arg)
577 {
578 	struct rcar_du_crtc *rcrtc = arg;
579 	irqreturn_t ret = IRQ_NONE;
580 	u32 status;
581 
582 	spin_lock(&rcrtc->vblank_lock);
583 
584 	status = rcar_du_crtc_read(rcrtc, DSSR);
585 	rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
586 
587 	if (status & DSSR_VBK) {
588 		/*
589 		 * Wake up the vblank wait if the counter reaches 0. This must
590 		 * be protected by the vblank_lock to avoid races in
591 		 * rcar_du_crtc_disable_planes().
592 		 */
593 		if (rcrtc->vblank_count) {
594 			if (--rcrtc->vblank_count == 0)
595 				wake_up(&rcrtc->vblank_wait);
596 		}
597 	}
598 	spin_unlock(&rcrtc->vblank_lock);
599 
600 	if (status & DSSR_VBK) {
601 		drm_crtc_handle_vblank(&rcrtc->crtc);
602 		rcar_du_crtc_finish_page_flip(rcrtc);
603 		ret = IRQ_HANDLED;
604 	}
605 
606 	return ret;
607 }
608 
609 /* -----------------------------------------------------------------------------
610  * Initialization
611  */
612 
rcar_du_crtc_create(struct rcar_du_group * rgrp,unsigned int index)613 int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
614 {
615 	static const unsigned int mmio_offsets[] = {
616 		DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET, DU3_REG_OFFSET
617 	};
618 
619 	struct rcar_du_device *rcdu = rgrp->dev;
620 	struct platform_device *pdev = to_platform_device(rcdu->dev);
621 	struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index];
622 	struct drm_crtc *crtc = &rcrtc->crtc;
623 	struct drm_plane *primary;
624 	unsigned int irqflags;
625 	struct clk *clk;
626 	char clk_name[9];
627 	char *name;
628 	int irq;
629 	int ret;
630 
631 	/* Get the CRTC clock and the optional external clock. */
632 	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
633 		sprintf(clk_name, "du.%u", index);
634 		name = clk_name;
635 	} else {
636 		name = NULL;
637 	}
638 
639 	rcrtc->clock = devm_clk_get(rcdu->dev, name);
640 	if (IS_ERR(rcrtc->clock)) {
641 		dev_err(rcdu->dev, "no clock for CRTC %u\n", index);
642 		return PTR_ERR(rcrtc->clock);
643 	}
644 
645 	sprintf(clk_name, "dclkin.%u", index);
646 	clk = devm_clk_get(rcdu->dev, clk_name);
647 	if (!IS_ERR(clk)) {
648 		rcrtc->extclock = clk;
649 	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
650 		dev_info(rcdu->dev, "can't get external clock %u\n", index);
651 		return -EPROBE_DEFER;
652 	}
653 
654 	init_waitqueue_head(&rcrtc->flip_wait);
655 	init_waitqueue_head(&rcrtc->vblank_wait);
656 	spin_lock_init(&rcrtc->vblank_lock);
657 
658 	rcrtc->group = rgrp;
659 	rcrtc->mmio_offset = mmio_offsets[index];
660 	rcrtc->index = index;
661 
662 	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
663 		primary = &rcrtc->vsp->planes[0].plane;
664 	else
665 		primary = &rgrp->planes[index % 2].plane;
666 
667 	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary,
668 					NULL, &crtc_funcs, NULL);
669 	if (ret < 0)
670 		return ret;
671 
672 	drm_crtc_helper_add(crtc, &crtc_helper_funcs);
673 
674 	/* Start with vertical blanking interrupt reporting disabled. */
675 	drm_crtc_vblank_off(crtc);
676 
677 	/* Register the interrupt handler. */
678 	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
679 		irq = platform_get_irq(pdev, index);
680 		irqflags = 0;
681 	} else {
682 		irq = platform_get_irq(pdev, 0);
683 		irqflags = IRQF_SHARED;
684 	}
685 
686 	if (irq < 0) {
687 		dev_err(rcdu->dev, "no IRQ for CRTC %u\n", index);
688 		return irq;
689 	}
690 
691 	ret = devm_request_irq(rcdu->dev, irq, rcar_du_crtc_irq, irqflags,
692 			       dev_name(rcdu->dev), rcrtc);
693 	if (ret < 0) {
694 		dev_err(rcdu->dev,
695 			"failed to register IRQ for CRTC %u\n", index);
696 		return ret;
697 	}
698 
699 	return 0;
700 }
701 
rcar_du_crtc_enable_vblank(struct rcar_du_crtc * rcrtc,bool enable)702 void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable)
703 {
704 	if (enable) {
705 		rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
706 		rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
707 	} else {
708 		rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE);
709 	}
710 }
711