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