Linux Audio

Check our new training course

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