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