xref: /openbmc/linux/drivers/gpu/drm/mxsfb/lcdif_kms.c (revision f43e47c090dc7fe32d5410d8740c3a004eb2676f)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2022 Marek Vasut <marex@denx.de>
4  *
5  * This code is based on drivers/gpu/drm/mxsfb/mxsfb*
6  */
7 
8 #include <linux/clk.h>
9 #include <linux/io.h>
10 #include <linux/iopoll.h>
11 #include <linux/media-bus-format.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/spinlock.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_color_mgmt.h>
19 #include <drm/drm_crtc.h>
20 #include <drm/drm_encoder.h>
21 #include <drm/drm_fb_dma_helper.h>
22 #include <drm/drm_fourcc.h>
23 #include <drm/drm_framebuffer.h>
24 #include <drm/drm_gem_atomic_helper.h>
25 #include <drm/drm_gem_dma_helper.h>
26 #include <drm/drm_plane.h>
27 #include <drm/drm_vblank.h>
28 
29 #include "lcdif_drv.h"
30 #include "lcdif_regs.h"
31 
32 /* -----------------------------------------------------------------------------
33  * CRTC
34  */
35 
36 /*
37  * For conversion from YCbCr to RGB, the CSC operates as follows:
38  *
39  * |R|   |A1 A2 A3|   |Y  + D1|
40  * |G| = |B1 B2 B3| * |Cb + D2|
41  * |B|   |C1 C2 C3|   |Cr + D3|
42  *
43  * The A, B and C coefficients are expressed as Q2.8 fixed point values, and
44  * the D coefficients as Q0.8. Despite the reference manual stating the
45  * opposite, the D1, D2 and D3 offset values are added to Y, Cb and Cr, not
46  * subtracted. They must thus be programmed with negative values.
47  */
48 static const u32 lcdif_yuv2rgb_coeffs[3][2][6] = {
49 	[DRM_COLOR_YCBCR_BT601] = {
50 		[DRM_COLOR_YCBCR_LIMITED_RANGE] = {
51 			/*
52 			 * BT.601 limited range:
53 			 *
54 			 * |R|   |1.1644  0.0000  1.5960|   |Y  - 16 |
55 			 * |G| = |1.1644 -0.3917 -0.8129| * |Cb - 128|
56 			 * |B|   |1.1644  2.0172  0.0000|   |Cr - 128|
57 			 */
58 			CSC0_COEF0_A1(0x12a) | CSC0_COEF0_A2(0x000),
59 			CSC0_COEF1_A3(0x199) | CSC0_COEF1_B1(0x12a),
60 			CSC0_COEF2_B2(0x79c) | CSC0_COEF2_B3(0x730),
61 			CSC0_COEF3_C1(0x12a) | CSC0_COEF3_C2(0x204),
62 			CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x1f0),
63 			CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
64 		},
65 		[DRM_COLOR_YCBCR_FULL_RANGE] = {
66 			/*
67 			 * BT.601 full range:
68 			 *
69 			 * |R|   |1.0000  0.0000  1.4020|   |Y  - 0  |
70 			 * |G| = |1.0000 -0.3441 -0.7141| * |Cb - 128|
71 			 * |B|   |1.0000  1.7720  0.0000|   |Cr - 128|
72 			 */
73 			CSC0_COEF0_A1(0x100) | CSC0_COEF0_A2(0x000),
74 			CSC0_COEF1_A3(0x167) | CSC0_COEF1_B1(0x100),
75 			CSC0_COEF2_B2(0x7a8) | CSC0_COEF2_B3(0x749),
76 			CSC0_COEF3_C1(0x100) | CSC0_COEF3_C2(0x1c6),
77 			CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x000),
78 			CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
79 		},
80 	},
81 	[DRM_COLOR_YCBCR_BT709] = {
82 		[DRM_COLOR_YCBCR_LIMITED_RANGE] = {
83 			/*
84 			 * Rec.709 limited range:
85 			 *
86 			 * |R|   |1.1644  0.0000  1.7927|   |Y  - 16 |
87 			 * |G| = |1.1644 -0.2132 -0.5329| * |Cb - 128|
88 			 * |B|   |1.1644  2.1124  0.0000|   |Cr - 128|
89 			 */
90 			CSC0_COEF0_A1(0x12a) | CSC0_COEF0_A2(0x000),
91 			CSC0_COEF1_A3(0x1cb) | CSC0_COEF1_B1(0x12a),
92 			CSC0_COEF2_B2(0x7c9) | CSC0_COEF2_B3(0x778),
93 			CSC0_COEF3_C1(0x12a) | CSC0_COEF3_C2(0x21d),
94 			CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x1f0),
95 			CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
96 		},
97 		[DRM_COLOR_YCBCR_FULL_RANGE] = {
98 			/*
99 			 * Rec.709 full range:
100 			 *
101 			 * |R|   |1.0000  0.0000  1.5748|   |Y  - 0  |
102 			 * |G| = |1.0000 -0.1873 -0.4681| * |Cb - 128|
103 			 * |B|   |1.0000  1.8556  0.0000|   |Cr - 128|
104 			 */
105 			CSC0_COEF0_A1(0x100) | CSC0_COEF0_A2(0x000),
106 			CSC0_COEF1_A3(0x193) | CSC0_COEF1_B1(0x100),
107 			CSC0_COEF2_B2(0x7d0) | CSC0_COEF2_B3(0x788),
108 			CSC0_COEF3_C1(0x100) | CSC0_COEF3_C2(0x1db),
109 			CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x000),
110 			CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
111 		},
112 	},
113 	[DRM_COLOR_YCBCR_BT2020] = {
114 		[DRM_COLOR_YCBCR_LIMITED_RANGE] = {
115 			/*
116 			 * BT.2020 limited range:
117 			 *
118 			 * |R|   |1.1644  0.0000  1.6787|   |Y  - 16 |
119 			 * |G| = |1.1644 -0.1874 -0.6505| * |Cb - 128|
120 			 * |B|   |1.1644  2.1418  0.0000|   |Cr - 128|
121 			 */
122 			CSC0_COEF0_A1(0x12a) | CSC0_COEF0_A2(0x000),
123 			CSC0_COEF1_A3(0x1ae) | CSC0_COEF1_B1(0x12a),
124 			CSC0_COEF2_B2(0x7d0) | CSC0_COEF2_B3(0x759),
125 			CSC0_COEF3_C1(0x12a) | CSC0_COEF3_C2(0x224),
126 			CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x1f0),
127 			CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
128 		},
129 		[DRM_COLOR_YCBCR_FULL_RANGE] = {
130 			/*
131 			 * BT.2020 full range:
132 			 *
133 			 * |R|   |1.0000  0.0000  1.4746|   |Y  - 0  |
134 			 * |G| = |1.0000 -0.1646 -0.5714| * |Cb - 128|
135 			 * |B|   |1.0000  1.8814  0.0000|   |Cr - 128|
136 			 */
137 			CSC0_COEF0_A1(0x100) | CSC0_COEF0_A2(0x000),
138 			CSC0_COEF1_A3(0x179) | CSC0_COEF1_B1(0x100),
139 			CSC0_COEF2_B2(0x7d6) | CSC0_COEF2_B3(0x76e),
140 			CSC0_COEF3_C1(0x100) | CSC0_COEF3_C2(0x1e2),
141 			CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x000),
142 			CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
143 		},
144 	},
145 };
146 
147 static void lcdif_set_formats(struct lcdif_drm_private *lcdif,
148 			      struct drm_plane_state *plane_state,
149 			      const u32 bus_format)
150 {
151 	struct drm_device *drm = lcdif->drm;
152 	const u32 format = plane_state->fb->format->format;
153 	bool in_yuv = false;
154 	bool out_yuv = false;
155 
156 	switch (bus_format) {
157 	case MEDIA_BUS_FMT_RGB565_1X16:
158 		writel(DISP_PARA_LINE_PATTERN_RGB565,
159 		       lcdif->base + LCDC_V8_DISP_PARA);
160 		break;
161 	case MEDIA_BUS_FMT_RGB888_1X24:
162 		writel(DISP_PARA_LINE_PATTERN_RGB888,
163 		       lcdif->base + LCDC_V8_DISP_PARA);
164 		break;
165 	case MEDIA_BUS_FMT_UYVY8_1X16:
166 		writel(DISP_PARA_LINE_PATTERN_UYVY_H,
167 		       lcdif->base + LCDC_V8_DISP_PARA);
168 		out_yuv = true;
169 		break;
170 	default:
171 		dev_err(drm->dev, "Unknown media bus format 0x%x\n", bus_format);
172 		break;
173 	}
174 
175 	switch (format) {
176 	/* RGB Formats */
177 	case DRM_FORMAT_RGB565:
178 		writel(CTRLDESCL0_5_BPP_16_RGB565,
179 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
180 		break;
181 	case DRM_FORMAT_RGB888:
182 		writel(CTRLDESCL0_5_BPP_24_RGB888,
183 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
184 		break;
185 	case DRM_FORMAT_XRGB1555:
186 		writel(CTRLDESCL0_5_BPP_16_ARGB1555,
187 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
188 		break;
189 	case DRM_FORMAT_XRGB4444:
190 		writel(CTRLDESCL0_5_BPP_16_ARGB4444,
191 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
192 		break;
193 	case DRM_FORMAT_XBGR8888:
194 		writel(CTRLDESCL0_5_BPP_32_ABGR8888,
195 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
196 		break;
197 	case DRM_FORMAT_XRGB8888:
198 		writel(CTRLDESCL0_5_BPP_32_ARGB8888,
199 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
200 		break;
201 
202 	/* YUV Formats */
203 	case DRM_FORMAT_YUYV:
204 		writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_VY2UY1,
205 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
206 		in_yuv = true;
207 		break;
208 	case DRM_FORMAT_YVYU:
209 		writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_UY2VY1,
210 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
211 		in_yuv = true;
212 		break;
213 	case DRM_FORMAT_UYVY:
214 		writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_Y2VY1U,
215 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
216 		in_yuv = true;
217 		break;
218 	case DRM_FORMAT_VYUY:
219 		writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_Y2UY1V,
220 		       lcdif->base + LCDC_V8_CTRLDESCL0_5);
221 		in_yuv = true;
222 		break;
223 
224 	default:
225 		dev_err(drm->dev, "Unknown pixel format 0x%x\n", format);
226 		break;
227 	}
228 
229 	/*
230 	 * The CSC differentiates between "YCbCr" and "YUV", but the reference
231 	 * manual doesn't detail how they differ. Experiments showed that the
232 	 * luminance value is unaffected, only the calculations involving chroma
233 	 * values differ. The YCbCr mode behaves as expected, with chroma values
234 	 * being offset by 128. The YUV mode isn't fully understood.
235 	 */
236 	if (!in_yuv && out_yuv) {
237 		/* RGB -> YCbCr */
238 		writel(CSC0_CTRL_CSC_MODE_RGB2YCbCr,
239 		       lcdif->base + LCDC_V8_CSC0_CTRL);
240 
241 		/*
242 		 * CSC: BT.601 Limited Range RGB to YCbCr coefficients.
243 		 *
244 		 * |Y |   | 0.2568  0.5041  0.0979|   |R|   |16 |
245 		 * |Cb| = |-0.1482 -0.2910  0.4392| * |G| + |128|
246 		 * |Cr|   | 0.4392  0.4392 -0.3678|   |B|   |128|
247 		 */
248 		writel(CSC0_COEF0_A2(0x081) | CSC0_COEF0_A1(0x041),
249 		       lcdif->base + LCDC_V8_CSC0_COEF0);
250 		writel(CSC0_COEF1_B1(0x7db) | CSC0_COEF1_A3(0x019),
251 		       lcdif->base + LCDC_V8_CSC0_COEF1);
252 		writel(CSC0_COEF2_B3(0x070) | CSC0_COEF2_B2(0x7b6),
253 		       lcdif->base + LCDC_V8_CSC0_COEF2);
254 		writel(CSC0_COEF3_C2(0x7a2) | CSC0_COEF3_C1(0x070),
255 		       lcdif->base + LCDC_V8_CSC0_COEF3);
256 		writel(CSC0_COEF4_D1(0x010) | CSC0_COEF4_C3(0x7ee),
257 		       lcdif->base + LCDC_V8_CSC0_COEF4);
258 		writel(CSC0_COEF5_D3(0x080) | CSC0_COEF5_D2(0x080),
259 		       lcdif->base + LCDC_V8_CSC0_COEF5);
260 	} else if (in_yuv && !out_yuv) {
261 		/* YCbCr -> RGB */
262 		const u32 *coeffs =
263 			lcdif_yuv2rgb_coeffs[plane_state->color_encoding]
264 					    [plane_state->color_range];
265 
266 		writel(CSC0_CTRL_CSC_MODE_YCbCr2RGB,
267 		       lcdif->base + LCDC_V8_CSC0_CTRL);
268 
269 		writel(coeffs[0], lcdif->base + LCDC_V8_CSC0_COEF0);
270 		writel(coeffs[1], lcdif->base + LCDC_V8_CSC0_COEF1);
271 		writel(coeffs[2], lcdif->base + LCDC_V8_CSC0_COEF2);
272 		writel(coeffs[3], lcdif->base + LCDC_V8_CSC0_COEF3);
273 		writel(coeffs[4], lcdif->base + LCDC_V8_CSC0_COEF4);
274 		writel(coeffs[5], lcdif->base + LCDC_V8_CSC0_COEF5);
275 	} else {
276 		/* RGB -> RGB, YCbCr -> YCbCr: bypass colorspace converter. */
277 		writel(CSC0_CTRL_BYPASS, lcdif->base + LCDC_V8_CSC0_CTRL);
278 	}
279 }
280 
281 static void lcdif_set_mode(struct lcdif_drm_private *lcdif, u32 bus_flags)
282 {
283 	struct drm_display_mode *m = &lcdif->crtc.state->adjusted_mode;
284 	u32 ctrl = 0;
285 
286 	if (m->flags & DRM_MODE_FLAG_NHSYNC)
287 		ctrl |= CTRL_INV_HS;
288 	if (m->flags & DRM_MODE_FLAG_NVSYNC)
289 		ctrl |= CTRL_INV_VS;
290 	if (bus_flags & DRM_BUS_FLAG_DE_LOW)
291 		ctrl |= CTRL_INV_DE;
292 	if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
293 		ctrl |= CTRL_INV_PXCK;
294 
295 	writel(ctrl, lcdif->base + LCDC_V8_CTRL);
296 
297 	writel(DISP_SIZE_DELTA_Y(m->vdisplay) |
298 	       DISP_SIZE_DELTA_X(m->hdisplay),
299 	       lcdif->base + LCDC_V8_DISP_SIZE);
300 
301 	writel(HSYN_PARA_BP_H(m->htotal - m->hsync_end) |
302 	       HSYN_PARA_FP_H(m->hsync_start - m->hdisplay),
303 	       lcdif->base + LCDC_V8_HSYN_PARA);
304 
305 	writel(VSYN_PARA_BP_V(m->vtotal - m->vsync_end) |
306 	       VSYN_PARA_FP_V(m->vsync_start - m->vdisplay),
307 	       lcdif->base + LCDC_V8_VSYN_PARA);
308 
309 	writel(VSYN_HSYN_WIDTH_PW_V(m->vsync_end - m->vsync_start) |
310 	       VSYN_HSYN_WIDTH_PW_H(m->hsync_end - m->hsync_start),
311 	       lcdif->base + LCDC_V8_VSYN_HSYN_WIDTH);
312 
313 	writel(CTRLDESCL0_1_HEIGHT(m->vdisplay) |
314 	       CTRLDESCL0_1_WIDTH(m->hdisplay),
315 	       lcdif->base + LCDC_V8_CTRLDESCL0_1);
316 
317 	/*
318 	 * Undocumented P_SIZE and T_SIZE register but those written in the
319 	 * downstream kernel those registers control the AXI burst size. As of
320 	 * now there are two known values:
321 	 *  1 - 128Byte
322 	 *  2 - 256Byte
323 	 * Downstream set it to 256B burst size to improve the memory
324 	 * efficiency so set it here too.
325 	 */
326 	ctrl = CTRLDESCL0_3_P_SIZE(2) | CTRLDESCL0_3_T_SIZE(2) |
327 	       CTRLDESCL0_3_PITCH(lcdif->crtc.primary->state->fb->pitches[0]);
328 	writel(ctrl, lcdif->base + LCDC_V8_CTRLDESCL0_3);
329 }
330 
331 static void lcdif_enable_controller(struct lcdif_drm_private *lcdif)
332 {
333 	u32 reg;
334 
335 	reg = readl(lcdif->base + LCDC_V8_DISP_PARA);
336 	reg |= DISP_PARA_DISP_ON;
337 	writel(reg, lcdif->base + LCDC_V8_DISP_PARA);
338 
339 	reg = readl(lcdif->base + LCDC_V8_CTRLDESCL0_5);
340 	reg |= CTRLDESCL0_5_EN;
341 	writel(reg, lcdif->base + LCDC_V8_CTRLDESCL0_5);
342 }
343 
344 static void lcdif_disable_controller(struct lcdif_drm_private *lcdif)
345 {
346 	u32 reg;
347 	int ret;
348 
349 	reg = readl(lcdif->base + LCDC_V8_CTRLDESCL0_5);
350 	reg &= ~CTRLDESCL0_5_EN;
351 	writel(reg, lcdif->base + LCDC_V8_CTRLDESCL0_5);
352 
353 	ret = readl_poll_timeout(lcdif->base + LCDC_V8_CTRLDESCL0_5,
354 				 reg, !(reg & CTRLDESCL0_5_EN),
355 				 0, 36000);	/* Wait ~2 frame times max */
356 	if (ret)
357 		drm_err(lcdif->drm, "Failed to disable controller!\n");
358 
359 	reg = readl(lcdif->base + LCDC_V8_DISP_PARA);
360 	reg &= ~DISP_PARA_DISP_ON;
361 	writel(reg, lcdif->base + LCDC_V8_DISP_PARA);
362 }
363 
364 static void lcdif_reset_block(struct lcdif_drm_private *lcdif)
365 {
366 	writel(CTRL_SW_RESET, lcdif->base + LCDC_V8_CTRL + REG_SET);
367 	readl(lcdif->base + LCDC_V8_CTRL);
368 	writel(CTRL_SW_RESET, lcdif->base + LCDC_V8_CTRL + REG_CLR);
369 	readl(lcdif->base + LCDC_V8_CTRL);
370 }
371 
372 static void lcdif_crtc_mode_set_nofb(struct lcdif_drm_private *lcdif,
373 				     struct drm_plane_state *plane_state,
374 				     struct drm_bridge_state *bridge_state,
375 				     const u32 bus_format)
376 {
377 	struct drm_device *drm = lcdif->crtc.dev;
378 	struct drm_display_mode *m = &lcdif->crtc.state->adjusted_mode;
379 	u32 bus_flags = 0;
380 
381 	if (lcdif->bridge && lcdif->bridge->timings)
382 		bus_flags = lcdif->bridge->timings->input_bus_flags;
383 	else if (bridge_state)
384 		bus_flags = bridge_state->input_bus_cfg.flags;
385 
386 	DRM_DEV_DEBUG_DRIVER(drm->dev, "Pixel clock: %dkHz (actual: %dkHz)\n",
387 			     m->crtc_clock,
388 			     (int)(clk_get_rate(lcdif->clk) / 1000));
389 	DRM_DEV_DEBUG_DRIVER(drm->dev, "Bridge bus_flags: 0x%08X\n",
390 			     bus_flags);
391 	DRM_DEV_DEBUG_DRIVER(drm->dev, "Mode flags: 0x%08X\n", m->flags);
392 
393 	/* Mandatory eLCDIF reset as per the Reference Manual */
394 	lcdif_reset_block(lcdif);
395 
396 	lcdif_set_formats(lcdif, plane_state, bus_format);
397 
398 	lcdif_set_mode(lcdif, bus_flags);
399 }
400 
401 static int lcdif_crtc_atomic_check(struct drm_crtc *crtc,
402 				   struct drm_atomic_state *state)
403 {
404 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
405 									  crtc);
406 	bool has_primary = crtc_state->plane_mask &
407 			   drm_plane_mask(crtc->primary);
408 
409 	/* The primary plane has to be enabled when the CRTC is active. */
410 	if (crtc_state->active && !has_primary)
411 		return -EINVAL;
412 
413 	return drm_atomic_add_affected_planes(state, crtc);
414 }
415 
416 static void lcdif_crtc_atomic_flush(struct drm_crtc *crtc,
417 				    struct drm_atomic_state *state)
418 {
419 	struct lcdif_drm_private *lcdif = to_lcdif_drm_private(crtc->dev);
420 	struct drm_pending_vblank_event *event;
421 	u32 reg;
422 
423 	reg = readl(lcdif->base + LCDC_V8_CTRLDESCL0_5);
424 	reg |= CTRLDESCL0_5_SHADOW_LOAD_EN;
425 	writel(reg, lcdif->base + LCDC_V8_CTRLDESCL0_5);
426 
427 	event = crtc->state->event;
428 	crtc->state->event = NULL;
429 
430 	if (!event)
431 		return;
432 
433 	spin_lock_irq(&crtc->dev->event_lock);
434 	if (drm_crtc_vblank_get(crtc) == 0)
435 		drm_crtc_arm_vblank_event(crtc, event);
436 	else
437 		drm_crtc_send_vblank_event(crtc, event);
438 	spin_unlock_irq(&crtc->dev->event_lock);
439 }
440 
441 static void lcdif_crtc_atomic_enable(struct drm_crtc *crtc,
442 				     struct drm_atomic_state *state)
443 {
444 	struct lcdif_drm_private *lcdif = to_lcdif_drm_private(crtc->dev);
445 	struct drm_plane_state *new_pstate = drm_atomic_get_new_plane_state(state,
446 									    crtc->primary);
447 	struct drm_display_mode *m = &lcdif->crtc.state->adjusted_mode;
448 	struct drm_bridge_state *bridge_state = NULL;
449 	struct drm_device *drm = lcdif->drm;
450 	u32 bus_format = 0;
451 	dma_addr_t paddr;
452 
453 	/* If there is a bridge attached to the LCDIF, use its bus format */
454 	if (lcdif->bridge) {
455 		bridge_state =
456 			drm_atomic_get_new_bridge_state(state,
457 							lcdif->bridge);
458 		if (!bridge_state)
459 			bus_format = MEDIA_BUS_FMT_FIXED;
460 		else
461 			bus_format = bridge_state->input_bus_cfg.format;
462 
463 		if (bus_format == MEDIA_BUS_FMT_FIXED) {
464 			dev_warn_once(drm->dev,
465 				      "Bridge does not provide bus format, assuming MEDIA_BUS_FMT_RGB888_1X24.\n"
466 				      "Please fix bridge driver by handling atomic_get_input_bus_fmts.\n");
467 			bus_format = MEDIA_BUS_FMT_RGB888_1X24;
468 		}
469 	}
470 
471 	/* If all else fails, default to RGB888_1X24 */
472 	if (!bus_format)
473 		bus_format = MEDIA_BUS_FMT_RGB888_1X24;
474 
475 	clk_set_rate(lcdif->clk, m->crtc_clock * 1000);
476 
477 	pm_runtime_get_sync(drm->dev);
478 
479 	lcdif_crtc_mode_set_nofb(lcdif, new_pstate, bridge_state, bus_format);
480 
481 	/* Write cur_buf as well to avoid an initial corrupt frame */
482 	paddr = drm_fb_dma_get_gem_addr(new_pstate->fb, new_pstate, 0);
483 	if (paddr) {
484 		writel(lower_32_bits(paddr),
485 		       lcdif->base + LCDC_V8_CTRLDESCL_LOW0_4);
486 		writel(CTRLDESCL_HIGH0_4_ADDR_HIGH(upper_32_bits(paddr)),
487 		       lcdif->base + LCDC_V8_CTRLDESCL_HIGH0_4);
488 	}
489 	lcdif_enable_controller(lcdif);
490 
491 	drm_crtc_vblank_on(crtc);
492 }
493 
494 static void lcdif_crtc_atomic_disable(struct drm_crtc *crtc,
495 				      struct drm_atomic_state *state)
496 {
497 	struct lcdif_drm_private *lcdif = to_lcdif_drm_private(crtc->dev);
498 	struct drm_device *drm = lcdif->drm;
499 	struct drm_pending_vblank_event *event;
500 
501 	drm_crtc_vblank_off(crtc);
502 
503 	lcdif_disable_controller(lcdif);
504 
505 	spin_lock_irq(&drm->event_lock);
506 	event = crtc->state->event;
507 	if (event) {
508 		crtc->state->event = NULL;
509 		drm_crtc_send_vblank_event(crtc, event);
510 	}
511 	spin_unlock_irq(&drm->event_lock);
512 
513 	pm_runtime_put_sync(drm->dev);
514 }
515 
516 static int lcdif_crtc_enable_vblank(struct drm_crtc *crtc)
517 {
518 	struct lcdif_drm_private *lcdif = to_lcdif_drm_private(crtc->dev);
519 
520 	/* Clear and enable VBLANK IRQ */
521 	writel(INT_STATUS_D0_VS_BLANK, lcdif->base + LCDC_V8_INT_STATUS_D0);
522 	writel(INT_ENABLE_D0_VS_BLANK_EN, lcdif->base + LCDC_V8_INT_ENABLE_D0);
523 
524 	return 0;
525 }
526 
527 static void lcdif_crtc_disable_vblank(struct drm_crtc *crtc)
528 {
529 	struct lcdif_drm_private *lcdif = to_lcdif_drm_private(crtc->dev);
530 
531 	/* Disable and clear VBLANK IRQ */
532 	writel(0, lcdif->base + LCDC_V8_INT_ENABLE_D0);
533 	writel(INT_STATUS_D0_VS_BLANK, lcdif->base + LCDC_V8_INT_STATUS_D0);
534 }
535 
536 static const struct drm_crtc_helper_funcs lcdif_crtc_helper_funcs = {
537 	.atomic_check = lcdif_crtc_atomic_check,
538 	.atomic_flush = lcdif_crtc_atomic_flush,
539 	.atomic_enable = lcdif_crtc_atomic_enable,
540 	.atomic_disable = lcdif_crtc_atomic_disable,
541 };
542 
543 static const struct drm_crtc_funcs lcdif_crtc_funcs = {
544 	.reset = drm_atomic_helper_crtc_reset,
545 	.destroy = drm_crtc_cleanup,
546 	.set_config = drm_atomic_helper_set_config,
547 	.page_flip = drm_atomic_helper_page_flip,
548 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
549 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
550 	.enable_vblank = lcdif_crtc_enable_vblank,
551 	.disable_vblank = lcdif_crtc_disable_vblank,
552 };
553 
554 /* -----------------------------------------------------------------------------
555  * Encoder
556  */
557 
558 static const struct drm_encoder_funcs lcdif_encoder_funcs = {
559 	.destroy = drm_encoder_cleanup,
560 };
561 
562 /* -----------------------------------------------------------------------------
563  * Planes
564  */
565 
566 static int lcdif_plane_atomic_check(struct drm_plane *plane,
567 				    struct drm_atomic_state *state)
568 {
569 	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state,
570 									     plane);
571 	struct lcdif_drm_private *lcdif = to_lcdif_drm_private(plane->dev);
572 	struct drm_crtc_state *crtc_state;
573 
574 	crtc_state = drm_atomic_get_new_crtc_state(state,
575 						   &lcdif->crtc);
576 
577 	return drm_atomic_helper_check_plane_state(plane_state, crtc_state,
578 						   DRM_PLANE_NO_SCALING,
579 						   DRM_PLANE_NO_SCALING,
580 						   false, true);
581 }
582 
583 static void lcdif_plane_primary_atomic_update(struct drm_plane *plane,
584 					      struct drm_atomic_state *state)
585 {
586 	struct lcdif_drm_private *lcdif = to_lcdif_drm_private(plane->dev);
587 	struct drm_plane_state *new_pstate = drm_atomic_get_new_plane_state(state,
588 									    plane);
589 	dma_addr_t paddr;
590 
591 	paddr = drm_fb_dma_get_gem_addr(new_pstate->fb, new_pstate, 0);
592 	if (paddr) {
593 		writel(lower_32_bits(paddr),
594 		       lcdif->base + LCDC_V8_CTRLDESCL_LOW0_4);
595 		writel(CTRLDESCL_HIGH0_4_ADDR_HIGH(upper_32_bits(paddr)),
596 		       lcdif->base + LCDC_V8_CTRLDESCL_HIGH0_4);
597 	}
598 }
599 
600 static bool lcdif_format_mod_supported(struct drm_plane *plane,
601 				       uint32_t format,
602 				       uint64_t modifier)
603 {
604 	return modifier == DRM_FORMAT_MOD_LINEAR;
605 }
606 
607 static const struct drm_plane_helper_funcs lcdif_plane_primary_helper_funcs = {
608 	.atomic_check = lcdif_plane_atomic_check,
609 	.atomic_update = lcdif_plane_primary_atomic_update,
610 };
611 
612 static const struct drm_plane_funcs lcdif_plane_funcs = {
613 	.format_mod_supported	= lcdif_format_mod_supported,
614 	.update_plane		= drm_atomic_helper_update_plane,
615 	.disable_plane		= drm_atomic_helper_disable_plane,
616 	.destroy		= drm_plane_cleanup,
617 	.reset			= drm_atomic_helper_plane_reset,
618 	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
619 	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
620 };
621 
622 static const u32 lcdif_primary_plane_formats[] = {
623 	/* RGB */
624 	DRM_FORMAT_RGB565,
625 	DRM_FORMAT_RGB888,
626 	DRM_FORMAT_XBGR8888,
627 	DRM_FORMAT_XRGB1555,
628 	DRM_FORMAT_XRGB4444,
629 	DRM_FORMAT_XRGB8888,
630 
631 	/* Packed YCbCr */
632 	DRM_FORMAT_YUYV,
633 	DRM_FORMAT_YVYU,
634 	DRM_FORMAT_UYVY,
635 	DRM_FORMAT_VYUY,
636 };
637 
638 static const u64 lcdif_modifiers[] = {
639 	DRM_FORMAT_MOD_LINEAR,
640 	DRM_FORMAT_MOD_INVALID
641 };
642 
643 /* -----------------------------------------------------------------------------
644  * Initialization
645  */
646 
647 int lcdif_kms_init(struct lcdif_drm_private *lcdif)
648 {
649 	const u32 supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) |
650 					BIT(DRM_COLOR_YCBCR_BT709) |
651 					BIT(DRM_COLOR_YCBCR_BT2020);
652 	const u32 supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
653 				     BIT(DRM_COLOR_YCBCR_FULL_RANGE);
654 	struct drm_encoder *encoder = &lcdif->encoder;
655 	struct drm_crtc *crtc = &lcdif->crtc;
656 	int ret;
657 
658 	drm_plane_helper_add(&lcdif->planes.primary,
659 			     &lcdif_plane_primary_helper_funcs);
660 	ret = drm_universal_plane_init(lcdif->drm, &lcdif->planes.primary, 1,
661 				       &lcdif_plane_funcs,
662 				       lcdif_primary_plane_formats,
663 				       ARRAY_SIZE(lcdif_primary_plane_formats),
664 				       lcdif_modifiers, DRM_PLANE_TYPE_PRIMARY,
665 				       NULL);
666 	if (ret)
667 		return ret;
668 
669 	ret = drm_plane_create_color_properties(&lcdif->planes.primary,
670 						supported_encodings,
671 						supported_ranges,
672 						DRM_COLOR_YCBCR_BT601,
673 						DRM_COLOR_YCBCR_LIMITED_RANGE);
674 	if (ret)
675 		return ret;
676 
677 	drm_crtc_helper_add(crtc, &lcdif_crtc_helper_funcs);
678 	ret = drm_crtc_init_with_planes(lcdif->drm, crtc,
679 					&lcdif->planes.primary, NULL,
680 					&lcdif_crtc_funcs, NULL);
681 	if (ret)
682 		return ret;
683 
684 	encoder->possible_crtcs = drm_crtc_mask(crtc);
685 	return drm_encoder_init(lcdif->drm, encoder, &lcdif_encoder_funcs,
686 				DRM_MODE_ENCODER_NONE, NULL);
687 }
688