1 // SPDX-License-Identifier: GPL-2.0
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
8 #include <linux/delay.h>
9 #include <linux/dma-buf.h>
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>
22 #include "mcde_display_regs.h"
27 /* TODO: implement FIFO C0 and FIFO C1 */
59 enum mcde_dsi_formatter
{
60 MCDE_DSI_FORMATTER_0
= 0,
65 void mcde_display_irq(struct mcde
*mcde
)
67 u32 mispp
, misovl
, mischnl
;
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
);
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
81 * TODO: Currently only one DSI link is supported.
83 if (mcde_dsi_irq(mcde
->mdsi
)) {
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.
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
);
101 spin_unlock(&mcde
->flow_lock
);
105 /* Vblank from one of the channels */
106 if (mispp
& MCDE_PP_VCMPA
) {
107 dev_dbg(mcde
->dev
, "chnl A vblank IRQ\n");
110 if (mispp
& MCDE_PP_VCMPB
) {
111 dev_dbg(mcde
->dev
, "chnl B vblank IRQ\n");
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
);
125 drm_crtc_handle_vblank(&mcde
->pipe
.crtc
);
128 dev_info(mcde
->dev
, "some stray overlay IRQ %08x\n", misovl
);
129 writel(misovl
, mcde
->regs
+ MCDE_RISOVL
);
132 dev_info(mcde
->dev
, "some stray channel error IRQ %08x\n",
134 writel(mischnl
, mcde
->regs
+ MCDE_RISCHNL
);
137 void mcde_display_disable_irqs(struct mcde
*mcde
)
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
);
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
);
150 static int mcde_display_check(struct drm_simple_display_pipe
*pipe
,
151 struct drm_plane_state
*pstate
,
152 struct drm_crtc_state
*cstate
)
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
;
159 u32 offset
= drm_fb_cma_get_gem_addr(fb
, pstate
, 0);
161 /* FB base address must be dword aligned. */
163 DRM_DEBUG_KMS("FB not 32-bit aligned\n");
168 * There's no pitch register, the mode's hdisplay
171 if (fb
->pitches
[0] != mode
->hdisplay
* fb
->format
->cpp
[0]) {
172 DRM_DEBUG_KMS("can't handle pitches\n");
177 * We can't change the FB format in a flicker-free
178 * manner (and only update it during CRTC enable).
180 if (old_fb
&& old_fb
->format
!= fb
->format
)
181 cstate
->mode_changed
= true;
187 static int mcde_configure_extsrc(struct mcde
*mcde
, enum mcde_extsrc src
,
196 conf
= MCDE_EXTSRC0CONF
;
200 conf
= MCDE_EXTSRC1CONF
;
204 conf
= MCDE_EXTSRC2CONF
;
208 conf
= MCDE_EXTSRC3CONF
;
212 conf
= MCDE_EXTSRC4CONF
;
216 conf
= MCDE_EXTSRC5CONF
;
220 conf
= MCDE_EXTSRC6CONF
;
224 conf
= MCDE_EXTSRC7CONF
;
228 conf
= MCDE_EXTSRC8CONF
;
232 conf
= MCDE_EXTSRC9CONF
;
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
242 val
= 0 << MCDE_EXTSRCXCONF_BUF_ID_SHIFT
;
243 val
|= 1 << MCDE_EXTSRCXCONF_BUF_NB_SHIFT
;
244 val
|= 0 << MCDE_EXTSRCXCONF_PRI_OVLID_SHIFT
;
246 * MCDE has inverse semantics from DRM on RBG/BGR which is why
247 * all the modes are inversed here.
250 case DRM_FORMAT_ARGB8888
:
251 val
|= MCDE_EXTSRCXCONF_BPP_ARGB8888
<<
252 MCDE_EXTSRCXCONF_BPP_SHIFT
;
253 val
|= MCDE_EXTSRCXCONF_BGR
;
255 case DRM_FORMAT_ABGR8888
:
256 val
|= MCDE_EXTSRCXCONF_BPP_ARGB8888
<<
257 MCDE_EXTSRCXCONF_BPP_SHIFT
;
259 case DRM_FORMAT_XRGB8888
:
260 val
|= MCDE_EXTSRCXCONF_BPP_XRGB8888
<<
261 MCDE_EXTSRCXCONF_BPP_SHIFT
;
262 val
|= MCDE_EXTSRCXCONF_BGR
;
264 case DRM_FORMAT_XBGR8888
:
265 val
|= MCDE_EXTSRCXCONF_BPP_XRGB8888
<<
266 MCDE_EXTSRCXCONF_BPP_SHIFT
;
268 case DRM_FORMAT_RGB888
:
269 val
|= MCDE_EXTSRCXCONF_BPP_RGB888
<<
270 MCDE_EXTSRCXCONF_BPP_SHIFT
;
271 val
|= MCDE_EXTSRCXCONF_BGR
;
273 case DRM_FORMAT_BGR888
:
274 val
|= MCDE_EXTSRCXCONF_BPP_RGB888
<<
275 MCDE_EXTSRCXCONF_BPP_SHIFT
;
277 case DRM_FORMAT_ARGB4444
:
278 val
|= MCDE_EXTSRCXCONF_BPP_ARGB4444
<<
279 MCDE_EXTSRCXCONF_BPP_SHIFT
;
280 val
|= MCDE_EXTSRCXCONF_BGR
;
282 case DRM_FORMAT_ABGR4444
:
283 val
|= MCDE_EXTSRCXCONF_BPP_ARGB4444
<<
284 MCDE_EXTSRCXCONF_BPP_SHIFT
;
286 case DRM_FORMAT_XRGB4444
:
287 val
|= MCDE_EXTSRCXCONF_BPP_RGB444
<<
288 MCDE_EXTSRCXCONF_BPP_SHIFT
;
289 val
|= MCDE_EXTSRCXCONF_BGR
;
291 case DRM_FORMAT_XBGR4444
:
292 val
|= MCDE_EXTSRCXCONF_BPP_RGB444
<<
293 MCDE_EXTSRCXCONF_BPP_SHIFT
;
295 case DRM_FORMAT_XRGB1555
:
296 val
|= MCDE_EXTSRCXCONF_BPP_IRGB1555
<<
297 MCDE_EXTSRCXCONF_BPP_SHIFT
;
298 val
|= MCDE_EXTSRCXCONF_BGR
;
300 case DRM_FORMAT_XBGR1555
:
301 val
|= MCDE_EXTSRCXCONF_BPP_IRGB1555
<<
302 MCDE_EXTSRCXCONF_BPP_SHIFT
;
304 case DRM_FORMAT_RGB565
:
305 val
|= MCDE_EXTSRCXCONF_BPP_RGB565
<<
306 MCDE_EXTSRCXCONF_BPP_SHIFT
;
307 val
|= MCDE_EXTSRCXCONF_BGR
;
309 case DRM_FORMAT_BGR565
:
310 val
|= MCDE_EXTSRCXCONF_BPP_RGB565
<<
311 MCDE_EXTSRCXCONF_BPP_SHIFT
;
313 case DRM_FORMAT_YUV422
:
314 val
|= MCDE_EXTSRCXCONF_BPP_YCBCR422
<<
315 MCDE_EXTSRCXCONF_BPP_SHIFT
;
318 dev_err(mcde
->dev
, "Unknown pixel format 0x%08x\n",
322 writel(val
, mcde
->regs
+ conf
);
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
);
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
,
348 conf1
= MCDE_OVL0CONF
;
349 conf2
= MCDE_OVL0CONF2
;
350 crop
= MCDE_OVL0CROP
;
351 ljinc
= MCDE_OVL0LJINC
;
353 comp
= MCDE_OVL0COMP
;
356 conf1
= MCDE_OVL1CONF
;
357 conf2
= MCDE_OVL1CONF2
;
358 crop
= MCDE_OVL1CROP
;
359 ljinc
= MCDE_OVL1LJINC
;
361 comp
= MCDE_OVL1COMP
;
364 conf1
= MCDE_OVL2CONF
;
365 conf2
= MCDE_OVL2CONF2
;
366 crop
= MCDE_OVL2CROP
;
367 ljinc
= MCDE_OVL2LJINC
;
369 comp
= MCDE_OVL2COMP
;
372 conf1
= MCDE_OVL3CONF
;
373 conf2
= MCDE_OVL3CONF2
;
374 crop
= MCDE_OVL3CROP
;
375 ljinc
= MCDE_OVL3LJINC
;
377 comp
= MCDE_OVL3COMP
;
380 conf1
= MCDE_OVL4CONF
;
381 conf2
= MCDE_OVL4CONF2
;
382 crop
= MCDE_OVL4CROP
;
383 ljinc
= MCDE_OVL4LJINC
;
385 comp
= MCDE_OVL4COMP
;
388 conf1
= MCDE_OVL5CONF
;
389 conf2
= MCDE_OVL5CONF2
;
390 crop
= MCDE_OVL5CROP
;
391 ljinc
= MCDE_OVL5LJINC
;
393 comp
= MCDE_OVL5COMP
;
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
);
403 val
= MCDE_OVLXCONF2_BP_PER_PIXEL_ALPHA
;
404 val
|= 0xff << MCDE_OVLXCONF2_ALPHAVALUE_SHIFT
;
405 /* OPQ: overlay is opaque */
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
:
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
;
425 dev_err(mcde
->dev
, "Unknown pixel format 0x%08x\n",
429 /* The default watermark level for overlay 0 is 48 */
430 val
|= 48 << MCDE_OVLXCONF2_PIXELFETCHERWATERMARKLEVEL_SHIFT
;
431 writel(val
, mcde
->regs
+ conf2
);
433 /* Number of bytes to fetch per line */
434 writel(mcde
->stride
, mcde
->regs
+ ljinc
);
436 writel(0, mcde
->regs
+ crop
);
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
);
451 * Set up the overlay compositor to route the overlay out to
452 * the desired channel
454 val
= ch
<< MCDE_OVLXCOMP_CH_ID_SHIFT
;
455 writel(val
, mcde
->regs
+ comp
);
458 static void mcde_configure_channel(struct mcde
*mcde
, enum mcde_channel ch
,
460 const struct drm_display_mode
*mode
)
471 conf
= MCDE_CHNL0CONF
;
472 sync
= MCDE_CHNL0SYNCHMOD
;
473 stat
= MCDE_CHNL0STAT
;
474 bgcol
= MCDE_CHNL0BCKGNDCOL
;
475 mux
= MCDE_CHNL0MUXING
;
478 conf
= MCDE_CHNL1CONF
;
479 sync
= MCDE_CHNL1SYNCHMOD
;
480 stat
= MCDE_CHNL1STAT
;
481 bgcol
= MCDE_CHNL1BCKGNDCOL
;
482 mux
= MCDE_CHNL1MUXING
;
485 conf
= MCDE_CHNL2CONF
;
486 sync
= MCDE_CHNL2SYNCHMOD
;
487 stat
= MCDE_CHNL2STAT
;
488 bgcol
= MCDE_CHNL2BCKGNDCOL
;
489 mux
= MCDE_CHNL2MUXING
;
492 conf
= MCDE_CHNL3CONF
;
493 sync
= MCDE_CHNL3SYNCHMOD
;
494 stat
= MCDE_CHNL3STAT
;
495 bgcol
= MCDE_CHNL3BCKGNDCOL
;
496 mux
= MCDE_CHNL3MUXING
;
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
;
505 val
= MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SOFTWARE
506 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT
;
509 val
|= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0
510 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT
;
512 val
|= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER
513 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT
;
515 writel(val
, mcde
->regs
+ sync
);
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
);
523 * Normalize color conversion:
524 * black background, OLED conversion disable on channel
526 val
= MCDE_CHNLXSTAT_CHNLBLBCKGND_EN
|
527 MCDE_CHNLXSTAT_CHNLRD
;
528 writel(val
, mcde
->regs
+ stat
);
529 writel(0, mcde
->regs
+ bgcol
);
531 /* Set up muxing: connect the channel to the desired FIFO */
534 writel(MCDE_CHNLXMUXING_FIFO_ID_FIFO_A
,
538 writel(MCDE_CHNLXMUXING_FIFO_ID_FIFO_B
,
544 static void mcde_configure_fifo(struct mcde
*mcde
, enum mcde_fifo fifo
,
545 enum mcde_dsi_formatter fmt
,
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
;
570 /* Select the formatter to use for this FIFO */
571 val
|= fmt
<< MCDE_CTRLX_FORMID_SHIFT
;
572 writel(val
, mcde
->regs
+ ctrl
);
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
);
579 /* Set-up from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() */
581 /* Use the MCDE clock for this FIFO */
582 val
= MCDE_CRX1_CLKSEL_MCDECLK
<< MCDE_CRX1_CLKSEL_SHIFT
;
584 /* TODO: when adding DPI support add OUTBPP etc here */
585 writel(val
, mcde
->regs
+ cr1
);
588 static void mcde_configure_dsi_formatter(struct mcde
*mcde
,
589 enum mcde_dsi_formatter 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
;
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
;
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
;
633 * 8 bit commands and DCS commands (notgen = not generic)
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
;
643 case MIPI_DSI_FMT_RGB666
:
644 val
|= MCDE_DSICONF0_PACKING_RGB666
<<
645 MCDE_DSICONF0_PACKING_SHIFT
;
647 case MIPI_DSI_FMT_RGB666_PACKED
:
648 val
|= MCDE_DSICONF0_PACKING_RGB666_PACKED
<<
649 MCDE_DSICONF0_PACKING_SHIFT
;
651 case MIPI_DSI_FMT_RGB565
:
652 val
|= MCDE_DSICONF0_PACKING_RGB565
<<
653 MCDE_DSICONF0_PACKING_SHIFT
;
656 dev_err(mcde
->dev
, "unknown DSI format\n");
659 writel(val
, mcde
->regs
+ conf0
);
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
);
672 * FIXME: the vendor driver has some hack around this value in
673 * CMD mode with autotrig.
675 writel(0, mcde
->regs
+ delay0
);
676 writel(0, mcde
->regs
+ delay1
);
679 static void mcde_enable_fifo(struct mcde
*mcde
, enum mcde_fifo fifo
)
692 dev_err(mcde
->dev
, "cannot enable FIFO %c\n",
697 spin_lock(&mcde
->flow_lock
);
698 val
= readl(mcde
->regs
+ cr
);
699 val
|= MCDE_CRX0_FLOEN
;
700 writel(val
, mcde
->regs
+ cr
);
702 spin_unlock(&mcde
->flow_lock
);
705 static void mcde_disable_fifo(struct mcde
*mcde
, enum mcde_fifo fifo
,
720 dev_err(mcde
->dev
, "cannot disable FIFO %c\n",
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
);
735 /* Check that we really drained and stopped the flow */
736 while (readl(mcde
->regs
+ cr
) & MCDE_CRX0_FLOEN
) {
737 usleep_range(1000, 1500);
740 "FIFO timeout while clearing FIFO %c\n",
748 * This drains a pipe i.e. a FIFO connected to a certain channel
750 static void mcde_drain_pipe(struct mcde
*mcde
, enum mcde_fifo fifo
,
751 enum mcde_channel ch
)
768 synsw
= MCDE_CHNL0SYNCHSW
;
771 synsw
= MCDE_CHNL1SYNCHSW
;
774 synsw
= MCDE_CHNL2SYNCHSW
;
777 synsw
= MCDE_CHNL3SYNCHSW
;
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);
793 static int mcde_dsi_get_pkt_div(int ppl
, int fifo_size
)
796 * DSI command mode line packets should be split into an even number of
797 * packets smaller than or equal to the fifo size.
800 const int max_div
= DIV_ROUND_UP(MCDE_MAX_WIDTH
, fifo_size
);
802 for (div
= 1; div
< max_div
; div
++)
803 if (ppl
% div
== 0 && ppl
/ div
<= fifo_size
)
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
)
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];
824 struct drm_format_name_buf tmp
;
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
));
833 /* TODO: deal with this for non-DSI output */
834 dev_err(drm
->dev
, "no DSI master attached!\n");
838 dev_info(drm
->dev
, "output in %s mode, format %dbpp\n",
839 (mcde
->mdsi
->mode_flags
& MIPI_DSI_MODE_VIDEO
) ?
841 mipi_dsi_pixel_format_to_bpp(mcde
->mdsi
->format
));
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",
848 /* Calculations from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() */
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
859 fifo_wtrmrk
= mode
->hdisplay
;
860 if (mcde
->mdsi
->mode_flags
& MIPI_DSI_MODE_VIDEO
) {
861 fifo_wtrmrk
= min(fifo_wtrmrk
, 128);
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);
868 dev_dbg(drm
->dev
, "FIFO watermark after flooring: %d bytes\n",
870 dev_dbg(drm
->dev
, "Packet divisor: %d bytes\n", pkt_div
);
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
))
878 dev_dbg(drm
->dev
, "DSI packet size: %d * %d bytes per line\n",
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",
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
);
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
);
893 * We set up our display pipeline:
894 * EXTSRC 0 -> OVERLAY 0 -> CHANNEL 0 -> FIFO A -> DSI FORMATTER 0
896 * First configure the external source (memory) on external source 0
897 * using the desired bitstream/bitmap format
899 mcde_configure_extsrc(mcde
, MCDE_EXTSRC_0
, format
);
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
906 mcde_configure_overlay(mcde
, MCDE_OVERLAY_0
, MCDE_EXTSRC_0
,
907 MCDE_CHANNEL_0
, mode
, format
);
910 * Configure pixel-per-line and line-per-frame for channel 0 and then
911 * route channel 0 to FIFO A
913 mcde_configure_channel(mcde
, MCDE_CHANNEL_0
, MCDE_FIFO_A
, mode
);
915 /* Configure FIFO A to use DSI formatter 0 */
916 mcde_configure_fifo(mcde
, MCDE_FIFO_A
, MCDE_DSI_FORMATTER_0
,
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
);
924 if (mode
->flags
& DRM_MODE_FLAG_NVSYNC
)
925 val
= MCDE_VSCRC_VSPOL
;
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
);
935 drm_crtc_vblank_on(crtc
);
937 if (mcde
->video_mode
)
939 * Keep FIFO permanently enabled in video mode,
940 * otherwise MCDE will stop feeding data to the panel.
942 mcde_enable_fifo(mcde
, MCDE_FIFO_A
);
944 dev_info(drm
->dev
, "MCDE display is enabled\n");
947 static void mcde_display_disable(struct drm_simple_display_pipe
*pipe
)
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
;
954 drm_crtc_vblank_off(crtc
);
956 /* Disable FIFO A flow */
957 mcde_disable_fifo(mcde
, MCDE_FIFO_A
, true);
959 event
= crtc
->state
->event
;
961 crtc
->state
->event
= NULL
;
963 spin_lock_irq(&crtc
->dev
->event_lock
);
964 drm_crtc_send_vblank_event(crtc
, event
);
965 spin_unlock_irq(&crtc
->dev
->event_lock
);
968 dev_info(drm
->dev
, "MCDE display is disabled\n");
971 static void mcde_display_send_one_frame(struct mcde
*mcde
)
973 /* Request a TE ACK */
975 mcde_dsi_te_request(mcde
->mdsi
);
977 /* Enable FIFO A flow */
978 mcde_enable_fifo(mcde
, MCDE_FIFO_A
);
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
987 dev_dbg(mcde
->dev
, "sent TE0 framebuffer update\n");
991 /* Trigger a software sync out on channel 0 */
992 writel(MCDE_CHNLXSYNCHSW_SW_TRIG
,
993 mcde
->regs
+ MCDE_CHNL0SYNCHSW
);
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
1002 mcde_disable_fifo(mcde
, MCDE_FIFO_A
, true);
1004 dev_dbg(mcde
->dev
, "sent SW framebuffer update\n");
1007 static void mcde_set_extsrc(struct mcde
*mcde
, u32 buffer_address
)
1009 /* Write bitmap base address to register */
1010 writel(buffer_address
, mcde
->regs
+ MCDE_EXTSRCXA0
);
1012 * Base address for next line this is probably only used
1013 * in interlace modes.
1015 writel(buffer_address
+ mcde
->stride
, mcde
->regs
+ MCDE_EXTSRCXA1
);
1018 static void mcde_display_update(struct drm_simple_display_pipe
*pipe
,
1019 struct drm_plane_state
*old_pstate
)
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
;
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.
1035 crtc
->state
->event
= NULL
;
1037 spin_lock_irq(&crtc
->dev
->event_lock
);
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.
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
);
1049 dev_dbg(mcde
->dev
, "insert fake vblank event\n");
1050 drm_crtc_send_vblank_event(crtc
, event
);
1053 spin_unlock_irq(&crtc
->dev
->event_lock
);
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.
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");
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.
1073 dev_info(mcde
->dev
, "ignored a display update\n");
1077 static int mcde_display_enable_vblank(struct drm_simple_display_pipe
*pipe
)
1079 struct drm_crtc
*crtc
= &pipe
->crtc
;
1080 struct drm_device
*drm
= crtc
->dev
;
1081 struct mcde
*mcde
= drm
->dev_private
;
1084 /* Enable all VBLANK IRQs */
1085 val
= MCDE_PP_VCMPA
|
1091 writel(val
, mcde
->regs
+ MCDE_IMSCPP
);
1096 static void mcde_display_disable_vblank(struct drm_simple_display_pipe
*pipe
)
1098 struct drm_crtc
*crtc
= &pipe
->crtc
;
1099 struct drm_device
*drm
= crtc
->dev
;
1100 struct mcde
*mcde
= drm
->dev_private
;
1102 /* Disable all VBLANK IRQs */
1103 writel(0, mcde
->regs
+ MCDE_IMSCPP
);
1104 /* Clear any pending IRQs */
1105 writel(0xFFFFFFFF, mcde
->regs
+ MCDE_RISPP
);
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
,
1118 int mcde_display_init(struct drm_device
*drm
)
1120 struct mcde
*mcde
= drm
->dev_private
;
1122 static const u32 formats
[] = {
1123 DRM_FORMAT_ARGB8888
,
1124 DRM_FORMAT_ABGR8888
,
1125 DRM_FORMAT_XRGB8888
,
1126 DRM_FORMAT_XBGR8888
,
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
,
1141 ret
= drm_simple_display_pipe_init(drm
, &mcde
->pipe
,
1142 &mcde_display_funcs
,
1143 formats
, ARRAY_SIZE(formats
),
1151 EXPORT_SYMBOL_GPL(mcde_display_init
);