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 11 #include <drm/drm_device.h> 12 #include <drm/drm_fb_cma_helper.h> 13 #include <drm/drm_fourcc.h> 14 #include <drm/drm_gem_cma_helper.h> 15 #include <drm/drm_gem_framebuffer_helper.h> 16 #include <drm/drm_mipi_dsi.h> 17 #include <drm/drm_simple_kms_helper.h> 18 #include <drm/drm_vblank.h> 19 #include <video/mipi_display.h> 20 21 #include "mcde_drm.h" 22 #include "mcde_display_regs.h" 23 24 enum mcde_fifo { 25 MCDE_FIFO_A, 26 MCDE_FIFO_B, 27 /* TODO: implement FIFO C0 and FIFO C1 */ 28 }; 29 30 enum mcde_channel { 31 MCDE_CHANNEL_0 = 0, 32 MCDE_CHANNEL_1, 33 MCDE_CHANNEL_2, 34 MCDE_CHANNEL_3, 35 }; 36 37 enum mcde_extsrc { 38 MCDE_EXTSRC_0 = 0, 39 MCDE_EXTSRC_1, 40 MCDE_EXTSRC_2, 41 MCDE_EXTSRC_3, 42 MCDE_EXTSRC_4, 43 MCDE_EXTSRC_5, 44 MCDE_EXTSRC_6, 45 MCDE_EXTSRC_7, 46 MCDE_EXTSRC_8, 47 MCDE_EXTSRC_9, 48 }; 49 50 enum mcde_overlay { 51 MCDE_OVERLAY_0 = 0, 52 MCDE_OVERLAY_1, 53 MCDE_OVERLAY_2, 54 MCDE_OVERLAY_3, 55 MCDE_OVERLAY_4, 56 MCDE_OVERLAY_5, 57 }; 58 59 enum mcde_dsi_formatter { 60 MCDE_DSI_FORMATTER_0 = 0, 61 MCDE_DSI_FORMATTER_1, 62 MCDE_DSI_FORMATTER_2, 63 }; 64 65 void mcde_display_irq(struct mcde *mcde) 66 { 67 u32 mispp, misovl, mischnl; 68 bool vblank = false; 69 70 /* Handle display IRQs */ 71 mispp = readl(mcde->regs + MCDE_MISPP); 72 misovl = readl(mcde->regs + MCDE_MISOVL); 73 mischnl = readl(mcde->regs + MCDE_MISCHNL); 74 75 /* 76 * Handle IRQs from the DSI link. All IRQs from the DSI links 77 * are just latched onto the MCDE IRQ line, so we need to traverse 78 * any active DSI masters and check if an IRQ is originating from 79 * them. 80 * 81 * TODO: Currently only one DSI link is supported. 82 */ 83 if (mcde_dsi_irq(mcde->mdsi)) { 84 u32 val; 85 86 /* 87 * In oneshot mode we do not send continuous updates 88 * to the display, instead we only push out updates when 89 * the update function is called, then we disable the 90 * flow on the channel once we get the TE IRQ. 91 */ 92 if (mcde->oneshot_mode) { 93 spin_lock(&mcde->flow_lock); 94 if (--mcde->flow_active == 0) { 95 dev_dbg(mcde->dev, "TE0 IRQ\n"); 96 /* Disable FIFO A flow */ 97 val = readl(mcde->regs + MCDE_CRA0); 98 val &= ~MCDE_CRX0_FLOEN; 99 writel(val, mcde->regs + MCDE_CRA0); 100 } 101 spin_unlock(&mcde->flow_lock); 102 } 103 } 104 105 /* Vblank from one of the channels */ 106 if (mispp & MCDE_PP_VCMPA) { 107 dev_dbg(mcde->dev, "chnl A vblank IRQ\n"); 108 vblank = true; 109 } 110 if (mispp & MCDE_PP_VCMPB) { 111 dev_dbg(mcde->dev, "chnl B vblank IRQ\n"); 112 vblank = true; 113 } 114 if (mispp & MCDE_PP_VCMPC0) 115 dev_dbg(mcde->dev, "chnl C0 vblank IRQ\n"); 116 if (mispp & MCDE_PP_VCMPC1) 117 dev_dbg(mcde->dev, "chnl C1 vblank IRQ\n"); 118 if (mispp & MCDE_PP_VSCC0) 119 dev_dbg(mcde->dev, "chnl C0 TE IRQ\n"); 120 if (mispp & MCDE_PP_VSCC1) 121 dev_dbg(mcde->dev, "chnl C1 TE IRQ\n"); 122 writel(mispp, mcde->regs + MCDE_RISPP); 123 124 if (vblank) 125 drm_crtc_handle_vblank(&mcde->pipe.crtc); 126 127 if (misovl) 128 dev_info(mcde->dev, "some stray overlay IRQ %08x\n", misovl); 129 writel(misovl, mcde->regs + MCDE_RISOVL); 130 131 if (mischnl) 132 dev_info(mcde->dev, "some stray channel error IRQ %08x\n", 133 mischnl); 134 writel(mischnl, mcde->regs + MCDE_RISCHNL); 135 } 136 137 void mcde_display_disable_irqs(struct mcde *mcde) 138 { 139 /* Disable all IRQs */ 140 writel(0, mcde->regs + MCDE_IMSCPP); 141 writel(0, mcde->regs + MCDE_IMSCOVL); 142 writel(0, mcde->regs + MCDE_IMSCCHNL); 143 144 /* Clear any pending IRQs */ 145 writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP); 146 writel(0xFFFFFFFF, mcde->regs + MCDE_RISOVL); 147 writel(0xFFFFFFFF, mcde->regs + MCDE_RISCHNL); 148 } 149 150 static int mcde_display_check(struct drm_simple_display_pipe *pipe, 151 struct drm_plane_state *pstate, 152 struct drm_crtc_state *cstate) 153 { 154 const struct drm_display_mode *mode = &cstate->mode; 155 struct drm_framebuffer *old_fb = pipe->plane.state->fb; 156 struct drm_framebuffer *fb = pstate->fb; 157 158 if (fb) { 159 u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0); 160 161 /* FB base address must be dword aligned. */ 162 if (offset & 3) { 163 DRM_DEBUG_KMS("FB not 32-bit aligned\n"); 164 return -EINVAL; 165 } 166 167 /* 168 * There's no pitch register, the mode's hdisplay 169 * controls this. 170 */ 171 if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) { 172 DRM_DEBUG_KMS("can't handle pitches\n"); 173 return -EINVAL; 174 } 175 176 /* 177 * We can't change the FB format in a flicker-free 178 * manner (and only update it during CRTC enable). 179 */ 180 if (old_fb && old_fb->format != fb->format) 181 cstate->mode_changed = true; 182 } 183 184 return 0; 185 } 186 187 static int mcde_configure_extsrc(struct mcde *mcde, enum mcde_extsrc src, 188 u32 format) 189 { 190 u32 val; 191 u32 conf; 192 u32 cr; 193 194 switch (src) { 195 case MCDE_EXTSRC_0: 196 conf = MCDE_EXTSRC0CONF; 197 cr = MCDE_EXTSRC0CR; 198 break; 199 case MCDE_EXTSRC_1: 200 conf = MCDE_EXTSRC1CONF; 201 cr = MCDE_EXTSRC1CR; 202 break; 203 case MCDE_EXTSRC_2: 204 conf = MCDE_EXTSRC2CONF; 205 cr = MCDE_EXTSRC2CR; 206 break; 207 case MCDE_EXTSRC_3: 208 conf = MCDE_EXTSRC3CONF; 209 cr = MCDE_EXTSRC3CR; 210 break; 211 case MCDE_EXTSRC_4: 212 conf = MCDE_EXTSRC4CONF; 213 cr = MCDE_EXTSRC4CR; 214 break; 215 case MCDE_EXTSRC_5: 216 conf = MCDE_EXTSRC5CONF; 217 cr = MCDE_EXTSRC5CR; 218 break; 219 case MCDE_EXTSRC_6: 220 conf = MCDE_EXTSRC6CONF; 221 cr = MCDE_EXTSRC6CR; 222 break; 223 case MCDE_EXTSRC_7: 224 conf = MCDE_EXTSRC7CONF; 225 cr = MCDE_EXTSRC7CR; 226 break; 227 case MCDE_EXTSRC_8: 228 conf = MCDE_EXTSRC8CONF; 229 cr = MCDE_EXTSRC8CR; 230 break; 231 case MCDE_EXTSRC_9: 232 conf = MCDE_EXTSRC9CONF; 233 cr = MCDE_EXTSRC9CR; 234 break; 235 } 236 237 /* 238 * Configure external source 0 one buffer (buffer 0) 239 * primary overlay ID 0. 240 * From mcde_hw.c ovly_update_registers() in the vendor tree 241 */ 242 val = 0 << MCDE_EXTSRCXCONF_BUF_ID_SHIFT; 243 val |= 1 << MCDE_EXTSRCXCONF_BUF_NB_SHIFT; 244 val |= 0 << MCDE_EXTSRCXCONF_PRI_OVLID_SHIFT; 245 /* 246 * MCDE has inverse semantics from DRM on RBG/BGR which is why 247 * all the modes are inversed here. 248 */ 249 switch (format) { 250 case DRM_FORMAT_ARGB8888: 251 val |= MCDE_EXTSRCXCONF_BPP_ARGB8888 << 252 MCDE_EXTSRCXCONF_BPP_SHIFT; 253 val |= MCDE_EXTSRCXCONF_BGR; 254 break; 255 case DRM_FORMAT_ABGR8888: 256 val |= MCDE_EXTSRCXCONF_BPP_ARGB8888 << 257 MCDE_EXTSRCXCONF_BPP_SHIFT; 258 break; 259 case DRM_FORMAT_XRGB8888: 260 val |= MCDE_EXTSRCXCONF_BPP_XRGB8888 << 261 MCDE_EXTSRCXCONF_BPP_SHIFT; 262 val |= MCDE_EXTSRCXCONF_BGR; 263 break; 264 case DRM_FORMAT_XBGR8888: 265 val |= MCDE_EXTSRCXCONF_BPP_XRGB8888 << 266 MCDE_EXTSRCXCONF_BPP_SHIFT; 267 break; 268 case DRM_FORMAT_RGB888: 269 val |= MCDE_EXTSRCXCONF_BPP_RGB888 << 270 MCDE_EXTSRCXCONF_BPP_SHIFT; 271 val |= MCDE_EXTSRCXCONF_BGR; 272 break; 273 case DRM_FORMAT_BGR888: 274 val |= MCDE_EXTSRCXCONF_BPP_RGB888 << 275 MCDE_EXTSRCXCONF_BPP_SHIFT; 276 break; 277 case DRM_FORMAT_ARGB4444: 278 val |= MCDE_EXTSRCXCONF_BPP_ARGB4444 << 279 MCDE_EXTSRCXCONF_BPP_SHIFT; 280 val |= MCDE_EXTSRCXCONF_BGR; 281 break; 282 case DRM_FORMAT_ABGR4444: 283 val |= MCDE_EXTSRCXCONF_BPP_ARGB4444 << 284 MCDE_EXTSRCXCONF_BPP_SHIFT; 285 break; 286 case DRM_FORMAT_XRGB4444: 287 val |= MCDE_EXTSRCXCONF_BPP_RGB444 << 288 MCDE_EXTSRCXCONF_BPP_SHIFT; 289 val |= MCDE_EXTSRCXCONF_BGR; 290 break; 291 case DRM_FORMAT_XBGR4444: 292 val |= MCDE_EXTSRCXCONF_BPP_RGB444 << 293 MCDE_EXTSRCXCONF_BPP_SHIFT; 294 break; 295 case DRM_FORMAT_XRGB1555: 296 val |= MCDE_EXTSRCXCONF_BPP_IRGB1555 << 297 MCDE_EXTSRCXCONF_BPP_SHIFT; 298 val |= MCDE_EXTSRCXCONF_BGR; 299 break; 300 case DRM_FORMAT_XBGR1555: 301 val |= MCDE_EXTSRCXCONF_BPP_IRGB1555 << 302 MCDE_EXTSRCXCONF_BPP_SHIFT; 303 break; 304 case DRM_FORMAT_RGB565: 305 val |= MCDE_EXTSRCXCONF_BPP_RGB565 << 306 MCDE_EXTSRCXCONF_BPP_SHIFT; 307 val |= MCDE_EXTSRCXCONF_BGR; 308 break; 309 case DRM_FORMAT_BGR565: 310 val |= MCDE_EXTSRCXCONF_BPP_RGB565 << 311 MCDE_EXTSRCXCONF_BPP_SHIFT; 312 break; 313 case DRM_FORMAT_YUV422: 314 val |= MCDE_EXTSRCXCONF_BPP_YCBCR422 << 315 MCDE_EXTSRCXCONF_BPP_SHIFT; 316 break; 317 default: 318 dev_err(mcde->dev, "Unknown pixel format 0x%08x\n", 319 format); 320 return -EINVAL; 321 } 322 writel(val, mcde->regs + conf); 323 324 /* Software select, primary */ 325 val = MCDE_EXTSRCXCR_SEL_MOD_SOFTWARE_SEL; 326 val |= MCDE_EXTSRCXCR_MULTIOVL_CTRL_PRIMARY; 327 writel(val, mcde->regs + cr); 328 329 return 0; 330 } 331 332 static void mcde_configure_overlay(struct mcde *mcde, enum mcde_overlay ovl, 333 enum mcde_extsrc src, 334 enum mcde_channel ch, 335 const struct drm_display_mode *mode, 336 u32 format) 337 { 338 u32 val; 339 u32 conf1; 340 u32 conf2; 341 u32 crop; 342 u32 ljinc; 343 u32 cr; 344 u32 comp; 345 346 switch (ovl) { 347 case MCDE_OVERLAY_0: 348 conf1 = MCDE_OVL0CONF; 349 conf2 = MCDE_OVL0CONF2; 350 crop = MCDE_OVL0CROP; 351 ljinc = MCDE_OVL0LJINC; 352 cr = MCDE_OVL0CR; 353 comp = MCDE_OVL0COMP; 354 break; 355 case MCDE_OVERLAY_1: 356 conf1 = MCDE_OVL1CONF; 357 conf2 = MCDE_OVL1CONF2; 358 crop = MCDE_OVL1CROP; 359 ljinc = MCDE_OVL1LJINC; 360 cr = MCDE_OVL1CR; 361 comp = MCDE_OVL1COMP; 362 break; 363 case MCDE_OVERLAY_2: 364 conf1 = MCDE_OVL2CONF; 365 conf2 = MCDE_OVL2CONF2; 366 crop = MCDE_OVL2CROP; 367 ljinc = MCDE_OVL2LJINC; 368 cr = MCDE_OVL2CR; 369 comp = MCDE_OVL2COMP; 370 break; 371 case MCDE_OVERLAY_3: 372 conf1 = MCDE_OVL3CONF; 373 conf2 = MCDE_OVL3CONF2; 374 crop = MCDE_OVL3CROP; 375 ljinc = MCDE_OVL3LJINC; 376 cr = MCDE_OVL3CR; 377 comp = MCDE_OVL3COMP; 378 break; 379 case MCDE_OVERLAY_4: 380 conf1 = MCDE_OVL4CONF; 381 conf2 = MCDE_OVL4CONF2; 382 crop = MCDE_OVL4CROP; 383 ljinc = MCDE_OVL4LJINC; 384 cr = MCDE_OVL4CR; 385 comp = MCDE_OVL4COMP; 386 break; 387 case MCDE_OVERLAY_5: 388 conf1 = MCDE_OVL5CONF; 389 conf2 = MCDE_OVL5CONF2; 390 crop = MCDE_OVL5CROP; 391 ljinc = MCDE_OVL5LJINC; 392 cr = MCDE_OVL5CR; 393 comp = MCDE_OVL5COMP; 394 break; 395 } 396 397 val = mode->hdisplay << MCDE_OVLXCONF_PPL_SHIFT; 398 val |= mode->vdisplay << MCDE_OVLXCONF_LPF_SHIFT; 399 /* Use external source 0 that we just configured */ 400 val |= src << MCDE_OVLXCONF_EXTSRC_ID_SHIFT; 401 writel(val, mcde->regs + conf1); 402 403 val = MCDE_OVLXCONF2_BP_PER_PIXEL_ALPHA; 404 val |= 0xff << MCDE_OVLXCONF2_ALPHAVALUE_SHIFT; 405 /* OPQ: overlay is opaque */ 406 switch (format) { 407 case DRM_FORMAT_ARGB8888: 408 case DRM_FORMAT_ABGR8888: 409 case DRM_FORMAT_ARGB4444: 410 case DRM_FORMAT_ABGR4444: 411 case DRM_FORMAT_XRGB1555: 412 case DRM_FORMAT_XBGR1555: 413 /* No OPQ */ 414 break; 415 case DRM_FORMAT_XRGB8888: 416 case DRM_FORMAT_XBGR8888: 417 case DRM_FORMAT_RGB888: 418 case DRM_FORMAT_BGR888: 419 case DRM_FORMAT_RGB565: 420 case DRM_FORMAT_BGR565: 421 case DRM_FORMAT_YUV422: 422 val |= MCDE_OVLXCONF2_OPQ; 423 break; 424 default: 425 dev_err(mcde->dev, "Unknown pixel format 0x%08x\n", 426 format); 427 break; 428 } 429 /* The default watermark level for overlay 0 is 48 */ 430 val |= 48 << MCDE_OVLXCONF2_PIXELFETCHERWATERMARKLEVEL_SHIFT; 431 writel(val, mcde->regs + conf2); 432 433 /* Number of bytes to fetch per line */ 434 writel(mcde->stride, mcde->regs + ljinc); 435 /* No cropping */ 436 writel(0, mcde->regs + crop); 437 438 /* Set up overlay control register */ 439 val = MCDE_OVLXCR_OVLEN; 440 val |= MCDE_OVLXCR_COLCCTRL_DISABLED; 441 val |= MCDE_OVLXCR_BURSTSIZE_8W << 442 MCDE_OVLXCR_BURSTSIZE_SHIFT; 443 val |= MCDE_OVLXCR_MAXOUTSTANDING_8_REQ << 444 MCDE_OVLXCR_MAXOUTSTANDING_SHIFT; 445 /* Not using rotation but set it up anyways */ 446 val |= MCDE_OVLXCR_ROTBURSTSIZE_8W << 447 MCDE_OVLXCR_ROTBURSTSIZE_SHIFT; 448 writel(val, mcde->regs + cr); 449 450 /* 451 * Set up the overlay compositor to route the overlay out to 452 * the desired channel 453 */ 454 val = ch << MCDE_OVLXCOMP_CH_ID_SHIFT; 455 writel(val, mcde->regs + comp); 456 } 457 458 static void mcde_configure_channel(struct mcde *mcde, enum mcde_channel ch, 459 enum mcde_fifo fifo, 460 const struct drm_display_mode *mode) 461 { 462 u32 val; 463 u32 conf; 464 u32 sync; 465 u32 stat; 466 u32 bgcol; 467 u32 mux; 468 469 switch (ch) { 470 case MCDE_CHANNEL_0: 471 conf = MCDE_CHNL0CONF; 472 sync = MCDE_CHNL0SYNCHMOD; 473 stat = MCDE_CHNL0STAT; 474 bgcol = MCDE_CHNL0BCKGNDCOL; 475 mux = MCDE_CHNL0MUXING; 476 break; 477 case MCDE_CHANNEL_1: 478 conf = MCDE_CHNL1CONF; 479 sync = MCDE_CHNL1SYNCHMOD; 480 stat = MCDE_CHNL1STAT; 481 bgcol = MCDE_CHNL1BCKGNDCOL; 482 mux = MCDE_CHNL1MUXING; 483 break; 484 case MCDE_CHANNEL_2: 485 conf = MCDE_CHNL2CONF; 486 sync = MCDE_CHNL2SYNCHMOD; 487 stat = MCDE_CHNL2STAT; 488 bgcol = MCDE_CHNL2BCKGNDCOL; 489 mux = MCDE_CHNL2MUXING; 490 break; 491 case MCDE_CHANNEL_3: 492 conf = MCDE_CHNL3CONF; 493 sync = MCDE_CHNL3SYNCHMOD; 494 stat = MCDE_CHNL3STAT; 495 bgcol = MCDE_CHNL3BCKGNDCOL; 496 mux = MCDE_CHNL3MUXING; 497 return; 498 } 499 500 /* Set up channel 0 sync (based on chnl_update_registers()) */ 501 if (mcde->te_sync) { 502 /* 503 * Turn on hardware TE0 synchronization 504 */ 505 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE 506 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT; 507 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0 508 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT; 509 } else { 510 /* 511 * Set up sync source to software, out sync formatter 512 * Code mostly from mcde_hw.c chnl_update_registers() 513 */ 514 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SOFTWARE 515 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT; 516 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER 517 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT; 518 } 519 writel(val, mcde->regs + sync); 520 521 /* Set up pixels per line and lines per frame */ 522 val = (mode->hdisplay - 1) << MCDE_CHNLXCONF_PPL_SHIFT; 523 val |= (mode->vdisplay - 1) << MCDE_CHNLXCONF_LPF_SHIFT; 524 writel(val, mcde->regs + conf); 525 526 /* 527 * Normalize color conversion: 528 * black background, OLED conversion disable on channel 529 */ 530 val = MCDE_CHNLXSTAT_CHNLBLBCKGND_EN | 531 MCDE_CHNLXSTAT_CHNLRD; 532 writel(val, mcde->regs + stat); 533 writel(0, mcde->regs + bgcol); 534 535 /* Set up muxing: connect the channel to the desired FIFO */ 536 switch (fifo) { 537 case MCDE_FIFO_A: 538 writel(MCDE_CHNLXMUXING_FIFO_ID_FIFO_A, 539 mcde->regs + mux); 540 break; 541 case MCDE_FIFO_B: 542 writel(MCDE_CHNLXMUXING_FIFO_ID_FIFO_B, 543 mcde->regs + mux); 544 break; 545 } 546 } 547 548 static void mcde_configure_fifo(struct mcde *mcde, enum mcde_fifo fifo, 549 enum mcde_dsi_formatter fmt, 550 int fifo_wtrmrk) 551 { 552 u32 val; 553 u32 ctrl; 554 u32 cr0, cr1; 555 556 switch (fifo) { 557 case MCDE_FIFO_A: 558 ctrl = MCDE_CTRLA; 559 cr0 = MCDE_CRA0; 560 cr1 = MCDE_CRA1; 561 break; 562 case MCDE_FIFO_B: 563 ctrl = MCDE_CTRLB; 564 cr0 = MCDE_CRB0; 565 cr1 = MCDE_CRB1; 566 break; 567 } 568 569 val = fifo_wtrmrk << MCDE_CTRLX_FIFOWTRMRK_SHIFT; 570 /* We only support DSI formatting for now */ 571 val |= MCDE_CTRLX_FORMTYPE_DSI << 572 MCDE_CTRLX_FORMTYPE_SHIFT; 573 574 /* Select the formatter to use for this FIFO */ 575 val |= fmt << MCDE_CTRLX_FORMID_SHIFT; 576 writel(val, mcde->regs + ctrl); 577 578 /* Blend source with Alpha 0xff on FIFO */ 579 val = MCDE_CRX0_BLENDEN | 580 0xff << MCDE_CRX0_ALPHABLEND_SHIFT; 581 writel(val, mcde->regs + cr0); 582 583 /* Set-up from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() */ 584 585 /* Use the MCDE clock for this FIFO */ 586 val = MCDE_CRX1_CLKSEL_MCDECLK << MCDE_CRX1_CLKSEL_SHIFT; 587 588 /* TODO: when adding DPI support add OUTBPP etc here */ 589 writel(val, mcde->regs + cr1); 590 }; 591 592 static void mcde_configure_dsi_formatter(struct mcde *mcde, 593 enum mcde_dsi_formatter fmt, 594 u32 formatter_frame, 595 int pkt_size) 596 { 597 u32 val; 598 u32 conf0; 599 u32 frame; 600 u32 pkt; 601 u32 sync; 602 u32 cmdw; 603 u32 delay0, delay1; 604 605 switch (fmt) { 606 case MCDE_DSI_FORMATTER_0: 607 conf0 = MCDE_DSIVID0CONF0; 608 frame = MCDE_DSIVID0FRAME; 609 pkt = MCDE_DSIVID0PKT; 610 sync = MCDE_DSIVID0SYNC; 611 cmdw = MCDE_DSIVID0CMDW; 612 delay0 = MCDE_DSIVID0DELAY0; 613 delay1 = MCDE_DSIVID0DELAY1; 614 break; 615 case MCDE_DSI_FORMATTER_1: 616 conf0 = MCDE_DSIVID1CONF0; 617 frame = MCDE_DSIVID1FRAME; 618 pkt = MCDE_DSIVID1PKT; 619 sync = MCDE_DSIVID1SYNC; 620 cmdw = MCDE_DSIVID1CMDW; 621 delay0 = MCDE_DSIVID1DELAY0; 622 delay1 = MCDE_DSIVID1DELAY1; 623 break; 624 case MCDE_DSI_FORMATTER_2: 625 conf0 = MCDE_DSIVID2CONF0; 626 frame = MCDE_DSIVID2FRAME; 627 pkt = MCDE_DSIVID2PKT; 628 sync = MCDE_DSIVID2SYNC; 629 cmdw = MCDE_DSIVID2CMDW; 630 delay0 = MCDE_DSIVID2DELAY0; 631 delay1 = MCDE_DSIVID2DELAY1; 632 break; 633 } 634 635 /* 636 * Enable formatter 637 * 8 bit commands and DCS commands (notgen = not generic) 638 */ 639 val = MCDE_DSICONF0_CMD8 | MCDE_DSICONF0_DCSVID_NOTGEN; 640 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) 641 val |= MCDE_DSICONF0_VID_MODE_VID; 642 switch (mcde->mdsi->format) { 643 case MIPI_DSI_FMT_RGB888: 644 val |= MCDE_DSICONF0_PACKING_RGB888 << 645 MCDE_DSICONF0_PACKING_SHIFT; 646 break; 647 case MIPI_DSI_FMT_RGB666: 648 val |= MCDE_DSICONF0_PACKING_RGB666 << 649 MCDE_DSICONF0_PACKING_SHIFT; 650 break; 651 case MIPI_DSI_FMT_RGB666_PACKED: 652 val |= MCDE_DSICONF0_PACKING_RGB666_PACKED << 653 MCDE_DSICONF0_PACKING_SHIFT; 654 break; 655 case MIPI_DSI_FMT_RGB565: 656 val |= MCDE_DSICONF0_PACKING_RGB565 << 657 MCDE_DSICONF0_PACKING_SHIFT; 658 break; 659 default: 660 dev_err(mcde->dev, "unknown DSI format\n"); 661 return; 662 } 663 writel(val, mcde->regs + conf0); 664 665 writel(formatter_frame, mcde->regs + frame); 666 writel(pkt_size, mcde->regs + pkt); 667 writel(0, mcde->regs + sync); 668 /* Define the MIPI command: we want to write into display memory */ 669 val = MIPI_DCS_WRITE_MEMORY_CONTINUE << 670 MCDE_DSIVIDXCMDW_CMDW_CONTINUE_SHIFT; 671 val |= MIPI_DCS_WRITE_MEMORY_START << 672 MCDE_DSIVIDXCMDW_CMDW_START_SHIFT; 673 writel(val, mcde->regs + cmdw); 674 675 /* 676 * FIXME: the vendor driver has some hack around this value in 677 * CMD mode with autotrig. 678 */ 679 writel(0, mcde->regs + delay0); 680 writel(0, mcde->regs + delay1); 681 } 682 683 static void mcde_enable_fifo(struct mcde *mcde, enum mcde_fifo fifo) 684 { 685 u32 val; 686 u32 cr; 687 688 switch (fifo) { 689 case MCDE_FIFO_A: 690 cr = MCDE_CRA0; 691 break; 692 case MCDE_FIFO_B: 693 cr = MCDE_CRB0; 694 break; 695 default: 696 dev_err(mcde->dev, "cannot enable FIFO %c\n", 697 'A' + fifo); 698 return; 699 } 700 701 spin_lock(&mcde->flow_lock); 702 val = readl(mcde->regs + cr); 703 val |= MCDE_CRX0_FLOEN; 704 writel(val, mcde->regs + cr); 705 mcde->flow_active++; 706 spin_unlock(&mcde->flow_lock); 707 } 708 709 static void mcde_disable_fifo(struct mcde *mcde, enum mcde_fifo fifo, 710 bool wait_for_drain) 711 { 712 int timeout = 100; 713 u32 val; 714 u32 cr; 715 716 switch (fifo) { 717 case MCDE_FIFO_A: 718 cr = MCDE_CRA0; 719 break; 720 case MCDE_FIFO_B: 721 cr = MCDE_CRB0; 722 break; 723 default: 724 dev_err(mcde->dev, "cannot disable FIFO %c\n", 725 'A' + fifo); 726 return; 727 } 728 729 spin_lock(&mcde->flow_lock); 730 val = readl(mcde->regs + cr); 731 val &= ~MCDE_CRX0_FLOEN; 732 writel(val, mcde->regs + cr); 733 mcde->flow_active = 0; 734 spin_unlock(&mcde->flow_lock); 735 736 if (!wait_for_drain) 737 return; 738 739 /* Check that we really drained and stopped the flow */ 740 while (readl(mcde->regs + cr) & MCDE_CRX0_FLOEN) { 741 usleep_range(1000, 1500); 742 if (!--timeout) { 743 dev_err(mcde->dev, 744 "FIFO timeout while clearing FIFO %c\n", 745 'A' + fifo); 746 return; 747 } 748 } 749 } 750 751 /* 752 * This drains a pipe i.e. a FIFO connected to a certain channel 753 */ 754 static void mcde_drain_pipe(struct mcde *mcde, enum mcde_fifo fifo, 755 enum mcde_channel ch) 756 { 757 u32 val; 758 u32 ctrl; 759 u32 synsw; 760 761 switch (fifo) { 762 case MCDE_FIFO_A: 763 ctrl = MCDE_CTRLA; 764 break; 765 case MCDE_FIFO_B: 766 ctrl = MCDE_CTRLB; 767 break; 768 } 769 770 switch (ch) { 771 case MCDE_CHANNEL_0: 772 synsw = MCDE_CHNL0SYNCHSW; 773 break; 774 case MCDE_CHANNEL_1: 775 synsw = MCDE_CHNL1SYNCHSW; 776 break; 777 case MCDE_CHANNEL_2: 778 synsw = MCDE_CHNL2SYNCHSW; 779 break; 780 case MCDE_CHANNEL_3: 781 synsw = MCDE_CHNL3SYNCHSW; 782 return; 783 } 784 785 val = readl(mcde->regs + ctrl); 786 if (!(val & MCDE_CTRLX_FIFOEMPTY)) { 787 dev_err(mcde->dev, "Channel A FIFO not empty (handover)\n"); 788 /* Attempt to clear the FIFO */ 789 mcde_enable_fifo(mcde, fifo); 790 /* Trigger a software sync out on respective channel (0-3) */ 791 writel(MCDE_CHNLXSYNCHSW_SW_TRIG, mcde->regs + synsw); 792 /* Disable FIFO A flow again */ 793 mcde_disable_fifo(mcde, fifo, true); 794 } 795 } 796 797 static int mcde_dsi_get_pkt_div(int ppl, int fifo_size) 798 { 799 /* 800 * DSI command mode line packets should be split into an even number of 801 * packets smaller than or equal to the fifo size. 802 */ 803 int div; 804 const int max_div = DIV_ROUND_UP(MCDE_MAX_WIDTH, fifo_size); 805 806 for (div = 1; div < max_div; div++) 807 if (ppl % div == 0 && ppl / div <= fifo_size) 808 return div; 809 return 1; 810 } 811 812 static void mcde_display_enable(struct drm_simple_display_pipe *pipe, 813 struct drm_crtc_state *cstate, 814 struct drm_plane_state *plane_state) 815 { 816 struct drm_crtc *crtc = &pipe->crtc; 817 struct drm_plane *plane = &pipe->plane; 818 struct drm_device *drm = crtc->dev; 819 struct mcde *mcde = drm->dev_private; 820 const struct drm_display_mode *mode = &cstate->mode; 821 struct drm_framebuffer *fb = plane->state->fb; 822 u32 format = fb->format->format; 823 u32 formatter_ppl = mode->hdisplay; /* pixels per line */ 824 u32 formatter_lpf = mode->vdisplay; /* lines per frame */ 825 int pkt_size, fifo_wtrmrk; 826 int cpp = fb->format->cpp[0]; 827 int formatter_cpp; 828 struct drm_format_name_buf tmp; 829 u32 formatter_frame; 830 u32 pkt_div; 831 u32 val; 832 833 dev_info(drm->dev, "enable MCDE, %d x %d format %s\n", 834 mode->hdisplay, mode->vdisplay, 835 drm_get_format_name(format, &tmp)); 836 if (!mcde->mdsi) { 837 /* TODO: deal with this for non-DSI output */ 838 dev_err(drm->dev, "no DSI master attached!\n"); 839 return; 840 } 841 842 dev_info(drm->dev, "output in %s mode, format %dbpp\n", 843 (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? 844 "VIDEO" : "CMD", 845 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format)); 846 formatter_cpp = 847 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format) / 8; 848 dev_info(drm->dev, "overlay CPP %d bytes, DSI CPP %d bytes\n", 849 cpp, 850 formatter_cpp); 851 852 /* Calculations from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() */ 853 854 /* 855 * Set up FIFO A watermark level: 856 * 128 for LCD 32bpp video mode 857 * 48 for LCD 32bpp command mode 858 * 128 for LCD 16bpp video mode 859 * 64 for LCD 16bpp command mode 860 * 128 for HDMI 32bpp 861 * 192 for HDMI 16bpp 862 */ 863 fifo_wtrmrk = mode->hdisplay; 864 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) { 865 fifo_wtrmrk = min(fifo_wtrmrk, 128); 866 pkt_div = 1; 867 } else { 868 fifo_wtrmrk = min(fifo_wtrmrk, 48); 869 /* The FIFO is 640 entries deep on this v3 hardware */ 870 pkt_div = mcde_dsi_get_pkt_div(mode->hdisplay, 640); 871 } 872 dev_dbg(drm->dev, "FIFO watermark after flooring: %d bytes\n", 873 fifo_wtrmrk); 874 dev_dbg(drm->dev, "Packet divisor: %d bytes\n", pkt_div); 875 876 /* NOTE: pkt_div is 1 for video mode */ 877 pkt_size = (formatter_ppl * formatter_cpp) / pkt_div; 878 /* Commands CMD8 need one extra byte */ 879 if (!(mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO)) 880 pkt_size++; 881 882 dev_dbg(drm->dev, "DSI packet size: %d * %d bytes per line\n", 883 pkt_size, pkt_div); 884 dev_dbg(drm->dev, "Overlay frame size: %u bytes\n", 885 mode->hdisplay * mode->vdisplay * cpp); 886 mcde->stride = mode->hdisplay * cpp; 887 dev_dbg(drm->dev, "Overlay line stride: %u bytes\n", 888 mcde->stride); 889 /* NOTE: pkt_div is 1 for video mode */ 890 formatter_frame = pkt_size * pkt_div * formatter_lpf; 891 dev_dbg(drm->dev, "Formatter frame size: %u bytes\n", formatter_frame); 892 893 /* Drain the FIFO A + channel 0 pipe so we have a clean slate */ 894 mcde_drain_pipe(mcde, MCDE_FIFO_A, MCDE_CHANNEL_0); 895 896 /* 897 * We set up our display pipeline: 898 * EXTSRC 0 -> OVERLAY 0 -> CHANNEL 0 -> FIFO A -> DSI FORMATTER 0 899 * 900 * First configure the external source (memory) on external source 0 901 * using the desired bitstream/bitmap format 902 */ 903 mcde_configure_extsrc(mcde, MCDE_EXTSRC_0, format); 904 905 /* 906 * Configure overlay 0 according to format and mode and take input 907 * from external source 0 and route the output of this overlay to 908 * channel 0 909 */ 910 mcde_configure_overlay(mcde, MCDE_OVERLAY_0, MCDE_EXTSRC_0, 911 MCDE_CHANNEL_0, mode, format); 912 913 /* 914 * Configure pixel-per-line and line-per-frame for channel 0 and then 915 * route channel 0 to FIFO A 916 */ 917 mcde_configure_channel(mcde, MCDE_CHANNEL_0, MCDE_FIFO_A, mode); 918 919 /* Configure FIFO A to use DSI formatter 0 */ 920 mcde_configure_fifo(mcde, MCDE_FIFO_A, MCDE_DSI_FORMATTER_0, 921 fifo_wtrmrk); 922 923 /* Configure the DSI formatter 0 for the DSI panel output */ 924 mcde_configure_dsi_formatter(mcde, MCDE_DSI_FORMATTER_0, 925 formatter_frame, pkt_size); 926 927 if (mcde->te_sync) { 928 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 929 val = MCDE_VSCRC_VSPOL; 930 else 931 val = 0; 932 writel(val, mcde->regs + MCDE_VSCRC0); 933 /* Enable VSYNC capture on TE0 */ 934 val = readl(mcde->regs + MCDE_CRC); 935 val |= MCDE_CRC_SYCEN0; 936 writel(val, mcde->regs + MCDE_CRC); 937 938 drm_crtc_vblank_on(crtc); 939 } 940 941 dev_info(drm->dev, "MCDE display is enabled\n"); 942 } 943 944 static void mcde_display_disable(struct drm_simple_display_pipe *pipe) 945 { 946 struct drm_crtc *crtc = &pipe->crtc; 947 struct drm_device *drm = crtc->dev; 948 struct mcde *mcde = drm->dev_private; 949 950 if (mcde->te_sync) 951 drm_crtc_vblank_off(crtc); 952 953 /* Disable FIFO A flow */ 954 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); 955 956 dev_info(drm->dev, "MCDE display is disabled\n"); 957 } 958 959 static void mcde_display_send_one_frame(struct mcde *mcde) 960 { 961 /* Request a TE ACK */ 962 if (mcde->te_sync) 963 mcde_dsi_te_request(mcde->mdsi); 964 965 /* Enable FIFO A flow */ 966 mcde_enable_fifo(mcde, MCDE_FIFO_A); 967 968 if (mcde->te_sync) { 969 /* 970 * If oneshot mode is enabled, the flow will be disabled 971 * when the TE0 IRQ arrives in the interrupt handler. Otherwise 972 * updates are continuously streamed to the display after this 973 * point. 974 */ 975 dev_dbg(mcde->dev, "sent TE0 framebuffer update\n"); 976 return; 977 } 978 979 /* Trigger a software sync out on channel 0 */ 980 writel(MCDE_CHNLXSYNCHSW_SW_TRIG, 981 mcde->regs + MCDE_CHNL0SYNCHSW); 982 983 /* 984 * Disable FIFO A flow again: since we are using TE sync we 985 * need to wait for the FIFO to drain before we continue 986 * so repeated calls to this function will not cause a mess 987 * in the hardware by pushing updates will updates are going 988 * on already. 989 */ 990 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); 991 992 dev_dbg(mcde->dev, "sent SW framebuffer update\n"); 993 } 994 995 static void mcde_set_extsrc(struct mcde *mcde, u32 buffer_address) 996 { 997 /* Write bitmap base address to register */ 998 writel(buffer_address, mcde->regs + MCDE_EXTSRCXA0); 999 /* 1000 * Base address for next line this is probably only used 1001 * in interlace modes. 1002 */ 1003 writel(buffer_address + mcde->stride, mcde->regs + MCDE_EXTSRCXA1); 1004 } 1005 1006 static void mcde_display_update(struct drm_simple_display_pipe *pipe, 1007 struct drm_plane_state *old_pstate) 1008 { 1009 struct drm_crtc *crtc = &pipe->crtc; 1010 struct drm_device *drm = crtc->dev; 1011 struct mcde *mcde = drm->dev_private; 1012 struct drm_pending_vblank_event *event = crtc->state->event; 1013 struct drm_plane *plane = &pipe->plane; 1014 struct drm_plane_state *pstate = plane->state; 1015 struct drm_framebuffer *fb = pstate->fb; 1016 1017 /* 1018 * Handle any pending event first, we need to arm the vblank 1019 * interrupt before sending any update to the display so we don't 1020 * miss the interrupt. 1021 */ 1022 if (event) { 1023 crtc->state->event = NULL; 1024 1025 spin_lock_irq(&crtc->dev->event_lock); 1026 /* 1027 * Hardware must be on before we can arm any vblank event, 1028 * this is not a scanout controller where there is always 1029 * some periodic update going on, it is completely frozen 1030 * until we get an update. If MCDE output isn't yet enabled, 1031 * we just send a vblank dummy event back. 1032 */ 1033 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0) { 1034 dev_dbg(mcde->dev, "arm vblank event\n"); 1035 drm_crtc_arm_vblank_event(crtc, event); 1036 } else { 1037 dev_dbg(mcde->dev, "insert fake vblank event\n"); 1038 drm_crtc_send_vblank_event(crtc, event); 1039 } 1040 1041 spin_unlock_irq(&crtc->dev->event_lock); 1042 } 1043 1044 /* 1045 * We do not start sending framebuffer updates before the 1046 * display is enabled. Update events will however be dispatched 1047 * from the DRM core before the display is enabled. 1048 */ 1049 if (fb) { 1050 mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0)); 1051 /* Send a single frame using software sync */ 1052 mcde_display_send_one_frame(mcde); 1053 dev_info_once(mcde->dev, "sent first display update\n"); 1054 } else { 1055 /* 1056 * If an update is receieved before the MCDE is enabled 1057 * (before mcde_display_enable() is called) we can't really 1058 * do much with that buffer. 1059 */ 1060 dev_info(mcde->dev, "ignored a display update\n"); 1061 } 1062 } 1063 1064 static int mcde_display_enable_vblank(struct drm_simple_display_pipe *pipe) 1065 { 1066 struct drm_crtc *crtc = &pipe->crtc; 1067 struct drm_device *drm = crtc->dev; 1068 struct mcde *mcde = drm->dev_private; 1069 u32 val; 1070 1071 /* Enable all VBLANK IRQs */ 1072 val = MCDE_PP_VCMPA | 1073 MCDE_PP_VCMPB | 1074 MCDE_PP_VSCC0 | 1075 MCDE_PP_VSCC1 | 1076 MCDE_PP_VCMPC0 | 1077 MCDE_PP_VCMPC1; 1078 writel(val, mcde->regs + MCDE_IMSCPP); 1079 1080 return 0; 1081 } 1082 1083 static void mcde_display_disable_vblank(struct drm_simple_display_pipe *pipe) 1084 { 1085 struct drm_crtc *crtc = &pipe->crtc; 1086 struct drm_device *drm = crtc->dev; 1087 struct mcde *mcde = drm->dev_private; 1088 1089 /* Disable all VBLANK IRQs */ 1090 writel(0, mcde->regs + MCDE_IMSCPP); 1091 /* Clear any pending IRQs */ 1092 writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP); 1093 } 1094 1095 static struct drm_simple_display_pipe_funcs mcde_display_funcs = { 1096 .check = mcde_display_check, 1097 .enable = mcde_display_enable, 1098 .disable = mcde_display_disable, 1099 .update = mcde_display_update, 1100 .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb, 1101 }; 1102 1103 int mcde_display_init(struct drm_device *drm) 1104 { 1105 struct mcde *mcde = drm->dev_private; 1106 int ret; 1107 static const u32 formats[] = { 1108 DRM_FORMAT_ARGB8888, 1109 DRM_FORMAT_ABGR8888, 1110 DRM_FORMAT_XRGB8888, 1111 DRM_FORMAT_XBGR8888, 1112 DRM_FORMAT_RGB888, 1113 DRM_FORMAT_BGR888, 1114 DRM_FORMAT_ARGB4444, 1115 DRM_FORMAT_ABGR4444, 1116 DRM_FORMAT_XRGB4444, 1117 DRM_FORMAT_XBGR4444, 1118 /* These are actually IRGB1555 so intensity bit is lost */ 1119 DRM_FORMAT_XRGB1555, 1120 DRM_FORMAT_XBGR1555, 1121 DRM_FORMAT_RGB565, 1122 DRM_FORMAT_BGR565, 1123 DRM_FORMAT_YUV422, 1124 }; 1125 1126 /* Provide vblank only when we have TE enabled */ 1127 if (mcde->te_sync) { 1128 mcde_display_funcs.enable_vblank = mcde_display_enable_vblank; 1129 mcde_display_funcs.disable_vblank = mcde_display_disable_vblank; 1130 } 1131 1132 ret = drm_simple_display_pipe_init(drm, &mcde->pipe, 1133 &mcde_display_funcs, 1134 formats, ARRAY_SIZE(formats), 1135 NULL, 1136 mcde->connector); 1137 if (ret) 1138 return ret; 1139 1140 return 0; 1141 } 1142 EXPORT_SYMBOL_GPL(mcde_display_init); 1143