1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * RZ/G2L Display Unit CRTCs
4 *
5 * Copyright (C) 2023 Renesas Electronics Corporation
6 *
7 * Based on rcar_du_crtc.c
8 */
9
10 #include <linux/clk.h>
11 #include <linux/mutex.h>
12 #include <linux/platform_device.h>
13 #include <linux/reset.h>
14
15 #include <drm/drm_atomic.h>
16 #include <drm/drm_atomic_helper.h>
17 #include <drm/drm_bridge.h>
18 #include <drm/drm_crtc.h>
19 #include <drm/drm_device.h>
20 #include <drm/drm_framebuffer.h>
21 #include <drm/drm_gem_dma_helper.h>
22 #include <drm/drm_vblank.h>
23
24 #include "rzg2l_du_crtc.h"
25 #include "rzg2l_du_drv.h"
26 #include "rzg2l_du_encoder.h"
27 #include "rzg2l_du_kms.h"
28 #include "rzg2l_du_vsp.h"
29
30 #define DU_MCR0 0x00
31 #define DU_MCR0_DI_EN BIT(8)
32
33 #define DU_DITR0 0x10
34 #define DU_DITR0_DEMD_HIGH (BIT(8) | BIT(9))
35 #define DU_DITR0_VSPOL BIT(16)
36 #define DU_DITR0_HSPOL BIT(17)
37
38 #define DU_DITR1 0x14
39 #define DU_DITR1_VSA(x) ((x) << 0)
40 #define DU_DITR1_VACTIVE(x) ((x) << 16)
41
42 #define DU_DITR2 0x18
43 #define DU_DITR2_VBP(x) ((x) << 0)
44 #define DU_DITR2_VFP(x) ((x) << 16)
45
46 #define DU_DITR3 0x1c
47 #define DU_DITR3_HSA(x) ((x) << 0)
48 #define DU_DITR3_HACTIVE(x) ((x) << 16)
49
50 #define DU_DITR4 0x20
51 #define DU_DITR4_HBP(x) ((x) << 0)
52 #define DU_DITR4_HFP(x) ((x) << 16)
53
54 #define DU_MCR1 0x40
55 #define DU_MCR1_PB_AUTOCLR BIT(16)
56
57 #define DU_PBCR0 0x4c
58 #define DU_PBCR0_PB_DEP(x) ((x) << 0)
59
60 /* -----------------------------------------------------------------------------
61 * Hardware Setup
62 */
63
rzg2l_du_crtc_set_display_timing(struct rzg2l_du_crtc * rcrtc)64 static void rzg2l_du_crtc_set_display_timing(struct rzg2l_du_crtc *rcrtc)
65 {
66 const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
67 unsigned long mode_clock = mode->clock * 1000;
68 u32 ditr0, ditr1, ditr2, ditr3, ditr4, pbcr0;
69 struct rzg2l_du_device *rcdu = rcrtc->dev;
70
71 clk_prepare_enable(rcrtc->rzg2l_clocks.dclk);
72 clk_set_rate(rcrtc->rzg2l_clocks.dclk, mode_clock);
73
74 ditr0 = (DU_DITR0_DEMD_HIGH
75 | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DU_DITR0_VSPOL : 0)
76 | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DU_DITR0_HSPOL : 0));
77
78 ditr1 = DU_DITR1_VSA(mode->vsync_end - mode->vsync_start)
79 | DU_DITR1_VACTIVE(mode->vdisplay);
80
81 ditr2 = DU_DITR2_VBP(mode->vtotal - mode->vsync_end)
82 | DU_DITR2_VFP(mode->vsync_start - mode->vdisplay);
83
84 ditr3 = DU_DITR3_HSA(mode->hsync_end - mode->hsync_start)
85 | DU_DITR3_HACTIVE(mode->hdisplay);
86
87 ditr4 = DU_DITR4_HBP(mode->htotal - mode->hsync_end)
88 | DU_DITR4_HFP(mode->hsync_start - mode->hdisplay);
89
90 pbcr0 = DU_PBCR0_PB_DEP(0x1f);
91
92 writel(ditr0, rcdu->mmio + DU_DITR0);
93 writel(ditr1, rcdu->mmio + DU_DITR1);
94 writel(ditr2, rcdu->mmio + DU_DITR2);
95 writel(ditr3, rcdu->mmio + DU_DITR3);
96 writel(ditr4, rcdu->mmio + DU_DITR4);
97 writel(pbcr0, rcdu->mmio + DU_PBCR0);
98
99 /* Enable auto clear */
100 writel(DU_MCR1_PB_AUTOCLR, rcdu->mmio + DU_MCR1);
101 }
102
103 /* -----------------------------------------------------------------------------
104 * Page Flip
105 */
106
rzg2l_du_crtc_finish_page_flip(struct rzg2l_du_crtc * rcrtc)107 void rzg2l_du_crtc_finish_page_flip(struct rzg2l_du_crtc *rcrtc)
108 {
109 struct drm_pending_vblank_event *event;
110 struct drm_device *dev = rcrtc->crtc.dev;
111 unsigned long flags;
112
113 spin_lock_irqsave(&dev->event_lock, flags);
114 event = rcrtc->event;
115 rcrtc->event = NULL;
116 spin_unlock_irqrestore(&dev->event_lock, flags);
117
118 if (!event)
119 return;
120
121 spin_lock_irqsave(&dev->event_lock, flags);
122 drm_crtc_send_vblank_event(&rcrtc->crtc, event);
123 wake_up(&rcrtc->flip_wait);
124 spin_unlock_irqrestore(&dev->event_lock, flags);
125
126 drm_crtc_vblank_put(&rcrtc->crtc);
127 }
128
rzg2l_du_crtc_page_flip_pending(struct rzg2l_du_crtc * rcrtc)129 static bool rzg2l_du_crtc_page_flip_pending(struct rzg2l_du_crtc *rcrtc)
130 {
131 struct drm_device *dev = rcrtc->crtc.dev;
132 unsigned long flags;
133 bool pending;
134
135 spin_lock_irqsave(&dev->event_lock, flags);
136 pending = rcrtc->event;
137 spin_unlock_irqrestore(&dev->event_lock, flags);
138
139 return pending;
140 }
141
rzg2l_du_crtc_wait_page_flip(struct rzg2l_du_crtc * rcrtc)142 static void rzg2l_du_crtc_wait_page_flip(struct rzg2l_du_crtc *rcrtc)
143 {
144 struct rzg2l_du_device *rcdu = rcrtc->dev;
145
146 if (wait_event_timeout(rcrtc->flip_wait,
147 !rzg2l_du_crtc_page_flip_pending(rcrtc),
148 msecs_to_jiffies(50)))
149 return;
150
151 dev_warn(rcdu->dev, "page flip timeout\n");
152
153 rzg2l_du_crtc_finish_page_flip(rcrtc);
154 }
155
156 /* -----------------------------------------------------------------------------
157 * Start/Stop and Suspend/Resume
158 */
159
rzg2l_du_crtc_setup(struct rzg2l_du_crtc * rcrtc)160 static void rzg2l_du_crtc_setup(struct rzg2l_du_crtc *rcrtc)
161 {
162 /* Configure display timings and output routing */
163 rzg2l_du_crtc_set_display_timing(rcrtc);
164
165 /* Enable the VSP compositor. */
166 rzg2l_du_vsp_enable(rcrtc);
167
168 /* Turn vertical blanking interrupt reporting on. */
169 drm_crtc_vblank_on(&rcrtc->crtc);
170 }
171
rzg2l_du_crtc_get(struct rzg2l_du_crtc * rcrtc)172 static int rzg2l_du_crtc_get(struct rzg2l_du_crtc *rcrtc)
173 {
174 int ret;
175
176 /*
177 * Guard against double-get, as the function is called from both the
178 * .atomic_enable() and .atomic_flush() handlers.
179 */
180 if (rcrtc->initialized)
181 return 0;
182
183 ret = clk_prepare_enable(rcrtc->rzg2l_clocks.aclk);
184 if (ret < 0)
185 return ret;
186
187 ret = clk_prepare_enable(rcrtc->rzg2l_clocks.pclk);
188 if (ret < 0)
189 goto error_bus_clock;
190
191 ret = reset_control_deassert(rcrtc->rstc);
192 if (ret < 0)
193 goto error_peri_clock;
194
195 rzg2l_du_crtc_setup(rcrtc);
196 rcrtc->initialized = true;
197
198 return 0;
199
200 error_peri_clock:
201 clk_disable_unprepare(rcrtc->rzg2l_clocks.pclk);
202 error_bus_clock:
203 clk_disable_unprepare(rcrtc->rzg2l_clocks.aclk);
204 return ret;
205 }
206
rzg2l_du_crtc_put(struct rzg2l_du_crtc * rcrtc)207 static void rzg2l_du_crtc_put(struct rzg2l_du_crtc *rcrtc)
208 {
209 clk_disable_unprepare(rcrtc->rzg2l_clocks.dclk);
210 reset_control_assert(rcrtc->rstc);
211 clk_disable_unprepare(rcrtc->rzg2l_clocks.pclk);
212 clk_disable_unprepare(rcrtc->rzg2l_clocks.aclk);
213
214 rcrtc->initialized = false;
215 }
216
rzg2l_du_start_stop(struct rzg2l_du_crtc * rcrtc,bool start)217 static void rzg2l_du_start_stop(struct rzg2l_du_crtc *rcrtc, bool start)
218 {
219 struct rzg2l_du_device *rcdu = rcrtc->dev;
220
221 writel(start ? DU_MCR0_DI_EN : 0, rcdu->mmio + DU_MCR0);
222 }
223
rzg2l_du_crtc_start(struct rzg2l_du_crtc * rcrtc)224 static void rzg2l_du_crtc_start(struct rzg2l_du_crtc *rcrtc)
225 {
226 rzg2l_du_start_stop(rcrtc, true);
227 }
228
rzg2l_du_crtc_stop(struct rzg2l_du_crtc * rcrtc)229 static void rzg2l_du_crtc_stop(struct rzg2l_du_crtc *rcrtc)
230 {
231 struct drm_crtc *crtc = &rcrtc->crtc;
232
233 /*
234 * Disable vertical blanking interrupt reporting. We first need to wait
235 * for page flip completion before stopping the CRTC as userspace
236 * expects page flips to eventually complete.
237 */
238 rzg2l_du_crtc_wait_page_flip(rcrtc);
239 drm_crtc_vblank_off(crtc);
240
241 /* Disable the VSP compositor. */
242 rzg2l_du_vsp_disable(rcrtc);
243
244 rzg2l_du_start_stop(rcrtc, false);
245 }
246
247 /* -----------------------------------------------------------------------------
248 * CRTC Functions
249 */
250
rzg2l_du_crtc_atomic_enable(struct drm_crtc * crtc,struct drm_atomic_state * state)251 static void rzg2l_du_crtc_atomic_enable(struct drm_crtc *crtc,
252 struct drm_atomic_state *state)
253 {
254 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc);
255
256 rzg2l_du_crtc_get(rcrtc);
257
258 rzg2l_du_crtc_start(rcrtc);
259 }
260
rzg2l_du_crtc_atomic_disable(struct drm_crtc * crtc,struct drm_atomic_state * state)261 static void rzg2l_du_crtc_atomic_disable(struct drm_crtc *crtc,
262 struct drm_atomic_state *state)
263 {
264 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc);
265
266 rzg2l_du_crtc_stop(rcrtc);
267 rzg2l_du_crtc_put(rcrtc);
268
269 spin_lock_irq(&crtc->dev->event_lock);
270 if (crtc->state->event) {
271 drm_crtc_send_vblank_event(crtc, crtc->state->event);
272 crtc->state->event = NULL;
273 }
274 spin_unlock_irq(&crtc->dev->event_lock);
275 }
276
rzg2l_du_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_atomic_state * state)277 static void rzg2l_du_crtc_atomic_flush(struct drm_crtc *crtc,
278 struct drm_atomic_state *state)
279 {
280 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc);
281 struct drm_device *dev = rcrtc->crtc.dev;
282 unsigned long flags;
283
284 WARN_ON(!crtc->state->enable);
285
286 if (crtc->state->event) {
287 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
288
289 spin_lock_irqsave(&dev->event_lock, flags);
290 rcrtc->event = crtc->state->event;
291 crtc->state->event = NULL;
292 spin_unlock_irqrestore(&dev->event_lock, flags);
293 }
294
295 rzg2l_du_vsp_atomic_flush(rcrtc);
296 }
297
298 static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
299 .atomic_flush = rzg2l_du_crtc_atomic_flush,
300 .atomic_enable = rzg2l_du_crtc_atomic_enable,
301 .atomic_disable = rzg2l_du_crtc_atomic_disable,
302 };
303
304 static struct drm_crtc_state *
rzg2l_du_crtc_atomic_duplicate_state(struct drm_crtc * crtc)305 rzg2l_du_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
306 {
307 struct rzg2l_du_crtc_state *state;
308 struct rzg2l_du_crtc_state *copy;
309
310 if (WARN_ON(!crtc->state))
311 return NULL;
312
313 state = to_rzg2l_crtc_state(crtc->state);
314 copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
315 if (!copy)
316 return NULL;
317
318 __drm_atomic_helper_crtc_duplicate_state(crtc, ©->state);
319
320 return ©->state;
321 }
322
rzg2l_du_crtc_atomic_destroy_state(struct drm_crtc * crtc,struct drm_crtc_state * state)323 static void rzg2l_du_crtc_atomic_destroy_state(struct drm_crtc *crtc,
324 struct drm_crtc_state *state)
325 {
326 __drm_atomic_helper_crtc_destroy_state(state);
327 kfree(to_rzg2l_crtc_state(state));
328 }
329
rzg2l_du_crtc_reset(struct drm_crtc * crtc)330 static void rzg2l_du_crtc_reset(struct drm_crtc *crtc)
331 {
332 struct rzg2l_du_crtc_state *state;
333
334 if (crtc->state) {
335 rzg2l_du_crtc_atomic_destroy_state(crtc, crtc->state);
336 crtc->state = NULL;
337 }
338
339 state = kzalloc(sizeof(*state), GFP_KERNEL);
340 if (!state)
341 return;
342
343 __drm_atomic_helper_crtc_reset(crtc, &state->state);
344 }
345
rzg2l_du_crtc_enable_vblank(struct drm_crtc * crtc)346 static int rzg2l_du_crtc_enable_vblank(struct drm_crtc *crtc)
347 {
348 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc);
349
350 rcrtc->vblank_enable = true;
351
352 return 0;
353 }
354
rzg2l_du_crtc_disable_vblank(struct drm_crtc * crtc)355 static void rzg2l_du_crtc_disable_vblank(struct drm_crtc *crtc)
356 {
357 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc);
358
359 rcrtc->vblank_enable = false;
360 }
361
362 static const struct drm_crtc_funcs crtc_funcs_rz = {
363 .reset = rzg2l_du_crtc_reset,
364 .set_config = drm_atomic_helper_set_config,
365 .page_flip = drm_atomic_helper_page_flip,
366 .atomic_duplicate_state = rzg2l_du_crtc_atomic_duplicate_state,
367 .atomic_destroy_state = rzg2l_du_crtc_atomic_destroy_state,
368 .enable_vblank = rzg2l_du_crtc_enable_vblank,
369 .disable_vblank = rzg2l_du_crtc_disable_vblank,
370 };
371
372 /* -----------------------------------------------------------------------------
373 * Initialization
374 */
375
rzg2l_du_crtc_create(struct rzg2l_du_device * rcdu)376 int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu)
377 {
378 struct rzg2l_du_crtc *rcrtc = &rcdu->crtcs[0];
379 struct drm_crtc *crtc = &rcrtc->crtc;
380 struct drm_plane *primary;
381 int ret;
382
383 rcrtc->rstc = devm_reset_control_get_shared(rcdu->dev, NULL);
384 if (IS_ERR(rcrtc->rstc)) {
385 dev_err(rcdu->dev, "can't get cpg reset\n");
386 return PTR_ERR(rcrtc->rstc);
387 }
388
389 rcrtc->rzg2l_clocks.aclk = devm_clk_get(rcdu->dev, "aclk");
390 if (IS_ERR(rcrtc->rzg2l_clocks.aclk)) {
391 dev_err(rcdu->dev, "no axi clock for DU\n");
392 return PTR_ERR(rcrtc->rzg2l_clocks.aclk);
393 }
394
395 rcrtc->rzg2l_clocks.pclk = devm_clk_get(rcdu->dev, "pclk");
396 if (IS_ERR(rcrtc->rzg2l_clocks.pclk)) {
397 dev_err(rcdu->dev, "no peripheral clock for DU\n");
398 return PTR_ERR(rcrtc->rzg2l_clocks.pclk);
399 }
400
401 rcrtc->rzg2l_clocks.dclk = devm_clk_get(rcdu->dev, "vclk");
402 if (IS_ERR(rcrtc->rzg2l_clocks.dclk)) {
403 dev_err(rcdu->dev, "no video clock for DU\n");
404 return PTR_ERR(rcrtc->rzg2l_clocks.dclk);
405 }
406
407 init_waitqueue_head(&rcrtc->flip_wait);
408 rcrtc->dev = rcdu;
409
410 primary = rzg2l_du_vsp_get_drm_plane(rcrtc, rcrtc->vsp_pipe);
411 if (IS_ERR(primary))
412 return PTR_ERR(primary);
413
414 ret = drmm_crtc_init_with_planes(&rcdu->ddev, crtc, primary, NULL,
415 &crtc_funcs_rz, NULL);
416 if (ret < 0)
417 return ret;
418
419 drm_crtc_helper_add(crtc, &crtc_helper_funcs);
420
421 return 0;
422 }
423