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
64static 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
107void 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
129static 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
142static 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
160static 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
172static 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
200error_peri_clock:
201	clk_disable_unprepare(rcrtc->rzg2l_clocks.pclk);
202error_bus_clock:
203	clk_disable_unprepare(rcrtc->rzg2l_clocks.aclk);
204	return ret;
205}
206
207static 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
217static 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
224static void rzg2l_du_crtc_start(struct rzg2l_du_crtc *rcrtc)
225{
226	rzg2l_du_start_stop(rcrtc, true);
227}
228
229static 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
251static 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
261static 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
277static 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
298static 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
304static struct drm_crtc_state *
305rzg2l_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, &copy->state);
319
320	return &copy->state;
321}
322
323static 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
330static 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
346static 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
355static 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
362static 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
376int 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