xref: /linux/drivers/gpu/drm/tidss/tidss_dispc.c (revision a4871e6201c46c8e1d04308265b4b4c5753c8209)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/
4  * Author: Jyri Sarha <jsarha@ti.com>
5  */
6 
7 #include <linux/clk.h>
8 #include <linux/delay.h>
9 #include <linux/dma-mapping.h>
10 #include <linux/err.h>
11 #include <linux/interrupt.h>
12 #include <linux/io.h>
13 #include <linux/kernel.h>
14 #include <linux/media-bus-format.h>
15 #include <linux/module.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/of.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regmap.h>
21 #include <linux/sys_soc.h>
22 
23 #include <drm/drm_blend.h>
24 #include <drm/drm_fourcc.h>
25 #include <drm/drm_fb_dma_helper.h>
26 #include <drm/drm_framebuffer.h>
27 #include <drm/drm_gem_dma_helper.h>
28 #include <drm/drm_panel.h>
29 
30 #include "tidss_crtc.h"
31 #include "tidss_dispc.h"
32 #include "tidss_drv.h"
33 #include "tidss_irq.h"
34 #include "tidss_plane.h"
35 
36 #include "tidss_dispc_regs.h"
37 #include "tidss_scale_coefs.h"
38 
39 static const u16 tidss_k2g_common_regs[DISPC_COMMON_REG_TABLE_LEN] = {
40 	[DSS_REVISION_OFF] =                    0x00,
41 	[DSS_SYSCONFIG_OFF] =                   0x04,
42 	[DSS_SYSSTATUS_OFF] =                   0x08,
43 	[DISPC_IRQ_EOI_OFF] =                   0x20,
44 	[DISPC_IRQSTATUS_RAW_OFF] =             0x24,
45 	[DISPC_IRQSTATUS_OFF] =                 0x28,
46 	[DISPC_IRQENABLE_SET_OFF] =             0x2c,
47 	[DISPC_IRQENABLE_CLR_OFF] =             0x30,
48 
49 	[DISPC_GLOBAL_MFLAG_ATTRIBUTE_OFF] =    0x40,
50 	[DISPC_GLOBAL_BUFFER_OFF] =             0x44,
51 
52 	[DISPC_DBG_CONTROL_OFF] =               0x4c,
53 	[DISPC_DBG_STATUS_OFF] =                0x50,
54 
55 	[DISPC_CLKGATING_DISABLE_OFF] =         0x54,
56 };
57 
58 const struct dispc_features dispc_k2g_feats = {
59 	.min_pclk_khz = 4375,
60 
61 	.max_pclk_khz = {
62 		[DISPC_VP_DPI] = 150000,
63 	},
64 
65 	/*
66 	 * XXX According TRM the RGB input buffer width up to 2560 should
67 	 *     work on 3 taps, but in practice it only works up to 1280.
68 	 */
69 	.scaling = {
70 		.in_width_max_5tap_rgb = 1280,
71 		.in_width_max_3tap_rgb = 1280,
72 		.in_width_max_5tap_yuv = 2560,
73 		.in_width_max_3tap_yuv = 2560,
74 		.upscale_limit = 16,
75 		.downscale_limit_5tap = 4,
76 		.downscale_limit_3tap = 2,
77 		/*
78 		 * The max supported pixel inc value is 255. The value
79 		 * of pixel inc is calculated like this: 1+(xinc-1)*bpp.
80 		 * The maximum bpp of all formats supported by the HW
81 		 * is 8. So the maximum supported xinc value is 32,
82 		 * because 1+(32-1)*8 < 255 < 1+(33-1)*4.
83 		 */
84 		.xinc_max = 32,
85 	},
86 
87 	.subrev = DISPC_K2G,
88 
89 	.common = "common",
90 
91 	.common_regs = tidss_k2g_common_regs,
92 
93 	.num_vps = 1,
94 	.vp_name = { "vp1" },
95 	.ovr_name = { "ovr1" },
96 	.vpclk_name =  { "vp1" },
97 	.vp_bus_type = { DISPC_VP_DPI },
98 
99 	.vp_feat = { .color = {
100 			.has_ctm = true,
101 			.gamma_size = 256,
102 			.gamma_type = TIDSS_GAMMA_8BIT,
103 		},
104 	},
105 
106 	.num_vids = 1,
107 
108 	.vid_info = {
109 		{
110 			.name = "vid1",
111 			.is_lite = false,
112 			.hw_id = 0,
113 		},
114 	},
115 
116 	.vid_order = { 0 },
117 };
118 
119 static const u16 tidss_am65x_common_regs[DISPC_COMMON_REG_TABLE_LEN] = {
120 	[DSS_REVISION_OFF] =			0x4,
121 	[DSS_SYSCONFIG_OFF] =			0x8,
122 	[DSS_SYSSTATUS_OFF] =			0x20,
123 	[DISPC_IRQ_EOI_OFF] =			0x24,
124 	[DISPC_IRQSTATUS_RAW_OFF] =		0x28,
125 	[DISPC_IRQSTATUS_OFF] =			0x2c,
126 	[DISPC_IRQENABLE_SET_OFF] =		0x30,
127 	[DISPC_IRQENABLE_CLR_OFF] =		0x40,
128 	[DISPC_VID_IRQENABLE_OFF] =		0x44,
129 	[DISPC_VID_IRQSTATUS_OFF] =		0x58,
130 	[DISPC_VP_IRQENABLE_OFF] =		0x70,
131 	[DISPC_VP_IRQSTATUS_OFF] =		0x7c,
132 
133 	[WB_IRQENABLE_OFF] =			0x88,
134 	[WB_IRQSTATUS_OFF] =			0x8c,
135 
136 	[DISPC_GLOBAL_MFLAG_ATTRIBUTE_OFF] =	0x90,
137 	[DISPC_GLOBAL_OUTPUT_ENABLE_OFF] =	0x94,
138 	[DISPC_GLOBAL_BUFFER_OFF] =		0x98,
139 	[DSS_CBA_CFG_OFF] =			0x9c,
140 	[DISPC_DBG_CONTROL_OFF] =		0xa0,
141 	[DISPC_DBG_STATUS_OFF] =		0xa4,
142 	[DISPC_CLKGATING_DISABLE_OFF] =		0xa8,
143 	[DISPC_SECURE_DISABLE_OFF] =		0xac,
144 };
145 
146 const struct dispc_features dispc_am65x_feats = {
147 	.max_pclk_khz = {
148 		[DISPC_VP_DPI] = 165000,
149 		[DISPC_VP_OLDI] = 165000,
150 	},
151 
152 	.scaling = {
153 		.in_width_max_5tap_rgb = 1280,
154 		.in_width_max_3tap_rgb = 2560,
155 		.in_width_max_5tap_yuv = 2560,
156 		.in_width_max_3tap_yuv = 4096,
157 		.upscale_limit = 16,
158 		.downscale_limit_5tap = 4,
159 		.downscale_limit_3tap = 2,
160 		/*
161 		 * The max supported pixel inc value is 255. The value
162 		 * of pixel inc is calculated like this: 1+(xinc-1)*bpp.
163 		 * The maximum bpp of all formats supported by the HW
164 		 * is 8. So the maximum supported xinc value is 32,
165 		 * because 1+(32-1)*8 < 255 < 1+(33-1)*4.
166 		 */
167 		.xinc_max = 32,
168 	},
169 
170 	.subrev = DISPC_AM65X,
171 
172 	.common = "common",
173 	.common_regs = tidss_am65x_common_regs,
174 
175 	.num_vps = 2,
176 	.vp_name = { "vp1", "vp2" },
177 	.ovr_name = { "ovr1", "ovr2" },
178 	.vpclk_name =  { "vp1", "vp2" },
179 	.vp_bus_type = { DISPC_VP_OLDI, DISPC_VP_DPI },
180 
181 	.vp_feat = { .color = {
182 			.has_ctm = true,
183 			.gamma_size = 256,
184 			.gamma_type = TIDSS_GAMMA_8BIT,
185 		},
186 	},
187 
188 	.num_vids = 2,
189 	/* note: vid is plane_id 0 and vidl1 is plane_id 1 */
190 	.vid_info = {
191 		{
192 			.name = "vid",
193 			.is_lite = false,
194 			.hw_id = 0,
195 		},
196 		{
197 			.name = "vidl1",
198 			.is_lite = true,
199 			.hw_id = 1,
200 		},
201 	},
202 
203 	.vid_order = {1, 0},
204 };
205 
206 static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = {
207 	[DSS_REVISION_OFF] =			0x4,
208 	[DSS_SYSCONFIG_OFF] =			0x8,
209 	[DSS_SYSSTATUS_OFF] =			0x20,
210 	[DISPC_IRQ_EOI_OFF] =			0x80,
211 	[DISPC_IRQSTATUS_RAW_OFF] =		0x28,
212 	[DISPC_IRQSTATUS_OFF] =			0x2c,
213 	[DISPC_IRQENABLE_SET_OFF] =		0x30,
214 	[DISPC_IRQENABLE_CLR_OFF] =		0x34,
215 	[DISPC_VID_IRQENABLE_OFF] =		0x38,
216 	[DISPC_VID_IRQSTATUS_OFF] =		0x48,
217 	[DISPC_VP_IRQENABLE_OFF] =		0x58,
218 	[DISPC_VP_IRQSTATUS_OFF] =		0x68,
219 
220 	[WB_IRQENABLE_OFF] =			0x78,
221 	[WB_IRQSTATUS_OFF] =			0x7c,
222 
223 	[DISPC_GLOBAL_MFLAG_ATTRIBUTE_OFF] =	0x98,
224 	[DISPC_GLOBAL_OUTPUT_ENABLE_OFF] =	0x9c,
225 	[DISPC_GLOBAL_BUFFER_OFF] =		0xa0,
226 	[DSS_CBA_CFG_OFF] =			0xa4,
227 	[DISPC_DBG_CONTROL_OFF] =		0xa8,
228 	[DISPC_DBG_STATUS_OFF] =		0xac,
229 	[DISPC_CLKGATING_DISABLE_OFF] =		0xb0,
230 	[DISPC_SECURE_DISABLE_OFF] =		0x90,
231 
232 	[FBDC_REVISION_1_OFF] =			0xb8,
233 	[FBDC_REVISION_2_OFF] =			0xbc,
234 	[FBDC_REVISION_3_OFF] =			0xc0,
235 	[FBDC_REVISION_4_OFF] =			0xc4,
236 	[FBDC_REVISION_5_OFF] =			0xc8,
237 	[FBDC_REVISION_6_OFF] =			0xcc,
238 	[FBDC_COMMON_CONTROL_OFF] =		0xd0,
239 	[FBDC_CONSTANT_COLOR_0_OFF] =		0xd4,
240 	[FBDC_CONSTANT_COLOR_1_OFF] =		0xd8,
241 	[DISPC_CONNECTIONS_OFF] =		0xe4,
242 	[DISPC_MSS_VP1_OFF] =			0xe8,
243 	[DISPC_MSS_VP3_OFF] =			0xec,
244 };
245 
246 const struct dispc_features dispc_j721e_feats = {
247 	.max_pclk_khz = {
248 		[DISPC_VP_DPI] = 170000,
249 		[DISPC_VP_INTERNAL] = 600000,
250 	},
251 
252 	.scaling = {
253 		.in_width_max_5tap_rgb = 2048,
254 		.in_width_max_3tap_rgb = 4096,
255 		.in_width_max_5tap_yuv = 4096,
256 		.in_width_max_3tap_yuv = 4096,
257 		.upscale_limit = 16,
258 		.downscale_limit_5tap = 4,
259 		.downscale_limit_3tap = 2,
260 		/*
261 		 * The max supported pixel inc value is 255. The value
262 		 * of pixel inc is calculated like this: 1+(xinc-1)*bpp.
263 		 * The maximum bpp of all formats supported by the HW
264 		 * is 8. So the maximum supported xinc value is 32,
265 		 * because 1+(32-1)*8 < 255 < 1+(33-1)*4.
266 		 */
267 		.xinc_max = 32,
268 	},
269 
270 	.subrev = DISPC_J721E,
271 
272 	.common = "common_m",
273 	.common_regs = tidss_j721e_common_regs,
274 
275 	.num_vps = 4,
276 	.vp_name = { "vp1", "vp2", "vp3", "vp4" },
277 	.ovr_name = { "ovr1", "ovr2", "ovr3", "ovr4" },
278 	.vpclk_name = { "vp1", "vp2", "vp3", "vp4" },
279 	/* Currently hard coded VP routing (see dispc_initial_config()) */
280 	.vp_bus_type =	{ DISPC_VP_INTERNAL, DISPC_VP_DPI,
281 			  DISPC_VP_INTERNAL, DISPC_VP_DPI, },
282 	.vp_feat = { .color = {
283 			.has_ctm = true,
284 			.gamma_size = 1024,
285 			.gamma_type = TIDSS_GAMMA_10BIT,
286 		},
287 	},
288 
289 	.num_vids = 4,
290 
291 	.vid_info = {
292 		{
293 			.name = "vid1",
294 			.is_lite = false,
295 			.hw_id = 0,
296 		},
297 		{
298 			.name = "vidl1",
299 			.is_lite = true,
300 			.hw_id = 1,
301 		},
302 		{
303 			.name = "vid2",
304 			.is_lite = false,
305 			.hw_id = 2,
306 		},
307 		{
308 			.name = "vidl2",
309 			.is_lite = true,
310 			.hw_id = 3,
311 		},
312 	},
313 
314 	.vid_order = { 1, 3, 0, 2 },
315 };
316 
317 const struct dispc_features dispc_am625_feats = {
318 	.max_pclk_khz = {
319 		[DISPC_VP_DPI] = 165000,
320 		[DISPC_VP_INTERNAL] = 170000,
321 	},
322 
323 	.scaling = {
324 		.in_width_max_5tap_rgb = 1280,
325 		.in_width_max_3tap_rgb = 2560,
326 		.in_width_max_5tap_yuv = 2560,
327 		.in_width_max_3tap_yuv = 4096,
328 		.upscale_limit = 16,
329 		.downscale_limit_5tap = 4,
330 		.downscale_limit_3tap = 2,
331 		/*
332 		 * The max supported pixel inc value is 255. The value
333 		 * of pixel inc is calculated like this: 1+(xinc-1)*bpp.
334 		 * The maximum bpp of all formats supported by the HW
335 		 * is 8. So the maximum supported xinc value is 32,
336 		 * because 1+(32-1)*8 < 255 < 1+(33-1)*4.
337 		 */
338 		.xinc_max = 32,
339 	},
340 
341 	.subrev = DISPC_AM625,
342 
343 	.common = "common",
344 	.common_regs = tidss_am65x_common_regs,
345 
346 	.num_vps = 2,
347 	.vp_name = { "vp1", "vp2" },
348 	.ovr_name = { "ovr1", "ovr2" },
349 	.vpclk_name =  { "vp1", "vp2" },
350 	.vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_DPI },
351 
352 	.vp_feat = { .color = {
353 			.has_ctm = true,
354 			.gamma_size = 256,
355 			.gamma_type = TIDSS_GAMMA_8BIT,
356 		},
357 	},
358 
359 	.num_vids = 2,
360 
361 	/* note: vid is plane_id 0 and vidl1 is plane_id 1 */
362 	.vid_info = {
363 		{
364 			.name = "vid",
365 			.is_lite = false,
366 			.hw_id = 0,
367 		},
368 		{
369 			.name = "vidl1",
370 			.is_lite = true,
371 			.hw_id = 1,
372 		}
373 	},
374 
375 	.vid_order = {1, 0},
376 };
377 
378 const struct dispc_features dispc_am62a7_feats = {
379 	/*
380 	 * if the code reaches dispc_mode_valid with VP1,
381 	 * it should return MODE_BAD.
382 	 */
383 	.max_pclk_khz = {
384 		[DISPC_VP_TIED_OFF] = 0,
385 		[DISPC_VP_DPI] = 165000,
386 	},
387 
388 	.scaling = {
389 		.in_width_max_5tap_rgb = 1280,
390 		.in_width_max_3tap_rgb = 2560,
391 		.in_width_max_5tap_yuv = 2560,
392 		.in_width_max_3tap_yuv = 4096,
393 		.upscale_limit = 16,
394 		.downscale_limit_5tap = 4,
395 		.downscale_limit_3tap = 2,
396 		/*
397 		 * The max supported pixel inc value is 255. The value
398 		 * of pixel inc is calculated like this: 1+(xinc-1)*bpp.
399 		 * The maximum bpp of all formats supported by the HW
400 		 * is 8. So the maximum supported xinc value is 32,
401 		 * because 1+(32-1)*8 < 255 < 1+(33-1)*4.
402 		 */
403 		.xinc_max = 32,
404 	},
405 
406 	.subrev = DISPC_AM62A7,
407 
408 	.common = "common",
409 	.common_regs = tidss_am65x_common_regs,
410 
411 	.num_vps = 2,
412 	.vp_name = { "vp1", "vp2" },
413 	.ovr_name = { "ovr1", "ovr2" },
414 	.vpclk_name =  { "vp1", "vp2" },
415 	/* VP1 of the DSS in AM62A7 SoC is tied off internally */
416 	.vp_bus_type = { DISPC_VP_TIED_OFF, DISPC_VP_DPI },
417 
418 	.vp_feat = { .color = {
419 			.has_ctm = true,
420 			.gamma_size = 256,
421 			.gamma_type = TIDSS_GAMMA_8BIT,
422 		},
423 	},
424 
425 	.num_vids = 2,
426 
427 	.vid_info = {
428 		{
429 			.name = "vid",
430 			.is_lite = false,
431 			.hw_id = 0,
432 		},
433 		{
434 			.name = "vidl1",
435 			.is_lite = true,
436 			.hw_id = 1,
437 		}
438 	},
439 
440 	.vid_order = {1, 0},
441 };
442 
443 const struct dispc_features dispc_am62l_feats = {
444 	.max_pclk_khz = {
445 		[DISPC_VP_DPI] = 165000,
446 	},
447 
448 	.subrev = DISPC_AM62L,
449 
450 	.common = "common",
451 	.common_regs = tidss_am65x_common_regs,
452 
453 	.num_vps = 1,
454 	.vp_name = { "vp1" },
455 	.ovr_name = { "ovr1" },
456 	.vpclk_name =  { "vp1" },
457 	.vp_bus_type = { DISPC_VP_DPI },
458 
459 	.vp_feat = { .color = {
460 			.has_ctm = true,
461 			.gamma_size = 256,
462 			.gamma_type = TIDSS_GAMMA_8BIT,
463 		},
464 	},
465 
466 	.num_vids = 1,
467 
468 	.vid_info = {
469 		{
470 			.name = "vidl1",
471 			.is_lite = true,
472 			.hw_id = 1,
473 		}
474 	},
475 
476 	.vid_order = {0},
477 };
478 
479 static const u16 *dispc_common_regmap;
480 
481 struct dss_vp_data {
482 	u32 *gamma_table;
483 };
484 
485 struct dispc_device {
486 	struct tidss_device *tidss;
487 	struct device *dev;
488 
489 	void __iomem *base_common;
490 	void __iomem *base_vid[TIDSS_MAX_PLANES];
491 	void __iomem *base_ovr[TIDSS_MAX_PORTS];
492 	void __iomem *base_vp[TIDSS_MAX_PORTS];
493 
494 	struct regmap *oldi_io_ctrl;
495 
496 	struct clk *vp_clk[TIDSS_MAX_PORTS];
497 
498 	const struct dispc_features *feat;
499 
500 	struct clk *fclk;
501 
502 	bool is_enabled;
503 
504 	struct dss_vp_data vp_data[TIDSS_MAX_PORTS];
505 
506 	u32 *fourccs;
507 	u32 num_fourccs;
508 
509 	u32 memory_bandwidth_limit;
510 
511 	struct dispc_errata errata;
512 };
513 
514 static void dispc_write(struct dispc_device *dispc, u16 reg, u32 val)
515 {
516 	iowrite32(val, dispc->base_common + reg);
517 }
518 
519 static u32 dispc_read(struct dispc_device *dispc, u16 reg)
520 {
521 	return ioread32(dispc->base_common + reg);
522 }
523 
524 static
525 void dispc_vid_write(struct dispc_device *dispc, u32 hw_plane, u16 reg, u32 val)
526 {
527 	void __iomem *base = dispc->base_vid[hw_plane];
528 
529 	iowrite32(val, base + reg);
530 }
531 
532 static u32 dispc_vid_read(struct dispc_device *dispc, u32 hw_plane, u16 reg)
533 {
534 	void __iomem *base = dispc->base_vid[hw_plane];
535 
536 	return ioread32(base + reg);
537 }
538 
539 static void dispc_ovr_write(struct dispc_device *dispc, u32 hw_videoport,
540 			    u16 reg, u32 val)
541 {
542 	void __iomem *base = dispc->base_ovr[hw_videoport];
543 
544 	iowrite32(val, base + reg);
545 }
546 
547 static u32 dispc_ovr_read(struct dispc_device *dispc, u32 hw_videoport, u16 reg)
548 {
549 	void __iomem *base = dispc->base_ovr[hw_videoport];
550 
551 	return ioread32(base + reg);
552 }
553 
554 static void dispc_vp_write(struct dispc_device *dispc, u32 hw_videoport,
555 			   u16 reg, u32 val)
556 {
557 	void __iomem *base = dispc->base_vp[hw_videoport];
558 
559 	iowrite32(val, base + reg);
560 }
561 
562 static u32 dispc_vp_read(struct dispc_device *dispc, u32 hw_videoport, u16 reg)
563 {
564 	void __iomem *base = dispc->base_vp[hw_videoport];
565 
566 	return ioread32(base + reg);
567 }
568 
569 /*
570  * TRM gives bitfields as start:end, where start is the higher bit
571  * number. For example 7:0
572  */
573 
574 static u32 FLD_MASK(u32 start, u32 end)
575 {
576 	return ((1 << (start - end + 1)) - 1) << end;
577 }
578 
579 static u32 FLD_VAL(u32 val, u32 start, u32 end)
580 {
581 	return (val << end) & FLD_MASK(start, end);
582 }
583 
584 static u32 FLD_GET(u32 val, u32 start, u32 end)
585 {
586 	return (val & FLD_MASK(start, end)) >> end;
587 }
588 
589 static u32 FLD_MOD(u32 orig, u32 val, u32 start, u32 end)
590 {
591 	return (orig & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end);
592 }
593 
594 static u32 REG_GET(struct dispc_device *dispc, u32 idx, u32 start, u32 end)
595 {
596 	return FLD_GET(dispc_read(dispc, idx), start, end);
597 }
598 
599 static void REG_FLD_MOD(struct dispc_device *dispc, u32 idx, u32 val,
600 			u32 start, u32 end)
601 {
602 	dispc_write(dispc, idx, FLD_MOD(dispc_read(dispc, idx), val,
603 					start, end));
604 }
605 
606 static u32 VID_REG_GET(struct dispc_device *dispc, u32 hw_plane, u32 idx,
607 		       u32 start, u32 end)
608 {
609 	return FLD_GET(dispc_vid_read(dispc, hw_plane, idx), start, end);
610 }
611 
612 static void VID_REG_FLD_MOD(struct dispc_device *dispc, u32 hw_plane, u32 idx,
613 			    u32 val, u32 start, u32 end)
614 {
615 	dispc_vid_write(dispc, hw_plane, idx,
616 			FLD_MOD(dispc_vid_read(dispc, hw_plane, idx),
617 				val, start, end));
618 }
619 
620 static u32 VP_REG_GET(struct dispc_device *dispc, u32 vp, u32 idx,
621 		      u32 start, u32 end)
622 {
623 	return FLD_GET(dispc_vp_read(dispc, vp, idx), start, end);
624 }
625 
626 static void VP_REG_FLD_MOD(struct dispc_device *dispc, u32 vp, u32 idx, u32 val,
627 			   u32 start, u32 end)
628 {
629 	dispc_vp_write(dispc, vp, idx, FLD_MOD(dispc_vp_read(dispc, vp, idx),
630 					       val, start, end));
631 }
632 
633 __maybe_unused
634 static u32 OVR_REG_GET(struct dispc_device *dispc, u32 ovr, u32 idx,
635 		       u32 start, u32 end)
636 {
637 	return FLD_GET(dispc_ovr_read(dispc, ovr, idx), start, end);
638 }
639 
640 static void OVR_REG_FLD_MOD(struct dispc_device *dispc, u32 ovr, u32 idx,
641 			    u32 val, u32 start, u32 end)
642 {
643 	dispc_ovr_write(dispc, ovr, idx,
644 			FLD_MOD(dispc_ovr_read(dispc, ovr, idx),
645 				val, start, end));
646 }
647 
648 static dispc_irq_t dispc_vp_irq_from_raw(u32 stat, u32 hw_videoport)
649 {
650 	dispc_irq_t vp_stat = 0;
651 
652 	if (stat & BIT(0))
653 		vp_stat |= DSS_IRQ_VP_FRAME_DONE(hw_videoport);
654 	if (stat & BIT(1))
655 		vp_stat |= DSS_IRQ_VP_VSYNC_EVEN(hw_videoport);
656 	if (stat & BIT(2))
657 		vp_stat |= DSS_IRQ_VP_VSYNC_ODD(hw_videoport);
658 	if (stat & BIT(4))
659 		vp_stat |= DSS_IRQ_VP_SYNC_LOST(hw_videoport);
660 
661 	return vp_stat;
662 }
663 
664 static u32 dispc_vp_irq_to_raw(dispc_irq_t vpstat, u32 hw_videoport)
665 {
666 	u32 stat = 0;
667 
668 	if (vpstat & DSS_IRQ_VP_FRAME_DONE(hw_videoport))
669 		stat |= BIT(0);
670 	if (vpstat & DSS_IRQ_VP_VSYNC_EVEN(hw_videoport))
671 		stat |= BIT(1);
672 	if (vpstat & DSS_IRQ_VP_VSYNC_ODD(hw_videoport))
673 		stat |= BIT(2);
674 	if (vpstat & DSS_IRQ_VP_SYNC_LOST(hw_videoport))
675 		stat |= BIT(4);
676 
677 	return stat;
678 }
679 
680 static dispc_irq_t dispc_vid_irq_from_raw(u32 stat, u32 hw_plane)
681 {
682 	dispc_irq_t vid_stat = 0;
683 
684 	if (stat & BIT(0))
685 		vid_stat |= DSS_IRQ_PLANE_FIFO_UNDERFLOW(hw_plane);
686 
687 	return vid_stat;
688 }
689 
690 static u32 dispc_vid_irq_to_raw(dispc_irq_t vidstat, u32 hw_plane)
691 {
692 	u32 stat = 0;
693 
694 	if (vidstat & DSS_IRQ_PLANE_FIFO_UNDERFLOW(hw_plane))
695 		stat |= BIT(0);
696 
697 	return stat;
698 }
699 
700 static dispc_irq_t dispc_k2g_vp_read_irqstatus(struct dispc_device *dispc,
701 					       u32 hw_videoport)
702 {
703 	u32 stat = dispc_vp_read(dispc, hw_videoport, DISPC_VP_K2G_IRQSTATUS);
704 
705 	return dispc_vp_irq_from_raw(stat, hw_videoport);
706 }
707 
708 static void dispc_k2g_vp_write_irqstatus(struct dispc_device *dispc,
709 					 u32 hw_videoport, dispc_irq_t vpstat)
710 {
711 	u32 stat = dispc_vp_irq_to_raw(vpstat, hw_videoport);
712 
713 	dispc_vp_write(dispc, hw_videoport, DISPC_VP_K2G_IRQSTATUS, stat);
714 }
715 
716 static dispc_irq_t dispc_k2g_vid_read_irqstatus(struct dispc_device *dispc,
717 						u32 hw_plane)
718 {
719 	u32 stat = dispc_vid_read(dispc, hw_plane, DISPC_VID_K2G_IRQSTATUS);
720 
721 	return dispc_vid_irq_from_raw(stat, hw_plane);
722 }
723 
724 static void dispc_k2g_vid_write_irqstatus(struct dispc_device *dispc,
725 					  u32 hw_plane, dispc_irq_t vidstat)
726 {
727 	u32 stat = dispc_vid_irq_to_raw(vidstat, hw_plane);
728 
729 	dispc_vid_write(dispc, hw_plane, DISPC_VID_K2G_IRQSTATUS, stat);
730 }
731 
732 static dispc_irq_t dispc_k2g_vp_read_irqenable(struct dispc_device *dispc,
733 					       u32 hw_videoport)
734 {
735 	u32 stat = dispc_vp_read(dispc, hw_videoport, DISPC_VP_K2G_IRQENABLE);
736 
737 	return dispc_vp_irq_from_raw(stat, hw_videoport);
738 }
739 
740 static void dispc_k2g_vp_set_irqenable(struct dispc_device *dispc,
741 				       u32 hw_videoport, dispc_irq_t vpstat)
742 {
743 	u32 stat = dispc_vp_irq_to_raw(vpstat, hw_videoport);
744 
745 	dispc_vp_write(dispc, hw_videoport, DISPC_VP_K2G_IRQENABLE, stat);
746 }
747 
748 static dispc_irq_t dispc_k2g_vid_read_irqenable(struct dispc_device *dispc,
749 						u32 hw_plane)
750 {
751 	u32 stat = dispc_vid_read(dispc, hw_plane, DISPC_VID_K2G_IRQENABLE);
752 
753 	return dispc_vid_irq_from_raw(stat, hw_plane);
754 }
755 
756 static void dispc_k2g_vid_set_irqenable(struct dispc_device *dispc,
757 					u32 hw_plane, dispc_irq_t vidstat)
758 {
759 	u32 stat = dispc_vid_irq_to_raw(vidstat, hw_plane);
760 
761 	dispc_vid_write(dispc, hw_plane, DISPC_VID_K2G_IRQENABLE, stat);
762 }
763 
764 static void dispc_k2g_clear_irqstatus(struct dispc_device *dispc,
765 				      dispc_irq_t mask)
766 {
767 	dispc_k2g_vp_write_irqstatus(dispc, 0, mask);
768 	dispc_k2g_vid_write_irqstatus(dispc, 0, mask);
769 }
770 
771 static
772 dispc_irq_t dispc_k2g_read_and_clear_irqstatus(struct dispc_device *dispc)
773 {
774 	dispc_irq_t stat = 0;
775 
776 	/* always clear the top level irqstatus */
777 	dispc_write(dispc, DISPC_IRQSTATUS,
778 		    dispc_read(dispc, DISPC_IRQSTATUS));
779 
780 	stat |= dispc_k2g_vp_read_irqstatus(dispc, 0);
781 	stat |= dispc_k2g_vid_read_irqstatus(dispc, 0);
782 
783 	dispc_k2g_clear_irqstatus(dispc, stat);
784 
785 	return stat;
786 }
787 
788 static dispc_irq_t dispc_k2g_read_irqenable(struct dispc_device *dispc)
789 {
790 	dispc_irq_t stat = 0;
791 
792 	stat |= dispc_k2g_vp_read_irqenable(dispc, 0);
793 	stat |= dispc_k2g_vid_read_irqenable(dispc, 0);
794 
795 	return stat;
796 }
797 
798 static
799 void dispc_k2g_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask)
800 {
801 	dispc_irq_t old_mask = dispc_k2g_read_irqenable(dispc);
802 
803 	/* clear the irqstatus for irqs that will be enabled */
804 	dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & mask);
805 
806 	dispc_k2g_vp_set_irqenable(dispc, 0, mask);
807 	dispc_k2g_vid_set_irqenable(dispc, 0, mask);
808 
809 	dispc_write(dispc, DISPC_IRQENABLE_SET, (1 << 0) | (1 << 7));
810 
811 	/* clear the irqstatus for irqs that were disabled */
812 	dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & old_mask);
813 
814 	/* flush posted write */
815 	dispc_k2g_read_irqenable(dispc);
816 }
817 
818 static dispc_irq_t dispc_k3_vp_read_irqstatus(struct dispc_device *dispc,
819 					      u32 hw_videoport)
820 {
821 	u32 stat = dispc_read(dispc, DISPC_VP_IRQSTATUS(hw_videoport));
822 
823 	return dispc_vp_irq_from_raw(stat, hw_videoport);
824 }
825 
826 static void dispc_k3_vp_write_irqstatus(struct dispc_device *dispc,
827 					u32 hw_videoport, dispc_irq_t vpstat)
828 {
829 	u32 stat = dispc_vp_irq_to_raw(vpstat, hw_videoport);
830 
831 	dispc_write(dispc, DISPC_VP_IRQSTATUS(hw_videoport), stat);
832 }
833 
834 static dispc_irq_t dispc_k3_vid_read_irqstatus(struct dispc_device *dispc,
835 					       u32 hw_plane)
836 {
837 	u32 hw_id = dispc->feat->vid_info[hw_plane].hw_id;
838 	u32 stat = dispc_read(dispc, DISPC_VID_IRQSTATUS(hw_id));
839 
840 	return dispc_vid_irq_from_raw(stat, hw_plane);
841 }
842 
843 static void dispc_k3_vid_write_irqstatus(struct dispc_device *dispc,
844 					 u32 hw_plane, dispc_irq_t vidstat)
845 {
846 	u32 hw_id = dispc->feat->vid_info[hw_plane].hw_id;
847 	u32 stat = dispc_vid_irq_to_raw(vidstat, hw_plane);
848 
849 	dispc_write(dispc, DISPC_VID_IRQSTATUS(hw_id), stat);
850 }
851 
852 static dispc_irq_t dispc_k3_vp_read_irqenable(struct dispc_device *dispc,
853 					      u32 hw_videoport)
854 {
855 	u32 stat = dispc_read(dispc, DISPC_VP_IRQENABLE(hw_videoport));
856 
857 	return dispc_vp_irq_from_raw(stat, hw_videoport);
858 }
859 
860 static void dispc_k3_vp_set_irqenable(struct dispc_device *dispc,
861 				      u32 hw_videoport, dispc_irq_t vpstat)
862 {
863 	u32 stat = dispc_vp_irq_to_raw(vpstat, hw_videoport);
864 
865 	dispc_write(dispc, DISPC_VP_IRQENABLE(hw_videoport), stat);
866 }
867 
868 static dispc_irq_t dispc_k3_vid_read_irqenable(struct dispc_device *dispc,
869 					       u32 hw_plane)
870 {
871 	u32 hw_id = dispc->feat->vid_info[hw_plane].hw_id;
872 	u32 stat = dispc_read(dispc, DISPC_VID_IRQENABLE(hw_id));
873 
874 	return dispc_vid_irq_from_raw(stat, hw_plane);
875 }
876 
877 static void dispc_k3_vid_set_irqenable(struct dispc_device *dispc,
878 				       u32 hw_plane, dispc_irq_t vidstat)
879 {
880 	u32 hw_id = dispc->feat->vid_info[hw_plane].hw_id;
881 	u32 stat = dispc_vid_irq_to_raw(vidstat, hw_plane);
882 
883 	dispc_write(dispc, DISPC_VID_IRQENABLE(hw_id), stat);
884 }
885 
886 static
887 void dispc_k3_clear_irqstatus(struct dispc_device *dispc, dispc_irq_t clearmask)
888 {
889 	unsigned int i;
890 
891 	for (i = 0; i < dispc->feat->num_vps; ++i) {
892 		if (clearmask & DSS_IRQ_VP_MASK(i))
893 			dispc_k3_vp_write_irqstatus(dispc, i, clearmask);
894 	}
895 
896 	for (i = 0; i < dispc->feat->num_vids; ++i) {
897 		if (clearmask & DSS_IRQ_PLANE_MASK(i))
898 			dispc_k3_vid_write_irqstatus(dispc, i, clearmask);
899 	}
900 
901 	/* always clear the top level irqstatus */
902 	dispc_write(dispc, DISPC_IRQSTATUS, dispc_read(dispc, DISPC_IRQSTATUS));
903 
904 	/* Flush posted writes */
905 	dispc_read(dispc, DISPC_IRQSTATUS);
906 }
907 
908 static
909 dispc_irq_t dispc_k3_read_and_clear_irqstatus(struct dispc_device *dispc)
910 {
911 	dispc_irq_t status = 0;
912 	unsigned int i;
913 
914 	for (i = 0; i < dispc->feat->num_vps; ++i)
915 		status |= dispc_k3_vp_read_irqstatus(dispc, i);
916 
917 	for (i = 0; i < dispc->feat->num_vids; ++i)
918 		status |= dispc_k3_vid_read_irqstatus(dispc, i);
919 
920 	dispc_k3_clear_irqstatus(dispc, status);
921 
922 	return status;
923 }
924 
925 static dispc_irq_t dispc_k3_read_irqenable(struct dispc_device *dispc)
926 {
927 	dispc_irq_t enable = 0;
928 	unsigned int i;
929 
930 	for (i = 0; i < dispc->feat->num_vps; ++i)
931 		enable |= dispc_k3_vp_read_irqenable(dispc, i);
932 
933 	for (i = 0; i < dispc->feat->num_vids; ++i)
934 		enable |= dispc_k3_vid_read_irqenable(dispc, i);
935 
936 	return enable;
937 }
938 
939 static void dispc_k3_set_irqenable(struct dispc_device *dispc,
940 				   dispc_irq_t mask)
941 {
942 	unsigned int i;
943 	u32 main_enable = 0, main_disable = 0;
944 	dispc_irq_t old_mask;
945 
946 	old_mask = dispc_k3_read_irqenable(dispc);
947 
948 	/* clear the irqstatus for irqs that will be enabled */
949 	dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & mask);
950 
951 	for (i = 0; i < dispc->feat->num_vps; ++i) {
952 		dispc_k3_vp_set_irqenable(dispc, i, mask);
953 		if (mask & DSS_IRQ_VP_MASK(i))
954 			main_enable |= BIT(i);		/* VP IRQ */
955 		else
956 			main_disable |= BIT(i);		/* VP IRQ */
957 	}
958 
959 	for (i = 0; i < dispc->feat->num_vids; ++i) {
960 		u32 hw_id = dispc->feat->vid_info[i].hw_id;
961 
962 		dispc_k3_vid_set_irqenable(dispc, i, mask);
963 
964 		if (mask & DSS_IRQ_PLANE_MASK(i))
965 			main_enable |= BIT(hw_id + 4);	/* VID IRQ */
966 		else
967 			main_disable |= BIT(hw_id + 4);	/* VID IRQ */
968 	}
969 
970 	if (main_enable)
971 		dispc_write(dispc, DISPC_IRQENABLE_SET, main_enable);
972 
973 	if (main_disable)
974 		dispc_write(dispc, DISPC_IRQENABLE_CLR, main_disable);
975 
976 	/* clear the irqstatus for irqs that were disabled */
977 	dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & old_mask);
978 
979 	/* Flush posted writes */
980 	dispc_read(dispc, DISPC_IRQENABLE_SET);
981 }
982 
983 dispc_irq_t dispc_read_and_clear_irqstatus(struct dispc_device *dispc)
984 {
985 	switch (dispc->feat->subrev) {
986 	case DISPC_K2G:
987 		return dispc_k2g_read_and_clear_irqstatus(dispc);
988 	case DISPC_AM625:
989 	case DISPC_AM62A7:
990 	case DISPC_AM62L:
991 	case DISPC_AM65X:
992 	case DISPC_J721E:
993 		return dispc_k3_read_and_clear_irqstatus(dispc);
994 	default:
995 		WARN_ON(1);
996 		return 0;
997 	}
998 }
999 
1000 void dispc_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask)
1001 {
1002 	switch (dispc->feat->subrev) {
1003 	case DISPC_K2G:
1004 		dispc_k2g_set_irqenable(dispc, mask);
1005 		break;
1006 	case DISPC_AM625:
1007 	case DISPC_AM62A7:
1008 	case DISPC_AM62L:
1009 	case DISPC_AM65X:
1010 	case DISPC_J721E:
1011 		dispc_k3_set_irqenable(dispc, mask);
1012 		break;
1013 	default:
1014 		WARN_ON(1);
1015 		break;
1016 	}
1017 }
1018 
1019 enum dispc_oldi_mode_reg_val { SPWG_18 = 0, JEIDA_24 = 1, SPWG_24 = 2 };
1020 
1021 struct dispc_bus_format {
1022 	u32 bus_fmt;
1023 	u32 data_width;
1024 	bool is_oldi_fmt;
1025 	enum dispc_oldi_mode_reg_val oldi_mode_reg_val;
1026 };
1027 
1028 static const struct dispc_bus_format dispc_bus_formats[] = {
1029 	{ MEDIA_BUS_FMT_RGB444_1X12,		12, false, 0 },
1030 	{ MEDIA_BUS_FMT_RGB565_1X16,		16, false, 0 },
1031 	{ MEDIA_BUS_FMT_RGB666_1X18,		18, false, 0 },
1032 	{ MEDIA_BUS_FMT_RGB888_1X24,		24, false, 0 },
1033 	{ MEDIA_BUS_FMT_RGB101010_1X30,		30, false, 0 },
1034 	{ MEDIA_BUS_FMT_RGB121212_1X36,		36, false, 0 },
1035 	{ MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,	18, true, SPWG_18 },
1036 	{ MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,	24, true, SPWG_24 },
1037 	{ MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,	24, true, JEIDA_24 },
1038 };
1039 
1040 static const
1041 struct dispc_bus_format *dispc_vp_find_bus_fmt(struct dispc_device *dispc,
1042 					       u32 hw_videoport,
1043 					       u32 bus_fmt, u32 bus_flags)
1044 {
1045 	unsigned int i;
1046 
1047 	for (i = 0; i < ARRAY_SIZE(dispc_bus_formats); ++i) {
1048 		if (dispc_bus_formats[i].bus_fmt == bus_fmt)
1049 			return &dispc_bus_formats[i];
1050 	}
1051 
1052 	return NULL;
1053 }
1054 
1055 int dispc_vp_bus_check(struct dispc_device *dispc, u32 hw_videoport,
1056 		       const struct drm_crtc_state *state)
1057 {
1058 	const struct tidss_crtc_state *tstate = to_tidss_crtc_state(state);
1059 	const struct dispc_bus_format *fmt;
1060 
1061 	fmt = dispc_vp_find_bus_fmt(dispc, hw_videoport, tstate->bus_format,
1062 				    tstate->bus_flags);
1063 	if (!fmt) {
1064 		dev_dbg(dispc->dev, "%s: Unsupported bus format: %u\n",
1065 			__func__, tstate->bus_format);
1066 		return -EINVAL;
1067 	}
1068 
1069 	if (dispc->feat->vp_bus_type[hw_videoport] != DISPC_VP_OLDI &&
1070 	    fmt->is_oldi_fmt) {
1071 		dev_dbg(dispc->dev, "%s: %s is not OLDI-port\n",
1072 			__func__, dispc->feat->vp_name[hw_videoport]);
1073 		return -EINVAL;
1074 	}
1075 
1076 	return 0;
1077 }
1078 
1079 static void dispc_oldi_tx_power(struct dispc_device *dispc, bool power)
1080 {
1081 	u32 val = power ? 0 : OLDI_PWRDN_TX;
1082 
1083 	if (WARN_ON(!dispc->oldi_io_ctrl))
1084 		return;
1085 
1086 	regmap_update_bits(dispc->oldi_io_ctrl, OLDI_DAT0_IO_CTRL,
1087 			   OLDI_PWRDN_TX, val);
1088 	regmap_update_bits(dispc->oldi_io_ctrl, OLDI_DAT1_IO_CTRL,
1089 			   OLDI_PWRDN_TX, val);
1090 	regmap_update_bits(dispc->oldi_io_ctrl, OLDI_DAT2_IO_CTRL,
1091 			   OLDI_PWRDN_TX, val);
1092 	regmap_update_bits(dispc->oldi_io_ctrl, OLDI_DAT3_IO_CTRL,
1093 			   OLDI_PWRDN_TX, val);
1094 	regmap_update_bits(dispc->oldi_io_ctrl, OLDI_CLK_IO_CTRL,
1095 			   OLDI_PWRDN_TX, val);
1096 }
1097 
1098 static void dispc_set_num_datalines(struct dispc_device *dispc,
1099 				    u32 hw_videoport, int num_lines)
1100 {
1101 	int v;
1102 
1103 	switch (num_lines) {
1104 	case 12:
1105 		v = 0; break;
1106 	case 16:
1107 		v = 1; break;
1108 	case 18:
1109 		v = 2; break;
1110 	case 24:
1111 		v = 3; break;
1112 	case 30:
1113 		v = 4; break;
1114 	case 36:
1115 		v = 5; break;
1116 	default:
1117 		WARN_ON(1);
1118 		v = 3;
1119 	}
1120 
1121 	VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, v, 10, 8);
1122 }
1123 
1124 static void dispc_enable_oldi(struct dispc_device *dispc, u32 hw_videoport,
1125 			      const struct dispc_bus_format *fmt)
1126 {
1127 	u32 oldi_cfg = 0;
1128 	u32 oldi_reset_bit = BIT(5 + hw_videoport);
1129 	int count = 0;
1130 
1131 	/*
1132 	 * For the moment DUALMODESYNC, MASTERSLAVE, MODE, and SRC
1133 	 * bits of DISPC_VP_DSS_OLDI_CFG are set statically to 0.
1134 	 */
1135 
1136 	if (fmt->data_width == 24)
1137 		oldi_cfg |= BIT(8); /* MSB */
1138 	else if (fmt->data_width != 18)
1139 		dev_warn(dispc->dev, "%s: %d port width not supported\n",
1140 			 __func__, fmt->data_width);
1141 
1142 	oldi_cfg |= BIT(7); /* DEPOL */
1143 
1144 	oldi_cfg = FLD_MOD(oldi_cfg, fmt->oldi_mode_reg_val, 3, 1);
1145 
1146 	oldi_cfg |= BIT(12); /* SOFTRST */
1147 
1148 	oldi_cfg |= BIT(0); /* ENABLE */
1149 
1150 	dispc_vp_write(dispc, hw_videoport, DISPC_VP_DSS_OLDI_CFG, oldi_cfg);
1151 
1152 	while (!(oldi_reset_bit & dispc_read(dispc, DSS_SYSSTATUS)) &&
1153 	       count < 10000)
1154 		count++;
1155 
1156 	if (!(oldi_reset_bit & dispc_read(dispc, DSS_SYSSTATUS)))
1157 		dev_warn(dispc->dev, "%s: timeout waiting OLDI reset done\n",
1158 			 __func__);
1159 }
1160 
1161 void dispc_vp_prepare(struct dispc_device *dispc, u32 hw_videoport,
1162 		      const struct drm_crtc_state *state)
1163 {
1164 	const struct tidss_crtc_state *tstate = to_tidss_crtc_state(state);
1165 	const struct dispc_bus_format *fmt;
1166 
1167 	fmt = dispc_vp_find_bus_fmt(dispc, hw_videoport, tstate->bus_format,
1168 				    tstate->bus_flags);
1169 
1170 	if (WARN_ON(!fmt))
1171 		return;
1172 
1173 	if (dispc->feat->vp_bus_type[hw_videoport] == DISPC_VP_OLDI) {
1174 		dispc_oldi_tx_power(dispc, true);
1175 
1176 		dispc_enable_oldi(dispc, hw_videoport, fmt);
1177 	}
1178 }
1179 
1180 void dispc_vp_enable(struct dispc_device *dispc, u32 hw_videoport,
1181 		     const struct drm_crtc_state *state)
1182 {
1183 	const struct drm_display_mode *mode = &state->adjusted_mode;
1184 	const struct tidss_crtc_state *tstate = to_tidss_crtc_state(state);
1185 	bool align, onoff, rf, ieo, ipc, ihs, ivs;
1186 	const struct dispc_bus_format *fmt;
1187 	u32 hsw, hfp, hbp, vsw, vfp, vbp;
1188 
1189 	fmt = dispc_vp_find_bus_fmt(dispc, hw_videoport, tstate->bus_format,
1190 				    tstate->bus_flags);
1191 
1192 	if (WARN_ON(!fmt))
1193 		return;
1194 
1195 	dispc_set_num_datalines(dispc, hw_videoport, fmt->data_width);
1196 
1197 	hfp = mode->hsync_start - mode->hdisplay;
1198 	hsw = mode->hsync_end - mode->hsync_start;
1199 	hbp = mode->htotal - mode->hsync_end;
1200 
1201 	vfp = mode->vsync_start - mode->vdisplay;
1202 	vsw = mode->vsync_end - mode->vsync_start;
1203 	vbp = mode->vtotal - mode->vsync_end;
1204 
1205 	dispc_vp_write(dispc, hw_videoport, DISPC_VP_TIMING_H,
1206 		       FLD_VAL(hsw - 1, 7, 0) |
1207 		       FLD_VAL(hfp - 1, 19, 8) |
1208 		       FLD_VAL(hbp - 1, 31, 20));
1209 
1210 	dispc_vp_write(dispc, hw_videoport, DISPC_VP_TIMING_V,
1211 		       FLD_VAL(vsw - 1, 7, 0) |
1212 		       FLD_VAL(vfp, 19, 8) |
1213 		       FLD_VAL(vbp, 31, 20));
1214 
1215 	ivs = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
1216 
1217 	ihs = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
1218 
1219 	ieo = !!(tstate->bus_flags & DRM_BUS_FLAG_DE_LOW);
1220 
1221 	ipc = !!(tstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE);
1222 
1223 	/* always use the 'rf' setting */
1224 	onoff = true;
1225 
1226 	rf = !!(tstate->bus_flags & DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE);
1227 
1228 	/* always use aligned syncs */
1229 	align = true;
1230 
1231 	/* always use DE_HIGH for OLDI */
1232 	if (dispc->feat->vp_bus_type[hw_videoport] == DISPC_VP_OLDI)
1233 		ieo = false;
1234 
1235 	dispc_vp_write(dispc, hw_videoport, DISPC_VP_POL_FREQ,
1236 		       FLD_VAL(align, 18, 18) |
1237 		       FLD_VAL(onoff, 17, 17) |
1238 		       FLD_VAL(rf, 16, 16) |
1239 		       FLD_VAL(ieo, 15, 15) |
1240 		       FLD_VAL(ipc, 14, 14) |
1241 		       FLD_VAL(ihs, 13, 13) |
1242 		       FLD_VAL(ivs, 12, 12));
1243 
1244 	dispc_vp_write(dispc, hw_videoport, DISPC_VP_SIZE_SCREEN,
1245 		       FLD_VAL(mode->hdisplay - 1, 11, 0) |
1246 		       FLD_VAL(mode->vdisplay - 1, 27, 16));
1247 
1248 	VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 1, 0, 0);
1249 }
1250 
1251 void dispc_vp_disable(struct dispc_device *dispc, u32 hw_videoport)
1252 {
1253 	VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 0, 0, 0);
1254 }
1255 
1256 void dispc_vp_unprepare(struct dispc_device *dispc, u32 hw_videoport)
1257 {
1258 	if (dispc->feat->vp_bus_type[hw_videoport] == DISPC_VP_OLDI) {
1259 		dispc_vp_write(dispc, hw_videoport, DISPC_VP_DSS_OLDI_CFG, 0);
1260 
1261 		dispc_oldi_tx_power(dispc, false);
1262 	}
1263 }
1264 
1265 bool dispc_vp_go_busy(struct dispc_device *dispc, u32 hw_videoport)
1266 {
1267 	return VP_REG_GET(dispc, hw_videoport, DISPC_VP_CONTROL, 5, 5);
1268 }
1269 
1270 void dispc_vp_go(struct dispc_device *dispc, u32 hw_videoport)
1271 {
1272 	WARN_ON(VP_REG_GET(dispc, hw_videoport, DISPC_VP_CONTROL, 5, 5));
1273 	VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 1, 5, 5);
1274 }
1275 
1276 enum c8_to_c12_mode { C8_TO_C12_REPLICATE, C8_TO_C12_MAX, C8_TO_C12_MIN };
1277 
1278 static u16 c8_to_c12(u8 c8, enum c8_to_c12_mode mode)
1279 {
1280 	u16 c12;
1281 
1282 	c12 = c8 << 4;
1283 
1284 	switch (mode) {
1285 	case C8_TO_C12_REPLICATE:
1286 		/* Copy c8 4 MSB to 4 LSB for full scale c12 */
1287 		c12 |= c8 >> 4;
1288 		break;
1289 	case C8_TO_C12_MAX:
1290 		c12 |= 0xF;
1291 		break;
1292 	default:
1293 	case C8_TO_C12_MIN:
1294 		break;
1295 	}
1296 
1297 	return c12;
1298 }
1299 
1300 static u64 argb8888_to_argb12121212(u32 argb8888, enum c8_to_c12_mode m)
1301 {
1302 	u8 a, r, g, b;
1303 	u64 v;
1304 
1305 	a = (argb8888 >> 24) & 0xff;
1306 	r = (argb8888 >> 16) & 0xff;
1307 	g = (argb8888 >> 8) & 0xff;
1308 	b = (argb8888 >> 0) & 0xff;
1309 
1310 	v = ((u64)c8_to_c12(a, m) << 36) | ((u64)c8_to_c12(r, m) << 24) |
1311 		((u64)c8_to_c12(g, m) << 12) | (u64)c8_to_c12(b, m);
1312 
1313 	return v;
1314 }
1315 
1316 static void dispc_vp_set_default_color(struct dispc_device *dispc,
1317 				       u32 hw_videoport, u32 default_color)
1318 {
1319 	u64 v;
1320 
1321 	v = argb8888_to_argb12121212(default_color, C8_TO_C12_REPLICATE);
1322 
1323 	dispc_ovr_write(dispc, hw_videoport,
1324 			DISPC_OVR_DEFAULT_COLOR, v & 0xffffffff);
1325 	dispc_ovr_write(dispc, hw_videoport,
1326 			DISPC_OVR_DEFAULT_COLOR2, (v >> 32) & 0xffff);
1327 }
1328 
1329 enum drm_mode_status dispc_vp_mode_valid(struct dispc_device *dispc,
1330 					 u32 hw_videoport,
1331 					 const struct drm_display_mode *mode)
1332 {
1333 	u32 hsw, hfp, hbp, vsw, vfp, vbp;
1334 	enum dispc_vp_bus_type bus_type;
1335 	int max_pclk;
1336 
1337 	bus_type = dispc->feat->vp_bus_type[hw_videoport];
1338 
1339 	max_pclk = dispc->feat->max_pclk_khz[bus_type];
1340 
1341 	if (WARN_ON(max_pclk == 0))
1342 		return MODE_BAD;
1343 
1344 	if (mode->clock < dispc->feat->min_pclk_khz)
1345 		return MODE_CLOCK_LOW;
1346 
1347 	if (mode->clock > max_pclk)
1348 		return MODE_CLOCK_HIGH;
1349 
1350 	if (mode->hdisplay > 4096)
1351 		return MODE_BAD;
1352 
1353 	if (mode->vdisplay > 4096)
1354 		return MODE_BAD;
1355 
1356 	/* TODO: add interlace support */
1357 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1358 		return MODE_NO_INTERLACE;
1359 
1360 	/*
1361 	 * Enforce the output width is divisible by 2. Actually this
1362 	 * is only needed in following cases:
1363 	 * - YUV output selected (BT656, BT1120)
1364 	 * - Dithering enabled
1365 	 * - TDM with TDMCycleFormat == 3
1366 	 * But for simplicity we enforce that always.
1367 	 */
1368 	if ((mode->hdisplay % 2) != 0)
1369 		return MODE_BAD_HVALUE;
1370 
1371 	hfp = mode->hsync_start - mode->hdisplay;
1372 	hsw = mode->hsync_end - mode->hsync_start;
1373 	hbp = mode->htotal - mode->hsync_end;
1374 
1375 	vfp = mode->vsync_start - mode->vdisplay;
1376 	vsw = mode->vsync_end - mode->vsync_start;
1377 	vbp = mode->vtotal - mode->vsync_end;
1378 
1379 	if (hsw < 1 || hsw > 256 ||
1380 	    hfp < 1 || hfp > 4096 ||
1381 	    hbp < 1 || hbp > 4096)
1382 		return MODE_BAD_HVALUE;
1383 
1384 	if (vsw < 1 || vsw > 256 ||
1385 	    vfp > 4095 || vbp > 4095)
1386 		return MODE_BAD_VVALUE;
1387 
1388 	if (dispc->memory_bandwidth_limit) {
1389 		const unsigned int bpp = 4;
1390 		u64 bandwidth;
1391 
1392 		bandwidth = 1000 * mode->clock;
1393 		bandwidth = bandwidth * mode->hdisplay * mode->vdisplay * bpp;
1394 		bandwidth = div_u64(bandwidth, mode->htotal * mode->vtotal);
1395 
1396 		if (dispc->memory_bandwidth_limit < bandwidth)
1397 			return MODE_BAD;
1398 	}
1399 
1400 	return MODE_OK;
1401 }
1402 
1403 int dispc_vp_enable_clk(struct dispc_device *dispc, u32 hw_videoport)
1404 {
1405 	int ret = clk_prepare_enable(dispc->vp_clk[hw_videoport]);
1406 
1407 	if (ret)
1408 		dev_err(dispc->dev, "%s: enabling clk failed: %d\n", __func__,
1409 			ret);
1410 
1411 	return ret;
1412 }
1413 
1414 void dispc_vp_disable_clk(struct dispc_device *dispc, u32 hw_videoport)
1415 {
1416 	clk_disable_unprepare(dispc->vp_clk[hw_videoport]);
1417 }
1418 
1419 /*
1420  * Calculate the percentage difference between the requested pixel clock rate
1421  * and the effective rate resulting from calculating the clock divider value.
1422  */
1423 static
1424 unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate)
1425 {
1426 	int r = rate / 100, rr = real_rate / 100;
1427 
1428 	return (unsigned int)(abs(((rr - r) * 100) / r));
1429 }
1430 
1431 int dispc_vp_set_clk_rate(struct dispc_device *dispc, u32 hw_videoport,
1432 			  unsigned long rate)
1433 {
1434 	int r;
1435 	unsigned long new_rate;
1436 
1437 	r = clk_set_rate(dispc->vp_clk[hw_videoport], rate);
1438 	if (r) {
1439 		dev_err(dispc->dev, "vp%d: failed to set clk rate to %lu\n",
1440 			hw_videoport, rate);
1441 		return r;
1442 	}
1443 
1444 	new_rate = clk_get_rate(dispc->vp_clk[hw_videoport]);
1445 
1446 	if (dispc_pclk_diff(rate, new_rate) > 5)
1447 		dev_warn(dispc->dev,
1448 			 "vp%d: Clock rate %lu differs over 5%% from requested %lu\n",
1449 			 hw_videoport, new_rate, rate);
1450 
1451 	dev_dbg(dispc->dev, "vp%d: new rate %lu Hz (requested %lu Hz)\n",
1452 		hw_videoport, clk_get_rate(dispc->vp_clk[hw_videoport]), rate);
1453 
1454 	return 0;
1455 }
1456 
1457 /* OVR */
1458 static void dispc_k2g_ovr_set_plane(struct dispc_device *dispc,
1459 				    u32 hw_plane, u32 hw_videoport,
1460 				    u32 x, u32 y, u32 layer)
1461 {
1462 	/* On k2g there is only one plane and no need for ovr */
1463 	dispc_vid_write(dispc, hw_plane, DISPC_VID_K2G_POSITION,
1464 			x | (y << 16));
1465 }
1466 
1467 static void dispc_am65x_ovr_set_plane(struct dispc_device *dispc,
1468 				      u32 hw_plane, u32 hw_videoport,
1469 				      u32 x, u32 y, u32 layer)
1470 {
1471 	u32 hw_id = dispc->feat->vid_info[hw_plane].hw_id;
1472 
1473 	OVR_REG_FLD_MOD(dispc, hw_videoport, DISPC_OVR_ATTRIBUTES(layer),
1474 			hw_id, 4, 1);
1475 	OVR_REG_FLD_MOD(dispc, hw_videoport, DISPC_OVR_ATTRIBUTES(layer),
1476 			x, 17, 6);
1477 	OVR_REG_FLD_MOD(dispc, hw_videoport, DISPC_OVR_ATTRIBUTES(layer),
1478 			y, 30, 19);
1479 }
1480 
1481 static void dispc_j721e_ovr_set_plane(struct dispc_device *dispc,
1482 				      u32 hw_plane, u32 hw_videoport,
1483 				      u32 x, u32 y, u32 layer)
1484 {
1485 	u32 hw_id = dispc->feat->vid_info[hw_plane].hw_id;
1486 
1487 	OVR_REG_FLD_MOD(dispc, hw_videoport, DISPC_OVR_ATTRIBUTES(layer),
1488 			hw_id, 4, 1);
1489 	OVR_REG_FLD_MOD(dispc, hw_videoport, DISPC_OVR_ATTRIBUTES2(layer),
1490 			x, 13, 0);
1491 	OVR_REG_FLD_MOD(dispc, hw_videoport, DISPC_OVR_ATTRIBUTES2(layer),
1492 			y, 29, 16);
1493 }
1494 
1495 void dispc_ovr_set_plane(struct dispc_device *dispc, u32 hw_plane,
1496 			 u32 hw_videoport, u32 x, u32 y, u32 layer)
1497 {
1498 	switch (dispc->feat->subrev) {
1499 	case DISPC_K2G:
1500 		dispc_k2g_ovr_set_plane(dispc, hw_plane, hw_videoport,
1501 					x, y, layer);
1502 		break;
1503 	case DISPC_AM625:
1504 	case DISPC_AM62A7:
1505 	case DISPC_AM62L:
1506 	case DISPC_AM65X:
1507 		dispc_am65x_ovr_set_plane(dispc, hw_plane, hw_videoport,
1508 					  x, y, layer);
1509 		break;
1510 	case DISPC_J721E:
1511 		dispc_j721e_ovr_set_plane(dispc, hw_plane, hw_videoport,
1512 					  x, y, layer);
1513 		break;
1514 	default:
1515 		WARN_ON(1);
1516 		break;
1517 	}
1518 }
1519 
1520 void dispc_ovr_enable_layer(struct dispc_device *dispc,
1521 			    u32 hw_videoport, u32 layer, bool enable)
1522 {
1523 	if (dispc->feat->subrev == DISPC_K2G)
1524 		return;
1525 
1526 	OVR_REG_FLD_MOD(dispc, hw_videoport, DISPC_OVR_ATTRIBUTES(layer),
1527 			!!enable, 0, 0);
1528 }
1529 
1530 /* CSC */
1531 enum csc_ctm {
1532 	CSC_RR, CSC_RG, CSC_RB,
1533 	CSC_GR, CSC_GG, CSC_GB,
1534 	CSC_BR, CSC_BG, CSC_BB,
1535 };
1536 
1537 enum csc_yuv2rgb {
1538 	CSC_RY, CSC_RCB, CSC_RCR,
1539 	CSC_GY, CSC_GCB, CSC_GCR,
1540 	CSC_BY, CSC_BCB, CSC_BCR,
1541 };
1542 
1543 enum csc_rgb2yuv {
1544 	CSC_YR,  CSC_YG,  CSC_YB,
1545 	CSC_CBR, CSC_CBG, CSC_CBB,
1546 	CSC_CRR, CSC_CRG, CSC_CRB,
1547 };
1548 
1549 struct dispc_csc_coef {
1550 	void (*to_regval)(const struct dispc_csc_coef *csc, u32 *regval);
1551 	int m[9];
1552 	int preoffset[3];
1553 	int postoffset[3];
1554 	enum { CLIP_LIMITED_RANGE = 0, CLIP_FULL_RANGE = 1, } cliping;
1555 	const char *name;
1556 };
1557 
1558 #define DISPC_CSC_REGVAL_LEN 8
1559 
1560 static
1561 void dispc_csc_offset_regval(const struct dispc_csc_coef *csc, u32 *regval)
1562 {
1563 #define OVAL(x, y) (FLD_VAL(x, 15, 3) | FLD_VAL(y, 31, 19))
1564 	regval[5] = OVAL(csc->preoffset[0], csc->preoffset[1]);
1565 	regval[6] = OVAL(csc->preoffset[2], csc->postoffset[0]);
1566 	regval[7] = OVAL(csc->postoffset[1], csc->postoffset[2]);
1567 #undef OVAL
1568 }
1569 
1570 #define CVAL(x, y) (FLD_VAL(x, 10, 0) | FLD_VAL(y, 26, 16))
1571 static
1572 void dispc_csc_yuv2rgb_regval(const struct dispc_csc_coef *csc, u32 *regval)
1573 {
1574 	regval[0] = CVAL(csc->m[CSC_RY], csc->m[CSC_RCR]);
1575 	regval[1] = CVAL(csc->m[CSC_RCB], csc->m[CSC_GY]);
1576 	regval[2] = CVAL(csc->m[CSC_GCR], csc->m[CSC_GCB]);
1577 	regval[3] = CVAL(csc->m[CSC_BY], csc->m[CSC_BCR]);
1578 	regval[4] = CVAL(csc->m[CSC_BCB], 0);
1579 
1580 	dispc_csc_offset_regval(csc, regval);
1581 }
1582 
1583 __maybe_unused static
1584 void dispc_csc_rgb2yuv_regval(const struct dispc_csc_coef *csc, u32 *regval)
1585 {
1586 	regval[0] = CVAL(csc->m[CSC_YR], csc->m[CSC_YG]);
1587 	regval[1] = CVAL(csc->m[CSC_YB], csc->m[CSC_CRR]);
1588 	regval[2] = CVAL(csc->m[CSC_CRG], csc->m[CSC_CRB]);
1589 	regval[3] = CVAL(csc->m[CSC_CBR], csc->m[CSC_CBG]);
1590 	regval[4] = CVAL(csc->m[CSC_CBB], 0);
1591 
1592 	dispc_csc_offset_regval(csc, regval);
1593 }
1594 
1595 static void dispc_csc_cpr_regval(const struct dispc_csc_coef *csc,
1596 				 u32 *regval)
1597 {
1598 	regval[0] = CVAL(csc->m[CSC_RR], csc->m[CSC_RG]);
1599 	regval[1] = CVAL(csc->m[CSC_RB], csc->m[CSC_GR]);
1600 	regval[2] = CVAL(csc->m[CSC_GG], csc->m[CSC_GB]);
1601 	regval[3] = CVAL(csc->m[CSC_BR], csc->m[CSC_BG]);
1602 	regval[4] = CVAL(csc->m[CSC_BB], 0);
1603 
1604 	dispc_csc_offset_regval(csc, regval);
1605 }
1606 
1607 #undef CVAL
1608 
1609 static void dispc_k2g_vid_write_csc(struct dispc_device *dispc, u32 hw_plane,
1610 				    const struct dispc_csc_coef *csc)
1611 {
1612 	static const u16 dispc_vid_csc_coef_reg[] = {
1613 		DISPC_VID_CSC_COEF(0), DISPC_VID_CSC_COEF(1),
1614 		DISPC_VID_CSC_COEF(2), DISPC_VID_CSC_COEF(3),
1615 		DISPC_VID_CSC_COEF(4), DISPC_VID_CSC_COEF(5),
1616 		DISPC_VID_CSC_COEF(6), /* K2G has no post offset support */
1617 	};
1618 	u32 regval[DISPC_CSC_REGVAL_LEN];
1619 	unsigned int i;
1620 
1621 	csc->to_regval(csc, regval);
1622 
1623 	if (regval[7] != 0)
1624 		dev_warn(dispc->dev, "%s: No post offset support for %s\n",
1625 			 __func__, csc->name);
1626 
1627 	for (i = 0; i < ARRAY_SIZE(dispc_vid_csc_coef_reg); i++)
1628 		dispc_vid_write(dispc, hw_plane, dispc_vid_csc_coef_reg[i],
1629 				regval[i]);
1630 }
1631 
1632 static void dispc_k3_vid_write_csc(struct dispc_device *dispc, u32 hw_plane,
1633 				   const struct dispc_csc_coef *csc)
1634 {
1635 	static const u16 dispc_vid_csc_coef_reg[DISPC_CSC_REGVAL_LEN] = {
1636 		DISPC_VID_CSC_COEF(0), DISPC_VID_CSC_COEF(1),
1637 		DISPC_VID_CSC_COEF(2), DISPC_VID_CSC_COEF(3),
1638 		DISPC_VID_CSC_COEF(4), DISPC_VID_CSC_COEF(5),
1639 		DISPC_VID_CSC_COEF(6), DISPC_VID_CSC_COEF7,
1640 	};
1641 	u32 regval[DISPC_CSC_REGVAL_LEN];
1642 	unsigned int i;
1643 
1644 	csc->to_regval(csc, regval);
1645 
1646 	for (i = 0; i < ARRAY_SIZE(dispc_vid_csc_coef_reg); i++)
1647 		dispc_vid_write(dispc, hw_plane, dispc_vid_csc_coef_reg[i],
1648 				regval[i]);
1649 }
1650 
1651 /* YUV -> RGB, ITU-R BT.601, full range */
1652 static const struct dispc_csc_coef csc_yuv2rgb_bt601_full = {
1653 	dispc_csc_yuv2rgb_regval,
1654 	{ 256,   0,  358,	/* ry, rcb, rcr |1.000  0.000  1.402|*/
1655 	  256, -88, -182,	/* gy, gcb, gcr |1.000 -0.344 -0.714|*/
1656 	  256, 452,    0, },	/* by, bcb, bcr |1.000  1.772  0.000|*/
1657 	{    0, -2048, -2048, },	/* full range */
1658 	{    0,     0,     0, },
1659 	CLIP_FULL_RANGE,
1660 	"BT.601 Full",
1661 };
1662 
1663 /* YUV -> RGB, ITU-R BT.601, limited range */
1664 static const struct dispc_csc_coef csc_yuv2rgb_bt601_lim = {
1665 	dispc_csc_yuv2rgb_regval,
1666 	{ 298,    0,  409,	/* ry, rcb, rcr |1.164  0.000  1.596|*/
1667 	  298, -100, -208,	/* gy, gcb, gcr |1.164 -0.392 -0.813|*/
1668 	  298,  516,    0, },	/* by, bcb, bcr |1.164  2.017  0.000|*/
1669 	{ -256, -2048, -2048, },	/* limited range */
1670 	{    0,     0,     0, },
1671 	CLIP_FULL_RANGE,
1672 	"BT.601 Limited",
1673 };
1674 
1675 /* YUV -> RGB, ITU-R BT.709, full range */
1676 static const struct dispc_csc_coef csc_yuv2rgb_bt709_full = {
1677 	dispc_csc_yuv2rgb_regval,
1678 	{ 256,	  0,  402,	/* ry, rcb, rcr |1.000	0.000  1.570|*/
1679 	  256,  -48, -120,	/* gy, gcb, gcr |1.000 -0.187 -0.467|*/
1680 	  256,  475,    0, },	/* by, bcb, bcr |1.000	1.856  0.000|*/
1681 	{    0, -2048, -2048, },	/* full range */
1682 	{    0,     0,     0, },
1683 	CLIP_FULL_RANGE,
1684 	"BT.709 Full",
1685 };
1686 
1687 /* YUV -> RGB, ITU-R BT.709, limited range */
1688 static const struct dispc_csc_coef csc_yuv2rgb_bt709_lim = {
1689 	dispc_csc_yuv2rgb_regval,
1690 	{ 298,    0,  459,	/* ry, rcb, rcr |1.164  0.000  1.793|*/
1691 	  298,  -55, -136,	/* gy, gcb, gcr |1.164 -0.213 -0.533|*/
1692 	  298,  541,    0, },	/* by, bcb, bcr |1.164  2.112  0.000|*/
1693 	{ -256, -2048, -2048, },	/* limited range */
1694 	{    0,     0,     0, },
1695 	CLIP_FULL_RANGE,
1696 	"BT.709 Limited",
1697 };
1698 
1699 static const struct {
1700 	enum drm_color_encoding encoding;
1701 	enum drm_color_range range;
1702 	const struct dispc_csc_coef *csc;
1703 } dispc_csc_table[] = {
1704 	{ DRM_COLOR_YCBCR_BT601, DRM_COLOR_YCBCR_FULL_RANGE,
1705 	  &csc_yuv2rgb_bt601_full, },
1706 	{ DRM_COLOR_YCBCR_BT601, DRM_COLOR_YCBCR_LIMITED_RANGE,
1707 	  &csc_yuv2rgb_bt601_lim, },
1708 	{ DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_FULL_RANGE,
1709 	  &csc_yuv2rgb_bt709_full, },
1710 	{ DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE,
1711 	  &csc_yuv2rgb_bt709_lim, },
1712 };
1713 
1714 static const
1715 struct dispc_csc_coef *dispc_find_csc(enum drm_color_encoding encoding,
1716 				      enum drm_color_range range)
1717 {
1718 	unsigned int i;
1719 
1720 	for (i = 0; i < ARRAY_SIZE(dispc_csc_table); i++) {
1721 		if (dispc_csc_table[i].encoding == encoding &&
1722 		    dispc_csc_table[i].range == range) {
1723 			return dispc_csc_table[i].csc;
1724 		}
1725 	}
1726 	return NULL;
1727 }
1728 
1729 static void dispc_vid_csc_setup(struct dispc_device *dispc, u32 hw_plane,
1730 				const struct drm_plane_state *state)
1731 {
1732 	const struct dispc_csc_coef *coef;
1733 
1734 	coef = dispc_find_csc(state->color_encoding, state->color_range);
1735 	if (!coef) {
1736 		dev_err(dispc->dev, "%s: CSC (%u,%u) not found\n",
1737 			__func__, state->color_encoding, state->color_range);
1738 		return;
1739 	}
1740 
1741 	if (dispc->feat->subrev == DISPC_K2G)
1742 		dispc_k2g_vid_write_csc(dispc, hw_plane, coef);
1743 	else
1744 		dispc_k3_vid_write_csc(dispc, hw_plane, coef);
1745 }
1746 
1747 static void dispc_vid_csc_enable(struct dispc_device *dispc, u32 hw_plane,
1748 				 bool enable)
1749 {
1750 	VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES, !!enable, 9, 9);
1751 }
1752 
1753 /* SCALER */
1754 
1755 static u32 dispc_calc_fir_inc(u32 in, u32 out)
1756 {
1757 	return (u32)div_u64(0x200000ull * in, out);
1758 }
1759 
1760 enum dispc_vid_fir_coef_set {
1761 	DISPC_VID_FIR_COEF_HORIZ,
1762 	DISPC_VID_FIR_COEF_HORIZ_UV,
1763 	DISPC_VID_FIR_COEF_VERT,
1764 	DISPC_VID_FIR_COEF_VERT_UV,
1765 };
1766 
1767 static void dispc_vid_write_fir_coefs(struct dispc_device *dispc,
1768 				      u32 hw_plane,
1769 				      enum dispc_vid_fir_coef_set coef_set,
1770 				      const struct tidss_scale_coefs *coefs)
1771 {
1772 	static const u16 c0_regs[] = {
1773 		[DISPC_VID_FIR_COEF_HORIZ] = DISPC_VID_FIR_COEFS_H0,
1774 		[DISPC_VID_FIR_COEF_HORIZ_UV] = DISPC_VID_FIR_COEFS_H0_C,
1775 		[DISPC_VID_FIR_COEF_VERT] = DISPC_VID_FIR_COEFS_V0,
1776 		[DISPC_VID_FIR_COEF_VERT_UV] = DISPC_VID_FIR_COEFS_V0_C,
1777 	};
1778 
1779 	static const u16 c12_regs[] = {
1780 		[DISPC_VID_FIR_COEF_HORIZ] = DISPC_VID_FIR_COEFS_H12,
1781 		[DISPC_VID_FIR_COEF_HORIZ_UV] = DISPC_VID_FIR_COEFS_H12_C,
1782 		[DISPC_VID_FIR_COEF_VERT] = DISPC_VID_FIR_COEFS_V12,
1783 		[DISPC_VID_FIR_COEF_VERT_UV] = DISPC_VID_FIR_COEFS_V12_C,
1784 	};
1785 
1786 	const u16 c0_base = c0_regs[coef_set];
1787 	const u16 c12_base = c12_regs[coef_set];
1788 	int phase;
1789 
1790 	if (!coefs) {
1791 		dev_err(dispc->dev, "%s: No coefficients given.\n", __func__);
1792 		return;
1793 	}
1794 
1795 	for (phase = 0; phase <= 8; ++phase) {
1796 		u16 reg = c0_base + phase * 4;
1797 		u16 c0 = coefs->c0[phase];
1798 
1799 		dispc_vid_write(dispc, hw_plane, reg, c0);
1800 	}
1801 
1802 	for (phase = 0; phase <= 15; ++phase) {
1803 		u16 reg = c12_base + phase * 4;
1804 		s16 c1, c2;
1805 		u32 c12;
1806 
1807 		c1 = coefs->c1[phase];
1808 		c2 = coefs->c2[phase];
1809 		c12 = FLD_VAL(c1, 19, 10) | FLD_VAL(c2, 29, 20);
1810 
1811 		dispc_vid_write(dispc, hw_plane, reg, c12);
1812 	}
1813 }
1814 
1815 static bool dispc_fourcc_is_yuv(u32 fourcc)
1816 {
1817 	switch (fourcc) {
1818 	case DRM_FORMAT_YUYV:
1819 	case DRM_FORMAT_UYVY:
1820 	case DRM_FORMAT_NV12:
1821 		return true;
1822 	default:
1823 		return false;
1824 	}
1825 }
1826 
1827 struct dispc_scaling_params {
1828 	int xinc, yinc;
1829 	u32 in_w, in_h, in_w_uv, in_h_uv;
1830 	u32 fir_xinc, fir_yinc, fir_xinc_uv, fir_yinc_uv;
1831 	bool scale_x, scale_y;
1832 	const struct tidss_scale_coefs *xcoef, *ycoef, *xcoef_uv, *ycoef_uv;
1833 	bool five_taps;
1834 };
1835 
1836 static int dispc_vid_calc_scaling(struct dispc_device *dispc,
1837 				  const struct drm_plane_state *state,
1838 				  struct dispc_scaling_params *sp,
1839 				  bool lite_plane)
1840 {
1841 	const struct dispc_features_scaling *f = &dispc->feat->scaling;
1842 	u32 fourcc = state->fb->format->format;
1843 	u32 in_width_max_5tap = f->in_width_max_5tap_rgb;
1844 	u32 in_width_max_3tap = f->in_width_max_3tap_rgb;
1845 	u32 downscale_limit;
1846 	u32 in_width_max;
1847 
1848 	memset(sp, 0, sizeof(*sp));
1849 	sp->xinc = 1;
1850 	sp->yinc = 1;
1851 	sp->in_w = state->src_w >> 16;
1852 	sp->in_w_uv = sp->in_w;
1853 	sp->in_h = state->src_h >> 16;
1854 	sp->in_h_uv = sp->in_h;
1855 
1856 	sp->scale_x = sp->in_w != state->crtc_w;
1857 	sp->scale_y = sp->in_h != state->crtc_h;
1858 
1859 	if (dispc_fourcc_is_yuv(fourcc)) {
1860 		in_width_max_5tap = f->in_width_max_5tap_yuv;
1861 		in_width_max_3tap = f->in_width_max_3tap_yuv;
1862 
1863 		sp->in_w_uv >>= 1;
1864 		sp->scale_x = true;
1865 
1866 		if (fourcc == DRM_FORMAT_NV12) {
1867 			sp->in_h_uv >>= 1;
1868 			sp->scale_y = true;
1869 		}
1870 	}
1871 
1872 	/* Skip the rest if no scaling is used */
1873 	if ((!sp->scale_x && !sp->scale_y) || lite_plane)
1874 		return 0;
1875 
1876 	if (sp->in_w > in_width_max_5tap) {
1877 		sp->five_taps = false;
1878 		in_width_max = in_width_max_3tap;
1879 		downscale_limit = f->downscale_limit_3tap;
1880 	} else {
1881 		sp->five_taps = true;
1882 		in_width_max = in_width_max_5tap;
1883 		downscale_limit = f->downscale_limit_5tap;
1884 	}
1885 
1886 	if (sp->scale_x) {
1887 		sp->fir_xinc = dispc_calc_fir_inc(sp->in_w, state->crtc_w);
1888 
1889 		if (sp->fir_xinc < dispc_calc_fir_inc(1, f->upscale_limit)) {
1890 			dev_dbg(dispc->dev,
1891 				"%s: X-scaling factor %u/%u > %u\n",
1892 				__func__, state->crtc_w, state->src_w >> 16,
1893 				f->upscale_limit);
1894 			return -EINVAL;
1895 		}
1896 
1897 		if (sp->fir_xinc >= dispc_calc_fir_inc(downscale_limit, 1)) {
1898 			sp->xinc = DIV_ROUND_UP(DIV_ROUND_UP(sp->in_w,
1899 							     state->crtc_w),
1900 						downscale_limit);
1901 
1902 			if (sp->xinc > f->xinc_max) {
1903 				dev_dbg(dispc->dev,
1904 					"%s: X-scaling factor %u/%u < 1/%u\n",
1905 					__func__, state->crtc_w,
1906 					state->src_w >> 16,
1907 					downscale_limit * f->xinc_max);
1908 				return -EINVAL;
1909 			}
1910 
1911 			sp->in_w = (state->src_w >> 16) / sp->xinc;
1912 		}
1913 
1914 		while (sp->in_w > in_width_max) {
1915 			sp->xinc++;
1916 			sp->in_w = (state->src_w >> 16) / sp->xinc;
1917 		}
1918 
1919 		if (sp->xinc > f->xinc_max) {
1920 			dev_dbg(dispc->dev,
1921 				"%s: Too wide input buffer %u > %u\n", __func__,
1922 				state->src_w >> 16, in_width_max * f->xinc_max);
1923 			return -EINVAL;
1924 		}
1925 
1926 		/*
1927 		 * We need even line length for YUV formats. Decimation
1928 		 * can lead to odd length, so we need to make it even
1929 		 * again.
1930 		 */
1931 		if (dispc_fourcc_is_yuv(fourcc))
1932 			sp->in_w &= ~1;
1933 
1934 		sp->fir_xinc = dispc_calc_fir_inc(sp->in_w, state->crtc_w);
1935 	}
1936 
1937 	if (sp->scale_y) {
1938 		sp->fir_yinc = dispc_calc_fir_inc(sp->in_h, state->crtc_h);
1939 
1940 		if (sp->fir_yinc < dispc_calc_fir_inc(1, f->upscale_limit)) {
1941 			dev_dbg(dispc->dev,
1942 				"%s: Y-scaling factor %u/%u > %u\n",
1943 				__func__, state->crtc_h, state->src_h >> 16,
1944 				f->upscale_limit);
1945 			return -EINVAL;
1946 		}
1947 
1948 		if (sp->fir_yinc >= dispc_calc_fir_inc(downscale_limit, 1)) {
1949 			sp->yinc = DIV_ROUND_UP(DIV_ROUND_UP(sp->in_h,
1950 							     state->crtc_h),
1951 						downscale_limit);
1952 
1953 			sp->in_h /= sp->yinc;
1954 			sp->fir_yinc = dispc_calc_fir_inc(sp->in_h,
1955 							  state->crtc_h);
1956 		}
1957 	}
1958 
1959 	dev_dbg(dispc->dev,
1960 		"%s: %ux%u decim %ux%u -> %ux%u firinc %u.%03ux%u.%03u taps %u -> %ux%u\n",
1961 		__func__, state->src_w >> 16, state->src_h >> 16,
1962 		sp->xinc, sp->yinc, sp->in_w, sp->in_h,
1963 		sp->fir_xinc / 0x200000u,
1964 		((sp->fir_xinc & 0x1FFFFFu) * 999u) / 0x1FFFFFu,
1965 		sp->fir_yinc / 0x200000u,
1966 		((sp->fir_yinc & 0x1FFFFFu) * 999u) / 0x1FFFFFu,
1967 		sp->five_taps ? 5 : 3,
1968 		state->crtc_w, state->crtc_h);
1969 
1970 	if (dispc_fourcc_is_yuv(fourcc)) {
1971 		if (sp->scale_x) {
1972 			sp->in_w_uv /= sp->xinc;
1973 			sp->fir_xinc_uv = dispc_calc_fir_inc(sp->in_w_uv,
1974 							     state->crtc_w);
1975 			sp->xcoef_uv = tidss_get_scale_coefs(dispc->dev,
1976 							     sp->fir_xinc_uv,
1977 							     true);
1978 		}
1979 		if (sp->scale_y) {
1980 			sp->in_h_uv /= sp->yinc;
1981 			sp->fir_yinc_uv = dispc_calc_fir_inc(sp->in_h_uv,
1982 							     state->crtc_h);
1983 			sp->ycoef_uv = tidss_get_scale_coefs(dispc->dev,
1984 							     sp->fir_yinc_uv,
1985 							     sp->five_taps);
1986 		}
1987 	}
1988 
1989 	if (sp->scale_x)
1990 		sp->xcoef = tidss_get_scale_coefs(dispc->dev, sp->fir_xinc,
1991 						  true);
1992 
1993 	if (sp->scale_y)
1994 		sp->ycoef = tidss_get_scale_coefs(dispc->dev, sp->fir_yinc,
1995 						  sp->five_taps);
1996 
1997 	return 0;
1998 }
1999 
2000 static void dispc_vid_set_scaling(struct dispc_device *dispc,
2001 				  u32 hw_plane,
2002 				  struct dispc_scaling_params *sp,
2003 				  u32 fourcc)
2004 {
2005 	/* HORIZONTAL RESIZE ENABLE */
2006 	VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES,
2007 			sp->scale_x, 7, 7);
2008 
2009 	/* VERTICAL RESIZE ENABLE */
2010 	VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES,
2011 			sp->scale_y, 8, 8);
2012 
2013 	/* Skip the rest if no scaling is used */
2014 	if (!sp->scale_x && !sp->scale_y)
2015 		return;
2016 
2017 	/* VERTICAL 5-TAPS  */
2018 	VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES,
2019 			sp->five_taps, 21, 21);
2020 
2021 	if (dispc_fourcc_is_yuv(fourcc)) {
2022 		if (sp->scale_x) {
2023 			dispc_vid_write(dispc, hw_plane, DISPC_VID_FIRH2,
2024 					sp->fir_xinc_uv);
2025 			dispc_vid_write_fir_coefs(dispc, hw_plane,
2026 						  DISPC_VID_FIR_COEF_HORIZ_UV,
2027 						  sp->xcoef_uv);
2028 		}
2029 		if (sp->scale_y) {
2030 			dispc_vid_write(dispc, hw_plane, DISPC_VID_FIRV2,
2031 					sp->fir_yinc_uv);
2032 			dispc_vid_write_fir_coefs(dispc, hw_plane,
2033 						  DISPC_VID_FIR_COEF_VERT_UV,
2034 						  sp->ycoef_uv);
2035 		}
2036 	}
2037 
2038 	if (sp->scale_x) {
2039 		dispc_vid_write(dispc, hw_plane, DISPC_VID_FIRH, sp->fir_xinc);
2040 		dispc_vid_write_fir_coefs(dispc, hw_plane,
2041 					  DISPC_VID_FIR_COEF_HORIZ,
2042 					  sp->xcoef);
2043 	}
2044 
2045 	if (sp->scale_y) {
2046 		dispc_vid_write(dispc, hw_plane, DISPC_VID_FIRV, sp->fir_yinc);
2047 		dispc_vid_write_fir_coefs(dispc, hw_plane,
2048 					  DISPC_VID_FIR_COEF_VERT, sp->ycoef);
2049 	}
2050 }
2051 
2052 /* OTHER */
2053 
2054 static const struct {
2055 	u32 fourcc;
2056 	u8 dss_code;
2057 } dispc_color_formats[] = {
2058 	{ DRM_FORMAT_ARGB4444, 0x0, },
2059 	{ DRM_FORMAT_ABGR4444, 0x1, },
2060 	{ DRM_FORMAT_RGBA4444, 0x2, },
2061 
2062 	{ DRM_FORMAT_RGB565, 0x3, },
2063 	{ DRM_FORMAT_BGR565, 0x4, },
2064 
2065 	{ DRM_FORMAT_ARGB1555, 0x5, },
2066 	{ DRM_FORMAT_ABGR1555, 0x6, },
2067 
2068 	{ DRM_FORMAT_ARGB8888, 0x7, },
2069 	{ DRM_FORMAT_ABGR8888, 0x8, },
2070 	{ DRM_FORMAT_RGBA8888, 0x9, },
2071 	{ DRM_FORMAT_BGRA8888, 0xa, },
2072 
2073 	{ DRM_FORMAT_RGB888, 0xb, },
2074 	{ DRM_FORMAT_BGR888, 0xc, },
2075 
2076 	{ DRM_FORMAT_ARGB2101010, 0xe, },
2077 	{ DRM_FORMAT_ABGR2101010, 0xf, },
2078 
2079 	{ DRM_FORMAT_XRGB4444, 0x20, },
2080 	{ DRM_FORMAT_XBGR4444, 0x21, },
2081 	{ DRM_FORMAT_RGBX4444, 0x22, },
2082 
2083 	{ DRM_FORMAT_XRGB1555, 0x25, },
2084 	{ DRM_FORMAT_XBGR1555, 0x26, },
2085 
2086 	{ DRM_FORMAT_XRGB8888, 0x27, },
2087 	{ DRM_FORMAT_XBGR8888, 0x28, },
2088 	{ DRM_FORMAT_RGBX8888, 0x29, },
2089 	{ DRM_FORMAT_BGRX8888, 0x2a, },
2090 
2091 	{ DRM_FORMAT_XRGB2101010, 0x2e, },
2092 	{ DRM_FORMAT_XBGR2101010, 0x2f, },
2093 
2094 	{ DRM_FORMAT_YUYV, 0x3e, },
2095 	{ DRM_FORMAT_UYVY, 0x3f, },
2096 
2097 	{ DRM_FORMAT_NV12, 0x3d, },
2098 };
2099 
2100 static void dispc_plane_set_pixel_format(struct dispc_device *dispc,
2101 					 u32 hw_plane, u32 fourcc)
2102 {
2103 	unsigned int i;
2104 
2105 	for (i = 0; i < ARRAY_SIZE(dispc_color_formats); ++i) {
2106 		if (dispc_color_formats[i].fourcc == fourcc) {
2107 			VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES,
2108 					dispc_color_formats[i].dss_code,
2109 					6, 1);
2110 			return;
2111 		}
2112 	}
2113 
2114 	WARN_ON(1);
2115 }
2116 
2117 const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *len)
2118 {
2119 	WARN_ON(!dispc->fourccs);
2120 
2121 	*len = dispc->num_fourccs;
2122 
2123 	return dispc->fourccs;
2124 }
2125 
2126 static s32 pixinc(int pixels, u8 ps)
2127 {
2128 	if (pixels == 1)
2129 		return 1;
2130 	else if (pixels > 1)
2131 		return 1 + (pixels - 1) * ps;
2132 	else if (pixels < 0)
2133 		return 1 - (-pixels + 1) * ps;
2134 
2135 	WARN_ON(1);
2136 	return 0;
2137 }
2138 
2139 int dispc_plane_check(struct dispc_device *dispc, u32 hw_plane,
2140 		      const struct drm_plane_state *state,
2141 		      u32 hw_videoport)
2142 {
2143 	bool lite = dispc->feat->vid_info[hw_plane].is_lite;
2144 	u32 fourcc = state->fb->format->format;
2145 	bool need_scaling = state->src_w >> 16 != state->crtc_w ||
2146 		state->src_h >> 16 != state->crtc_h;
2147 	struct dispc_scaling_params scaling;
2148 	int ret;
2149 
2150 	if (dispc_fourcc_is_yuv(fourcc)) {
2151 		if (!dispc_find_csc(state->color_encoding,
2152 				    state->color_range)) {
2153 			dev_dbg(dispc->dev,
2154 				"%s: Unsupported CSC (%u,%u) for HW plane %u\n",
2155 				__func__, state->color_encoding,
2156 				state->color_range, hw_plane);
2157 			return -EINVAL;
2158 		}
2159 	}
2160 
2161 	if (need_scaling) {
2162 		if (lite) {
2163 			dev_dbg(dispc->dev,
2164 				"%s: Lite plane %u can't scale %ux%u!=%ux%u\n",
2165 				__func__, hw_plane,
2166 				state->src_w >> 16, state->src_h >> 16,
2167 				state->crtc_w, state->crtc_h);
2168 			return -EINVAL;
2169 		}
2170 		ret = dispc_vid_calc_scaling(dispc, state, &scaling, false);
2171 		if (ret)
2172 			return ret;
2173 	}
2174 
2175 	return 0;
2176 }
2177 
2178 static
2179 dma_addr_t dispc_plane_state_dma_addr(const struct drm_plane_state *state)
2180 {
2181 	struct drm_framebuffer *fb = state->fb;
2182 	struct drm_gem_dma_object *gem;
2183 	u32 x = state->src_x >> 16;
2184 	u32 y = state->src_y >> 16;
2185 
2186 	gem = drm_fb_dma_get_gem_obj(state->fb, 0);
2187 
2188 	return gem->dma_addr + fb->offsets[0] + x * fb->format->cpp[0] +
2189 		y * fb->pitches[0];
2190 }
2191 
2192 static
2193 dma_addr_t dispc_plane_state_p_uv_addr(const struct drm_plane_state *state)
2194 {
2195 	struct drm_framebuffer *fb = state->fb;
2196 	struct drm_gem_dma_object *gem;
2197 	u32 x = state->src_x >> 16;
2198 	u32 y = state->src_y >> 16;
2199 
2200 	if (WARN_ON(state->fb->format->num_planes != 2))
2201 		return 0;
2202 
2203 	gem = drm_fb_dma_get_gem_obj(fb, 1);
2204 
2205 	return gem->dma_addr + fb->offsets[1] +
2206 		(x * fb->format->cpp[1] / fb->format->hsub) +
2207 		(y * fb->pitches[1] / fb->format->vsub);
2208 }
2209 
2210 void dispc_plane_setup(struct dispc_device *dispc, u32 hw_plane,
2211 		       const struct drm_plane_state *state,
2212 		       u32 hw_videoport)
2213 {
2214 	bool lite = dispc->feat->vid_info[hw_plane].is_lite;
2215 	u32 fourcc = state->fb->format->format;
2216 	u16 cpp = state->fb->format->cpp[0];
2217 	u32 fb_width = state->fb->pitches[0] / cpp;
2218 	dma_addr_t dma_addr = dispc_plane_state_dma_addr(state);
2219 	struct dispc_scaling_params scale;
2220 
2221 	dispc_vid_calc_scaling(dispc, state, &scale, lite);
2222 
2223 	dispc_plane_set_pixel_format(dispc, hw_plane, fourcc);
2224 
2225 	dispc_vid_write(dispc, hw_plane, DISPC_VID_BA_0, dma_addr & 0xffffffff);
2226 	dispc_vid_write(dispc, hw_plane, DISPC_VID_BA_EXT_0, (u64)dma_addr >> 32);
2227 	dispc_vid_write(dispc, hw_plane, DISPC_VID_BA_1, dma_addr & 0xffffffff);
2228 	dispc_vid_write(dispc, hw_plane, DISPC_VID_BA_EXT_1, (u64)dma_addr >> 32);
2229 
2230 	dispc_vid_write(dispc, hw_plane, DISPC_VID_PICTURE_SIZE,
2231 			(scale.in_w - 1) | ((scale.in_h - 1) << 16));
2232 
2233 	/* For YUV422 format we use the macropixel size for pixel inc */
2234 	if (fourcc == DRM_FORMAT_YUYV || fourcc == DRM_FORMAT_UYVY)
2235 		dispc_vid_write(dispc, hw_plane, DISPC_VID_PIXEL_INC,
2236 				pixinc(scale.xinc, cpp * 2));
2237 	else
2238 		dispc_vid_write(dispc, hw_plane, DISPC_VID_PIXEL_INC,
2239 				pixinc(scale.xinc, cpp));
2240 
2241 	dispc_vid_write(dispc, hw_plane, DISPC_VID_ROW_INC,
2242 			pixinc(1 + (scale.yinc * fb_width -
2243 				    scale.xinc * scale.in_w),
2244 			       cpp));
2245 
2246 	if (state->fb->format->num_planes == 2) {
2247 		u16 cpp_uv = state->fb->format->cpp[1];
2248 		u32 fb_width_uv = state->fb->pitches[1] / cpp_uv;
2249 		dma_addr_t p_uv_addr = dispc_plane_state_p_uv_addr(state);
2250 
2251 		dispc_vid_write(dispc, hw_plane,
2252 				DISPC_VID_BA_UV_0, p_uv_addr & 0xffffffff);
2253 		dispc_vid_write(dispc, hw_plane,
2254 				DISPC_VID_BA_UV_EXT_0, (u64)p_uv_addr >> 32);
2255 		dispc_vid_write(dispc, hw_plane,
2256 				DISPC_VID_BA_UV_1, p_uv_addr & 0xffffffff);
2257 		dispc_vid_write(dispc, hw_plane,
2258 				DISPC_VID_BA_UV_EXT_1, (u64)p_uv_addr >> 32);
2259 
2260 		dispc_vid_write(dispc, hw_plane, DISPC_VID_ROW_INC_UV,
2261 				pixinc(1 + (scale.yinc * fb_width_uv -
2262 					    scale.xinc * scale.in_w_uv),
2263 				       cpp_uv));
2264 	}
2265 
2266 	if (!lite) {
2267 		dispc_vid_write(dispc, hw_plane, DISPC_VID_SIZE,
2268 				(state->crtc_w - 1) |
2269 				((state->crtc_h - 1) << 16));
2270 
2271 		dispc_vid_set_scaling(dispc, hw_plane, &scale, fourcc);
2272 	}
2273 
2274 	/* enable YUV->RGB color conversion */
2275 	if (dispc_fourcc_is_yuv(fourcc)) {
2276 		dispc_vid_csc_setup(dispc, hw_plane, state);
2277 		dispc_vid_csc_enable(dispc, hw_plane, true);
2278 	} else {
2279 		dispc_vid_csc_enable(dispc, hw_plane, false);
2280 	}
2281 
2282 	dispc_vid_write(dispc, hw_plane, DISPC_VID_GLOBAL_ALPHA,
2283 			0xFF & (state->alpha >> 8));
2284 
2285 	if (state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
2286 		VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES, 1,
2287 				28, 28);
2288 	else
2289 		VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES, 0,
2290 				28, 28);
2291 }
2292 
2293 void dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool enable)
2294 {
2295 	VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES, !!enable, 0, 0);
2296 }
2297 
2298 static u32 dispc_vid_get_fifo_size(struct dispc_device *dispc, u32 hw_plane)
2299 {
2300 	return VID_REG_GET(dispc, hw_plane, DISPC_VID_BUF_SIZE_STATUS, 15, 0);
2301 }
2302 
2303 static void dispc_vid_set_mflag_threshold(struct dispc_device *dispc,
2304 					  u32 hw_plane, u32 low, u32 high)
2305 {
2306 	dispc_vid_write(dispc, hw_plane, DISPC_VID_MFLAG_THRESHOLD,
2307 			FLD_VAL(high, 31, 16) | FLD_VAL(low, 15, 0));
2308 }
2309 
2310 static void dispc_vid_set_buf_threshold(struct dispc_device *dispc,
2311 					u32 hw_plane, u32 low, u32 high)
2312 {
2313 	dispc_vid_write(dispc, hw_plane, DISPC_VID_BUF_THRESHOLD,
2314 			FLD_VAL(high, 31, 16) | FLD_VAL(low, 15, 0));
2315 }
2316 
2317 static void dispc_k2g_plane_init(struct dispc_device *dispc)
2318 {
2319 	unsigned int hw_plane;
2320 
2321 	dev_dbg(dispc->dev, "%s()\n", __func__);
2322 
2323 	/* MFLAG_CTRL = ENABLED */
2324 	REG_FLD_MOD(dispc, DISPC_GLOBAL_MFLAG_ATTRIBUTE, 2, 1, 0);
2325 	/* MFLAG_START = MFLAGNORMALSTARTMODE */
2326 	REG_FLD_MOD(dispc, DISPC_GLOBAL_MFLAG_ATTRIBUTE, 0, 6, 6);
2327 
2328 	for (hw_plane = 0; hw_plane < dispc->feat->num_vids; hw_plane++) {
2329 		u32 size = dispc_vid_get_fifo_size(dispc, hw_plane);
2330 		u32 thr_low, thr_high;
2331 		u32 mflag_low, mflag_high;
2332 		u32 preload;
2333 
2334 		thr_high = size - 1;
2335 		thr_low = size / 2;
2336 
2337 		mflag_high = size * 2 / 3;
2338 		mflag_low = size / 3;
2339 
2340 		preload = thr_low;
2341 
2342 		dev_dbg(dispc->dev,
2343 			"%s: bufsize %u, buf_threshold %u/%u, mflag threshold %u/%u preload %u\n",
2344 			dispc->feat->vid_info[hw_plane].name,
2345 			size,
2346 			thr_high, thr_low,
2347 			mflag_high, mflag_low,
2348 			preload);
2349 
2350 		dispc_vid_set_buf_threshold(dispc, hw_plane,
2351 					    thr_low, thr_high);
2352 		dispc_vid_set_mflag_threshold(dispc, hw_plane,
2353 					      mflag_low, mflag_high);
2354 
2355 		dispc_vid_write(dispc, hw_plane, DISPC_VID_PRELOAD, preload);
2356 
2357 		/*
2358 		 * Prefetch up to fifo high-threshold value to minimize the
2359 		 * possibility of underflows. Note that this means the PRELOAD
2360 		 * register is ignored.
2361 		 */
2362 		VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES, 1,
2363 				19, 19);
2364 	}
2365 }
2366 
2367 static void dispc_k3_plane_init(struct dispc_device *dispc)
2368 {
2369 	unsigned int hw_plane;
2370 	u32 cba_lo_pri = 1;
2371 	u32 cba_hi_pri = 0;
2372 
2373 	dev_dbg(dispc->dev, "%s()\n", __func__);
2374 
2375 	REG_FLD_MOD(dispc, DSS_CBA_CFG, cba_lo_pri, 2, 0);
2376 	REG_FLD_MOD(dispc, DSS_CBA_CFG, cba_hi_pri, 5, 3);
2377 
2378 	/* MFLAG_CTRL = ENABLED */
2379 	REG_FLD_MOD(dispc, DISPC_GLOBAL_MFLAG_ATTRIBUTE, 2, 1, 0);
2380 	/* MFLAG_START = MFLAGNORMALSTARTMODE */
2381 	REG_FLD_MOD(dispc, DISPC_GLOBAL_MFLAG_ATTRIBUTE, 0, 6, 6);
2382 
2383 	for (hw_plane = 0; hw_plane < dispc->feat->num_vids; hw_plane++) {
2384 		u32 size = dispc_vid_get_fifo_size(dispc, hw_plane);
2385 		u32 thr_low, thr_high;
2386 		u32 mflag_low, mflag_high;
2387 		u32 preload;
2388 
2389 		thr_high = size - 1;
2390 		thr_low = size / 2;
2391 
2392 		mflag_high = size * 2 / 3;
2393 		mflag_low = size / 3;
2394 
2395 		preload = thr_low;
2396 
2397 		dev_dbg(dispc->dev,
2398 			"%s: bufsize %u, buf_threshold %u/%u, mflag threshold %u/%u preload %u\n",
2399 			dispc->feat->vid_info[hw_plane].name,
2400 			size,
2401 			thr_high, thr_low,
2402 			mflag_high, mflag_low,
2403 			preload);
2404 
2405 		dispc_vid_set_buf_threshold(dispc, hw_plane,
2406 					    thr_low, thr_high);
2407 		dispc_vid_set_mflag_threshold(dispc, hw_plane,
2408 					      mflag_low, mflag_high);
2409 
2410 		dispc_vid_write(dispc, hw_plane, DISPC_VID_PRELOAD, preload);
2411 
2412 		/* Prefech up to PRELOAD value */
2413 		VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES, 0,
2414 				19, 19);
2415 	}
2416 }
2417 
2418 static void dispc_plane_init(struct dispc_device *dispc)
2419 {
2420 	switch (dispc->feat->subrev) {
2421 	case DISPC_K2G:
2422 		dispc_k2g_plane_init(dispc);
2423 		break;
2424 	case DISPC_AM625:
2425 	case DISPC_AM62A7:
2426 	case DISPC_AM62L:
2427 	case DISPC_AM65X:
2428 	case DISPC_J721E:
2429 		dispc_k3_plane_init(dispc);
2430 		break;
2431 	default:
2432 		WARN_ON(1);
2433 	}
2434 }
2435 
2436 static void dispc_vp_init(struct dispc_device *dispc)
2437 {
2438 	unsigned int i;
2439 
2440 	dev_dbg(dispc->dev, "%s()\n", __func__);
2441 
2442 	/* Enable the gamma Shadow bit-field for all VPs*/
2443 	for (i = 0; i < dispc->feat->num_vps; i++)
2444 		VP_REG_FLD_MOD(dispc, i, DISPC_VP_CONFIG, 1, 2, 2);
2445 }
2446 
2447 static void dispc_initial_config(struct dispc_device *dispc)
2448 {
2449 	dispc_plane_init(dispc);
2450 	dispc_vp_init(dispc);
2451 
2452 	/* Note: Hardcoded DPI routing on J721E for now */
2453 	if (dispc->feat->subrev == DISPC_J721E) {
2454 		dispc_write(dispc, DISPC_CONNECTIONS,
2455 			    FLD_VAL(2, 3, 0) |		/* VP1 to DPI0 */
2456 			    FLD_VAL(8, 7, 4)		/* VP3 to DPI1 */
2457 			);
2458 	}
2459 }
2460 
2461 static void dispc_k2g_vp_write_gamma_table(struct dispc_device *dispc,
2462 					   u32 hw_videoport)
2463 {
2464 	u32 *table = dispc->vp_data[hw_videoport].gamma_table;
2465 	u32 hwlen = dispc->feat->vp_feat.color.gamma_size;
2466 	unsigned int i;
2467 
2468 	dev_dbg(dispc->dev, "%s: hw_videoport %d\n", __func__, hw_videoport);
2469 
2470 	if (WARN_ON(dispc->feat->vp_feat.color.gamma_type != TIDSS_GAMMA_8BIT))
2471 		return;
2472 
2473 	for (i = 0; i < hwlen; ++i) {
2474 		u32 v = table[i];
2475 
2476 		v |= i << 24;
2477 
2478 		dispc_vp_write(dispc, hw_videoport, DISPC_VP_K2G_GAMMA_TABLE,
2479 			       v);
2480 	}
2481 }
2482 
2483 static void dispc_am65x_vp_write_gamma_table(struct dispc_device *dispc,
2484 					     u32 hw_videoport)
2485 {
2486 	u32 *table = dispc->vp_data[hw_videoport].gamma_table;
2487 	u32 hwlen = dispc->feat->vp_feat.color.gamma_size;
2488 	unsigned int i;
2489 
2490 	dev_dbg(dispc->dev, "%s: hw_videoport %d\n", __func__, hw_videoport);
2491 
2492 	if (WARN_ON(dispc->feat->vp_feat.color.gamma_type != TIDSS_GAMMA_8BIT))
2493 		return;
2494 
2495 	for (i = 0; i < hwlen; ++i) {
2496 		u32 v = table[i];
2497 
2498 		v |= i << 24;
2499 
2500 		dispc_vp_write(dispc, hw_videoport, DISPC_VP_GAMMA_TABLE, v);
2501 	}
2502 }
2503 
2504 static void dispc_j721e_vp_write_gamma_table(struct dispc_device *dispc,
2505 					     u32 hw_videoport)
2506 {
2507 	u32 *table = dispc->vp_data[hw_videoport].gamma_table;
2508 	u32 hwlen = dispc->feat->vp_feat.color.gamma_size;
2509 	unsigned int i;
2510 
2511 	dev_dbg(dispc->dev, "%s: hw_videoport %d\n", __func__, hw_videoport);
2512 
2513 	if (WARN_ON(dispc->feat->vp_feat.color.gamma_type != TIDSS_GAMMA_10BIT))
2514 		return;
2515 
2516 	for (i = 0; i < hwlen; ++i) {
2517 		u32 v = table[i];
2518 
2519 		if (i == 0)
2520 			v |= 1 << 31;
2521 
2522 		dispc_vp_write(dispc, hw_videoport, DISPC_VP_GAMMA_TABLE, v);
2523 	}
2524 }
2525 
2526 static void dispc_vp_write_gamma_table(struct dispc_device *dispc,
2527 				       u32 hw_videoport)
2528 {
2529 	switch (dispc->feat->subrev) {
2530 	case DISPC_K2G:
2531 		dispc_k2g_vp_write_gamma_table(dispc, hw_videoport);
2532 		break;
2533 	case DISPC_AM625:
2534 	case DISPC_AM62A7:
2535 	case DISPC_AM62L:
2536 	case DISPC_AM65X:
2537 		dispc_am65x_vp_write_gamma_table(dispc, hw_videoport);
2538 		break;
2539 	case DISPC_J721E:
2540 		dispc_j721e_vp_write_gamma_table(dispc, hw_videoport);
2541 		break;
2542 	default:
2543 		WARN_ON(1);
2544 		break;
2545 	}
2546 }
2547 
2548 static const struct drm_color_lut dispc_vp_gamma_default_lut[] = {
2549 	{ .red = 0, .green = 0, .blue = 0, },
2550 	{ .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, },
2551 };
2552 
2553 static void dispc_vp_set_gamma(struct dispc_device *dispc,
2554 			       u32 hw_videoport,
2555 			       const struct drm_color_lut *lut,
2556 			       unsigned int length)
2557 {
2558 	u32 *table = dispc->vp_data[hw_videoport].gamma_table;
2559 	u32 hwlen = dispc->feat->vp_feat.color.gamma_size;
2560 	u32 hwbits;
2561 	unsigned int i;
2562 
2563 	dev_dbg(dispc->dev, "%s: hw_videoport %d, lut len %u, hw len %u\n",
2564 		__func__, hw_videoport, length, hwlen);
2565 
2566 	if (dispc->feat->vp_feat.color.gamma_type == TIDSS_GAMMA_10BIT)
2567 		hwbits = 10;
2568 	else
2569 		hwbits = 8;
2570 
2571 	if (!lut || length < 2) {
2572 		lut = dispc_vp_gamma_default_lut;
2573 		length = ARRAY_SIZE(dispc_vp_gamma_default_lut);
2574 	}
2575 
2576 	for (i = 0; i < length - 1; ++i) {
2577 		unsigned int first = i * (hwlen - 1) / (length - 1);
2578 		unsigned int last = (i + 1) * (hwlen - 1) / (length - 1);
2579 		unsigned int w = last - first;
2580 		u16 r, g, b;
2581 		unsigned int j;
2582 
2583 		if (w == 0)
2584 			continue;
2585 
2586 		for (j = 0; j <= w; j++) {
2587 			r = (lut[i].red * (w - j) + lut[i + 1].red * j) / w;
2588 			g = (lut[i].green * (w - j) + lut[i + 1].green * j) / w;
2589 			b = (lut[i].blue * (w - j) + lut[i + 1].blue * j) / w;
2590 
2591 			r >>= 16 - hwbits;
2592 			g >>= 16 - hwbits;
2593 			b >>= 16 - hwbits;
2594 
2595 			table[first + j] = (r << (hwbits * 2)) |
2596 				(g << hwbits) | b;
2597 		}
2598 	}
2599 
2600 	dispc_vp_write_gamma_table(dispc, hw_videoport);
2601 }
2602 
2603 static s16 dispc_S31_32_to_s2_8(s64 coef)
2604 {
2605 	u64 sign_bit = 1ULL << 63;
2606 	u64 cbits = (u64)coef;
2607 	s16 ret;
2608 
2609 	if (cbits & sign_bit)
2610 		ret = -clamp_val(((cbits & ~sign_bit) >> 24), 0, 0x200);
2611 	else
2612 		ret = clamp_val(((cbits & ~sign_bit) >> 24), 0, 0x1FF);
2613 
2614 	return ret;
2615 }
2616 
2617 static void dispc_k2g_cpr_from_ctm(const struct drm_color_ctm *ctm,
2618 				   struct dispc_csc_coef *cpr)
2619 {
2620 	memset(cpr, 0, sizeof(*cpr));
2621 
2622 	cpr->to_regval = dispc_csc_cpr_regval;
2623 	cpr->m[CSC_RR] = dispc_S31_32_to_s2_8(ctm->matrix[0]);
2624 	cpr->m[CSC_RG] = dispc_S31_32_to_s2_8(ctm->matrix[1]);
2625 	cpr->m[CSC_RB] = dispc_S31_32_to_s2_8(ctm->matrix[2]);
2626 	cpr->m[CSC_GR] = dispc_S31_32_to_s2_8(ctm->matrix[3]);
2627 	cpr->m[CSC_GG] = dispc_S31_32_to_s2_8(ctm->matrix[4]);
2628 	cpr->m[CSC_GB] = dispc_S31_32_to_s2_8(ctm->matrix[5]);
2629 	cpr->m[CSC_BR] = dispc_S31_32_to_s2_8(ctm->matrix[6]);
2630 	cpr->m[CSC_BG] = dispc_S31_32_to_s2_8(ctm->matrix[7]);
2631 	cpr->m[CSC_BB] = dispc_S31_32_to_s2_8(ctm->matrix[8]);
2632 }
2633 
2634 #define CVAL(xR, xG, xB) (FLD_VAL(xR, 9, 0) | FLD_VAL(xG, 20, 11) |	\
2635 			  FLD_VAL(xB, 31, 22))
2636 
2637 static void dispc_k2g_vp_csc_cpr_regval(const struct dispc_csc_coef *csc,
2638 					u32 *regval)
2639 {
2640 	regval[0] = CVAL(csc->m[CSC_BB], csc->m[CSC_BG], csc->m[CSC_BR]);
2641 	regval[1] = CVAL(csc->m[CSC_GB], csc->m[CSC_GG], csc->m[CSC_GR]);
2642 	regval[2] = CVAL(csc->m[CSC_RB], csc->m[CSC_RG], csc->m[CSC_RR]);
2643 }
2644 
2645 #undef CVAL
2646 
2647 static void dispc_k2g_vp_write_csc(struct dispc_device *dispc, u32 hw_videoport,
2648 				   const struct dispc_csc_coef *csc)
2649 {
2650 	static const u16 dispc_vp_cpr_coef_reg[] = {
2651 		DISPC_VP_CSC_COEF0, DISPC_VP_CSC_COEF1, DISPC_VP_CSC_COEF2,
2652 		/* K2G CPR is packed to three registers. */
2653 	};
2654 	u32 regval[DISPC_CSC_REGVAL_LEN];
2655 	unsigned int i;
2656 
2657 	dispc_k2g_vp_csc_cpr_regval(csc, regval);
2658 
2659 	for (i = 0; i < ARRAY_SIZE(dispc_vp_cpr_coef_reg); i++)
2660 		dispc_vp_write(dispc, hw_videoport, dispc_vp_cpr_coef_reg[i],
2661 			       regval[i]);
2662 }
2663 
2664 static void dispc_k2g_vp_set_ctm(struct dispc_device *dispc, u32 hw_videoport,
2665 				 struct drm_color_ctm *ctm)
2666 {
2667 	u32 cprenable = 0;
2668 
2669 	if (ctm) {
2670 		struct dispc_csc_coef cpr;
2671 
2672 		dispc_k2g_cpr_from_ctm(ctm, &cpr);
2673 		dispc_k2g_vp_write_csc(dispc, hw_videoport, &cpr);
2674 		cprenable = 1;
2675 	}
2676 
2677 	VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONFIG,
2678 		       cprenable, 15, 15);
2679 }
2680 
2681 static s16 dispc_S31_32_to_s3_8(s64 coef)
2682 {
2683 	u64 sign_bit = 1ULL << 63;
2684 	u64 cbits = (u64)coef;
2685 	s16 ret;
2686 
2687 	if (cbits & sign_bit)
2688 		ret = -clamp_val(((cbits & ~sign_bit) >> 24), 0, 0x400);
2689 	else
2690 		ret = clamp_val(((cbits & ~sign_bit) >> 24), 0, 0x3FF);
2691 
2692 	return ret;
2693 }
2694 
2695 static void dispc_csc_from_ctm(const struct drm_color_ctm *ctm,
2696 			       struct dispc_csc_coef *cpr)
2697 {
2698 	memset(cpr, 0, sizeof(*cpr));
2699 
2700 	cpr->to_regval = dispc_csc_cpr_regval;
2701 	cpr->m[CSC_RR] = dispc_S31_32_to_s3_8(ctm->matrix[0]);
2702 	cpr->m[CSC_RG] = dispc_S31_32_to_s3_8(ctm->matrix[1]);
2703 	cpr->m[CSC_RB] = dispc_S31_32_to_s3_8(ctm->matrix[2]);
2704 	cpr->m[CSC_GR] = dispc_S31_32_to_s3_8(ctm->matrix[3]);
2705 	cpr->m[CSC_GG] = dispc_S31_32_to_s3_8(ctm->matrix[4]);
2706 	cpr->m[CSC_GB] = dispc_S31_32_to_s3_8(ctm->matrix[5]);
2707 	cpr->m[CSC_BR] = dispc_S31_32_to_s3_8(ctm->matrix[6]);
2708 	cpr->m[CSC_BG] = dispc_S31_32_to_s3_8(ctm->matrix[7]);
2709 	cpr->m[CSC_BB] = dispc_S31_32_to_s3_8(ctm->matrix[8]);
2710 }
2711 
2712 static void dispc_k3_vp_write_csc(struct dispc_device *dispc, u32 hw_videoport,
2713 				  const struct dispc_csc_coef *csc)
2714 {
2715 	static const u16 dispc_vp_csc_coef_reg[DISPC_CSC_REGVAL_LEN] = {
2716 		DISPC_VP_CSC_COEF0, DISPC_VP_CSC_COEF1, DISPC_VP_CSC_COEF2,
2717 		DISPC_VP_CSC_COEF3, DISPC_VP_CSC_COEF4, DISPC_VP_CSC_COEF5,
2718 		DISPC_VP_CSC_COEF6, DISPC_VP_CSC_COEF7,
2719 	};
2720 	u32 regval[DISPC_CSC_REGVAL_LEN];
2721 	unsigned int i;
2722 
2723 	csc->to_regval(csc, regval);
2724 
2725 	for (i = 0; i < ARRAY_SIZE(regval); i++)
2726 		dispc_vp_write(dispc, hw_videoport, dispc_vp_csc_coef_reg[i],
2727 			       regval[i]);
2728 }
2729 
2730 static void dispc_k3_vp_set_ctm(struct dispc_device *dispc, u32 hw_videoport,
2731 				struct drm_color_ctm *ctm)
2732 {
2733 	u32 colorconvenable = 0;
2734 
2735 	if (ctm) {
2736 		struct dispc_csc_coef csc;
2737 
2738 		dispc_csc_from_ctm(ctm, &csc);
2739 		dispc_k3_vp_write_csc(dispc, hw_videoport, &csc);
2740 		colorconvenable = 1;
2741 	}
2742 
2743 	VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONFIG,
2744 		       colorconvenable, 24, 24);
2745 }
2746 
2747 static void dispc_vp_set_color_mgmt(struct dispc_device *dispc,
2748 				    u32 hw_videoport,
2749 				    const struct drm_crtc_state *state,
2750 				    bool newmodeset)
2751 {
2752 	struct drm_color_lut *lut = NULL;
2753 	struct drm_color_ctm *ctm = NULL;
2754 	unsigned int length = 0;
2755 
2756 	if (!(state->color_mgmt_changed || newmodeset))
2757 		return;
2758 
2759 	if (state->gamma_lut) {
2760 		lut = (struct drm_color_lut *)state->gamma_lut->data;
2761 		length = state->gamma_lut->length / sizeof(*lut);
2762 	}
2763 
2764 	dispc_vp_set_gamma(dispc, hw_videoport, lut, length);
2765 
2766 	if (state->ctm)
2767 		ctm = (struct drm_color_ctm *)state->ctm->data;
2768 
2769 	if (dispc->feat->subrev == DISPC_K2G)
2770 		dispc_k2g_vp_set_ctm(dispc, hw_videoport, ctm);
2771 	else
2772 		dispc_k3_vp_set_ctm(dispc, hw_videoport, ctm);
2773 }
2774 
2775 void dispc_vp_setup(struct dispc_device *dispc, u32 hw_videoport,
2776 		    const struct drm_crtc_state *state, bool newmodeset)
2777 {
2778 	dispc_vp_set_default_color(dispc, hw_videoport, 0);
2779 	dispc_vp_set_color_mgmt(dispc, hw_videoport, state, newmodeset);
2780 }
2781 
2782 int dispc_runtime_suspend(struct dispc_device *dispc)
2783 {
2784 	dev_dbg(dispc->dev, "suspend\n");
2785 
2786 	dispc->is_enabled = false;
2787 
2788 	clk_disable_unprepare(dispc->fclk);
2789 
2790 	return 0;
2791 }
2792 
2793 int dispc_runtime_resume(struct dispc_device *dispc)
2794 {
2795 	dev_dbg(dispc->dev, "resume\n");
2796 
2797 	clk_prepare_enable(dispc->fclk);
2798 
2799 	if (REG_GET(dispc, DSS_SYSSTATUS, 0, 0) == 0)
2800 		dev_warn(dispc->dev, "DSS FUNC RESET not done!\n");
2801 
2802 	dev_dbg(dispc->dev, "OMAP DSS7 rev 0x%x\n",
2803 		dispc_read(dispc, DSS_REVISION));
2804 
2805 	dev_dbg(dispc->dev, "VP RESETDONE %d,%d,%d\n",
2806 		REG_GET(dispc, DSS_SYSSTATUS, 1, 1),
2807 		REG_GET(dispc, DSS_SYSSTATUS, 2, 2),
2808 		REG_GET(dispc, DSS_SYSSTATUS, 3, 3));
2809 
2810 	if (dispc->feat->subrev == DISPC_AM625 ||
2811 	    dispc->feat->subrev == DISPC_AM65X)
2812 		dev_dbg(dispc->dev, "OLDI RESETDONE %d,%d,%d\n",
2813 			REG_GET(dispc, DSS_SYSSTATUS, 5, 5),
2814 			REG_GET(dispc, DSS_SYSSTATUS, 6, 6),
2815 			REG_GET(dispc, DSS_SYSSTATUS, 7, 7));
2816 
2817 	dev_dbg(dispc->dev, "DISPC IDLE %d\n",
2818 		REG_GET(dispc, DSS_SYSSTATUS, 9, 9));
2819 
2820 	dispc_initial_config(dispc);
2821 
2822 	dispc->is_enabled = true;
2823 
2824 	tidss_irq_resume(dispc->tidss);
2825 
2826 	return 0;
2827 }
2828 
2829 void dispc_remove(struct tidss_device *tidss)
2830 {
2831 	dev_dbg(tidss->dev, "%s\n", __func__);
2832 
2833 	tidss->dispc = NULL;
2834 }
2835 
2836 static int dispc_iomap_resource(struct platform_device *pdev, const char *name,
2837 				void __iomem **base)
2838 {
2839 	void __iomem *b;
2840 
2841 	b = devm_platform_ioremap_resource_byname(pdev, name);
2842 	if (IS_ERR(b)) {
2843 		dev_err(&pdev->dev, "cannot ioremap resource '%s'\n", name);
2844 		return PTR_ERR(b);
2845 	}
2846 
2847 	*base = b;
2848 
2849 	return 0;
2850 }
2851 
2852 static int dispc_init_am65x_oldi_io_ctrl(struct device *dev,
2853 					 struct dispc_device *dispc)
2854 {
2855 	dispc->oldi_io_ctrl =
2856 		syscon_regmap_lookup_by_phandle(dev->of_node,
2857 						"ti,am65x-oldi-io-ctrl");
2858 	if (PTR_ERR(dispc->oldi_io_ctrl) == -ENODEV) {
2859 		dispc->oldi_io_ctrl = NULL;
2860 	} else if (IS_ERR(dispc->oldi_io_ctrl)) {
2861 		dev_err(dev, "%s: syscon_regmap_lookup_by_phandle failed %ld\n",
2862 			__func__, PTR_ERR(dispc->oldi_io_ctrl));
2863 		return PTR_ERR(dispc->oldi_io_ctrl);
2864 	}
2865 	return 0;
2866 }
2867 
2868 static void dispc_init_errata(struct dispc_device *dispc)
2869 {
2870 	static const struct soc_device_attribute am65x_sr10_soc_devices[] = {
2871 		{ .family = "AM65X", .revision = "SR1.0" },
2872 		{ /* sentinel */ }
2873 	};
2874 
2875 	if (soc_device_match(am65x_sr10_soc_devices)) {
2876 		dispc->errata.i2000 = true;
2877 		dev_info(dispc->dev, "WA for erratum i2000: YUV formats disabled\n");
2878 	}
2879 }
2880 
2881 /*
2882  * K2G display controller does not support soft reset, so we do a basic manual
2883  * reset here: make sure the IRQs are masked and VPs are disabled.
2884  */
2885 static void dispc_softreset_k2g(struct dispc_device *dispc)
2886 {
2887 	unsigned long flags;
2888 
2889 	spin_lock_irqsave(&dispc->tidss->irq_lock, flags);
2890 	dispc_set_irqenable(dispc, 0);
2891 	dispc_read_and_clear_irqstatus(dispc);
2892 	spin_unlock_irqrestore(&dispc->tidss->irq_lock, flags);
2893 
2894 	for (unsigned int vp_idx = 0; vp_idx < dispc->feat->num_vps; ++vp_idx)
2895 		VP_REG_FLD_MOD(dispc, vp_idx, DISPC_VP_CONTROL, 0, 0, 0);
2896 }
2897 
2898 static int dispc_softreset(struct dispc_device *dispc)
2899 {
2900 	u32 val;
2901 	int ret;
2902 
2903 	if (dispc->feat->subrev == DISPC_K2G) {
2904 		dispc_softreset_k2g(dispc);
2905 		return 0;
2906 	}
2907 
2908 	/* Soft reset */
2909 	REG_FLD_MOD(dispc, DSS_SYSCONFIG, 1, 1, 1);
2910 	/* Wait for reset to complete */
2911 	ret = readl_poll_timeout(dispc->base_common + DSS_SYSSTATUS,
2912 				 val, val & 1, 100, 5000);
2913 	if (ret) {
2914 		dev_err(dispc->dev, "failed to reset dispc\n");
2915 		return ret;
2916 	}
2917 
2918 	return 0;
2919 }
2920 
2921 static int dispc_init_hw(struct dispc_device *dispc)
2922 {
2923 	struct device *dev = dispc->dev;
2924 	int ret;
2925 
2926 	ret = pm_runtime_set_active(dev);
2927 	if (ret) {
2928 		dev_err(dev, "Failed to set DSS PM to active\n");
2929 		return ret;
2930 	}
2931 
2932 	ret = clk_prepare_enable(dispc->fclk);
2933 	if (ret) {
2934 		dev_err(dev, "Failed to enable DSS fclk\n");
2935 		goto err_runtime_suspend;
2936 	}
2937 
2938 	ret = dispc_softreset(dispc);
2939 	if (ret)
2940 		goto err_clk_disable;
2941 
2942 	clk_disable_unprepare(dispc->fclk);
2943 	ret = pm_runtime_set_suspended(dev);
2944 	if (ret) {
2945 		dev_err(dev, "Failed to set DSS PM to suspended\n");
2946 		return ret;
2947 	}
2948 
2949 	return 0;
2950 
2951 err_clk_disable:
2952 	clk_disable_unprepare(dispc->fclk);
2953 
2954 err_runtime_suspend:
2955 	ret = pm_runtime_set_suspended(dev);
2956 	if (ret) {
2957 		dev_err(dev, "Failed to set DSS PM to suspended\n");
2958 		return ret;
2959 	}
2960 
2961 	return ret;
2962 }
2963 
2964 int dispc_init(struct tidss_device *tidss)
2965 {
2966 	struct device *dev = tidss->dev;
2967 	struct platform_device *pdev = to_platform_device(dev);
2968 	struct dispc_device *dispc;
2969 	const struct dispc_features *feat;
2970 	unsigned int i, num_fourccs;
2971 	int r = 0;
2972 
2973 	dev_dbg(dev, "%s\n", __func__);
2974 
2975 	feat = tidss->feat;
2976 
2977 	if (feat->subrev != DISPC_K2G) {
2978 		r = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
2979 		if (r)
2980 			dev_warn(dev, "cannot set DMA masks to 48-bit\n");
2981 	}
2982 
2983 	dma_set_max_seg_size(dev, UINT_MAX);
2984 
2985 	dispc = devm_kzalloc(dev, sizeof(*dispc), GFP_KERNEL);
2986 	if (!dispc)
2987 		return -ENOMEM;
2988 
2989 	dispc->tidss = tidss;
2990 	dispc->dev = dev;
2991 	dispc->feat = feat;
2992 
2993 	dispc_init_errata(dispc);
2994 
2995 	dispc->fourccs = devm_kcalloc(dev, ARRAY_SIZE(dispc_color_formats),
2996 				      sizeof(*dispc->fourccs), GFP_KERNEL);
2997 	if (!dispc->fourccs)
2998 		return -ENOMEM;
2999 
3000 	num_fourccs = 0;
3001 	for (i = 0; i < ARRAY_SIZE(dispc_color_formats); ++i) {
3002 		if (dispc->errata.i2000 &&
3003 		    dispc_fourcc_is_yuv(dispc_color_formats[i].fourcc)) {
3004 			continue;
3005 		}
3006 		dispc->fourccs[num_fourccs++] = dispc_color_formats[i].fourcc;
3007 	}
3008 
3009 	dispc->num_fourccs = num_fourccs;
3010 
3011 	dispc_common_regmap = dispc->feat->common_regs;
3012 
3013 	r = dispc_iomap_resource(pdev, dispc->feat->common,
3014 				 &dispc->base_common);
3015 	if (r)
3016 		return r;
3017 
3018 	for (i = 0; i < dispc->feat->num_vids; i++) {
3019 		r = dispc_iomap_resource(pdev, dispc->feat->vid_info[i].name,
3020 					 &dispc->base_vid[i]);
3021 		if (r)
3022 			return r;
3023 	}
3024 
3025 	for (i = 0; i < dispc->feat->num_vps; i++) {
3026 		u32 gamma_size = dispc->feat->vp_feat.color.gamma_size;
3027 		u32 *gamma_table;
3028 		struct clk *clk;
3029 
3030 		r = dispc_iomap_resource(pdev, dispc->feat->ovr_name[i],
3031 					 &dispc->base_ovr[i]);
3032 		if (r)
3033 			return r;
3034 
3035 		r = dispc_iomap_resource(pdev, dispc->feat->vp_name[i],
3036 					 &dispc->base_vp[i]);
3037 		if (r)
3038 			return r;
3039 
3040 		clk = devm_clk_get(dev, dispc->feat->vpclk_name[i]);
3041 		if (IS_ERR(clk)) {
3042 			dev_err(dev, "%s: Failed to get clk %s:%ld\n", __func__,
3043 				dispc->feat->vpclk_name[i], PTR_ERR(clk));
3044 			return PTR_ERR(clk);
3045 		}
3046 		dispc->vp_clk[i] = clk;
3047 
3048 		gamma_table = devm_kmalloc_array(dev, gamma_size,
3049 						 sizeof(*gamma_table),
3050 						 GFP_KERNEL);
3051 		if (!gamma_table)
3052 			return -ENOMEM;
3053 		dispc->vp_data[i].gamma_table = gamma_table;
3054 	}
3055 
3056 	if (feat->subrev == DISPC_AM65X) {
3057 		r = dispc_init_am65x_oldi_io_ctrl(dev, dispc);
3058 		if (r)
3059 			return r;
3060 	}
3061 
3062 	dispc->fclk = devm_clk_get(dev, "fck");
3063 	if (IS_ERR(dispc->fclk)) {
3064 		dev_err(dev, "%s: Failed to get fclk: %ld\n",
3065 			__func__, PTR_ERR(dispc->fclk));
3066 		return PTR_ERR(dispc->fclk);
3067 	}
3068 	dev_dbg(dev, "DSS fclk %lu Hz\n", clk_get_rate(dispc->fclk));
3069 
3070 	of_property_read_u32(dispc->dev->of_node, "max-memory-bandwidth",
3071 			     &dispc->memory_bandwidth_limit);
3072 
3073 	r = dispc_init_hw(dispc);
3074 	if (r)
3075 		return r;
3076 
3077 	tidss->dispc = dispc;
3078 
3079 	return 0;
3080 }
3081