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->video_mode || mcde->te_sync) 502 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE 503 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT; 504 else 505 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SOFTWARE 506 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT; 507 508 if (mcde->te_sync) 509 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0 510 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT; 511 else 512 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER 513 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT; 514 515 writel(val, mcde->regs + sync); 516 517 /* Set up pixels per line and lines per frame */ 518 val = (mode->hdisplay - 1) << MCDE_CHNLXCONF_PPL_SHIFT; 519 val |= (mode->vdisplay - 1) << MCDE_CHNLXCONF_LPF_SHIFT; 520 writel(val, mcde->regs + conf); 521 522 /* 523 * Normalize color conversion: 524 * black background, OLED conversion disable on channel 525 */ 526 val = MCDE_CHNLXSTAT_CHNLBLBCKGND_EN | 527 MCDE_CHNLXSTAT_CHNLRD; 528 writel(val, mcde->regs + stat); 529 writel(0, mcde->regs + bgcol); 530 531 /* Set up muxing: connect the channel to the desired FIFO */ 532 switch (fifo) { 533 case MCDE_FIFO_A: 534 writel(MCDE_CHNLXMUXING_FIFO_ID_FIFO_A, 535 mcde->regs + mux); 536 break; 537 case MCDE_FIFO_B: 538 writel(MCDE_CHNLXMUXING_FIFO_ID_FIFO_B, 539 mcde->regs + mux); 540 break; 541 } 542 } 543 544 static void mcde_configure_fifo(struct mcde *mcde, enum mcde_fifo fifo, 545 enum mcde_dsi_formatter fmt, 546 int fifo_wtrmrk) 547 { 548 u32 val; 549 u32 ctrl; 550 u32 cr0, cr1; 551 552 switch (fifo) { 553 case MCDE_FIFO_A: 554 ctrl = MCDE_CTRLA; 555 cr0 = MCDE_CRA0; 556 cr1 = MCDE_CRA1; 557 break; 558 case MCDE_FIFO_B: 559 ctrl = MCDE_CTRLB; 560 cr0 = MCDE_CRB0; 561 cr1 = MCDE_CRB1; 562 break; 563 } 564 565 val = fifo_wtrmrk << MCDE_CTRLX_FIFOWTRMRK_SHIFT; 566 /* We only support DSI formatting for now */ 567 val |= MCDE_CTRLX_FORMTYPE_DSI << 568 MCDE_CTRLX_FORMTYPE_SHIFT; 569 570 /* Select the formatter to use for this FIFO */ 571 val |= fmt << MCDE_CTRLX_FORMID_SHIFT; 572 writel(val, mcde->regs + ctrl); 573 574 /* Blend source with Alpha 0xff on FIFO */ 575 val = MCDE_CRX0_BLENDEN | 576 0xff << MCDE_CRX0_ALPHABLEND_SHIFT; 577 writel(val, mcde->regs + cr0); 578 579 /* Set-up from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() */ 580 581 /* Use the MCDE clock for this FIFO */ 582 val = MCDE_CRX1_CLKSEL_MCDECLK << MCDE_CRX1_CLKSEL_SHIFT; 583 584 /* TODO: when adding DPI support add OUTBPP etc here */ 585 writel(val, mcde->regs + cr1); 586 }; 587 588 static void mcde_configure_dsi_formatter(struct mcde *mcde, 589 enum mcde_dsi_formatter fmt, 590 u32 formatter_frame, 591 int pkt_size) 592 { 593 u32 val; 594 u32 conf0; 595 u32 frame; 596 u32 pkt; 597 u32 sync; 598 u32 cmdw; 599 u32 delay0, delay1; 600 601 switch (fmt) { 602 case MCDE_DSI_FORMATTER_0: 603 conf0 = MCDE_DSIVID0CONF0; 604 frame = MCDE_DSIVID0FRAME; 605 pkt = MCDE_DSIVID0PKT; 606 sync = MCDE_DSIVID0SYNC; 607 cmdw = MCDE_DSIVID0CMDW; 608 delay0 = MCDE_DSIVID0DELAY0; 609 delay1 = MCDE_DSIVID0DELAY1; 610 break; 611 case MCDE_DSI_FORMATTER_1: 612 conf0 = MCDE_DSIVID1CONF0; 613 frame = MCDE_DSIVID1FRAME; 614 pkt = MCDE_DSIVID1PKT; 615 sync = MCDE_DSIVID1SYNC; 616 cmdw = MCDE_DSIVID1CMDW; 617 delay0 = MCDE_DSIVID1DELAY0; 618 delay1 = MCDE_DSIVID1DELAY1; 619 break; 620 case MCDE_DSI_FORMATTER_2: 621 conf0 = MCDE_DSIVID2CONF0; 622 frame = MCDE_DSIVID2FRAME; 623 pkt = MCDE_DSIVID2PKT; 624 sync = MCDE_DSIVID2SYNC; 625 cmdw = MCDE_DSIVID2CMDW; 626 delay0 = MCDE_DSIVID2DELAY0; 627 delay1 = MCDE_DSIVID2DELAY1; 628 break; 629 } 630 631 /* 632 * Enable formatter 633 * 8 bit commands and DCS commands (notgen = not generic) 634 */ 635 val = MCDE_DSICONF0_CMD8 | MCDE_DSICONF0_DCSVID_NOTGEN; 636 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) 637 val |= MCDE_DSICONF0_VID_MODE_VID; 638 switch (mcde->mdsi->format) { 639 case MIPI_DSI_FMT_RGB888: 640 val |= MCDE_DSICONF0_PACKING_RGB888 << 641 MCDE_DSICONF0_PACKING_SHIFT; 642 break; 643 case MIPI_DSI_FMT_RGB666: 644 val |= MCDE_DSICONF0_PACKING_RGB666 << 645 MCDE_DSICONF0_PACKING_SHIFT; 646 break; 647 case MIPI_DSI_FMT_RGB666_PACKED: 648 val |= MCDE_DSICONF0_PACKING_RGB666_PACKED << 649 MCDE_DSICONF0_PACKING_SHIFT; 650 break; 651 case MIPI_DSI_FMT_RGB565: 652 val |= MCDE_DSICONF0_PACKING_RGB565 << 653 MCDE_DSICONF0_PACKING_SHIFT; 654 break; 655 default: 656 dev_err(mcde->dev, "unknown DSI format\n"); 657 return; 658 } 659 writel(val, mcde->regs + conf0); 660 661 writel(formatter_frame, mcde->regs + frame); 662 writel(pkt_size, mcde->regs + pkt); 663 writel(0, mcde->regs + sync); 664 /* Define the MIPI command: we want to write into display memory */ 665 val = MIPI_DCS_WRITE_MEMORY_CONTINUE << 666 MCDE_DSIVIDXCMDW_CMDW_CONTINUE_SHIFT; 667 val |= MIPI_DCS_WRITE_MEMORY_START << 668 MCDE_DSIVIDXCMDW_CMDW_START_SHIFT; 669 writel(val, mcde->regs + cmdw); 670 671 /* 672 * FIXME: the vendor driver has some hack around this value in 673 * CMD mode with autotrig. 674 */ 675 writel(0, mcde->regs + delay0); 676 writel(0, mcde->regs + delay1); 677 } 678 679 static void mcde_enable_fifo(struct mcde *mcde, enum mcde_fifo fifo) 680 { 681 u32 val; 682 u32 cr; 683 684 switch (fifo) { 685 case MCDE_FIFO_A: 686 cr = MCDE_CRA0; 687 break; 688 case MCDE_FIFO_B: 689 cr = MCDE_CRB0; 690 break; 691 default: 692 dev_err(mcde->dev, "cannot enable FIFO %c\n", 693 'A' + fifo); 694 return; 695 } 696 697 spin_lock(&mcde->flow_lock); 698 val = readl(mcde->regs + cr); 699 val |= MCDE_CRX0_FLOEN; 700 writel(val, mcde->regs + cr); 701 mcde->flow_active++; 702 spin_unlock(&mcde->flow_lock); 703 } 704 705 static void mcde_disable_fifo(struct mcde *mcde, enum mcde_fifo fifo, 706 bool wait_for_drain) 707 { 708 int timeout = 100; 709 u32 val; 710 u32 cr; 711 712 switch (fifo) { 713 case MCDE_FIFO_A: 714 cr = MCDE_CRA0; 715 break; 716 case MCDE_FIFO_B: 717 cr = MCDE_CRB0; 718 break; 719 default: 720 dev_err(mcde->dev, "cannot disable FIFO %c\n", 721 'A' + fifo); 722 return; 723 } 724 725 spin_lock(&mcde->flow_lock); 726 val = readl(mcde->regs + cr); 727 val &= ~MCDE_CRX0_FLOEN; 728 writel(val, mcde->regs + cr); 729 mcde->flow_active = 0; 730 spin_unlock(&mcde->flow_lock); 731 732 if (!wait_for_drain) 733 return; 734 735 /* Check that we really drained and stopped the flow */ 736 while (readl(mcde->regs + cr) & MCDE_CRX0_FLOEN) { 737 usleep_range(1000, 1500); 738 if (!--timeout) { 739 dev_err(mcde->dev, 740 "FIFO timeout while clearing FIFO %c\n", 741 'A' + fifo); 742 return; 743 } 744 } 745 } 746 747 /* 748 * This drains a pipe i.e. a FIFO connected to a certain channel 749 */ 750 static void mcde_drain_pipe(struct mcde *mcde, enum mcde_fifo fifo, 751 enum mcde_channel ch) 752 { 753 u32 val; 754 u32 ctrl; 755 u32 synsw; 756 757 switch (fifo) { 758 case MCDE_FIFO_A: 759 ctrl = MCDE_CTRLA; 760 break; 761 case MCDE_FIFO_B: 762 ctrl = MCDE_CTRLB; 763 break; 764 } 765 766 switch (ch) { 767 case MCDE_CHANNEL_0: 768 synsw = MCDE_CHNL0SYNCHSW; 769 break; 770 case MCDE_CHANNEL_1: 771 synsw = MCDE_CHNL1SYNCHSW; 772 break; 773 case MCDE_CHANNEL_2: 774 synsw = MCDE_CHNL2SYNCHSW; 775 break; 776 case MCDE_CHANNEL_3: 777 synsw = MCDE_CHNL3SYNCHSW; 778 return; 779 } 780 781 val = readl(mcde->regs + ctrl); 782 if (!(val & MCDE_CTRLX_FIFOEMPTY)) { 783 dev_err(mcde->dev, "Channel A FIFO not empty (handover)\n"); 784 /* Attempt to clear the FIFO */ 785 mcde_enable_fifo(mcde, fifo); 786 /* Trigger a software sync out on respective channel (0-3) */ 787 writel(MCDE_CHNLXSYNCHSW_SW_TRIG, mcde->regs + synsw); 788 /* Disable FIFO A flow again */ 789 mcde_disable_fifo(mcde, fifo, true); 790 } 791 } 792 793 static int mcde_dsi_get_pkt_div(int ppl, int fifo_size) 794 { 795 /* 796 * DSI command mode line packets should be split into an even number of 797 * packets smaller than or equal to the fifo size. 798 */ 799 int div; 800 const int max_div = DIV_ROUND_UP(MCDE_MAX_WIDTH, fifo_size); 801 802 for (div = 1; div < max_div; div++) 803 if (ppl % div == 0 && ppl / div <= fifo_size) 804 return div; 805 return 1; 806 } 807 808 static void mcde_display_enable(struct drm_simple_display_pipe *pipe, 809 struct drm_crtc_state *cstate, 810 struct drm_plane_state *plane_state) 811 { 812 struct drm_crtc *crtc = &pipe->crtc; 813 struct drm_plane *plane = &pipe->plane; 814 struct drm_device *drm = crtc->dev; 815 struct mcde *mcde = drm->dev_private; 816 const struct drm_display_mode *mode = &cstate->mode; 817 struct drm_framebuffer *fb = plane->state->fb; 818 u32 format = fb->format->format; 819 u32 formatter_ppl = mode->hdisplay; /* pixels per line */ 820 u32 formatter_lpf = mode->vdisplay; /* lines per frame */ 821 int pkt_size, fifo_wtrmrk; 822 int cpp = fb->format->cpp[0]; 823 int formatter_cpp; 824 struct drm_format_name_buf tmp; 825 u32 formatter_frame; 826 u32 pkt_div; 827 u32 val; 828 829 dev_info(drm->dev, "enable MCDE, %d x %d format %s\n", 830 mode->hdisplay, mode->vdisplay, 831 drm_get_format_name(format, &tmp)); 832 if (!mcde->mdsi) { 833 /* TODO: deal with this for non-DSI output */ 834 dev_err(drm->dev, "no DSI master attached!\n"); 835 return; 836 } 837 838 dev_info(drm->dev, "output in %s mode, format %dbpp\n", 839 (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? 840 "VIDEO" : "CMD", 841 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format)); 842 formatter_cpp = 843 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format) / 8; 844 dev_info(drm->dev, "overlay CPP %d bytes, DSI CPP %d bytes\n", 845 cpp, 846 formatter_cpp); 847 848 /* Calculations from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() */ 849 850 /* 851 * Set up FIFO A watermark level: 852 * 128 for LCD 32bpp video mode 853 * 48 for LCD 32bpp command mode 854 * 128 for LCD 16bpp video mode 855 * 64 for LCD 16bpp command mode 856 * 128 for HDMI 32bpp 857 * 192 for HDMI 16bpp 858 */ 859 fifo_wtrmrk = mode->hdisplay; 860 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) { 861 fifo_wtrmrk = min(fifo_wtrmrk, 128); 862 pkt_div = 1; 863 } else { 864 fifo_wtrmrk = min(fifo_wtrmrk, 48); 865 /* The FIFO is 640 entries deep on this v3 hardware */ 866 pkt_div = mcde_dsi_get_pkt_div(mode->hdisplay, 640); 867 } 868 dev_dbg(drm->dev, "FIFO watermark after flooring: %d bytes\n", 869 fifo_wtrmrk); 870 dev_dbg(drm->dev, "Packet divisor: %d bytes\n", pkt_div); 871 872 /* NOTE: pkt_div is 1 for video mode */ 873 pkt_size = (formatter_ppl * formatter_cpp) / pkt_div; 874 /* Commands CMD8 need one extra byte */ 875 if (!(mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO)) 876 pkt_size++; 877 878 dev_dbg(drm->dev, "DSI packet size: %d * %d bytes per line\n", 879 pkt_size, pkt_div); 880 dev_dbg(drm->dev, "Overlay frame size: %u bytes\n", 881 mode->hdisplay * mode->vdisplay * cpp); 882 mcde->stride = mode->hdisplay * cpp; 883 dev_dbg(drm->dev, "Overlay line stride: %u bytes\n", 884 mcde->stride); 885 /* NOTE: pkt_div is 1 for video mode */ 886 formatter_frame = pkt_size * pkt_div * formatter_lpf; 887 dev_dbg(drm->dev, "Formatter frame size: %u bytes\n", formatter_frame); 888 889 /* Drain the FIFO A + channel 0 pipe so we have a clean slate */ 890 mcde_drain_pipe(mcde, MCDE_FIFO_A, MCDE_CHANNEL_0); 891 892 /* 893 * We set up our display pipeline: 894 * EXTSRC 0 -> OVERLAY 0 -> CHANNEL 0 -> FIFO A -> DSI FORMATTER 0 895 * 896 * First configure the external source (memory) on external source 0 897 * using the desired bitstream/bitmap format 898 */ 899 mcde_configure_extsrc(mcde, MCDE_EXTSRC_0, format); 900 901 /* 902 * Configure overlay 0 according to format and mode and take input 903 * from external source 0 and route the output of this overlay to 904 * channel 0 905 */ 906 mcde_configure_overlay(mcde, MCDE_OVERLAY_0, MCDE_EXTSRC_0, 907 MCDE_CHANNEL_0, mode, format); 908 909 /* 910 * Configure pixel-per-line and line-per-frame for channel 0 and then 911 * route channel 0 to FIFO A 912 */ 913 mcde_configure_channel(mcde, MCDE_CHANNEL_0, MCDE_FIFO_A, mode); 914 915 /* Configure FIFO A to use DSI formatter 0 */ 916 mcde_configure_fifo(mcde, MCDE_FIFO_A, MCDE_DSI_FORMATTER_0, 917 fifo_wtrmrk); 918 919 /* Configure the DSI formatter 0 for the DSI panel output */ 920 mcde_configure_dsi_formatter(mcde, MCDE_DSI_FORMATTER_0, 921 formatter_frame, pkt_size); 922 923 if (mcde->te_sync) { 924 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 925 val = MCDE_VSCRC_VSPOL; 926 else 927 val = 0; 928 writel(val, mcde->regs + MCDE_VSCRC0); 929 /* Enable VSYNC capture on TE0 */ 930 val = readl(mcde->regs + MCDE_CRC); 931 val |= MCDE_CRC_SYCEN0; 932 writel(val, mcde->regs + MCDE_CRC); 933 } 934 935 drm_crtc_vblank_on(crtc); 936 937 if (mcde->video_mode) 938 /* 939 * Keep FIFO permanently enabled in video mode, 940 * otherwise MCDE will stop feeding data to the panel. 941 */ 942 mcde_enable_fifo(mcde, MCDE_FIFO_A); 943 944 dev_info(drm->dev, "MCDE display is enabled\n"); 945 } 946 947 static void mcde_display_disable(struct drm_simple_display_pipe *pipe) 948 { 949 struct drm_crtc *crtc = &pipe->crtc; 950 struct drm_device *drm = crtc->dev; 951 struct mcde *mcde = drm->dev_private; 952 struct drm_pending_vblank_event *event; 953 954 drm_crtc_vblank_off(crtc); 955 956 /* Disable FIFO A flow */ 957 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); 958 959 event = crtc->state->event; 960 if (event) { 961 crtc->state->event = NULL; 962 963 spin_lock_irq(&crtc->dev->event_lock); 964 drm_crtc_send_vblank_event(crtc, event); 965 spin_unlock_irq(&crtc->dev->event_lock); 966 } 967 968 dev_info(drm->dev, "MCDE display is disabled\n"); 969 } 970 971 static void mcde_display_send_one_frame(struct mcde *mcde) 972 { 973 /* Request a TE ACK */ 974 if (mcde->te_sync) 975 mcde_dsi_te_request(mcde->mdsi); 976 977 /* Enable FIFO A flow */ 978 mcde_enable_fifo(mcde, MCDE_FIFO_A); 979 980 if (mcde->te_sync) { 981 /* 982 * If oneshot mode is enabled, the flow will be disabled 983 * when the TE0 IRQ arrives in the interrupt handler. Otherwise 984 * updates are continuously streamed to the display after this 985 * point. 986 */ 987 dev_dbg(mcde->dev, "sent TE0 framebuffer update\n"); 988 return; 989 } 990 991 /* Trigger a software sync out on channel 0 */ 992 writel(MCDE_CHNLXSYNCHSW_SW_TRIG, 993 mcde->regs + MCDE_CHNL0SYNCHSW); 994 995 /* 996 * Disable FIFO A flow again: since we are using TE sync we 997 * need to wait for the FIFO to drain before we continue 998 * so repeated calls to this function will not cause a mess 999 * in the hardware by pushing updates will updates are going 1000 * on already. 1001 */ 1002 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); 1003 1004 dev_dbg(mcde->dev, "sent SW framebuffer update\n"); 1005 } 1006 1007 static void mcde_set_extsrc(struct mcde *mcde, u32 buffer_address) 1008 { 1009 /* Write bitmap base address to register */ 1010 writel(buffer_address, mcde->regs + MCDE_EXTSRCXA0); 1011 /* 1012 * Base address for next line this is probably only used 1013 * in interlace modes. 1014 */ 1015 writel(buffer_address + mcde->stride, mcde->regs + MCDE_EXTSRCXA1); 1016 } 1017 1018 static void mcde_display_update(struct drm_simple_display_pipe *pipe, 1019 struct drm_plane_state *old_pstate) 1020 { 1021 struct drm_crtc *crtc = &pipe->crtc; 1022 struct drm_device *drm = crtc->dev; 1023 struct mcde *mcde = drm->dev_private; 1024 struct drm_pending_vblank_event *event = crtc->state->event; 1025 struct drm_plane *plane = &pipe->plane; 1026 struct drm_plane_state *pstate = plane->state; 1027 struct drm_framebuffer *fb = pstate->fb; 1028 1029 /* 1030 * Handle any pending event first, we need to arm the vblank 1031 * interrupt before sending any update to the display so we don't 1032 * miss the interrupt. 1033 */ 1034 if (event) { 1035 crtc->state->event = NULL; 1036 1037 spin_lock_irq(&crtc->dev->event_lock); 1038 /* 1039 * Hardware must be on before we can arm any vblank event, 1040 * this is not a scanout controller where there is always 1041 * some periodic update going on, it is completely frozen 1042 * until we get an update. If MCDE output isn't yet enabled, 1043 * we just send a vblank dummy event back. 1044 */ 1045 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0) { 1046 dev_dbg(mcde->dev, "arm vblank event\n"); 1047 drm_crtc_arm_vblank_event(crtc, event); 1048 } else { 1049 dev_dbg(mcde->dev, "insert fake vblank event\n"); 1050 drm_crtc_send_vblank_event(crtc, event); 1051 } 1052 1053 spin_unlock_irq(&crtc->dev->event_lock); 1054 } 1055 1056 /* 1057 * We do not start sending framebuffer updates before the 1058 * display is enabled. Update events will however be dispatched 1059 * from the DRM core before the display is enabled. 1060 */ 1061 if (fb) { 1062 mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0)); 1063 if (!mcde->video_mode) 1064 /* Send a single frame using software sync */ 1065 mcde_display_send_one_frame(mcde); 1066 dev_info_once(mcde->dev, "sent first display update\n"); 1067 } else { 1068 /* 1069 * If an update is receieved before the MCDE is enabled 1070 * (before mcde_display_enable() is called) we can't really 1071 * do much with that buffer. 1072 */ 1073 dev_info(mcde->dev, "ignored a display update\n"); 1074 } 1075 } 1076 1077 static int mcde_display_enable_vblank(struct drm_simple_display_pipe *pipe) 1078 { 1079 struct drm_crtc *crtc = &pipe->crtc; 1080 struct drm_device *drm = crtc->dev; 1081 struct mcde *mcde = drm->dev_private; 1082 u32 val; 1083 1084 /* Enable all VBLANK IRQs */ 1085 val = MCDE_PP_VCMPA | 1086 MCDE_PP_VCMPB | 1087 MCDE_PP_VSCC0 | 1088 MCDE_PP_VSCC1 | 1089 MCDE_PP_VCMPC0 | 1090 MCDE_PP_VCMPC1; 1091 writel(val, mcde->regs + MCDE_IMSCPP); 1092 1093 return 0; 1094 } 1095 1096 static void mcde_display_disable_vblank(struct drm_simple_display_pipe *pipe) 1097 { 1098 struct drm_crtc *crtc = &pipe->crtc; 1099 struct drm_device *drm = crtc->dev; 1100 struct mcde *mcde = drm->dev_private; 1101 1102 /* Disable all VBLANK IRQs */ 1103 writel(0, mcde->regs + MCDE_IMSCPP); 1104 /* Clear any pending IRQs */ 1105 writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP); 1106 } 1107 1108 static struct drm_simple_display_pipe_funcs mcde_display_funcs = { 1109 .check = mcde_display_check, 1110 .enable = mcde_display_enable, 1111 .disable = mcde_display_disable, 1112 .update = mcde_display_update, 1113 .enable_vblank = mcde_display_enable_vblank, 1114 .disable_vblank = mcde_display_disable_vblank, 1115 .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb, 1116 }; 1117 1118 int mcde_display_init(struct drm_device *drm) 1119 { 1120 struct mcde *mcde = drm->dev_private; 1121 int ret; 1122 static const u32 formats[] = { 1123 DRM_FORMAT_ARGB8888, 1124 DRM_FORMAT_ABGR8888, 1125 DRM_FORMAT_XRGB8888, 1126 DRM_FORMAT_XBGR8888, 1127 DRM_FORMAT_RGB888, 1128 DRM_FORMAT_BGR888, 1129 DRM_FORMAT_ARGB4444, 1130 DRM_FORMAT_ABGR4444, 1131 DRM_FORMAT_XRGB4444, 1132 DRM_FORMAT_XBGR4444, 1133 /* These are actually IRGB1555 so intensity bit is lost */ 1134 DRM_FORMAT_XRGB1555, 1135 DRM_FORMAT_XBGR1555, 1136 DRM_FORMAT_RGB565, 1137 DRM_FORMAT_BGR565, 1138 DRM_FORMAT_YUV422, 1139 }; 1140 1141 ret = drm_simple_display_pipe_init(drm, &mcde->pipe, 1142 &mcde_display_funcs, 1143 formats, ARRAY_SIZE(formats), 1144 NULL, 1145 mcde->connector); 1146 if (ret) 1147 return ret; 1148 1149 return 0; 1150 } 1151 EXPORT_SYMBOL_GPL(mcde_display_init); 1152