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