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