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