mcde_display.c (41166B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2018 Linus Walleij <linus.walleij@linaro.org> 4 * Parts of this file were based on the MCDE driver by Marcus Lorentzon 5 * (C) ST-Ericsson SA 2013 6 */ 7#include <linux/clk.h> 8#include <linux/delay.h> 9#include <linux/dma-buf.h> 10#include <linux/regulator/consumer.h> 11#include <linux/media-bus-format.h> 12 13#include <drm/drm_device.h> 14#include <drm/drm_fb_cma_helper.h> 15#include <drm/drm_fourcc.h> 16#include <drm/drm_gem_atomic_helper.h> 17#include <drm/drm_gem_cma_helper.h> 18#include <drm/drm_mipi_dsi.h> 19#include <drm/drm_simple_kms_helper.h> 20#include <drm/drm_bridge.h> 21#include <drm/drm_vblank.h> 22#include <video/mipi_display.h> 23 24#include "mcde_drm.h" 25#include "mcde_display_regs.h" 26 27enum mcde_fifo { 28 MCDE_FIFO_A, 29 MCDE_FIFO_B, 30 /* TODO: implement FIFO C0 and FIFO C1 */ 31}; 32 33enum mcde_channel { 34 MCDE_CHANNEL_0 = 0, 35 MCDE_CHANNEL_1, 36 MCDE_CHANNEL_2, 37 MCDE_CHANNEL_3, 38}; 39 40enum mcde_extsrc { 41 MCDE_EXTSRC_0 = 0, 42 MCDE_EXTSRC_1, 43 MCDE_EXTSRC_2, 44 MCDE_EXTSRC_3, 45 MCDE_EXTSRC_4, 46 MCDE_EXTSRC_5, 47 MCDE_EXTSRC_6, 48 MCDE_EXTSRC_7, 49 MCDE_EXTSRC_8, 50 MCDE_EXTSRC_9, 51}; 52 53enum mcde_overlay { 54 MCDE_OVERLAY_0 = 0, 55 MCDE_OVERLAY_1, 56 MCDE_OVERLAY_2, 57 MCDE_OVERLAY_3, 58 MCDE_OVERLAY_4, 59 MCDE_OVERLAY_5, 60}; 61 62enum mcde_formatter { 63 MCDE_DSI_FORMATTER_0 = 0, 64 MCDE_DSI_FORMATTER_1, 65 MCDE_DSI_FORMATTER_2, 66 MCDE_DSI_FORMATTER_3, 67 MCDE_DSI_FORMATTER_4, 68 MCDE_DSI_FORMATTER_5, 69 MCDE_DPI_FORMATTER_0, 70 MCDE_DPI_FORMATTER_1, 71}; 72 73void mcde_display_irq(struct mcde *mcde) 74{ 75 u32 mispp, misovl, mischnl; 76 bool vblank = false; 77 78 /* Handle display IRQs */ 79 mispp = readl(mcde->regs + MCDE_MISPP); 80 misovl = readl(mcde->regs + MCDE_MISOVL); 81 mischnl = readl(mcde->regs + MCDE_MISCHNL); 82 83 /* 84 * Handle IRQs from the DSI link. All IRQs from the DSI links 85 * are just latched onto the MCDE IRQ line, so we need to traverse 86 * any active DSI masters and check if an IRQ is originating from 87 * them. 88 * 89 * TODO: Currently only one DSI link is supported. 90 */ 91 if (!mcde->dpi_output && mcde_dsi_irq(mcde->mdsi)) { 92 u32 val; 93 94 /* 95 * In oneshot mode we do not send continuous updates 96 * to the display, instead we only push out updates when 97 * the update function is called, then we disable the 98 * flow on the channel once we get the TE IRQ. 99 */ 100 if (mcde->flow_mode == MCDE_COMMAND_ONESHOT_FLOW) { 101 spin_lock(&mcde->flow_lock); 102 if (--mcde->flow_active == 0) { 103 dev_dbg(mcde->dev, "TE0 IRQ\n"); 104 /* Disable FIFO A flow */ 105 val = readl(mcde->regs + MCDE_CRA0); 106 val &= ~MCDE_CRX0_FLOEN; 107 writel(val, mcde->regs + MCDE_CRA0); 108 } 109 spin_unlock(&mcde->flow_lock); 110 } 111 } 112 113 /* Vblank from one of the channels */ 114 if (mispp & MCDE_PP_VCMPA) { 115 dev_dbg(mcde->dev, "chnl A vblank IRQ\n"); 116 vblank = true; 117 } 118 if (mispp & MCDE_PP_VCMPB) { 119 dev_dbg(mcde->dev, "chnl B vblank IRQ\n"); 120 vblank = true; 121 } 122 if (mispp & MCDE_PP_VCMPC0) 123 dev_dbg(mcde->dev, "chnl C0 vblank IRQ\n"); 124 if (mispp & MCDE_PP_VCMPC1) 125 dev_dbg(mcde->dev, "chnl C1 vblank IRQ\n"); 126 if (mispp & MCDE_PP_VSCC0) 127 dev_dbg(mcde->dev, "chnl C0 TE IRQ\n"); 128 if (mispp & MCDE_PP_VSCC1) 129 dev_dbg(mcde->dev, "chnl C1 TE IRQ\n"); 130 writel(mispp, mcde->regs + MCDE_RISPP); 131 132 if (vblank) 133 drm_crtc_handle_vblank(&mcde->pipe.crtc); 134 135 if (misovl) 136 dev_info(mcde->dev, "some stray overlay IRQ %08x\n", misovl); 137 writel(misovl, mcde->regs + MCDE_RISOVL); 138 139 if (mischnl) 140 dev_info(mcde->dev, "some stray channel error IRQ %08x\n", 141 mischnl); 142 writel(mischnl, mcde->regs + MCDE_RISCHNL); 143} 144 145void mcde_display_disable_irqs(struct mcde *mcde) 146{ 147 /* Disable all IRQs */ 148 writel(0, mcde->regs + MCDE_IMSCPP); 149 writel(0, mcde->regs + MCDE_IMSCOVL); 150 writel(0, mcde->regs + MCDE_IMSCCHNL); 151 152 /* Clear any pending IRQs */ 153 writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP); 154 writel(0xFFFFFFFF, mcde->regs + MCDE_RISOVL); 155 writel(0xFFFFFFFF, mcde->regs + MCDE_RISCHNL); 156} 157 158static int mcde_display_check(struct drm_simple_display_pipe *pipe, 159 struct drm_plane_state *pstate, 160 struct drm_crtc_state *cstate) 161{ 162 const struct drm_display_mode *mode = &cstate->mode; 163 struct drm_framebuffer *old_fb = pipe->plane.state->fb; 164 struct drm_framebuffer *fb = pstate->fb; 165 166 if (fb) { 167 u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0); 168 169 /* FB base address must be dword aligned. */ 170 if (offset & 3) { 171 DRM_DEBUG_KMS("FB not 32-bit aligned\n"); 172 return -EINVAL; 173 } 174 175 /* 176 * There's no pitch register, the mode's hdisplay 177 * controls this. 178 */ 179 if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) { 180 DRM_DEBUG_KMS("can't handle pitches\n"); 181 return -EINVAL; 182 } 183 184 /* 185 * We can't change the FB format in a flicker-free 186 * manner (and only update it during CRTC enable). 187 */ 188 if (old_fb && old_fb->format != fb->format) 189 cstate->mode_changed = true; 190 } 191 192 return 0; 193} 194 195static int mcde_configure_extsrc(struct mcde *mcde, enum mcde_extsrc src, 196 u32 format) 197{ 198 u32 val; 199 u32 conf; 200 u32 cr; 201 202 switch (src) { 203 case MCDE_EXTSRC_0: 204 conf = MCDE_EXTSRC0CONF; 205 cr = MCDE_EXTSRC0CR; 206 break; 207 case MCDE_EXTSRC_1: 208 conf = MCDE_EXTSRC1CONF; 209 cr = MCDE_EXTSRC1CR; 210 break; 211 case MCDE_EXTSRC_2: 212 conf = MCDE_EXTSRC2CONF; 213 cr = MCDE_EXTSRC2CR; 214 break; 215 case MCDE_EXTSRC_3: 216 conf = MCDE_EXTSRC3CONF; 217 cr = MCDE_EXTSRC3CR; 218 break; 219 case MCDE_EXTSRC_4: 220 conf = MCDE_EXTSRC4CONF; 221 cr = MCDE_EXTSRC4CR; 222 break; 223 case MCDE_EXTSRC_5: 224 conf = MCDE_EXTSRC5CONF; 225 cr = MCDE_EXTSRC5CR; 226 break; 227 case MCDE_EXTSRC_6: 228 conf = MCDE_EXTSRC6CONF; 229 cr = MCDE_EXTSRC6CR; 230 break; 231 case MCDE_EXTSRC_7: 232 conf = MCDE_EXTSRC7CONF; 233 cr = MCDE_EXTSRC7CR; 234 break; 235 case MCDE_EXTSRC_8: 236 conf = MCDE_EXTSRC8CONF; 237 cr = MCDE_EXTSRC8CR; 238 break; 239 case MCDE_EXTSRC_9: 240 conf = MCDE_EXTSRC9CONF; 241 cr = MCDE_EXTSRC9CR; 242 break; 243 } 244 245 /* 246 * Configure external source 0 one buffer (buffer 0) 247 * primary overlay ID 0. 248 * From mcde_hw.c ovly_update_registers() in the vendor tree 249 */ 250 val = 0 << MCDE_EXTSRCXCONF_BUF_ID_SHIFT; 251 val |= 1 << MCDE_EXTSRCXCONF_BUF_NB_SHIFT; 252 val |= 0 << MCDE_EXTSRCXCONF_PRI_OVLID_SHIFT; 253 254 switch (format) { 255 case DRM_FORMAT_ARGB8888: 256 val |= MCDE_EXTSRCXCONF_BPP_ARGB8888 << 257 MCDE_EXTSRCXCONF_BPP_SHIFT; 258 break; 259 case DRM_FORMAT_ABGR8888: 260 val |= MCDE_EXTSRCXCONF_BPP_ARGB8888 << 261 MCDE_EXTSRCXCONF_BPP_SHIFT; 262 val |= MCDE_EXTSRCXCONF_BGR; 263 break; 264 case DRM_FORMAT_XRGB8888: 265 val |= MCDE_EXTSRCXCONF_BPP_XRGB8888 << 266 MCDE_EXTSRCXCONF_BPP_SHIFT; 267 break; 268 case DRM_FORMAT_XBGR8888: 269 val |= MCDE_EXTSRCXCONF_BPP_XRGB8888 << 270 MCDE_EXTSRCXCONF_BPP_SHIFT; 271 val |= MCDE_EXTSRCXCONF_BGR; 272 break; 273 case DRM_FORMAT_RGB888: 274 val |= MCDE_EXTSRCXCONF_BPP_RGB888 << 275 MCDE_EXTSRCXCONF_BPP_SHIFT; 276 break; 277 case DRM_FORMAT_BGR888: 278 val |= MCDE_EXTSRCXCONF_BPP_RGB888 << 279 MCDE_EXTSRCXCONF_BPP_SHIFT; 280 val |= MCDE_EXTSRCXCONF_BGR; 281 break; 282 case DRM_FORMAT_ARGB4444: 283 val |= MCDE_EXTSRCXCONF_BPP_ARGB4444 << 284 MCDE_EXTSRCXCONF_BPP_SHIFT; 285 break; 286 case DRM_FORMAT_ABGR4444: 287 val |= MCDE_EXTSRCXCONF_BPP_ARGB4444 << 288 MCDE_EXTSRCXCONF_BPP_SHIFT; 289 val |= MCDE_EXTSRCXCONF_BGR; 290 break; 291 case DRM_FORMAT_XRGB4444: 292 val |= MCDE_EXTSRCXCONF_BPP_RGB444 << 293 MCDE_EXTSRCXCONF_BPP_SHIFT; 294 break; 295 case DRM_FORMAT_XBGR4444: 296 val |= MCDE_EXTSRCXCONF_BPP_RGB444 << 297 MCDE_EXTSRCXCONF_BPP_SHIFT; 298 val |= MCDE_EXTSRCXCONF_BGR; 299 break; 300 case DRM_FORMAT_XRGB1555: 301 val |= MCDE_EXTSRCXCONF_BPP_IRGB1555 << 302 MCDE_EXTSRCXCONF_BPP_SHIFT; 303 break; 304 case DRM_FORMAT_XBGR1555: 305 val |= MCDE_EXTSRCXCONF_BPP_IRGB1555 << 306 MCDE_EXTSRCXCONF_BPP_SHIFT; 307 val |= MCDE_EXTSRCXCONF_BGR; 308 break; 309 case DRM_FORMAT_RGB565: 310 val |= MCDE_EXTSRCXCONF_BPP_RGB565 << 311 MCDE_EXTSRCXCONF_BPP_SHIFT; 312 break; 313 case DRM_FORMAT_BGR565: 314 val |= MCDE_EXTSRCXCONF_BPP_RGB565 << 315 MCDE_EXTSRCXCONF_BPP_SHIFT; 316 val |= MCDE_EXTSRCXCONF_BGR; 317 break; 318 case DRM_FORMAT_YUV422: 319 val |= MCDE_EXTSRCXCONF_BPP_YCBCR422 << 320 MCDE_EXTSRCXCONF_BPP_SHIFT; 321 break; 322 default: 323 dev_err(mcde->dev, "Unknown pixel format 0x%08x\n", 324 format); 325 return -EINVAL; 326 } 327 writel(val, mcde->regs + conf); 328 329 /* Software select, primary */ 330 val = MCDE_EXTSRCXCR_SEL_MOD_SOFTWARE_SEL; 331 val |= MCDE_EXTSRCXCR_MULTIOVL_CTRL_PRIMARY; 332 writel(val, mcde->regs + cr); 333 334 return 0; 335} 336 337static void mcde_configure_overlay(struct mcde *mcde, enum mcde_overlay ovl, 338 enum mcde_extsrc src, 339 enum mcde_channel ch, 340 const struct drm_display_mode *mode, 341 u32 format, int cpp) 342{ 343 u32 val; 344 u32 conf1; 345 u32 conf2; 346 u32 crop; 347 u32 ljinc; 348 u32 cr; 349 u32 comp; 350 u32 pixel_fetcher_watermark; 351 352 switch (ovl) { 353 case MCDE_OVERLAY_0: 354 conf1 = MCDE_OVL0CONF; 355 conf2 = MCDE_OVL0CONF2; 356 crop = MCDE_OVL0CROP; 357 ljinc = MCDE_OVL0LJINC; 358 cr = MCDE_OVL0CR; 359 comp = MCDE_OVL0COMP; 360 break; 361 case MCDE_OVERLAY_1: 362 conf1 = MCDE_OVL1CONF; 363 conf2 = MCDE_OVL1CONF2; 364 crop = MCDE_OVL1CROP; 365 ljinc = MCDE_OVL1LJINC; 366 cr = MCDE_OVL1CR; 367 comp = MCDE_OVL1COMP; 368 break; 369 case MCDE_OVERLAY_2: 370 conf1 = MCDE_OVL2CONF; 371 conf2 = MCDE_OVL2CONF2; 372 crop = MCDE_OVL2CROP; 373 ljinc = MCDE_OVL2LJINC; 374 cr = MCDE_OVL2CR; 375 comp = MCDE_OVL2COMP; 376 break; 377 case MCDE_OVERLAY_3: 378 conf1 = MCDE_OVL3CONF; 379 conf2 = MCDE_OVL3CONF2; 380 crop = MCDE_OVL3CROP; 381 ljinc = MCDE_OVL3LJINC; 382 cr = MCDE_OVL3CR; 383 comp = MCDE_OVL3COMP; 384 break; 385 case MCDE_OVERLAY_4: 386 conf1 = MCDE_OVL4CONF; 387 conf2 = MCDE_OVL4CONF2; 388 crop = MCDE_OVL4CROP; 389 ljinc = MCDE_OVL4LJINC; 390 cr = MCDE_OVL4CR; 391 comp = MCDE_OVL4COMP; 392 break; 393 case MCDE_OVERLAY_5: 394 conf1 = MCDE_OVL5CONF; 395 conf2 = MCDE_OVL5CONF2; 396 crop = MCDE_OVL5CROP; 397 ljinc = MCDE_OVL5LJINC; 398 cr = MCDE_OVL5CR; 399 comp = MCDE_OVL5COMP; 400 break; 401 } 402 403 val = mode->hdisplay << MCDE_OVLXCONF_PPL_SHIFT; 404 val |= mode->vdisplay << MCDE_OVLXCONF_LPF_SHIFT; 405 /* Use external source 0 that we just configured */ 406 val |= src << MCDE_OVLXCONF_EXTSRC_ID_SHIFT; 407 writel(val, mcde->regs + conf1); 408 409 val = MCDE_OVLXCONF2_BP_PER_PIXEL_ALPHA; 410 val |= 0xff << MCDE_OVLXCONF2_ALPHAVALUE_SHIFT; 411 /* OPQ: overlay is opaque */ 412 switch (format) { 413 case DRM_FORMAT_ARGB8888: 414 case DRM_FORMAT_ABGR8888: 415 case DRM_FORMAT_ARGB4444: 416 case DRM_FORMAT_ABGR4444: 417 case DRM_FORMAT_XRGB1555: 418 case DRM_FORMAT_XBGR1555: 419 /* No OPQ */ 420 break; 421 case DRM_FORMAT_XRGB8888: 422 case DRM_FORMAT_XBGR8888: 423 case DRM_FORMAT_RGB888: 424 case DRM_FORMAT_BGR888: 425 case DRM_FORMAT_RGB565: 426 case DRM_FORMAT_BGR565: 427 case DRM_FORMAT_YUV422: 428 val |= MCDE_OVLXCONF2_OPQ; 429 break; 430 default: 431 dev_err(mcde->dev, "Unknown pixel format 0x%08x\n", 432 format); 433 break; 434 } 435 436 /* 437 * Pixel fetch watermark level is max 0x1FFF pixels. 438 * Two basic rules should be followed: 439 * 1. The value should be at least 256 bits. 440 * 2. The sum of all active overlays pixelfetch watermark level 441 * multiplied with bits per pixel, should be lower than the 442 * size of input_fifo_size in bits. 443 * 3. The value should be a multiple of a line (256 bits). 444 */ 445 switch (cpp) { 446 case 2: 447 pixel_fetcher_watermark = 128; 448 break; 449 case 3: 450 pixel_fetcher_watermark = 96; 451 break; 452 case 4: 453 pixel_fetcher_watermark = 48; 454 break; 455 default: 456 pixel_fetcher_watermark = 48; 457 break; 458 } 459 dev_dbg(mcde->dev, "pixel fetcher watermark level %d pixels\n", 460 pixel_fetcher_watermark); 461 val |= pixel_fetcher_watermark << MCDE_OVLXCONF2_PIXELFETCHERWATERMARKLEVEL_SHIFT; 462 writel(val, mcde->regs + conf2); 463 464 /* Number of bytes to fetch per line */ 465 writel(mcde->stride, mcde->regs + ljinc); 466 /* No cropping */ 467 writel(0, mcde->regs + crop); 468 469 /* Set up overlay control register */ 470 val = MCDE_OVLXCR_OVLEN; 471 val |= MCDE_OVLXCR_COLCCTRL_DISABLED; 472 val |= MCDE_OVLXCR_BURSTSIZE_8W << 473 MCDE_OVLXCR_BURSTSIZE_SHIFT; 474 val |= MCDE_OVLXCR_MAXOUTSTANDING_8_REQ << 475 MCDE_OVLXCR_MAXOUTSTANDING_SHIFT; 476 /* Not using rotation but set it up anyways */ 477 val |= MCDE_OVLXCR_ROTBURSTSIZE_8W << 478 MCDE_OVLXCR_ROTBURSTSIZE_SHIFT; 479 writel(val, mcde->regs + cr); 480 481 /* 482 * Set up the overlay compositor to route the overlay out to 483 * the desired channel 484 */ 485 val = ch << MCDE_OVLXCOMP_CH_ID_SHIFT; 486 writel(val, mcde->regs + comp); 487} 488 489static void mcde_configure_channel(struct mcde *mcde, enum mcde_channel ch, 490 enum mcde_fifo fifo, 491 const struct drm_display_mode *mode) 492{ 493 u32 val; 494 u32 conf; 495 u32 sync; 496 u32 stat; 497 u32 bgcol; 498 u32 mux; 499 500 switch (ch) { 501 case MCDE_CHANNEL_0: 502 conf = MCDE_CHNL0CONF; 503 sync = MCDE_CHNL0SYNCHMOD; 504 stat = MCDE_CHNL0STAT; 505 bgcol = MCDE_CHNL0BCKGNDCOL; 506 mux = MCDE_CHNL0MUXING; 507 break; 508 case MCDE_CHANNEL_1: 509 conf = MCDE_CHNL1CONF; 510 sync = MCDE_CHNL1SYNCHMOD; 511 stat = MCDE_CHNL1STAT; 512 bgcol = MCDE_CHNL1BCKGNDCOL; 513 mux = MCDE_CHNL1MUXING; 514 break; 515 case MCDE_CHANNEL_2: 516 conf = MCDE_CHNL2CONF; 517 sync = MCDE_CHNL2SYNCHMOD; 518 stat = MCDE_CHNL2STAT; 519 bgcol = MCDE_CHNL2BCKGNDCOL; 520 mux = MCDE_CHNL2MUXING; 521 break; 522 case MCDE_CHANNEL_3: 523 conf = MCDE_CHNL3CONF; 524 sync = MCDE_CHNL3SYNCHMOD; 525 stat = MCDE_CHNL3STAT; 526 bgcol = MCDE_CHNL3BCKGNDCOL; 527 mux = MCDE_CHNL3MUXING; 528 return; 529 } 530 531 /* Set up channel 0 sync (based on chnl_update_registers()) */ 532 switch (mcde->flow_mode) { 533 case MCDE_COMMAND_ONESHOT_FLOW: 534 /* Oneshot is achieved with software sync */ 535 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SOFTWARE 536 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT; 537 break; 538 case MCDE_COMMAND_TE_FLOW: 539 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE 540 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT; 541 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0 542 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT; 543 break; 544 case MCDE_COMMAND_BTA_TE_FLOW: 545 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE 546 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT; 547 /* 548 * TODO: 549 * The vendor driver uses the formatter as sync source 550 * for BTA TE mode. Test to use TE if you have a panel 551 * that uses this mode. 552 */ 553 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER 554 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT; 555 break; 556 case MCDE_VIDEO_TE_FLOW: 557 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE 558 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT; 559 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0 560 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT; 561 break; 562 case MCDE_VIDEO_FORMATTER_FLOW: 563 case MCDE_DPI_FORMATTER_FLOW: 564 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE 565 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT; 566 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER 567 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT; 568 break; 569 default: 570 dev_err(mcde->dev, "unknown flow mode %d\n", 571 mcde->flow_mode); 572 return; 573 } 574 575 writel(val, mcde->regs + sync); 576 577 /* Set up pixels per line and lines per frame */ 578 val = (mode->hdisplay - 1) << MCDE_CHNLXCONF_PPL_SHIFT; 579 val |= (mode->vdisplay - 1) << MCDE_CHNLXCONF_LPF_SHIFT; 580 writel(val, mcde->regs + conf); 581 582 /* 583 * Normalize color conversion: 584 * black background, OLED conversion disable on channel 585 */ 586 val = MCDE_CHNLXSTAT_CHNLBLBCKGND_EN | 587 MCDE_CHNLXSTAT_CHNLRD; 588 writel(val, mcde->regs + stat); 589 writel(0, mcde->regs + bgcol); 590 591 /* Set up muxing: connect the channel to the desired FIFO */ 592 switch (fifo) { 593 case MCDE_FIFO_A: 594 writel(MCDE_CHNLXMUXING_FIFO_ID_FIFO_A, 595 mcde->regs + mux); 596 break; 597 case MCDE_FIFO_B: 598 writel(MCDE_CHNLXMUXING_FIFO_ID_FIFO_B, 599 mcde->regs + mux); 600 break; 601 } 602 603 /* 604 * If using DPI configure the sync event. 605 * TODO: this is for LCD only, it does not cover TV out. 606 */ 607 if (mcde->dpi_output) { 608 u32 stripwidth; 609 610 stripwidth = 0xF000 / (mode->vdisplay * 4); 611 dev_info(mcde->dev, "stripwidth: %d\n", stripwidth); 612 613 val = MCDE_SYNCHCONF_HWREQVEVENT_ACTIVE_VIDEO | 614 (mode->hdisplay - 1 - stripwidth) << MCDE_SYNCHCONF_HWREQVCNT_SHIFT | 615 MCDE_SYNCHCONF_SWINTVEVENT_ACTIVE_VIDEO | 616 (mode->hdisplay - 1 - stripwidth) << MCDE_SYNCHCONF_SWINTVCNT_SHIFT; 617 618 switch (fifo) { 619 case MCDE_FIFO_A: 620 writel(val, mcde->regs + MCDE_SYNCHCONFA); 621 break; 622 case MCDE_FIFO_B: 623 writel(val, mcde->regs + MCDE_SYNCHCONFB); 624 break; 625 } 626 } 627} 628 629static void mcde_configure_fifo(struct mcde *mcde, enum mcde_fifo fifo, 630 enum mcde_formatter fmt, 631 int fifo_wtrmrk) 632{ 633 u32 val; 634 u32 ctrl; 635 u32 cr0, cr1; 636 637 switch (fifo) { 638 case MCDE_FIFO_A: 639 ctrl = MCDE_CTRLA; 640 cr0 = MCDE_CRA0; 641 cr1 = MCDE_CRA1; 642 break; 643 case MCDE_FIFO_B: 644 ctrl = MCDE_CTRLB; 645 cr0 = MCDE_CRB0; 646 cr1 = MCDE_CRB1; 647 break; 648 } 649 650 val = fifo_wtrmrk << MCDE_CTRLX_FIFOWTRMRK_SHIFT; 651 652 /* 653 * Select the formatter to use for this FIFO 654 * 655 * The register definitions imply that different IDs should be used 656 * by the DSI formatters depending on if they are in VID or CMD 657 * mode, and the manual says they are dedicated but identical. 658 * The vendor code uses them as it seems fit. 659 */ 660 switch (fmt) { 661 case MCDE_DSI_FORMATTER_0: 662 val |= MCDE_CTRLX_FORMTYPE_DSI << MCDE_CTRLX_FORMTYPE_SHIFT; 663 val |= MCDE_CTRLX_FORMID_DSI0VID << MCDE_CTRLX_FORMID_SHIFT; 664 break; 665 case MCDE_DSI_FORMATTER_1: 666 val |= MCDE_CTRLX_FORMTYPE_DSI << MCDE_CTRLX_FORMTYPE_SHIFT; 667 val |= MCDE_CTRLX_FORMID_DSI0CMD << MCDE_CTRLX_FORMID_SHIFT; 668 break; 669 case MCDE_DSI_FORMATTER_2: 670 val |= MCDE_CTRLX_FORMTYPE_DSI << MCDE_CTRLX_FORMTYPE_SHIFT; 671 val |= MCDE_CTRLX_FORMID_DSI1VID << MCDE_CTRLX_FORMID_SHIFT; 672 break; 673 case MCDE_DSI_FORMATTER_3: 674 val |= MCDE_CTRLX_FORMTYPE_DSI << MCDE_CTRLX_FORMTYPE_SHIFT; 675 val |= MCDE_CTRLX_FORMID_DSI1CMD << MCDE_CTRLX_FORMID_SHIFT; 676 break; 677 case MCDE_DSI_FORMATTER_4: 678 val |= MCDE_CTRLX_FORMTYPE_DSI << MCDE_CTRLX_FORMTYPE_SHIFT; 679 val |= MCDE_CTRLX_FORMID_DSI2VID << MCDE_CTRLX_FORMID_SHIFT; 680 break; 681 case MCDE_DSI_FORMATTER_5: 682 val |= MCDE_CTRLX_FORMTYPE_DSI << MCDE_CTRLX_FORMTYPE_SHIFT; 683 val |= MCDE_CTRLX_FORMID_DSI2CMD << MCDE_CTRLX_FORMID_SHIFT; 684 break; 685 case MCDE_DPI_FORMATTER_0: 686 val |= MCDE_CTRLX_FORMTYPE_DPITV << MCDE_CTRLX_FORMTYPE_SHIFT; 687 val |= MCDE_CTRLX_FORMID_DPIA << MCDE_CTRLX_FORMID_SHIFT; 688 break; 689 case MCDE_DPI_FORMATTER_1: 690 val |= MCDE_CTRLX_FORMTYPE_DPITV << MCDE_CTRLX_FORMTYPE_SHIFT; 691 val |= MCDE_CTRLX_FORMID_DPIB << MCDE_CTRLX_FORMID_SHIFT; 692 break; 693 } 694 writel(val, mcde->regs + ctrl); 695 696 /* Blend source with Alpha 0xff on FIFO */ 697 val = MCDE_CRX0_BLENDEN | 698 0xff << MCDE_CRX0_ALPHABLEND_SHIFT; 699 writel(val, mcde->regs + cr0); 700 701 spin_lock(&mcde->fifo_crx1_lock); 702 val = readl(mcde->regs + cr1); 703 /* 704 * Set-up from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() 705 * FIXME: a different clock needs to be selected for TV out. 706 */ 707 if (mcde->dpi_output) { 708 struct drm_connector *connector = drm_panel_bridge_connector(mcde->bridge); 709 u32 bus_format; 710 711 /* Assume RGB888 24 bit if we have no further info */ 712 if (!connector->display_info.num_bus_formats) { 713 dev_info(mcde->dev, "panel does not specify bus format, assume RGB888\n"); 714 bus_format = MEDIA_BUS_FMT_RGB888_1X24; 715 } else { 716 bus_format = connector->display_info.bus_formats[0]; 717 } 718 719 /* 720 * Set up the CDWIN and OUTBPP for the LCD 721 * 722 * FIXME: fill this in if you know the correspondance between the MIPI 723 * DPI specification and the media bus formats. 724 */ 725 val &= ~MCDE_CRX1_CDWIN_MASK; 726 val &= ~MCDE_CRX1_OUTBPP_MASK; 727 switch (bus_format) { 728 case MEDIA_BUS_FMT_RGB888_1X24: 729 val |= MCDE_CRX1_CDWIN_24BPP << MCDE_CRX1_CDWIN_SHIFT; 730 val |= MCDE_CRX1_OUTBPP_24BPP << MCDE_CRX1_OUTBPP_SHIFT; 731 break; 732 default: 733 dev_err(mcde->dev, "unknown bus format, assume RGB888\n"); 734 val |= MCDE_CRX1_CDWIN_24BPP << MCDE_CRX1_CDWIN_SHIFT; 735 val |= MCDE_CRX1_OUTBPP_24BPP << MCDE_CRX1_OUTBPP_SHIFT; 736 break; 737 } 738 } else { 739 /* Use the MCDE clock for DSI */ 740 val &= ~MCDE_CRX1_CLKSEL_MASK; 741 val |= MCDE_CRX1_CLKSEL_MCDECLK << MCDE_CRX1_CLKSEL_SHIFT; 742 } 743 writel(val, mcde->regs + cr1); 744 spin_unlock(&mcde->fifo_crx1_lock); 745}; 746 747static void mcde_configure_dsi_formatter(struct mcde *mcde, 748 enum mcde_formatter fmt, 749 u32 formatter_frame, 750 int pkt_size) 751{ 752 u32 val; 753 u32 conf0; 754 u32 frame; 755 u32 pkt; 756 u32 sync; 757 u32 cmdw; 758 u32 delay0, delay1; 759 760 switch (fmt) { 761 case MCDE_DSI_FORMATTER_0: 762 conf0 = MCDE_DSIVID0CONF0; 763 frame = MCDE_DSIVID0FRAME; 764 pkt = MCDE_DSIVID0PKT; 765 sync = MCDE_DSIVID0SYNC; 766 cmdw = MCDE_DSIVID0CMDW; 767 delay0 = MCDE_DSIVID0DELAY0; 768 delay1 = MCDE_DSIVID0DELAY1; 769 break; 770 case MCDE_DSI_FORMATTER_1: 771 conf0 = MCDE_DSIVID1CONF0; 772 frame = MCDE_DSIVID1FRAME; 773 pkt = MCDE_DSIVID1PKT; 774 sync = MCDE_DSIVID1SYNC; 775 cmdw = MCDE_DSIVID1CMDW; 776 delay0 = MCDE_DSIVID1DELAY0; 777 delay1 = MCDE_DSIVID1DELAY1; 778 break; 779 case MCDE_DSI_FORMATTER_2: 780 conf0 = MCDE_DSIVID2CONF0; 781 frame = MCDE_DSIVID2FRAME; 782 pkt = MCDE_DSIVID2PKT; 783 sync = MCDE_DSIVID2SYNC; 784 cmdw = MCDE_DSIVID2CMDW; 785 delay0 = MCDE_DSIVID2DELAY0; 786 delay1 = MCDE_DSIVID2DELAY1; 787 break; 788 default: 789 dev_err(mcde->dev, "tried to configure a non-DSI formatter as DSI\n"); 790 return; 791 } 792 793 /* 794 * Enable formatter 795 * 8 bit commands and DCS commands (notgen = not generic) 796 */ 797 val = MCDE_DSICONF0_CMD8 | MCDE_DSICONF0_DCSVID_NOTGEN; 798 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) 799 val |= MCDE_DSICONF0_VID_MODE_VID; 800 switch (mcde->mdsi->format) { 801 case MIPI_DSI_FMT_RGB888: 802 val |= MCDE_DSICONF0_PACKING_RGB888 << 803 MCDE_DSICONF0_PACKING_SHIFT; 804 break; 805 case MIPI_DSI_FMT_RGB666: 806 val |= MCDE_DSICONF0_PACKING_RGB666 << 807 MCDE_DSICONF0_PACKING_SHIFT; 808 break; 809 case MIPI_DSI_FMT_RGB666_PACKED: 810 dev_err(mcde->dev, 811 "we cannot handle the packed RGB666 format\n"); 812 val |= MCDE_DSICONF0_PACKING_RGB666 << 813 MCDE_DSICONF0_PACKING_SHIFT; 814 break; 815 case MIPI_DSI_FMT_RGB565: 816 val |= MCDE_DSICONF0_PACKING_RGB565 << 817 MCDE_DSICONF0_PACKING_SHIFT; 818 break; 819 default: 820 dev_err(mcde->dev, "unknown DSI format\n"); 821 return; 822 } 823 writel(val, mcde->regs + conf0); 824 825 writel(formatter_frame, mcde->regs + frame); 826 writel(pkt_size, mcde->regs + pkt); 827 writel(0, mcde->regs + sync); 828 /* Define the MIPI command: we want to write into display memory */ 829 val = MIPI_DCS_WRITE_MEMORY_CONTINUE << 830 MCDE_DSIVIDXCMDW_CMDW_CONTINUE_SHIFT; 831 val |= MIPI_DCS_WRITE_MEMORY_START << 832 MCDE_DSIVIDXCMDW_CMDW_START_SHIFT; 833 writel(val, mcde->regs + cmdw); 834 835 /* 836 * FIXME: the vendor driver has some hack around this value in 837 * CMD mode with autotrig. 838 */ 839 writel(0, mcde->regs + delay0); 840 writel(0, mcde->regs + delay1); 841} 842 843static void mcde_enable_fifo(struct mcde *mcde, enum mcde_fifo fifo) 844{ 845 u32 val; 846 u32 cr; 847 848 switch (fifo) { 849 case MCDE_FIFO_A: 850 cr = MCDE_CRA0; 851 break; 852 case MCDE_FIFO_B: 853 cr = MCDE_CRB0; 854 break; 855 default: 856 dev_err(mcde->dev, "cannot enable FIFO %c\n", 857 'A' + fifo); 858 return; 859 } 860 861 spin_lock(&mcde->flow_lock); 862 val = readl(mcde->regs + cr); 863 val |= MCDE_CRX0_FLOEN; 864 writel(val, mcde->regs + cr); 865 mcde->flow_active++; 866 spin_unlock(&mcde->flow_lock); 867} 868 869static void mcde_disable_fifo(struct mcde *mcde, enum mcde_fifo fifo, 870 bool wait_for_drain) 871{ 872 int timeout = 100; 873 u32 val; 874 u32 cr; 875 876 switch (fifo) { 877 case MCDE_FIFO_A: 878 cr = MCDE_CRA0; 879 break; 880 case MCDE_FIFO_B: 881 cr = MCDE_CRB0; 882 break; 883 default: 884 dev_err(mcde->dev, "cannot disable FIFO %c\n", 885 'A' + fifo); 886 return; 887 } 888 889 spin_lock(&mcde->flow_lock); 890 val = readl(mcde->regs + cr); 891 val &= ~MCDE_CRX0_FLOEN; 892 writel(val, mcde->regs + cr); 893 mcde->flow_active = 0; 894 spin_unlock(&mcde->flow_lock); 895 896 if (!wait_for_drain) 897 return; 898 899 /* Check that we really drained and stopped the flow */ 900 while (readl(mcde->regs + cr) & MCDE_CRX0_FLOEN) { 901 usleep_range(1000, 1500); 902 if (!--timeout) { 903 dev_err(mcde->dev, 904 "FIFO timeout while clearing FIFO %c\n", 905 'A' + fifo); 906 return; 907 } 908 } 909} 910 911/* 912 * This drains a pipe i.e. a FIFO connected to a certain channel 913 */ 914static void mcde_drain_pipe(struct mcde *mcde, enum mcde_fifo fifo, 915 enum mcde_channel ch) 916{ 917 u32 val; 918 u32 ctrl; 919 u32 synsw; 920 921 switch (fifo) { 922 case MCDE_FIFO_A: 923 ctrl = MCDE_CTRLA; 924 break; 925 case MCDE_FIFO_B: 926 ctrl = MCDE_CTRLB; 927 break; 928 } 929 930 switch (ch) { 931 case MCDE_CHANNEL_0: 932 synsw = MCDE_CHNL0SYNCHSW; 933 break; 934 case MCDE_CHANNEL_1: 935 synsw = MCDE_CHNL1SYNCHSW; 936 break; 937 case MCDE_CHANNEL_2: 938 synsw = MCDE_CHNL2SYNCHSW; 939 break; 940 case MCDE_CHANNEL_3: 941 synsw = MCDE_CHNL3SYNCHSW; 942 return; 943 } 944 945 val = readl(mcde->regs + ctrl); 946 if (!(val & MCDE_CTRLX_FIFOEMPTY)) { 947 dev_err(mcde->dev, "Channel A FIFO not empty (handover)\n"); 948 /* Attempt to clear the FIFO */ 949 mcde_enable_fifo(mcde, fifo); 950 /* Trigger a software sync out on respective channel (0-3) */ 951 writel(MCDE_CHNLXSYNCHSW_SW_TRIG, mcde->regs + synsw); 952 /* Disable FIFO A flow again */ 953 mcde_disable_fifo(mcde, fifo, true); 954 } 955} 956 957static int mcde_dsi_get_pkt_div(int ppl, int fifo_size) 958{ 959 /* 960 * DSI command mode line packets should be split into an even number of 961 * packets smaller than or equal to the fifo size. 962 */ 963 int div; 964 const int max_div = DIV_ROUND_UP(MCDE_MAX_WIDTH, fifo_size); 965 966 for (div = 1; div < max_div; div++) 967 if (ppl % div == 0 && ppl / div <= fifo_size) 968 return div; 969 return 1; 970} 971 972static void mcde_setup_dpi(struct mcde *mcde, const struct drm_display_mode *mode, 973 int *fifo_wtrmrk_lvl) 974{ 975 struct drm_connector *connector = drm_panel_bridge_connector(mcde->bridge); 976 u32 hsw, hfp, hbp; 977 u32 vsw, vfp, vbp; 978 u32 val; 979 980 /* FIXME: we only support LCD, implement TV out */ 981 hsw = mode->hsync_end - mode->hsync_start; 982 hfp = mode->hsync_start - mode->hdisplay; 983 hbp = mode->htotal - mode->hsync_end; 984 vsw = mode->vsync_end - mode->vsync_start; 985 vfp = mode->vsync_start - mode->vdisplay; 986 vbp = mode->vtotal - mode->vsync_end; 987 988 dev_info(mcde->dev, "output on DPI LCD from channel A\n"); 989 /* Display actual values */ 990 dev_info(mcde->dev, "HSW: %d, HFP: %d, HBP: %d, VSW: %d, VFP: %d, VBP: %d\n", 991 hsw, hfp, hbp, vsw, vfp, vbp); 992 993 /* 994 * The pixel fetcher is 128 64-bit words deep = 1024 bytes. 995 * One overlay of 32bpp (4 cpp) assumed, fetch 160 pixels. 996 * 160 * 4 = 640 bytes. 997 */ 998 *fifo_wtrmrk_lvl = 640; 999 1000 /* Set up the main control, watermark level at 7 */ 1001 val = 7 << MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT; 1002 1003 /* 1004 * This sets up the internal silicon muxing of the DPI 1005 * lines. This is how the silicon connects out to the 1006 * external pins, then the pins need to be further 1007 * configured into "alternate functions" using pin control 1008 * to actually get the signals out. 1009 * 1010 * FIXME: this is hardcoded to the only setting found in 1011 * the wild. If we need to use different settings for 1012 * different DPI displays, make this parameterizable from 1013 * the device tree. 1014 */ 1015 /* 24 bits DPI: connect Ch A LSB to D[0:7] */ 1016 val |= 0 << MCDE_CONF0_OUTMUX0_SHIFT; 1017 /* 24 bits DPI: connect Ch A MID to D[8:15] */ 1018 val |= 1 << MCDE_CONF0_OUTMUX1_SHIFT; 1019 /* Don't care about this muxing */ 1020 val |= 0 << MCDE_CONF0_OUTMUX2_SHIFT; 1021 /* Don't care about this muxing */ 1022 val |= 0 << MCDE_CONF0_OUTMUX3_SHIFT; 1023 /* 24 bits DPI: connect Ch A MSB to D[32:39] */ 1024 val |= 2 << MCDE_CONF0_OUTMUX4_SHIFT; 1025 /* Syncmux bits zero: DPI channel A */ 1026 writel(val, mcde->regs + MCDE_CONF0); 1027 1028 /* This hammers us into LCD mode */ 1029 writel(0, mcde->regs + MCDE_TVCRA); 1030 1031 /* Front porch and sync width */ 1032 val = (vsw << MCDE_TVBL1_BEL1_SHIFT); 1033 val |= (vfp << MCDE_TVBL1_BSL1_SHIFT); 1034 writel(val, mcde->regs + MCDE_TVBL1A); 1035 /* The vendor driver sets the same value into TVBL2A */ 1036 writel(val, mcde->regs + MCDE_TVBL2A); 1037 1038 /* Vertical back porch */ 1039 val = (vbp << MCDE_TVDVO_DVO1_SHIFT); 1040 /* The vendor drivers sets the same value into TVDVOA */ 1041 val |= (vbp << MCDE_TVDVO_DVO2_SHIFT); 1042 writel(val, mcde->regs + MCDE_TVDVOA); 1043 1044 /* Horizontal back porch, as 0 = 1 cycle we need to subtract 1 */ 1045 writel((hbp - 1), mcde->regs + MCDE_TVTIM1A); 1046 1047 /* Horizongal sync width and horizonal front porch, 0 = 1 cycle */ 1048 val = ((hsw - 1) << MCDE_TVLBALW_LBW_SHIFT); 1049 val |= ((hfp - 1) << MCDE_TVLBALW_ALW_SHIFT); 1050 writel(val, mcde->regs + MCDE_TVLBALWA); 1051 1052 /* Blank some TV registers we don't use */ 1053 writel(0, mcde->regs + MCDE_TVISLA); 1054 writel(0, mcde->regs + MCDE_TVBLUA); 1055 1056 /* Set up sync inversion etc */ 1057 val = 0; 1058 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 1059 val |= MCDE_LCDTIM1B_IHS; 1060 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 1061 val |= MCDE_LCDTIM1B_IVS; 1062 if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW) 1063 val |= MCDE_LCDTIM1B_IOE; 1064 if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) 1065 val |= MCDE_LCDTIM1B_IPC; 1066 writel(val, mcde->regs + MCDE_LCDTIM1A); 1067} 1068 1069static void mcde_setup_dsi(struct mcde *mcde, const struct drm_display_mode *mode, 1070 int cpp, int *fifo_wtrmrk_lvl, int *dsi_formatter_frame, 1071 int *dsi_pkt_size) 1072{ 1073 u32 formatter_ppl = mode->hdisplay; /* pixels per line */ 1074 u32 formatter_lpf = mode->vdisplay; /* lines per frame */ 1075 int formatter_frame; 1076 int formatter_cpp; 1077 int fifo_wtrmrk; 1078 u32 pkt_div; 1079 int pkt_size; 1080 u32 val; 1081 1082 dev_info(mcde->dev, "output in %s mode, format %dbpp\n", 1083 (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? 1084 "VIDEO" : "CMD", 1085 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format)); 1086 formatter_cpp = 1087 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format) / 8; 1088 dev_info(mcde->dev, "Overlay CPP: %d bytes, DSI formatter CPP %d bytes\n", 1089 cpp, formatter_cpp); 1090 1091 /* Set up the main control, watermark level at 7 */ 1092 val = 7 << MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT; 1093 1094 /* 1095 * This is the internal silicon muxing of the DPI 1096 * (parallell display) lines. Since we are not using 1097 * this at all (we are using DSI) these are just 1098 * dummy values from the vendor tree. 1099 */ 1100 val |= 3 << MCDE_CONF0_OUTMUX0_SHIFT; 1101 val |= 3 << MCDE_CONF0_OUTMUX1_SHIFT; 1102 val |= 0 << MCDE_CONF0_OUTMUX2_SHIFT; 1103 val |= 4 << MCDE_CONF0_OUTMUX3_SHIFT; 1104 val |= 5 << MCDE_CONF0_OUTMUX4_SHIFT; 1105 writel(val, mcde->regs + MCDE_CONF0); 1106 1107 /* Calculations from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() */ 1108 1109 /* 1110 * Set up FIFO A watermark level: 1111 * 128 for LCD 32bpp video mode 1112 * 48 for LCD 32bpp command mode 1113 * 128 for LCD 16bpp video mode 1114 * 64 for LCD 16bpp command mode 1115 * 128 for HDMI 32bpp 1116 * 192 for HDMI 16bpp 1117 */ 1118 fifo_wtrmrk = mode->hdisplay; 1119 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) { 1120 fifo_wtrmrk = min(fifo_wtrmrk, 128); 1121 pkt_div = 1; 1122 } else { 1123 fifo_wtrmrk = min(fifo_wtrmrk, 48); 1124 /* The FIFO is 640 entries deep on this v3 hardware */ 1125 pkt_div = mcde_dsi_get_pkt_div(mode->hdisplay, 640); 1126 } 1127 dev_dbg(mcde->dev, "FIFO watermark after flooring: %d bytes\n", 1128 fifo_wtrmrk); 1129 dev_dbg(mcde->dev, "Packet divisor: %d bytes\n", pkt_div); 1130 1131 /* NOTE: pkt_div is 1 for video mode */ 1132 pkt_size = (formatter_ppl * formatter_cpp) / pkt_div; 1133 /* Commands CMD8 need one extra byte */ 1134 if (!(mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO)) 1135 pkt_size++; 1136 1137 dev_dbg(mcde->dev, "DSI packet size: %d * %d bytes per line\n", 1138 pkt_size, pkt_div); 1139 dev_dbg(mcde->dev, "Overlay frame size: %u bytes\n", 1140 mode->hdisplay * mode->vdisplay * cpp); 1141 /* NOTE: pkt_div is 1 for video mode */ 1142 formatter_frame = pkt_size * pkt_div * formatter_lpf; 1143 dev_dbg(mcde->dev, "Formatter frame size: %u bytes\n", formatter_frame); 1144 1145 *fifo_wtrmrk_lvl = fifo_wtrmrk; 1146 *dsi_pkt_size = pkt_size; 1147 *dsi_formatter_frame = formatter_frame; 1148} 1149 1150static void mcde_display_enable(struct drm_simple_display_pipe *pipe, 1151 struct drm_crtc_state *cstate, 1152 struct drm_plane_state *plane_state) 1153{ 1154 struct drm_crtc *crtc = &pipe->crtc; 1155 struct drm_plane *plane = &pipe->plane; 1156 struct drm_device *drm = crtc->dev; 1157 struct mcde *mcde = to_mcde(drm); 1158 const struct drm_display_mode *mode = &cstate->mode; 1159 struct drm_framebuffer *fb = plane->state->fb; 1160 u32 format = fb->format->format; 1161 int dsi_pkt_size; 1162 int fifo_wtrmrk; 1163 int cpp = fb->format->cpp[0]; 1164 u32 dsi_formatter_frame; 1165 u32 val; 1166 int ret; 1167 1168 /* This powers up the entire MCDE block and the DSI hardware */ 1169 ret = regulator_enable(mcde->epod); 1170 if (ret) { 1171 dev_err(drm->dev, "can't re-enable EPOD regulator\n"); 1172 return; 1173 } 1174 1175 dev_info(drm->dev, "enable MCDE, %d x %d format %p4cc\n", 1176 mode->hdisplay, mode->vdisplay, &format); 1177 1178 1179 /* Clear any pending interrupts */ 1180 mcde_display_disable_irqs(mcde); 1181 writel(0, mcde->regs + MCDE_IMSCERR); 1182 writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR); 1183 1184 if (mcde->dpi_output) 1185 mcde_setup_dpi(mcde, mode, &fifo_wtrmrk); 1186 else 1187 mcde_setup_dsi(mcde, mode, cpp, &fifo_wtrmrk, 1188 &dsi_formatter_frame, &dsi_pkt_size); 1189 1190 mcde->stride = mode->hdisplay * cpp; 1191 dev_dbg(drm->dev, "Overlay line stride: %u bytes\n", 1192 mcde->stride); 1193 1194 /* Drain the FIFO A + channel 0 pipe so we have a clean slate */ 1195 mcde_drain_pipe(mcde, MCDE_FIFO_A, MCDE_CHANNEL_0); 1196 1197 /* 1198 * We set up our display pipeline: 1199 * EXTSRC 0 -> OVERLAY 0 -> CHANNEL 0 -> FIFO A -> DSI FORMATTER 0 1200 * 1201 * First configure the external source (memory) on external source 0 1202 * using the desired bitstream/bitmap format 1203 */ 1204 mcde_configure_extsrc(mcde, MCDE_EXTSRC_0, format); 1205 1206 /* 1207 * Configure overlay 0 according to format and mode and take input 1208 * from external source 0 and route the output of this overlay to 1209 * channel 0 1210 */ 1211 mcde_configure_overlay(mcde, MCDE_OVERLAY_0, MCDE_EXTSRC_0, 1212 MCDE_CHANNEL_0, mode, format, cpp); 1213 1214 /* 1215 * Configure pixel-per-line and line-per-frame for channel 0 and then 1216 * route channel 0 to FIFO A 1217 */ 1218 mcde_configure_channel(mcde, MCDE_CHANNEL_0, MCDE_FIFO_A, mode); 1219 1220 if (mcde->dpi_output) { 1221 unsigned long lcd_freq; 1222 1223 /* Configure FIFO A to use DPI formatter 0 */ 1224 mcde_configure_fifo(mcde, MCDE_FIFO_A, MCDE_DPI_FORMATTER_0, 1225 fifo_wtrmrk); 1226 1227 /* Set up and enable the LCD clock */ 1228 lcd_freq = clk_round_rate(mcde->fifoa_clk, mode->clock * 1000); 1229 ret = clk_set_rate(mcde->fifoa_clk, lcd_freq); 1230 if (ret) 1231 dev_err(mcde->dev, "failed to set LCD clock rate %lu Hz\n", 1232 lcd_freq); 1233 ret = clk_prepare_enable(mcde->fifoa_clk); 1234 if (ret) { 1235 dev_err(mcde->dev, "failed to enable FIFO A DPI clock\n"); 1236 return; 1237 } 1238 dev_info(mcde->dev, "LCD FIFO A clk rate %lu Hz\n", 1239 clk_get_rate(mcde->fifoa_clk)); 1240 } else { 1241 /* Configure FIFO A to use DSI formatter 0 */ 1242 mcde_configure_fifo(mcde, MCDE_FIFO_A, MCDE_DSI_FORMATTER_0, 1243 fifo_wtrmrk); 1244 1245 /* 1246 * This brings up the DSI bridge which is tightly connected 1247 * to the MCDE DSI formatter. 1248 */ 1249 mcde_dsi_enable(mcde->bridge); 1250 1251 /* Configure the DSI formatter 0 for the DSI panel output */ 1252 mcde_configure_dsi_formatter(mcde, MCDE_DSI_FORMATTER_0, 1253 dsi_formatter_frame, dsi_pkt_size); 1254 } 1255 1256 switch (mcde->flow_mode) { 1257 case MCDE_COMMAND_TE_FLOW: 1258 case MCDE_COMMAND_BTA_TE_FLOW: 1259 case MCDE_VIDEO_TE_FLOW: 1260 /* We are using TE in some combination */ 1261 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 1262 val = MCDE_VSCRC_VSPOL; 1263 else 1264 val = 0; 1265 writel(val, mcde->regs + MCDE_VSCRC0); 1266 /* Enable VSYNC capture on TE0 */ 1267 val = readl(mcde->regs + MCDE_CRC); 1268 val |= MCDE_CRC_SYCEN0; 1269 writel(val, mcde->regs + MCDE_CRC); 1270 break; 1271 default: 1272 /* No TE capture */ 1273 break; 1274 } 1275 1276 drm_crtc_vblank_on(crtc); 1277 1278 /* 1279 * If we're using oneshot mode we don't start the flow 1280 * until each time the display is given an update, and 1281 * then we disable it immediately after. For all other 1282 * modes (command or video) we start the FIFO flow 1283 * right here. This is necessary for the hardware to 1284 * behave right. 1285 */ 1286 if (mcde->flow_mode != MCDE_COMMAND_ONESHOT_FLOW) { 1287 mcde_enable_fifo(mcde, MCDE_FIFO_A); 1288 dev_dbg(mcde->dev, "started MCDE video FIFO flow\n"); 1289 } 1290 1291 /* Enable MCDE with automatic clock gating */ 1292 val = readl(mcde->regs + MCDE_CR); 1293 val |= MCDE_CR_MCDEEN | MCDE_CR_AUTOCLKG_EN; 1294 writel(val, mcde->regs + MCDE_CR); 1295 1296 dev_info(drm->dev, "MCDE display is enabled\n"); 1297} 1298 1299static void mcde_display_disable(struct drm_simple_display_pipe *pipe) 1300{ 1301 struct drm_crtc *crtc = &pipe->crtc; 1302 struct drm_device *drm = crtc->dev; 1303 struct mcde *mcde = to_mcde(drm); 1304 struct drm_pending_vblank_event *event; 1305 int ret; 1306 1307 drm_crtc_vblank_off(crtc); 1308 1309 /* Disable FIFO A flow */ 1310 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); 1311 1312 if (mcde->dpi_output) { 1313 clk_disable_unprepare(mcde->fifoa_clk); 1314 } else { 1315 /* This disables the DSI bridge */ 1316 mcde_dsi_disable(mcde->bridge); 1317 } 1318 1319 event = crtc->state->event; 1320 if (event) { 1321 crtc->state->event = NULL; 1322 1323 spin_lock_irq(&crtc->dev->event_lock); 1324 drm_crtc_send_vblank_event(crtc, event); 1325 spin_unlock_irq(&crtc->dev->event_lock); 1326 } 1327 1328 ret = regulator_disable(mcde->epod); 1329 if (ret) 1330 dev_err(drm->dev, "can't disable EPOD regulator\n"); 1331 /* Make sure we are powered down (before we may power up again) */ 1332 usleep_range(50000, 70000); 1333 1334 dev_info(drm->dev, "MCDE display is disabled\n"); 1335} 1336 1337static void mcde_start_flow(struct mcde *mcde) 1338{ 1339 /* Request a TE ACK only in TE+BTA mode */ 1340 if (mcde->flow_mode == MCDE_COMMAND_BTA_TE_FLOW) 1341 mcde_dsi_te_request(mcde->mdsi); 1342 1343 /* Enable FIFO A flow */ 1344 mcde_enable_fifo(mcde, MCDE_FIFO_A); 1345 1346 /* 1347 * If oneshot mode is enabled, the flow will be disabled 1348 * when the TE0 IRQ arrives in the interrupt handler. Otherwise 1349 * updates are continuously streamed to the display after this 1350 * point. 1351 */ 1352 1353 if (mcde->flow_mode == MCDE_COMMAND_ONESHOT_FLOW) { 1354 /* Trigger a software sync out on channel 0 */ 1355 writel(MCDE_CHNLXSYNCHSW_SW_TRIG, 1356 mcde->regs + MCDE_CHNL0SYNCHSW); 1357 1358 /* 1359 * Disable FIFO A flow again: since we are using TE sync we 1360 * need to wait for the FIFO to drain before we continue 1361 * so repeated calls to this function will not cause a mess 1362 * in the hardware by pushing updates will updates are going 1363 * on already. 1364 */ 1365 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); 1366 } 1367 1368 dev_dbg(mcde->dev, "started MCDE FIFO flow\n"); 1369} 1370 1371static void mcde_set_extsrc(struct mcde *mcde, u32 buffer_address) 1372{ 1373 /* Write bitmap base address to register */ 1374 writel(buffer_address, mcde->regs + MCDE_EXTSRCXA0); 1375 /* 1376 * Base address for next line this is probably only used 1377 * in interlace modes. 1378 */ 1379 writel(buffer_address + mcde->stride, mcde->regs + MCDE_EXTSRCXA1); 1380} 1381 1382static void mcde_display_update(struct drm_simple_display_pipe *pipe, 1383 struct drm_plane_state *old_pstate) 1384{ 1385 struct drm_crtc *crtc = &pipe->crtc; 1386 struct drm_device *drm = crtc->dev; 1387 struct mcde *mcde = to_mcde(drm); 1388 struct drm_pending_vblank_event *event = crtc->state->event; 1389 struct drm_plane *plane = &pipe->plane; 1390 struct drm_plane_state *pstate = plane->state; 1391 struct drm_framebuffer *fb = pstate->fb; 1392 1393 /* 1394 * Handle any pending event first, we need to arm the vblank 1395 * interrupt before sending any update to the display so we don't 1396 * miss the interrupt. 1397 */ 1398 if (event) { 1399 crtc->state->event = NULL; 1400 1401 spin_lock_irq(&crtc->dev->event_lock); 1402 /* 1403 * Hardware must be on before we can arm any vblank event, 1404 * this is not a scanout controller where there is always 1405 * some periodic update going on, it is completely frozen 1406 * until we get an update. If MCDE output isn't yet enabled, 1407 * we just send a vblank dummy event back. 1408 */ 1409 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0) { 1410 dev_dbg(mcde->dev, "arm vblank event\n"); 1411 drm_crtc_arm_vblank_event(crtc, event); 1412 } else { 1413 dev_dbg(mcde->dev, "insert fake vblank event\n"); 1414 drm_crtc_send_vblank_event(crtc, event); 1415 } 1416 1417 spin_unlock_irq(&crtc->dev->event_lock); 1418 } 1419 1420 /* 1421 * We do not start sending framebuffer updates before the 1422 * display is enabled. Update events will however be dispatched 1423 * from the DRM core before the display is enabled. 1424 */ 1425 if (fb) { 1426 mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0)); 1427 dev_info_once(mcde->dev, "first update of display contents\n"); 1428 /* 1429 * Usually the flow is already active, unless we are in 1430 * oneshot mode, then we need to kick the flow right here. 1431 */ 1432 if (mcde->flow_active == 0) 1433 mcde_start_flow(mcde); 1434 } else { 1435 /* 1436 * If an update is receieved before the MCDE is enabled 1437 * (before mcde_display_enable() is called) we can't really 1438 * do much with that buffer. 1439 */ 1440 dev_info(mcde->dev, "ignored a display update\n"); 1441 } 1442} 1443 1444static int mcde_display_enable_vblank(struct drm_simple_display_pipe *pipe) 1445{ 1446 struct drm_crtc *crtc = &pipe->crtc; 1447 struct drm_device *drm = crtc->dev; 1448 struct mcde *mcde = to_mcde(drm); 1449 u32 val; 1450 1451 /* Enable all VBLANK IRQs */ 1452 val = MCDE_PP_VCMPA | 1453 MCDE_PP_VCMPB | 1454 MCDE_PP_VSCC0 | 1455 MCDE_PP_VSCC1 | 1456 MCDE_PP_VCMPC0 | 1457 MCDE_PP_VCMPC1; 1458 writel(val, mcde->regs + MCDE_IMSCPP); 1459 1460 return 0; 1461} 1462 1463static void mcde_display_disable_vblank(struct drm_simple_display_pipe *pipe) 1464{ 1465 struct drm_crtc *crtc = &pipe->crtc; 1466 struct drm_device *drm = crtc->dev; 1467 struct mcde *mcde = to_mcde(drm); 1468 1469 /* Disable all VBLANK IRQs */ 1470 writel(0, mcde->regs + MCDE_IMSCPP); 1471 /* Clear any pending IRQs */ 1472 writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP); 1473} 1474 1475static struct drm_simple_display_pipe_funcs mcde_display_funcs = { 1476 .check = mcde_display_check, 1477 .enable = mcde_display_enable, 1478 .disable = mcde_display_disable, 1479 .update = mcde_display_update, 1480 .enable_vblank = mcde_display_enable_vblank, 1481 .disable_vblank = mcde_display_disable_vblank, 1482}; 1483 1484int mcde_display_init(struct drm_device *drm) 1485{ 1486 struct mcde *mcde = to_mcde(drm); 1487 int ret; 1488 static const u32 formats[] = { 1489 DRM_FORMAT_ARGB8888, 1490 DRM_FORMAT_ABGR8888, 1491 DRM_FORMAT_XRGB8888, 1492 DRM_FORMAT_XBGR8888, 1493 DRM_FORMAT_RGB888, 1494 DRM_FORMAT_BGR888, 1495 DRM_FORMAT_ARGB4444, 1496 DRM_FORMAT_ABGR4444, 1497 DRM_FORMAT_XRGB4444, 1498 DRM_FORMAT_XBGR4444, 1499 /* These are actually IRGB1555 so intensity bit is lost */ 1500 DRM_FORMAT_XRGB1555, 1501 DRM_FORMAT_XBGR1555, 1502 DRM_FORMAT_RGB565, 1503 DRM_FORMAT_BGR565, 1504 DRM_FORMAT_YUV422, 1505 }; 1506 1507 ret = mcde_init_clock_divider(mcde); 1508 if (ret) 1509 return ret; 1510 1511 ret = drm_simple_display_pipe_init(drm, &mcde->pipe, 1512 &mcde_display_funcs, 1513 formats, ARRAY_SIZE(formats), 1514 NULL, 1515 mcde->connector); 1516 if (ret) 1517 return ret; 1518 1519 return 0; 1520} 1521EXPORT_SYMBOL_GPL(mcde_display_init);