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