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