Hi Linus.

A few repeated comments from last review, and then a bunch
of trivial nits below.
One major thing to consider is to use a regmap for all the register
access.
Another bigger item is the excessive use of logging. Is this relevant
now the driver works or just leftovers which should really be dropped?


> +++ b/drivers/gpu/drm/mcde/mcde_display.c
> @@ -0,0 +1,1292 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 Linus Walleij <linus.wall...@linaro.org>
> + * Parts of this file were based on the MCDE driver by Marcus Lorentzon
> + * (C) ST-Ericsson SA 2013
> + */
> +#include <linux/clk.h>
> +#include <linux/version.h>
> +#include <linux/dma-buf.h>
> +#include <linux/of_graph.h>
Sort includes alphabetically

> +
> +#include <drm/drmP.h>
Do not use drmP in new drivers.
> +#include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
> +#include <drm/drm_fb_cma_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <video/mipi_display.h>
Also sort these alphabetically.

> +#include "mcde_drm.h"
> +
....
> +#define MCDE_DSIVID0DELAY1 0x00000E18
> +#define MCDE_DSICMD0DELAY1 0x00000E38
> +#define MCDE_DSIVID1DELAY1 0x00000E58
> +#define MCDE_DSICMD1DELAY1 0x00000E78
> +#define MCDE_DSIVID2DELAY1 0x00000E98
> +#define MCDE_DSICMD2DELAY1 0x00000EB8
Consider to move all the register definitiosn to a seperate .h
file - local to this driver.
Then the _display, _drv and _dpmi files contains mainly src.


> +void mcde_display_irq(struct mcde *mcde)
> +{
> +     u32 mispp, misovl, mischnl;
> +     bool vblank;
> +
> +     /* Handle display IRQs */
> +     mispp = readl(mcde->regs + MCDE_MISPP);
> +     misovl = readl(mcde->regs + MCDE_MISOVL);
> +     mischnl = readl(mcde->regs + MCDE_MISCHNL);
> +
> +     /*
> +      * Handle IRQs from the DSI link. All IRQs from the DSI links
> +      * are just latched onto the MCDE IRQ line, so we need to traverse
> +      * any active DSI masters and check if an IRQ is originating from
> +      * them.
> +      *
> +      * TODO: Currently only one DSI link is supported.
> +      */
> +     if (mcde_dsi_irq(mcde->mdsi)) {
> +             u32 val;
> +
> +             /*
> +              * In oneshot mode we do not send continuous updates
> +              * to the display, instead we only push out updates when
> +              * the update function is called, then we disable the
> +              * flow on the channel once we get the TE IRQ.
> +              */
> +             if (mcde->oneshot_mode) {
> +                     spin_lock(&mcde->flow_lock);
> +                     if (--mcde->flow_active == 0) {
> +                             dev_dbg(mcde->dev, "TE0 IRQ\n");
> +                             /* Disable FIFO A flow */
> +                             val = readl(mcde->regs + MCDE_CRA0);
> +                             val &= ~MCDE_CRX0_FLOEN;
> +                             writel(val, mcde->regs + MCDE_CRA0);
> +                     }
> +                     spin_unlock(&mcde->flow_lock);
All the code that deals with flow_active would be better
in a few well-named helper functions.
Then is would be more obvious what is going on.
Also there seems to be a little code duplication
around flow_active later in this patch.

The dev_dbg(...) seems as it can flood the terminal if enabled.
Is it maybe a little to excessive logging?
See below for example.

> +             }
> +     }
> +
> +     /* Vblank from one of the channels */
> +     if (mispp & MCDE_PP_VCMPA) {
> +             dev_dbg(mcde->dev, "chnl A vblank IRQ\n");
> +             vblank = true;
> +     }
> +     if (mispp & MCDE_PP_VCMPB) {
> +             dev_dbg(mcde->dev, "chnl B vblank IRQ\n");
> +             vblank = true;
> +     }
> +     if (mispp & MCDE_PP_VCMPC0)
> +             dev_dbg(mcde->dev, "chnl C0 vblank IRQ\n");
> +     if (mispp & MCDE_PP_VCMPC1)
> +             dev_dbg(mcde->dev, "chnl C1 vblank IRQ\n");
> +     if (mispp & MCDE_PP_VSCC0)
> +             dev_dbg(mcde->dev, "chnl C0 TE IRQ\n");
> +     if (mispp & MCDE_PP_VSCC1)
> +             dev_dbg(mcde->dev, "chnl C1 TE IRQ\n");
> +     writel(mispp, mcde->regs + MCDE_RISPP);
> +
> +     if (vblank)
> +             drm_crtc_handle_vblank(&mcde->pipe.crtc);
> +
> +     if (misovl)
> +             dev_info(mcde->dev, "some stray overlay IRQ %08x\n", misovl);
> +     writel(misovl, mcde->regs + MCDE_RISOVL);
> +
> +     if (mischnl)
> +             dev_info(mcde->dev, "some stray channel error IRQ %08x\n",
> +                      mischnl);
> +     writel(mischnl, mcde->regs + MCDE_RISCHNL);
> +}
> +
> +void mcde_display_disable_irqs(struct mcde *mcde)
> +{
> +     /* Disable all IRQs */
> +     writel(0, mcde->regs + MCDE_IMSCPP);
> +     writel(0, mcde->regs + MCDE_IMSCOVL);
> +     writel(0, mcde->regs + MCDE_IMSCCHNL);
> +
> +     /* Clear any pending IRQs */
> +     writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP);
> +     writel(0xFFFFFFFF, mcde->regs + MCDE_RISOVL);
> +     writel(0xFFFFFFFF, mcde->regs + MCDE_RISCHNL);
> +}
> +
> +static int mcde_display_check(struct drm_simple_display_pipe *pipe,
> +                            struct drm_plane_state *pstate,
> +                            struct drm_crtc_state *cstate)
> +{
> +     const struct drm_display_mode *mode = &cstate->mode;
> +     struct drm_framebuffer *old_fb = pipe->plane.state->fb;
> +     struct drm_framebuffer *fb = pstate->fb;
> +
> +     if (fb) {
> +             u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0);
> +
> +             /* FB base address must be dword aligned. */
> +             if (offset & 3) {
> +                     DRM_DEBUG_KMS("FB not 32-bit aligned\n");
> +                     return -EINVAL;
> +             }
> +
> +             /*
> +              * There's no pitch register, the mode's hdisplay
> +              * controls this.
> +              */
> +             if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) {
> +                     DRM_DEBUG_KMS("can't handle pitches\n");
> +                     return -EINVAL;
> +             }
> +
> +             /*
> +              * We can't change the FB format in a flicker-free
> +              * manner (and only update it during CRTC enable).
> +              */
> +             if (old_fb && old_fb->format != fb->format)
> +                     cstate->mode_changed = true;
> +     }
> +
> +     return 0;
> +}
> +
> +static int mcde_dsi_get_pkt_div(int ppl, int fifo_size)
> +{
> +     /*
> +      * DSI command mode line packets should be split into an even number of
> +      * packets smaller than or equal to the fifo size.
> +      */
> +     int div;
> +     const int max_div = DIV_ROUND_UP(MCDE_MAX_WIDTH, fifo_size);
> +
> +     for (div = 1; div < max_div; div++)
> +             if (ppl % div == 0 && ppl / div <= fifo_size)
> +                     return div;
> +     return 1;
> +}
> +
> +static void mcde_display_enable(struct drm_simple_display_pipe *pipe,
> +                             struct drm_crtc_state *cstate,
> +                             struct drm_plane_state *plane_state)
> +{
> +     struct drm_crtc *crtc = &pipe->crtc;
> +     struct drm_plane *plane = &pipe->plane;
> +     struct drm_device *drm = crtc->dev;
> +     struct mcde *mcde = drm->dev_private;
> +     const struct drm_display_mode *mode = &cstate->mode;
> +     struct drm_framebuffer *fb = plane->state->fb;
> +     u32 format = fb->format->format;
> +     u32 formatter_ppl = mode->hdisplay; /* pixels per line */
> +     u32 formatter_lpf = mode->vdisplay; /* lines per frame */
> +     int pkt_size, fifo_wtrmrk;
> +     int cpp = drm_format_plane_cpp(format, 0);
> +     int formatter_cpp;
> +     struct drm_format_name_buf tmp;
> +     u32 formatter_frame;
> +     u32 pkt_div;
> +     u32 val;
Very long function. Consider to break it up in some well named smaller
chunks.

> +
> +     dev_info(drm->dev, "enable MCDE, %d x %d format %s\n",
> +              mode->hdisplay, mode->vdisplay,
> +              drm_get_format_name(format, &tmp));
> +     if (!mcde->mdsi) {
> +             /* TODO: deal with this for non-DSI output */
> +             dev_err(drm->dev, "no DSI master attached!\n");
> +             return;
> +     }
> +
> +     dev_info(drm->dev, "output in %s mode, format %dbpp\n",
> +              (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ?
> +              "VIDEO" : "CMD",
> +              mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format));
> +     formatter_cpp =
> +             mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format) / 8;
> +     dev_info(drm->dev, "overlay CPP %d bytes, DSI CPP %d bytes\n",
> +              cpp,
> +              formatter_cpp);
> +
> +     /* Calculations from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() */
> +
> +     /*
> +      * Set up FIFO A watermark level:
> +      * 128 for LCD 32bpp video mode
> +      * 48  for LCD 32bpp command mode
> +      * 128 for LCD 16bpp video mode
> +      * 64  for LCD 16bpp command mode
> +      * 128 for HDMI 32bpp
> +      * 192 for HDMI 16bpp
> +      */
> +     fifo_wtrmrk = mode->hdisplay;
> +     if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
> +             fifo_wtrmrk = min(fifo_wtrmrk, 128);
> +             pkt_div = 1;
> +     } else {
> +             fifo_wtrmrk = min(fifo_wtrmrk, 48);
> +             /* The FIFO is 640 entries deep on this v3 hardware */
> +             pkt_div = mcde_dsi_get_pkt_div(mode->hdisplay, 640);
> +     }
> +     dev_dbg(drm->dev, "FIFO watermark after flooring: %d bytes\n",
> +              fifo_wtrmrk);
> +     dev_dbg(drm->dev, "Packet divisor: %d bytes\n", pkt_div);
> +
> +
> +     /* NOTE: pkt_div is 1 for video mode */
> +     pkt_size = (formatter_ppl * formatter_cpp) / pkt_div;
> +     /* Commands CMD8 need one extra byte */
> +     if (!(mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO))
> +             pkt_size++;
> +
> +     dev_dbg(drm->dev, "DSI packet size: %d * %d bytes per line\n",
> +             pkt_size, pkt_div);
> +     dev_dbg(drm->dev, "Overlay frame size: %u bytes\n",
> +             mode->hdisplay * mode->vdisplay * cpp);
> +     mcde->stride = mode->hdisplay * cpp;
> +     dev_dbg(drm->dev, "Overlay line stride: %u bytes\n",
> +             mcde->stride);
> +     /* NOTE: pkt_div is 1 for video mode */
> +     formatter_frame = pkt_size * pkt_div * formatter_lpf;
> +     dev_dbg(drm->dev, "Formatter frame size: %u bytes\n", formatter_frame);
> +
> +     /* Check that the hardware on channel A is in a sane state */
> +     val = readl(mcde->regs + MCDE_CTRLA);
> +     if (!(val & MCDE_CTRLX_FIFOEMPTY)) {
> +             int timeout = 100;
> +
> +             dev_err(drm->dev, "Channel A FIFO not empty (handover)\n");
> +             /* Attempt to clear the FIFO */
> +             /* Enable FIFO A flow */
> +             val = readl(mcde->regs + MCDE_CRA0);
> +             val |= MCDE_CRX0_FLOEN;
> +             writel(val, mcde->regs + MCDE_CRA0);
> +             /* Trigger a software sync out on channel 0 */
> +             writel(MCDE_CHNLXSYNCHSW_SW_TRIG,
> +                    mcde->regs + MCDE_CHNL0SYNCHSW);
> +             /* Disable FIFO A flow again */
> +             val = readl(mcde->regs + MCDE_CRA0);
> +             val &= ~MCDE_CRX0_FLOEN;
> +             writel(val, mcde->regs + MCDE_CRA0);
> +             while (readl(mcde->regs + MCDE_CRA0) & MCDE_CRX0_FLOEN) {
> +                     usleep_range(1000, 1500);
> +                     if (!--timeout) {
> +                             dev_err(drm->dev,
> +                                     "FIFO A timeout while clearing\n");
> +                             break;
> +                     }
> +             }
> +     }
> +
> +     /* Set up FIFO A and channel 0 (based on chnl_update_registers()) */
> +
> +     if (mcde->te_sync) {
> +             /*
> +              * Turn on hardware TE0 synchronization
> +              */
> +             val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE
> +                     << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;
> +             val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0
> +                     << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;
> +     } else {
> +             /*
> +              * Set up sync source to software, out sync formatter
> +              * Code mostly from mcde_hw.c chnl_update_registers()
> +              */
> +             val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SOFTWARE
> +                     << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;
> +             val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER
> +                     << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;
> +     }
> +     writel(val, mcde->regs + MCDE_CHNL0SYNCHMOD);
> +
> +     /* Set up FIFO for channel A */
> +     val = fifo_wtrmrk << MCDE_CTRLX_FIFOWTRMRK_SHIFT;
> +     /* We only support DSI formatting for now */
> +     val |= MCDE_CTRLX_FORMTYPE_DSI <<
> +             MCDE_CTRLX_FORMTYPE_SHIFT;
> +     /* Use formatter 0 for FIFO A */
> +     val |= 0 << MCDE_CTRLX_FORMID_SHIFT;
> +     writel(val, mcde->regs + MCDE_CTRLA);
> +
> +     /* Set up muxing: connect channel 0 to FIFO A */
> +     writel(MCDE_CHNLXMUXING_FIFO_ID_FIFO_A,
> +            mcde->regs + MCDE_CHNL0MUXING);
> +
> +     /* Pixel-per-line and line-per-frame set-up for the channel */
> +     val = (mode->hdisplay - 1) << MCDE_CHNLXCONF_PPL_SHIFT;
> +     val |= (mode->vdisplay - 1) << MCDE_CHNLXCONF_LPF_SHIFT;
> +     writel(val, mcde->regs + MCDE_CHNL0CONF);
> +
> +     /*
> +      * Normalize color conversion:
> +      * black background, OLED conversion disable on channel 0
> +      * FIFO A, no rotation.
> +      */
> +     val = MCDE_CHNLXSTAT_CHNLBLBCKGND_EN |
> +             MCDE_CHNLXSTAT_CHNLRD;
> +     writel(val, mcde->regs + MCDE_CHNL0STAT);
> +     writel(0, mcde->regs + MCDE_CHNL0BCKGNDCOL);
> +     /* Blend source with Alpha 0xff on FIFO A */
> +     val = MCDE_CRX0_BLENDEN |
> +             0xff << MCDE_CRX0_ALPHABLEND_SHIFT;
> +     writel(val, mcde->regs + MCDE_CRA0);
> +
> +     /*
> +      * Configure external source 0 one buffer (buffer 0)
> +      * primary overlay ID 0.
> +      * From mcde_hw.c ovly_update_registers() in the vendor tree
> +      */
> +     val = 0 << MCDE_EXTSRCXCONF_BUF_ID_SHIFT;
> +     val |= 1 << MCDE_EXTSRCXCONF_BUF_NB_SHIFT;
> +     val |= 0 << MCDE_EXTSRCXCONF_PRI_OVLID_SHIFT;
> +     /*
> +      * MCDE has inverse semantics from DRM on RBG/BGR which is why
> +      * all the modes are inversed here.
> +      */
> +     switch (format) {
> +     case DRM_FORMAT_ARGB8888:
> +             val |= MCDE_EXTSRCXCONF_BPP_ARGB8888 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             val |= MCDE_EXTSRCXCONF_BGR;
> +             break;
> +     case DRM_FORMAT_ABGR8888:
> +             val |= MCDE_EXTSRCXCONF_BPP_ARGB8888 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             break;
> +     case DRM_FORMAT_XRGB8888:
> +             val |= MCDE_EXTSRCXCONF_BPP_XRGB8888 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             val |= MCDE_EXTSRCXCONF_BGR;
> +             break;
> +     case DRM_FORMAT_XBGR8888:
> +             val |= MCDE_EXTSRCXCONF_BPP_XRGB8888 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             break;
> +     case DRM_FORMAT_RGB888:
> +             val |= MCDE_EXTSRCXCONF_BPP_RGB888 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             val |= MCDE_EXTSRCXCONF_BGR;
> +             break;
> +     case DRM_FORMAT_BGR888:
> +             val |= MCDE_EXTSRCXCONF_BPP_RGB888 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             break;
> +     case DRM_FORMAT_ARGB4444:
> +             val |= MCDE_EXTSRCXCONF_BPP_ARGB4444 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             val |= MCDE_EXTSRCXCONF_BGR;
> +             break;
> +     case DRM_FORMAT_ABGR4444:
> +             val |= MCDE_EXTSRCXCONF_BPP_ARGB4444 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             break;
> +     case DRM_FORMAT_XRGB4444:
> +             val |= MCDE_EXTSRCXCONF_BPP_RGB444 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             val |= MCDE_EXTSRCXCONF_BGR;
> +             break;
> +     case DRM_FORMAT_XBGR4444:
> +             val |= MCDE_EXTSRCXCONF_BPP_RGB444 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             break;
> +     case DRM_FORMAT_XRGB1555:
> +             val |= MCDE_EXTSRCXCONF_BPP_IRGB1555 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             val |= MCDE_EXTSRCXCONF_BGR;
> +             break;
> +     case DRM_FORMAT_XBGR1555:
> +             val |= MCDE_EXTSRCXCONF_BPP_IRGB1555 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             break;
> +     case DRM_FORMAT_RGB565:
> +             val |= MCDE_EXTSRCXCONF_BPP_RGB565 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             val |= MCDE_EXTSRCXCONF_BGR;
> +             break;
> +     case DRM_FORMAT_BGR565:
> +             val |= MCDE_EXTSRCXCONF_BPP_RGB565 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             break;
> +     case DRM_FORMAT_YUV422:
> +             val |= MCDE_EXTSRCXCONF_BPP_YCBCR422 <<
> +                     MCDE_EXTSRCXCONF_BPP_SHIFT;
> +             break;
> +     default:
> +             dev_err(drm->dev, "Unknown pixel format 0x%08x\n",
> +                     fb->format->format);
> +             break;
> +     }
> +     writel(val, mcde->regs + MCDE_EXTSRC0CONF);
> +     /* Software select, primary */
> +     val = MCDE_EXTSRC0CR_SEL_MOD_SOFTWARE_SEL;
> +     val |= MCDE_EXTSRC0CR_MULTIOVL_CTRL_PRIMARY;
> +     writel(val, mcde->regs + MCDE_EXTSRC0CR);
> +
> +     /* Configure overlay 0 */
> +     val = mode->hdisplay << MCDE_OVLXCONF_PPL_SHIFT;
> +     val |= mode->vdisplay << MCDE_OVLXCONF_LPF_SHIFT;
> +     /* Use external source 0 that we just configured */
> +     val |= 0 << MCDE_OVLXCONF_EXTSRC_ID_SHIFT;
> +     writel(val, mcde->regs + MCDE_OVL0CONF);
> +
> +     val = MCDE_OVLXCONF2_BP_PER_PIXEL_ALPHA;
> +     val |= 0xff << MCDE_OVLXCONF2_ALPHAVALUE_SHIFT;
> +     /* OPQ: overlay is opaque */
> +     switch (format) {
> +     case DRM_FORMAT_ARGB8888:
> +     case DRM_FORMAT_ABGR8888:
> +     case DRM_FORMAT_ARGB4444:
> +     case DRM_FORMAT_ABGR4444:
> +     case DRM_FORMAT_XRGB1555:
> +     case DRM_FORMAT_XBGR1555:
> +             /* No OPQ */
> +             break;
> +     case DRM_FORMAT_XRGB8888:
> +     case DRM_FORMAT_XBGR8888:
> +     case DRM_FORMAT_RGB888:
> +     case DRM_FORMAT_BGR888:
> +     case DRM_FORMAT_RGB565:
> +     case DRM_FORMAT_BGR565:
> +     case DRM_FORMAT_YUV422:
> +             val |= MCDE_OVLXCONF2_OPQ;
> +             break;
> +     default:
> +             dev_err(drm->dev, "Unknown pixel format 0x%08x\n",
> +                     fb->format->format);
> +             break;
> +     }
> +     /* The default watermark level for overlay 0 is 48 */
> +     val |= 48 << MCDE_OVLXCONF2_PIXELFETCHERWATERMARKLEVEL_SHIFT;
> +     writel(val, mcde->regs + MCDE_OVL0CONF2);
> +
> +     /* Number of bytes to fetch per line */
> +     writel(mcde->stride, mcde->regs + MCDE_OVL0LJINC);
> +     /* No cropping */
> +     writel(0, mcde->regs + MCDE_OVL0CROP);
> +
> +     /* Set up overlay control register */
> +     val = MCDE_OVLXCR_OVLEN;
> +     val |= MCDE_OVLXCR_COLCCTRL_DISABLED;
> +     val |= MCDE_OVLXCR_BURSTSIZE_8W <<
> +             MCDE_OVLXCR_BURSTSIZE_SHIFT;
> +     val |= MCDE_OVLXCR_MAXOUTSTANDING_8_REQ <<
> +             MCDE_OVLXCR_MAXOUTSTANDING_SHIFT;
> +     /* Not using rotation but set it up anyways */
> +     val |= MCDE_OVLXCR_ROTBURSTSIZE_8W <<
> +             MCDE_OVLXCR_ROTBURSTSIZE_SHIFT;
> +     writel(val, mcde->regs + MCDE_OVL0CR);
> +
> +     /* Set-up from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() */
> +
> +     /* Channel formatter set-up for channel A */
> +     val = MCDE_CRX1_CLKSEL_MCDECLK << MCDE_CRX1_CLKSEL_SHIFT;
> +     /* TODO: when adding DPI support add OUTBPP etc here */
> +     writel(val, mcde->regs + MCDE_CRA1);
> +
> +     /*
> +      * Enable formatter
> +      * 8 bit commands and DCS commands (notgen = not generic)
> +      */
> +     val = MCDE_DSICONF0_CMD8 | MCDE_DSICONF0_DCSVID_NOTGEN;
> +     if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO)
> +             val |= MCDE_DSICONF0_VID_MODE_VID;
> +     switch (mcde->mdsi->format) {
> +     case MIPI_DSI_FMT_RGB888:
> +             val |= MCDE_DSICONF0_PACKING_RGB888 <<
> +                     MCDE_DSICONF0_PACKING_SHIFT;
> +             break;
> +     case MIPI_DSI_FMT_RGB666:
> +             val |= MCDE_DSICONF0_PACKING_RGB666 <<
> +                     MCDE_DSICONF0_PACKING_SHIFT;
> +             break;
> +     case MIPI_DSI_FMT_RGB666_PACKED:
> +             val |= MCDE_DSICONF0_PACKING_RGB666_PACKED <<
> +                     MCDE_DSICONF0_PACKING_SHIFT;
> +             break;
> +     case MIPI_DSI_FMT_RGB565:
> +             val |= MCDE_DSICONF0_PACKING_RGB565 <<
> +                     MCDE_DSICONF0_PACKING_SHIFT;
> +             break;
> +     default:
> +             dev_err(drm->dev, "unknown DSI format\n");
> +             return;
> +     }
> +     writel(val, mcde->regs + MCDE_DSIVID0CONF0);
> +
> +     writel(formatter_frame, mcde->regs + MCDE_DSIVID0FRAME);
> +     writel(pkt_size, mcde->regs + MCDE_DSIVID0PKT);
> +     writel(0, mcde->regs + MCDE_DSIVID0SYNC);
> +     /* Define the MIPI command: we want to write into display memory */
> +     val = MIPI_DCS_WRITE_MEMORY_CONTINUE <<
> +             MCDE_DSIVIDXCMDW_CMDW_CONTINUE_SHIFT;
> +     val |= MIPI_DCS_WRITE_MEMORY_START <<
> +             MCDE_DSIVIDXCMDW_CMDW_START_SHIFT;
> +     writel(val, mcde->regs + MCDE_DSIVID0CMDW);
> +     /*
> +      * FIXME: the vendor driver has some hack around this value in
> +      * CMD mode with autotrig.
> +      */
> +     writel(0, mcde->regs + MCDE_DSIVID0DELAY0);
> +     writel(0, mcde->regs + MCDE_DSIVID0DELAY1);
> +
> +     if (mcde->te_sync) {
> +             if (mode->flags & DRM_MODE_FLAG_NVSYNC)
> +                     val = MCDE_VSCRC_VSPOL;
> +             else
> +                     val = 0;
> +             writel(val, mcde->regs + MCDE_VSCRC0);
> +             /* Enable VSYNC capture on TE0 */
> +             val = readl(mcde->regs + MCDE_CRC);
> +             val |= MCDE_CRC_SYCEN0;
> +             writel(val, mcde->regs + MCDE_CRC);
> +
> +             drm_crtc_vblank_on(crtc);
> +     }
> +
> +     dev_info(drm->dev, "MCDE display is enabled\n");
> +     mcde->enabled = true;
> +}
> +
> +static void mcde_display_disable(struct drm_simple_display_pipe *pipe)
> +{
> +     struct drm_crtc *crtc = &pipe->crtc;
> +     struct drm_device *drm = crtc->dev;
> +     struct mcde *mcde = drm->dev_private;
> +     int timeout = 100;
> +     u32 val;
> +
> +     /* Stops framebuffer updates */
> +     mcde->enabled = false;
> +
> +     if (mcde->te_sync)
> +             drm_crtc_vblank_off(crtc);
> +
> +     /* Disable FIFO A flow */
> +     val = readl(mcde->regs + MCDE_CRA0);
> +     val &= ~MCDE_CRX0_FLOEN;
> +     writel(val, mcde->regs + MCDE_CRA0);
> +     while (readl(mcde->regs + MCDE_CRA0) & MCDE_CRX0_FLOEN) {
> +             usleep_range(1000, 1500);
> +             if (!--timeout) {
> +                     dev_err(drm->dev,
> +                             "FIFO A timeout while stopping\n");
> +                     break;
> +             }
> +     }

Here I recall regmap has something similar implmented.
So another good reason to use regmap.


> +     spin_lock(&mcde->flow_lock);
> +     mcde->flow_active = 0;
> +     spin_unlock(&mcde->flow_lock);
> +
> +     dev_info(drm->dev, "MCDE display is disabled\n");
> +}
> +
> +static void mcde_display_send_one_frame(struct mcde *mcde)
> +{
> +     int timeout = 100;
> +     u32 val;
> +
> +     /* Request a TE ACK */
> +     if (mcde->te_sync)
> +             mcde_dsi_te_request(mcde->mdsi);
> +
> +     /* Enable FIFO A flow */
> +     spin_lock(&mcde->flow_lock);
> +     val = readl(mcde->regs + MCDE_CRA0);
> +     val |= MCDE_CRX0_FLOEN;
> +     writel(val, mcde->regs + MCDE_CRA0);
> +     mcde->flow_active++;
> +     spin_unlock(&mcde->flow_lock);
> +
> +     if (mcde->te_sync) {
> +             /*
> +              * If oneshot mode is enabled, the flow will be disabled
> +              * when the TE0 IRQ arrives in the interrupt handler. Otherwise
> +              * updates are continuously streamed to the display after this
> +              * point.
> +              */
> +             dev_info(mcde->dev, "sent TE0 framebuffer update\n");
> +             return;
> +     }
> +
> +     /* Trigger a software sync out on channel 0 */
> +     writel(MCDE_CHNLXSYNCHSW_SW_TRIG,
> +            mcde->regs + MCDE_CHNL0SYNCHSW);
> +     /* Disable FIFO A flow again */
> +     spin_lock(&mcde->flow_lock);
> +     val = readl(mcde->regs + MCDE_CRA0);
> +     val &= ~MCDE_CRX0_FLOEN;
> +     writel(val, mcde->regs + MCDE_CRA0);
> +     mcde->flow_active = 0;
> +     spin_unlock(&mcde->flow_lock);
> +
> +     /*
> +      * At this point the DSI link should be running a
> +      * frame update.
> +      */
> +     while (readl(mcde->regs + MCDE_CRA0) & MCDE_CRX0_FLOEN) {
> +             usleep_range(1000, 1500);
> +             if (!--timeout) {
> +                     dev_err(mcde->dev, "FIFO A timeout\n");
> +                     break;
> +             }
> +     }
> +     dev_dbg(mcde->dev, "sent SW framebuffer update\n");
> +}
> +
> +static void mcde_set_extsrc(struct mcde *mcde, u32 buffer_address)
> +{
> +     /* Write bitmap base address to register */
> +     writel(buffer_address, mcde->regs + MCDE_EXTSRCXA0);
> +     /*
> +      * Base address for next line this is probably only used
> +      * in interlace modes.
> +      */
> +     writel(buffer_address + mcde->stride, mcde->regs + MCDE_EXTSRCXA1);
> +
> +     /* Set up overlay 0 compositor route to channel A */
> +     writel(0, mcde->regs + MCDE_OVL0COMP);
> +}
> +
> +static void mcde_display_update(struct drm_simple_display_pipe *pipe,
> +                              struct drm_plane_state *old_pstate)
> +{
> +     struct drm_crtc *crtc = &pipe->crtc;
> +     struct drm_device *drm = crtc->dev;
> +     struct mcde *mcde = drm->dev_private;
> +     struct drm_pending_vblank_event *event = crtc->state->event;
> +     struct drm_plane *plane = &pipe->plane;
> +     struct drm_plane_state *pstate = plane->state;
> +     struct drm_framebuffer *fb = pstate->fb;
> +
> +     /*
> +      * We do not start sending framebuffer updates before the
> +      * display is enabled. Update events will however be dispatched
> +      * from the DRM core before the display is enabled.
> +      */
> +     if (fb && mcde->enabled) {
> +             mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0));
> +             /* Send a single frame using software sync */
> +             mcde_display_send_one_frame(mcde);
> +     } else {
> +             /*
> +              * If an update is receieved before the MCDE is enabled
> +              * (before mcde_display_enable() is called) we can't really
> +              * do much with that buffer.
> +              */
> +             dev_info(mcde->dev, "ignored a display update\n");
> +     }
> +
> +     /* Handle any pending event */
> +     if (event) {
> +             crtc->state->event = NULL;
> +
> +             spin_lock_irq(&crtc->dev->event_lock);
> +             /*
> +              * Hardware must be on before we can arm any vblank event,
> +              * this is not a scanout controller where there is always
> +              * some periodic update going on, it is completely frozen
> +              * until we get an update. If MCDE output isn't yet enabled,
> +              * we just send a vblank dummy event back.
> +              */
> +             if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0 &&
> +                 mcde->enabled && mcde->vblank_irq_on) {
> +                     dev_dbg(mcde->dev, "arm vblank event\n");
> +                     drm_crtc_arm_vblank_event(crtc, event);
> +             } else {
> +                     dev_dbg(mcde->dev, "insert fake vblank event\n");
> +                     drm_crtc_send_vblank_event(crtc, event);
> +             }
> +
> +             spin_unlock_irq(&crtc->dev->event_lock);
> +     }
> +}
> +
> +static int mcde_display_enable_vblank(struct drm_simple_display_pipe *pipe)
> +{
> +     struct drm_crtc *crtc = &pipe->crtc;
> +     struct drm_device *drm = crtc->dev;
> +     struct mcde *mcde = drm->dev_private;
> +     u32 val;
> +
> +     /* Enable all VBLANK IRQs */
> +     val = MCDE_PP_VCMPA |
> +             MCDE_PP_VCMPB |
> +             MCDE_PP_VSCC0 |
> +             MCDE_PP_VSCC1 |
> +             MCDE_PP_VCMPC0 |
> +             MCDE_PP_VCMPC1;
> +     writel(val, mcde->regs + MCDE_IMSCPP);
> +     mcde->vblank_irq_on = true;
> +
> +     return 0;
> +}
> +
> +static void mcde_display_disable_vblank(struct drm_simple_display_pipe *pipe)
> +{
> +     struct drm_crtc *crtc = &pipe->crtc;
> +     struct drm_device *drm = crtc->dev;
> +     struct mcde *mcde = drm->dev_private;
> +
> +     /* Disable all VBLANK IRQs */
> +     writel(0, mcde->regs + MCDE_IMSCPP);
> +     /* Clear any pending IRQs */
> +     writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP);
> +     mcde->vblank_irq_on = false;
> +}
> +
> +static int mcde_display_prepare_fb(struct drm_simple_display_pipe *pipe,
> +                                 struct drm_plane_state *plane_state)
> +{
> +     return drm_gem_fb_prepare_fb(&pipe->plane, plane_state);
> +}
> +
> +static struct drm_simple_display_pipe_funcs mcde_display_funcs = {
> +     .check = mcde_display_check,
> +     .enable = mcde_display_enable,
> +     .disable = mcde_display_disable,
> +     .update = mcde_display_update,
> +     .prepare_fb = mcde_display_prepare_fb,
> +};
> +
> +int mcde_display_init(struct drm_device *drm)
> +{
> +     struct mcde *mcde = drm->dev_private;
> +     int ret;
> +     static const u32 formats[] = {
> +             DRM_FORMAT_ARGB8888,
> +             DRM_FORMAT_ABGR8888,
> +             DRM_FORMAT_XRGB8888,
> +             DRM_FORMAT_XBGR8888,
> +             DRM_FORMAT_RGB888,
> +             DRM_FORMAT_BGR888,
> +             DRM_FORMAT_ARGB4444,
> +             DRM_FORMAT_ABGR4444,
> +             DRM_FORMAT_XRGB4444,
> +             DRM_FORMAT_XBGR4444,
> +             /* These are actually IRGB1555 so intensity bit is lost */
> +             DRM_FORMAT_XRGB1555,
> +             DRM_FORMAT_XBGR1555,
> +             DRM_FORMAT_RGB565,
> +             DRM_FORMAT_BGR565,
> +             DRM_FORMAT_YUV422,
> +     };
> +
> +     /* Provide vblank only when we have TE enabled */
> +     if (mcde->te_sync) {
> +             mcde_display_funcs.enable_vblank = mcde_display_enable_vblank;
> +             mcde_display_funcs.disable_vblank = mcde_display_disable_vblank;
> +     }
> +
> +     ret = drm_simple_display_pipe_init(drm, &mcde->pipe,
> +                                        &mcde_display_funcs,
> +                                        formats, ARRAY_SIZE(formats),
> +                                        NULL,
> +                                        mcde->connector);
> +     if (ret)
> +             return ret;
> +
> +     return 0;
> +}
> +EXPORT_SYMBOL_GPL(mcde_display_init);
> diff --git a/drivers/gpu/drm/mcde/mcde_drm.h b/drivers/gpu/drm/mcde/mcde_drm.h
> new file mode 100644
> index 000000000000..8c04665ebcfc
> --- /dev/null
> +++ b/drivers/gpu/drm/mcde/mcde_drm.h
> @@ -0,0 +1,47 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2018 Linus Walleij <linus.wall...@linaro.org>
> + * Parts of this file were based on the MCDE driver by Marcus Lorentzon
> + * (C) ST-Ericsson SA 2013
> + */
> +#include <drm/drm_simple_kms_helper.h>
> +
> +#ifndef _MCDE_DRM_H_
> +#define _MCDE_DRM_H_
> +
> +struct mcde {
> +     struct device *dev;
> +
> +     struct drm_device *drm;

Consider to embed drm_device.
Se sample code in drm_drv.c - in drm-misc-next branch.
This will also teach you not to use devm_kzalloc and to start using
.release callback.

> +     struct drm_panel *panel;
> +     struct drm_bridge *bridge;
> +     struct drm_connector *connector;
> +     struct drm_simple_display_pipe pipe;
> +     struct mipi_dsi_device *mdsi;
> +     s16 stride;
> +     bool enabled;
> +     bool vblank_irq_on;
> +     bool te_sync;
> +     bool oneshot_mode;
> +     unsigned int flow_active;
> +     spinlock_t flow_lock; /* Locks the channel flow control */
> +
> +     void __iomem *regs;
> +
> +     struct clk *mcde_clk;
> +     struct clk *lcd_clk;
> +     struct clk *hdmi_clk;
> +
> +     struct regulator *epod;
> +     struct regulator *vana;
> +};
> +
> +bool mcde_dsi_irq(struct mipi_dsi_device *mdsi);
> +void mcde_dsi_te_request(struct mipi_dsi_device *mdsi);
> +extern struct platform_driver mcde_dsi_driver;
> +
> +void mcde_display_irq(struct mcde *mcde);
> +void mcde_display_disable_irqs(struct mcde *mcde);
> +int mcde_display_init(struct drm_device *drm);
> +
> +#endif /* _MCDE_DRM_H_ */
> diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
> new file mode 100644
> index 000000000000..1630289a7faa
> --- /dev/null
> +++ b/drivers/gpu/drm/mcde/mcde_drv.c
> @@ -0,0 +1,540 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 Linus Walleij <linus.wall...@linaro.org>
> + * Parts of this file were based on the MCDE driver by Marcus Lorentzon
> + * (C) ST-Ericsson SA 2013
> + */
> +
> +/**
> + * DOC: ST-Ericsson MCDE Driver
> + *
> + * The MCDE (short for Multi-channel display engine) is a graphics
> + * controller found in the Ux500 chipsets, such as NovaThor U8500.
> + * It was initially conceptualized by ST Microelectronics for the
> + * successor of the Nomadik line, STn8500 but productified in the
> + * ST-Ericsson U8500 where is was used for mass-market deployments
> + * in Android phones from Samsung and Sony Ericsson.
> + *
> + * It can do 1080p30 on SDTV CCIR656, DPI-2, DBI-2 or DSI for
> + * panels with or without frame buffering and can convert most
> + * input formats including most variants of RGB and YUV.
> + *
> + * The hardware has four display pipes, and the layout is a little
> + * bit like this:
> + *
> + * Memory     -> 6 channels -> 5 formatters -> DSI/DPI -> LCD/HDMI
> + * 10 sources    (overlays)                    3 x DSI
> + *
> + * The memory has 5 input channels (memory ports):
> + * 2 channel A (LCD/HDMI)
> + * 2 channel B (LCD/HDMI)
> + * 1 channel CO/C1 (Panel with embedded buffer)
> + *
> + * 3 of the formatters are for DSI
> + * 2 of the formatters are for DPI
> + *
> + * Behind the formatters are the DSI or DPI ports, that route to
> + * the external pins of the chip. As there are 3 DSI ports and one
> + * DPI port, it is possible to configure up to 4 display pipelines.
> + *
> + * In the current DRM/KMS setup, we use one channel and one formatter
> + * which we connect to the simple CMA framebuffer helpers. We then
> + * provide a bridge to the DSI port, and on the DSI port bridge we
> + * connect hang a panel bridge or other bridge. This may be subject
> + * to change as we exploit more of the hardware capabilities.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/dma-buf.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +#include <linux/component.h>
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_gem.h>
> +#include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
> +#include <drm/drm_fb_helper.h>
> +#include <drm/drm_fb_cma_helper.h>
> +#include <drm/drm_probe_helper.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_bridge.h>
Samme comments as before on include files (sort, drop drmP.h)

> +
> +#include "mcde_drm.h"
> +
> +#define DRIVER_DESC  "DRM module for MCDE"
> +
> +#define MCDE_CR 0x00000000
> +#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_SHIFT 0
> +#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_MASK 0x0000003F
> +#define MCDE_CR_IFIFOCTRLEN BIT(15)
> +#define MCDE_CR_UFRECOVERY_MODE_V422 BIT(16)
> +#define MCDE_CR_WRAP_MODE_V422_SHIFT BIT(17)
> +#define MCDE_CR_AUTOCLKG_EN BIT(30)
> +#define MCDE_CR_MCDEEN BIT(31)
> +
> +#define MCDE_CONF0 0x00000004
> +#define MCDE_CONF0_SYNCMUX0 BIT(0)
> +#define MCDE_CONF0_SYNCMUX1 BIT(1)
> +#define MCDE_CONF0_SYNCMUX2 BIT(2)
> +#define MCDE_CONF0_SYNCMUX3 BIT(3)
> +#define MCDE_CONF0_SYNCMUX4 BIT(4)
> +#define MCDE_CONF0_SYNCMUX5 BIT(5)
> +#define MCDE_CONF0_SYNCMUX6 BIT(6)
> +#define MCDE_CONF0_SYNCMUX7 BIT(7)
> +#define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT 12
> +#define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_MASK 0x00007000
> +#define MCDE_CONF0_OUTMUX0_SHIFT 16
> +#define MCDE_CONF0_OUTMUX0_MASK 0x00070000
> +#define MCDE_CONF0_OUTMUX1_SHIFT 19
> +#define MCDE_CONF0_OUTMUX1_MASK 0x00380000
> +#define MCDE_CONF0_OUTMUX2_SHIFT 22
> +#define MCDE_CONF0_OUTMUX2_MASK 0x01C00000
> +#define MCDE_CONF0_OUTMUX3_SHIFT 25
> +#define MCDE_CONF0_OUTMUX3_MASK 0x0E000000
> +#define MCDE_CONF0_OUTMUX4_SHIFT 28
> +#define MCDE_CONF0_OUTMUX4_MASK 0x70000000
> +
> +#define MCDE_SSP 0x00000008
> +#define MCDE_AIS 0x00000100
> +#define MCDE_IMSCERR 0x00000110
> +#define MCDE_RISERR 0x00000120
> +#define MCDE_MISERR 0x00000130
> +#define MCDE_SISERR 0x00000140
> +
> +#define MCDE_PID 0x000001FC
> +#define MCDE_PID_METALFIX_VERSION_SHIFT 0
> +#define MCDE_PID_METALFIX_VERSION_MASK 0x000000FF
> +#define MCDE_PID_DEVELOPMENT_VERSION_SHIFT 8
> +#define MCDE_PID_DEVELOPMENT_VERSION_MASK 0x0000FF00
> +#define MCDE_PID_MINOR_VERSION_SHIFT 16
> +#define MCDE_PID_MINOR_VERSION_MASK 0x00FF0000
> +#define MCDE_PID_MAJOR_VERSION_SHIFT 24
> +#define MCDE_PID_MAJOR_VERSION_MASK 0xFF000000
Likewise on register definitions => separate file?

> +
> +static const struct drm_mode_config_funcs mode_config_funcs = {
> +     .fb_create = drm_gem_fb_create,
> +     .atomic_check = drm_atomic_helper_check,
> +     .atomic_commit = drm_atomic_helper_commit,
> +};
> +
> +static irqreturn_t mcde_irq(int irq, void *data)
> +{
> +     struct mcde *mcde = data;
> +     u32 val;
> +
> +     val = readl(mcde->regs + MCDE_MISERR);
> +
> +     mcde_display_irq(mcde);
> +
> +     if (val)
> +             dev_info(mcde->dev, "some error IRQ\n");
> +     writel(val, mcde->regs + MCDE_RISERR);
> +
> +     return IRQ_HANDLED;
> +}
> +
> +static int mcde_modeset_init(struct drm_device *drm)
> +{
> +     struct drm_mode_config *mode_config;
> +     struct mcde *mcde = drm->dev_private;
> +     int ret;
> +
> +     if (!mcde->bridge) {
> +             dev_err(drm->dev, "no display output bridge yet\n");
> +             return -EPROBE_DEFER;
> +     }
> +
> +     mode_config = &drm->mode_config;
> +     mode_config->funcs = &mode_config_funcs;
> +     /* This hardware can do 1080p */
> +     mode_config->min_width = 1;
> +     mode_config->max_width = 1920;
> +     mode_config->min_height = 1;
> +     mode_config->max_height = 1080;
> +
> +     /*
> +      * Currently we only support vblank handling on the DSI bridge, using
> +      * TE synchronization. If TE sync is not set up, it is still possible
> +      * to push out a single update on demand, but this is hard for DRM to
> +      * exploit.
> +      */
> +     if (mcde->te_sync) {
> +             ret = drm_vblank_init(drm, 1);
> +             if (ret) {
> +                     dev_err(drm->dev, "failed to init vblank\n");
> +                     goto out_config;
> +             }
> +     }
> +
> +     ret = mcde_display_init(drm);
> +     if (ret) {
> +             dev_err(drm->dev, "failed to init display\n");
> +             goto out_config;
> +     }
> +
> +     /*
> +      * Attach the DSI bridge
> +      *
> +      * TODO: when adding support for the DPI bridge or several DSI bridges,
> +      * we selectively connect the bridge(s) here instead of this simple
> +      * attachment.
> +      */
> +     ret = drm_simple_display_pipe_attach_bridge(&mcde->pipe,
> +                                                    mcde->bridge);
> +     if (ret) {
> +             dev_err(drm->dev, "failed to attach display output bridge\n");
> +             goto out_config;
> +     }
> +
> +     drm_mode_config_reset(drm);
> +     drm_kms_helper_poll_init(drm);
> +     drm_fbdev_generic_setup(drm, 32);
> +
> +     return 0;
> +
> +out_config:
> +     drm_mode_config_cleanup(drm);
> +     return ret;
> +}
> +
> +DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
> +
> +static struct drm_driver mcde_drm_driver = {
> +     .driver_features =
> +             DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
> +     .lastclose = drm_fb_helper_lastclose,
> +     .ioctls = NULL,
> +     .fops = &drm_fops,
> +     .name = "mcde",
> +     .desc = DRIVER_DESC,
> +     .date = "20180529",
> +     .major = 1,
> +     .minor = 0,
> +     .patchlevel = 0,
> +     .dumb_create = drm_gem_cma_dumb_create,
> +     .gem_free_object_unlocked = drm_gem_cma_free_object,
> +     .gem_vm_ops = &drm_gem_cma_vm_ops,
> +
> +     .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
> +     .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
> +     .gem_prime_import = drm_gem_prime_import,
> +     .gem_prime_export = drm_gem_prime_export,
> +     .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
> +     .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
> +     .gem_prime_vmap = drm_gem_cma_prime_vmap,
> +     .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
> +     .gem_prime_mmap = drm_gem_cma_prime_mmap,
> +};
> +
> +static int mcde_drm_bind(struct device *dev)
> +{
> +     struct drm_device *drm = dev_get_drvdata(dev);
> +     int ret;
> +
> +     drm_mode_config_init(drm);
> +
> +     ret = component_bind_all(drm->dev, drm);
> +     if (ret) {
> +             dev_err(dev, "can't bind component devices\n");
> +             return ret;
> +     }
> +
> +     ret = mcde_modeset_init(drm);
> +     if (ret)
> +             goto unbind;
> +
> +     ret = drm_dev_register(drm, 0);
> +     if (ret < 0)
> +             goto unbind;
> +
> +     return 0;
> +
> +unbind:
> +     component_unbind_all(drm->dev, drm);
> +     return ret;
> +}
> +
> +static void mcde_drm_unbind(struct device *dev)
> +{
> +     struct drm_device *drm = dev_get_drvdata(dev);
> +
> +     drm_dev_unregister(drm);
> +     component_unbind_all(drm->dev, drm);
> +     drm_mode_config_cleanup(drm);
> +}
> +
> +static const struct component_master_ops mcde_drm_comp_ops = {
> +     .bind = mcde_drm_bind,
> +     .unbind = mcde_drm_unbind,
> +};
> +
> +static struct platform_driver *const mcde_component_drivers[] = {
> +     &mcde_dsi_driver,
> +};
> +
> +static int mcde_compare_dev(struct device *dev, void *data)
> +{
> +     return dev == data;
> +}
> +
> +static int mcde_probe(struct platform_device *pdev)
> +{
> +     struct device *dev = &pdev->dev;
> +     struct drm_device *drm;
> +     struct mcde *mcde;
> +     struct component_match *match;
> +     struct resource *res;
> +     u32 pid;
> +     u32 val;
> +     int irq;
> +     int ret;
> +     int i;
> +
> +     mcde = devm_kzalloc(dev, sizeof(*mcde), GFP_KERNEL);
> +     if (!mcde)
> +             return -ENOMEM;
> +     mcde->dev = dev;
> +
> +     drm = drm_dev_alloc(&mcde_drm_driver, dev);
> +     if (IS_ERR(drm))
> +             return PTR_ERR(drm);
> +     platform_set_drvdata(pdev, drm);
> +     mcde->drm = drm;
> +     /* Enable use of the TE signal and interrupt */
> +     mcde->te_sync = true;
> +     /* Enable continuous updates: this is what Linux' framebuffer expects */
> +     mcde->oneshot_mode = false;
> +     drm->dev_private = mcde;
> +
> +     /* First obtain and turn on the main power */
> +     mcde->epod = devm_regulator_get(dev, "epod");
> +     if (IS_ERR(mcde->epod)) {
> +             ret = PTR_ERR(mcde->epod);
> +             dev_err(dev, "can't get EPOD regulator\n");
Print error code.
> +             goto dev_unref;
> +     }
> +     ret = regulator_enable(mcde->epod);
> +     if (ret) {
> +             dev_err(dev, "can't enable EPOD regulator\n");
Print error code.
> +             goto dev_unref;
> +     }
> +     mcde->vana = devm_regulator_get(dev, "vana");
> +     if (IS_ERR(mcde->vana)) {
> +             ret = PTR_ERR(mcde->vana);
> +             dev_err(dev, "can't get VANA regulator\n");
Print error code.
> +             goto regulator_epod_off;
> +     }
> +     ret = regulator_enable(mcde->vana);
> +     if (ret) {
> +             dev_err(dev, "can't enable VANA regulator\n");
Print error code.
> +             goto regulator_epod_off;
> +     }
> +     /*
> +      * The vendor code uses ESRAM (onchip RAM) and need to activate
> +      * the v-esram34 regulator, but we don't use that yet
> +      */
> +
> +     /* Clock the silicon so we can access the registers */
> +     mcde->mcde_clk = devm_clk_get(dev, "mcde");
> +     if (IS_ERR(mcde->mcde_clk)) {
> +             dev_err(dev, "unable to get MCDE main clock\n");
Print error code.
> +             ret = PTR_ERR(mcde->mcde_clk);
> +             goto regulator_off;
> +     }
> +     ret = clk_prepare_enable(mcde->mcde_clk);
> +     if (ret) {
> +             dev_err(dev, "failed to enable MCDE main clock\n");
Print error code.
> +             goto regulator_off;
> +     }
> +     dev_info(dev, "MCDE clk rate %lu Hz\n", clk_get_rate(mcde->mcde_clk));
> +
> +     mcde->lcd_clk = devm_clk_get(dev, "lcd");
> +     if (IS_ERR(mcde->lcd_clk)) {
> +             dev_err(dev, "unable to get LCD clock\n");
Print error code.
> +             ret = PTR_ERR(mcde->lcd_clk);
> +             goto clk_disable;
> +     }
> +     mcde->hdmi_clk = devm_clk_get(dev, "hdmi");
> +     if (IS_ERR(mcde->hdmi_clk)) {
> +             dev_err(dev, "unable to get HDMI clock\n");
Print error code.
> +             ret = PTR_ERR(mcde->hdmi_clk);
> +             goto clk_disable;
> +     }
> +
> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +     mcde->regs = devm_ioremap_resource(dev, res);
> +     if (IS_ERR(mcde->regs)) {
> +             dev_err(dev, "no MCDE regs\n");
Print error code.
> +             ret = -EINVAL;
> +             goto clk_disable;
> +     }
> +
> +     irq = platform_get_irq(pdev, 0);
> +     if (!irq) {
> +             ret = -EINVAL;
> +             goto clk_disable;
> +     }
> +
> +     ret = devm_request_irq(dev, irq, mcde_irq, 0, "mcde", mcde);
> +     if (ret) {
> +             dev_err(dev, "failed to request irq %d\n", ret);
> +             goto clk_disable;
> +     }
> +
> +     /*
> +      * Check hardware revision, we only support U8500v2 version
> +      * as this was the only version used for mass market deployment,
> +      * but surely you can add more versions if you have them and
> +      * need them.
> +      */
> +     pid = readl(mcde->regs + MCDE_PID);
> +     dev_info(dev, "found MCDE HW revision %d.%d (dev %d, metal fix %d)\n",
> +              (pid & MCDE_PID_MAJOR_VERSION_MASK)
> +              >> MCDE_PID_MAJOR_VERSION_SHIFT,
> +              (pid & MCDE_PID_MINOR_VERSION_MASK)
> +              >> MCDE_PID_MINOR_VERSION_SHIFT,
> +              (pid & MCDE_PID_DEVELOPMENT_VERSION_MASK)
> +              >> MCDE_PID_DEVELOPMENT_VERSION_SHIFT,
> +              (pid & MCDE_PID_METALFIX_VERSION_MASK)
> +              >> MCDE_PID_METALFIX_VERSION_SHIFT);
> +     if (pid != 0x03000800) {
> +             dev_err(dev, "unsupported hardware revision\n");
> +             ret = -ENODEV;
> +             goto clk_disable;
> +     }
> +
> +     /* Set up the main control, watermark level at 7 */
> +     val = 7 << MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT;
> +     /* 24 bits DPI: connect LSB Ch B to D[0:7] */
> +     val |= 3 << MCDE_CONF0_OUTMUX0_SHIFT;
> +     /* TV out: connect LSB Ch B to D[8:15] */
> +     val |= 3 << MCDE_CONF0_OUTMUX1_SHIFT;
> +     /* Don't care about this muxing */
> +     val |= 0 << MCDE_CONF0_OUTMUX2_SHIFT;
> +     /* 24 bits DPI: connect MID Ch B to D[24:31] */
> +     val |= 4 << MCDE_CONF0_OUTMUX3_SHIFT;
> +     /* 5: 24 bits DPI: connect MSB Ch B to D[32:39] */
> +     val |= 5 << MCDE_CONF0_OUTMUX4_SHIFT;
> +     /* Syncmux bits zero: DPI channel A and B on output pins A and B resp */
> +     writel(val, mcde->regs + MCDE_CONF0);
> +
> +     /* Enable automatic clock gating */
> +     val = readl(mcde->regs + MCDE_CR);
> +     val |= MCDE_CR_MCDEEN | MCDE_CR_AUTOCLKG_EN;
> +     writel(val, mcde->regs + MCDE_CR);
> +
> +     /* Clear any pending interrupts */
> +     mcde_display_disable_irqs(mcde);
> +     writel(0, mcde->regs + MCDE_IMSCERR);
> +     writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR);
> +
> +     /* Spawn child devices for the DSI ports */
> +     devm_of_platform_populate(dev);
> +
> +     /* Create something that will match the subdrivers when we bind */

I could not follow what this parts does.
Maybe move to function and document this?

> +     for (i = 0; i < ARRAY_SIZE(mcde_component_drivers); i++) {
> +             struct device_driver *drv = &mcde_component_drivers[i]->driver;
> +             struct device *p = NULL, *d;
> +
> +             while ((d = bus_find_device(&platform_bus_type, p, drv,
> +                                         (void *)platform_bus_type.match))) {
> +                     put_device(p);
> +                     component_match_add(dev, &match, mcde_compare_dev, d);
> +                     p = d;
> +             }
> +             put_device(p);
> +     }
> +     if (IS_ERR(match)) {
> +             dev_err(dev, "could not create component match\n");
> +             ret = PTR_ERR(match);
> +             goto clk_disable;
> +     }
> +     ret = component_master_add_with_match(&pdev->dev, &mcde_drm_comp_ops,
> +                                           match);
> +     if (ret) {
> +             dev_err(dev, "failed to add component master\n");
> +             goto clk_disable;
> +     }
> +     return 0;
> +
> +clk_disable:
> +     clk_disable_unprepare(mcde->mcde_clk);
> +regulator_off:
> +     regulator_disable(mcde->vana);
> +regulator_epod_off:
> +     regulator_disable(mcde->epod);
> +dev_unref:
> +     drm_dev_put(drm);
> +     return ret;
> +
> +}
> +
> +static int mcde_remove(struct platform_device *pdev)
> +{
> +     struct drm_device *drm = platform_get_drvdata(pdev);
> +     struct mcde *mcde = drm->dev_private;
> +
> +     component_master_del(&pdev->dev, &mcde_drm_comp_ops);
> +     clk_disable_unprepare(mcde->mcde_clk);
What about the other clocks?

> +     regulator_disable(mcde->vana);
> +     regulator_disable(mcde->epod);
> +     drm_dev_put(drm);
> +
> +     return 0;
> +}
> +
> +static const struct of_device_id mcde_of_match[] = {
> +     {
> +             .compatible = "ste,mcde",
> +     },
> +     {},

Add /* sentinel */ like most other drivers do.
> +};
> +
> +static struct platform_driver mcde_driver = {
> +     .driver = {
> +             .name           = "mcde",
> +             .of_match_table = of_match_ptr(mcde_of_match),
> +     },
> +     .probe = mcde_probe,
> +     .remove = mcde_remove,
> +};
> +
> +static struct platform_driver *const component_drivers[] = {
> +     &mcde_dsi_driver,
> +};
> +
> +static int __init mcde_drm_register(void)
> +{
> +     int ret;
> +
> +     ret = platform_register_drivers(component_drivers,
> +                                     ARRAY_SIZE(component_drivers));
> +     if (ret)
> +             return ret;
> +
> +     return platform_driver_register(&mcde_driver);
> +}
> +
> +static void __exit mcde_drm_unregister(void)
> +{
> +     platform_unregister_drivers(component_drivers,
> +                                 ARRAY_SIZE(component_drivers));
> +     platform_driver_unregister(&mcde_driver);
> +}
> +
> +module_init(mcde_drm_register);
> +module_exit(mcde_drm_unregister);
> +
> +MODULE_ALIAS("platform:mcde-drm");
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_AUTHOR("Linus Walleij <linus.wall...@linaro.org>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c
> new file mode 100644
> index 000000000000..52b95c356753
> --- /dev/null
> +++ b/drivers/gpu/drm/mcde/mcde_dsi.c
> @@ -0,0 +1,1424 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/clk.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/io.h>
> +#include <linux/delay.h>
> +#include <linux/component.h>
> +#include <linux/of.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
> +#include <video/mipi_display.h>
Sort
> +
> +#include <drm/drm_device.h>
> +#include <drm/drm_drv.h>
> +#include <drm/drm_encoder.h>
> +#include <drm/drm_modeset_helper_vtables.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_probe_helper.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_of.h>
Sort.
Do you really need all these .h files?
> +
> +#include "mcde_drm.h"
> +
> +#define DSI_DEFAULT_LP_FREQ_HZ       19200000
> +#define DSI_DEFAULT_HS_FREQ_HZ       420160000
> +
> +#define DSI_MCTL_INTEGRATION_MODE 0x00000000
> +
> +#define DSI_MCTL_MAIN_DATA_CTL 0x00000004
> +#define DSI_MCTL_MAIN_DATA_CTL_LINK_EN BIT(0)
> +#define DSI_MCTL_MAIN_DATA_CTL_IF1_MODE BIT(1)
> +#define DSI_MCTL_MAIN_DATA_CTL_VID_EN BIT(2)
> +#define DSI_MCTL_MAIN_DATA_CTL_TVG_SEL BIT(3)
> +#define DSI_MCTL_MAIN_DATA_CTL_TBG_SEL BIT(4)
> +#define DSI_MCTL_MAIN_DATA_CTL_IF1_TE_EN BIT(5)
> +#define DSI_MCTL_MAIN_DATA_CTL_IF2_TE_EN BIT(6)
> +#define DSI_MCTL_MAIN_DATA_CTL_REG_TE_EN BIT(7)
> +#define DSI_MCTL_MAIN_DATA_CTL_READ_EN BIT(8)
> +#define DSI_MCTL_MAIN_DATA_CTL_BTA_EN BIT(9)
> +#define DSI_MCTL_MAIN_DATA_CTL_DISP_GEN_ECC BIT(10)
> +#define DSI_MCTL_MAIN_DATA_CTL_DISP_GEN_CHECKSUM BIT(11)
> +#define DSI_MCTL_MAIN_DATA_CTL_HOST_EOT_GEN BIT(12)
> +#define DSI_MCTL_MAIN_DATA_CTL_DISP_EOT_GEN BIT(13)
> +#define DSI_MCTL_MAIN_DATA_CTL_DLX_REMAP_EN BIT(14)
> +#define DSI_MCTL_MAIN_DATA_CTL_TE_POLLING_EN BIT(15)
> +
> +#define DSI_MCTL_MAIN_PHY_CTL 0x00000008
> +#define DSI_MCTL_MAIN_PHY_CTL_LANE2_EN BIT(0)
> +#define DSI_MCTL_MAIN_PHY_CTL_FORCE_STOP_MODE BIT(1)
> +#define DSI_MCTL_MAIN_PHY_CTL_CLK_CONTINUOUS BIT(2)
> +#define DSI_MCTL_MAIN_PHY_CTL_CLK_ULPM_EN BIT(3)
> +#define DSI_MCTL_MAIN_PHY_CTL_DAT1_ULPM_EN BIT(4)
> +#define DSI_MCTL_MAIN_PHY_CTL_DAT2_ULPM_EN BIT(5)
> +#define DSI_MCTL_MAIN_PHY_CTL_WAIT_BURST_TIME_SHIFT 6
> +#define DSI_MCTL_MAIN_PHY_CTL_WAIT_BURST_TIME_MASK 0x000003C0
> +#define DSI_MCTL_MAIN_PHY_CTL_CLOCK_FORCE_STOP_MODE BIT(10)
> +
> +#define DSI_MCTL_PLL_CTL 0x0000000C
> +#define DSI_MCTL_LANE_STS 0x00000010
> +
> +#define DSI_MCTL_DPHY_TIMEOUT 0x00000014
> +#define DSI_MCTL_DPHY_TIMEOUT_CLK_DIV_SHIFT 0
> +#define DSI_MCTL_DPHY_TIMEOUT_CLK_DIV_MASK 0x0000000F
> +#define DSI_MCTL_DPHY_TIMEOUT_HSTX_TO_VAL_SHIFT 4
> +#define DSI_MCTL_DPHY_TIMEOUT_HSTX_TO_VAL_MASK 0x0003FFF0
> +#define DSI_MCTL_DPHY_TIMEOUT_LPRX_TO_VAL_SHIFT 18
> +#define DSI_MCTL_DPHY_TIMEOUT_LPRX_TO_VAL_MASK 0xFFFC0000
> +
> +#define DSI_MCTL_ULPOUT_TIME 0x00000018
> +#define DSI_MCTL_ULPOUT_TIME_CKLANE_ULPOUT_TIME_SHIFT 0
> +#define DSI_MCTL_ULPOUT_TIME_CKLANE_ULPOUT_TIME_MASK 0x000001FF
> +#define DSI_MCTL_ULPOUT_TIME_DATA_ULPOUT_TIME_SHIFT 9
> +#define DSI_MCTL_ULPOUT_TIME_DATA_ULPOUT_TIME_MASK 0x0003FE00
> +
> +#define DSI_MCTL_DPHY_STATIC 0x0000001C
> +#define DSI_MCTL_DPHY_STATIC_SWAP_PINS_CLK BIT(0)
> +#define DSI_MCTL_DPHY_STATIC_HS_INVERT_CLK BIT(1)
> +#define DSI_MCTL_DPHY_STATIC_SWAP_PINS_DAT1 BIT(2)
> +#define DSI_MCTL_DPHY_STATIC_HS_INVERT_DAT1 BIT(3)
> +#define DSI_MCTL_DPHY_STATIC_SWAP_PINS_DAT2 BIT(4)
> +#define DSI_MCTL_DPHY_STATIC_HS_INVERT_DAT2 BIT(5)
> +#define DSI_MCTL_DPHY_STATIC_UI_X4_SHIFT 6
> +#define DSI_MCTL_DPHY_STATIC_UI_X4_MASK 0x00000FC0
> +
> +#define DSI_MCTL_MAIN_EN 0x00000020
> +#define DSI_MCTL_MAIN_EN_PLL_START BIT(0)
> +#define DSI_MCTL_MAIN_EN_CKLANE_EN BIT(3)
> +#define DSI_MCTL_MAIN_EN_DAT1_EN BIT(4)
> +#define DSI_MCTL_MAIN_EN_DAT2_EN BIT(5)
> +#define DSI_MCTL_MAIN_EN_CLKLANE_ULPM_REQ BIT(6)
> +#define DSI_MCTL_MAIN_EN_DAT1_ULPM_REQ BIT(7)
> +#define DSI_MCTL_MAIN_EN_DAT2_ULPM_REQ BIT(8)
> +#define DSI_MCTL_MAIN_EN_IF1_EN BIT(9)
> +#define DSI_MCTL_MAIN_EN_IF2_EN BIT(10)
> +
> +#define DSI_MCTL_MAIN_STS 0x00000024
> +#define DSI_MCTL_MAIN_STS_PLL_LOCK BIT(0)
> +#define DSI_MCTL_MAIN_STS_CLKLANE_READY BIT(1)
> +#define DSI_MCTL_MAIN_STS_DAT1_READY BIT(2)
> +#define DSI_MCTL_MAIN_STS_DAT2_READY BIT(3)
> +#define DSI_MCTL_MAIN_STS_HSTX_TO_ERR BIT(4)
> +#define DSI_MCTL_MAIN_STS_LPRX_TO_ERR BIT(5)
> +#define DSI_MCTL_MAIN_STS_CRS_UNTERM_PCK BIT(6)
> +#define DSI_MCTL_MAIN_STS_VRS_UNTERM_PCK BIT(7)
> +
> +#define DSI_MCTL_DPHY_ERR 0x00000028
> +#define DSI_INT_VID_RDDATA 0x00000030
> +#define DSI_INT_VID_GNT 0x00000034
> +#define DSI_INT_CMD_RDDATA 0x00000038
> +#define DSI_INT_CMD_GNT 0x0000003C
> +#define DSI_INT_INTERRUPT_CTL 0x00000040
> +
> +#define DSI_CMD_MODE_CTL 0x00000050
> +#define DSI_CMD_MODE_CTL_IF1_ID_SHIFT 0
> +#define DSI_CMD_MODE_CTL_IF1_ID_MASK 0x00000003
> +#define DSI_CMD_MODE_CTL_IF2_ID_SHIFT 2
> +#define DSI_CMD_MODE_CTL_IF2_ID_MASK 0x0000000C
> +#define DSI_CMD_MODE_CTL_IF1_LP_EN BIT(4)
> +#define DSI_CMD_MODE_CTL_IF2_LP_EN BIT(5)
> +#define DSI_CMD_MODE_CTL_ARB_MODE BIT(6)
> +#define DSI_CMD_MODE_CTL_ARB_PRI BIT(7)
> +#define DSI_CMD_MODE_CTL_FIL_VALUE_SHIFT 8
> +#define DSI_CMD_MODE_CTL_FIL_VALUE_MASK 0x0000FF00
> +#define DSI_CMD_MODE_CTL_TE_TIMEOUT_SHIFT 16
> +#define DSI_CMD_MODE_CTL_TE_TIMEOUT_MASK 0x03FF0000
> +
> +#define DSI_CMD_MODE_STS 0x00000054
> +#define DSI_CMD_MODE_STS_ERR_NO_TE BIT(0)
> +#define DSI_CMD_MODE_STS_ERR_TE_MISS BIT(1)
> +#define DSI_CMD_MODE_STS_ERR_SDI1_UNDERRUN BIT(2)
> +#define DSI_CMD_MODE_STS_ERR_SDI2_UNDERRUN BIT(3)
> +#define DSI_CMD_MODE_STS_ERR_UNWANTED_RD BIT(4)
> +#define DSI_CMD_MODE_STS_CSM_RUNNING BIT(5)
> +
> +#define DSI_DIRECT_CMD_SEND 0x00000060
> +
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS 0x00000064
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_SHIFT 0
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_MASK 0x00000007
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_WRITE 0
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_READ 1
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_TE_REQ 4
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_TRIG_REQ 5
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_BTA_REQ 6
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_LONGNOTSHORT BIT(3)
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_SHIFT 8
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_MASK 0x00003F00
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_TURN_ON_PERIPHERAL 50
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_SHUT_DOWN_PERIPHERAL 34
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_GENERIC_SHORT_WRITE_0 3
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_GENERIC_SHORT_WRITE_1 19
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_GENERIC_SHORT_WRITE_2 35
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_GENERIC_LONG_WRITE 41
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_DCS_SHORT_WRITE_0 5
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_DCS_SHORT_WRITE_1 21
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_DCS_LONG_WRITE 57
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_DCS_READ 6
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_SET_MAX_PKT_SIZE 55
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_ID_SHIFT 14
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_SIZE_SHIFT 16
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_LP_EN BIT(21)
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_TRIGGER_VAL_SHIFT 24
> +#define DSI_DIRECT_CMD_MAIN_SETTINGS_TRIGGER_VAL_MASK 0x0F000000
> +
> +#define DSI_DIRECT_CMD_STS 0x00000068
> +#define DSI_DIRECT_CMD_STS_CMD_TRANSMISSION BIT(0)
> +#define DSI_DIRECT_CMD_STS_WRITE_COMPLETED BIT(1)
> +#define DSI_DIRECT_CMD_STS_TRIGGER_COMPLETED BIT(2)
> +#define DSI_DIRECT_CMD_STS_READ_COMPLETED BIT(3)
> +#define DSI_DIRECT_CMD_STS_ACKNOWLEDGE_RECEIVED_SHIFT BIT(4)
> +#define DSI_DIRECT_CMD_STS_ACKNOWLEDGE_WITH_ERR_RECEIVED BIT(5)
> +#define DSI_DIRECT_CMD_STS_TRIGGER_RECEIVED BIT(6)
> +#define DSI_DIRECT_CMD_STS_TE_RECEIVED BIT(7)
> +#define DSI_DIRECT_CMD_STS_BTA_COMPLETED BIT(8)
> +#define DSI_DIRECT_CMD_STS_BTA_FINISHED BIT(9)
> +#define DSI_DIRECT_CMD_STS_READ_COMPLETED_WITH_ERR BIT(10)
> +#define DSI_DIRECT_CMD_STS_TRIGGER_VAL_MASK 0x00007800
> +#define DSI_DIRECT_CMD_STS_TRIGGER_VAL_SHIFT 11
> +#define DSI_DIRECT_CMD_STS_ACK_VAL_SHIFT 16
> +#define DSI_DIRECT_CMD_STS_ACK_VAL_MASK 0xFFFF0000
> +
> +#define DSI_DIRECT_CMD_RD_INIT 0x0000006C
> +#define DSI_DIRECT_CMD_RD_INIT_RESET_SHIFT 0
> +#define DSI_DIRECT_CMD_RD_INIT_RESET_MASK 0xFFFFFFFF
> +
> +#define DSI_DIRECT_CMD_WRDAT0 0x00000070
> +#define DSI_DIRECT_CMD_WRDAT1 0x00000074
> +#define DSI_DIRECT_CMD_WRDAT2 0x00000078
> +#define DSI_DIRECT_CMD_WRDAT3 0x0000007C
> +
> +#define DSI_DIRECT_CMD_RDDAT 0x00000080
> +
> +#define DSI_DIRECT_CMD_RD_PROPERTY 0x00000084
> +#define DSI_DIRECT_CMD_RD_PROPERTY_RD_SIZE_SHIFT 0
> +#define DSI_DIRECT_CMD_RD_PROPERTY_RD_SIZE_MASK 0x0000FFFF
> +#define DSI_DIRECT_CMD_RD_PROPERTY_RD_ID_SHIFT 16
> +#define DSI_DIRECT_CMD_RD_PROPERTY_RD_ID_MASK 0x00030000
> +#define DSI_DIRECT_CMD_RD_PROPERTY_RD_DCSNOTGENERIC_SHIFT 18
> +#define DSI_DIRECT_CMD_RD_PROPERTY_RD_DCSNOTGENERIC_MASK 0x00040000
> +
> +#define DSI_DIRECT_CMD_RD_STS 0x00000088
> +
> +#define DSI_VID_MAIN_CTL 0x00000090
> +#define DSI_VID_MAIN_CTL_START_MODE_SHIFT 0
> +#define DSI_VID_MAIN_CTL_START_MODE_MASK 0x00000003
> +#define DSI_VID_MAIN_CTL_STOP_MODE_SHIFT 2
> +#define DSI_VID_MAIN_CTL_STOP_MODE_MASK 0x0000000C
> +#define DSI_VID_MAIN_CTL_VID_ID_SHIFT 4
> +#define DSI_VID_MAIN_CTL_VID_ID_MASK 0x00000030
> +#define DSI_VID_MAIN_CTL_HEADER_SHIFT 6
> +#define DSI_VID_MAIN_CTL_HEADER_MASK 0x00000FC0
> +#define DSI_VID_MAIN_CTL_VID_PIXEL_MODE_16BITS 0
> +#define DSI_VID_MAIN_CTL_VID_PIXEL_MODE_18BITS BIT(12)
> +#define DSI_VID_MAIN_CTL_VID_PIXEL_MODE_18BITS_LOOSE BIT(13)
> +#define DSI_VID_MAIN_CTL_VID_PIXEL_MODE_24BITS (BIT(12) | BIT(13))
> +#define DSI_VID_MAIN_CTL_BURST_MODE BIT(14)
> +#define DSI_VID_MAIN_CTL_SYNC_PULSE_ACTIVE BIT(15)
> +#define DSI_VID_MAIN_CTL_SYNC_PULSE_HORIZONTAL BIT(16)
> +#define DSI_VID_MAIN_CTL_REG_BLKLINE_MODE_NULL 0
> +#define DSI_VID_MAIN_CTL_REG_BLKLINE_MODE_BLANKING BIT(17)
> +#define DSI_VID_MAIN_CTL_REG_BLKLINE_MODE_LP_0 BIT(18)
> +#define DSI_VID_MAIN_CTL_REG_BLKLINE_MODE_LP_1 (BIT(17) | BIT(18))
> +#define DSI_VID_MAIN_CTL_REG_BLKEOL_MODE_NULL 0
> +#define DSI_VID_MAIN_CTL_REG_BLKEOL_MODE_BLANKING BIT(19)
> +#define DSI_VID_MAIN_CTL_REG_BLKEOL_MODE_LP_0 BIT(20)
> +#define DSI_VID_MAIN_CTL_REG_BLKEOL_MODE_LP_1 (BIT(19) | BIT(20))
> +#define DSI_VID_MAIN_CTL_RECOVERY_MODE_SHIFT 21
> +#define DSI_VID_MAIN_CTL_RECOVERY_MODE_MASK 0x00600000
> +
> +#define DSI_VID_VSIZE 0x00000094
> +#define DSI_VID_VSIZE_VSA_LENGTH_SHIFT 0
> +#define DSI_VID_VSIZE_VSA_LENGTH_MASK 0x0000003F
> +#define DSI_VID_VSIZE_VBP_LENGTH_SHIFT 6
> +#define DSI_VID_VSIZE_VBP_LENGTH_MASK 0x00000FC0
> +#define DSI_VID_VSIZE_VFP_LENGTH_SHIFT 12
> +#define DSI_VID_VSIZE_VFP_LENGTH_MASK 0x000FF000
> +#define DSI_VID_VSIZE_VACT_LENGTH_SHIFT 20
> +#define DSI_VID_VSIZE_VACT_LENGTH_MASK 0x7FF00000
> +
> +#define DSI_VID_HSIZE1 0x00000098
> +#define DSI_VID_HSIZE1_HSA_LENGTH_SHIFT 0
> +#define DSI_VID_HSIZE1_HSA_LENGTH_MASK 0x000003FF
> +#define DSI_VID_HSIZE1_HBP_LENGTH_SHIFT 10
> +#define DSI_VID_HSIZE1_HBP_LENGTH_MASK 0x000FFC00
> +#define DSI_VID_HSIZE1_HFP_LENGTH_SHIFT 20
> +#define DSI_VID_HSIZE1_HFP_LENGTH_MASK 0x7FF00000
> +
> +#define DSI_VID_HSIZE2 0x0000009C
> +#define DSI_VID_HSIZE2_RGB_SIZE_SHIFT 0
> +#define DSI_VID_HSIZE2_RGB_SIZE_MASK 0x00001FFF
> +
> +#define DSI_VID_BLKSIZE1 0x000000A0
> +#define DSI_VID_BLKSIZE1_BLKLINE_EVENT_PCK_SHIFT 0
> +#define DSI_VID_BLKSIZE1_BLKLINE_EVENT_PCK_MASK 0x00001FFF
> +#define DSI_VID_BLKSIZE1_BLKEOL_PCK_SHIFT 13
> +#define DSI_VID_BLKSIZE1_BLKEOL_PCK_MASK 0x03FFE000
> +
> +#define DSI_VID_BLKSIZE2 0x000000A4
> +#define DSI_VID_BLKSIZE2_BLKLINE_PULSE_PCK_SHIFT 0
> +#define DSI_VID_BLKSIZE2_BLKLINE_PULSE_PCK_MASK 0x00001FFF
> +
> +#define DSI_VID_PCK_TIME 0x000000A8
> +#define DSI_VID_PCK_TIME_BLKEOL_DURATION_SHIFT 0
> +
> +#define DSI_VID_DPHY_TIME 0x000000AC
> +#define DSI_VID_DPHY_TIME_REG_LINE_DURATION_SHIFT 0
> +#define DSI_VID_DPHY_TIME_REG_LINE_DURATION_MASK 0x00001FFF
> +#define DSI_VID_DPHY_TIME_REG_WAKEUP_TIME_SHIFT 13
> +#define DSI_VID_DPHY_TIME_REG_WAKEUP_TIME_MASK 0x00FFE000
> +
> +#define DSI_VID_MODE_STS 0x000000BC
> +#define DSI_VID_MODE_STS_VSG_RUNNING BIT(0)
> +
> +#define DSI_VID_VCA_SETTING1 0x000000C0
> +#define DSI_VID_VCA_SETTING1_MAX_BURST_LIMIT_SHIFT 0
> +#define DSI_VID_VCA_SETTING1_MAX_BURST_LIMIT_MASK 0x0000FFFF
> +#define DSI_VID_VCA_SETTING1_BURST_LP BIT(16)
> +
> +#define DSI_VID_VCA_SETTING2 0x000000C4
> +#define DSI_VID_VCA_SETTING2_EXACT_BURST_LIMIT_SHIFT 0
> +#define DSI_VID_VCA_SETTING2_EXACT_BURST_LIMIT_MASK 0x0000FFFF
> +#define DSI_VID_VCA_SETTING2_MAX_LINE_LIMIT_SHIFT 16
> +#define DSI_VID_VCA_SETTING2_MAX_LINE_LIMIT_MASK 0xFFFF0000
> +
> +#define DSI_CMD_MODE_STS_CTL 0x000000F4
> +#define DSI_CMD_MODE_STS_CTL_ERR_NO_TE_EN BIT(0)
> +#define DSI_CMD_MODE_STS_CTL_ERR_TE_MISS_EN BIT(1)
> +#define DSI_CMD_MODE_STS_CTL_ERR_SDI1_UNDERRUN_EN BIT(2)
> +#define DSI_CMD_MODE_STS_CTL_ERR_SDI2_UNDERRUN_EN BIT(3)
> +#define DSI_CMD_MODE_STS_CTL_ERR_UNWANTED_RD_EN BIT(4)
> +#define DSI_CMD_MODE_STS_CTL_CSM_RUNNING_EN BIT(5)
> +#define DSI_CMD_MODE_STS_CTL_ERR_NO_TE_EDGE BIT(16)
> +#define DSI_CMD_MODE_STS_CTL_ERR_TE_MISS_EDGE BIT(17)
> +#define DSI_CMD_MODE_STS_CTL_ERR_SDI1_UNDERRUN_EDGE BIT(18)
> +#define DSI_CMD_MODE_STS_CTL_ERR_SDI2_UNDERRUN_EDGE BIT(19)
> +#define DSI_CMD_MODE_STS_CTL_ERR_UNWANTED_RD_EDGE BIT(20)
> +#define DSI_CMD_MODE_STS_CTL_CSM_RUNNING_EDGE BIT(21)
> +
> +#define DSI_DIRECT_CMD_STS_CTL 0x000000F8
> +#define DSI_DIRECT_CMD_STS_CTL_CMD_TRANSMISSION_EN BIT(0)
> +#define DSI_DIRECT_CMD_STS_CTL_WRITE_COMPLETED_EN BIT(1)
> +#define DSI_DIRECT_CMD_STS_CTL_TRIGGER_COMPLETED_EN BIT(2)
> +#define DSI_DIRECT_CMD_STS_CTL_READ_COMPLETED_EN BIT(3)
> +#define DSI_DIRECT_CMD_STS_CTL_ACKNOWLEDGE_RECEIVED_EN BIT(4)
> +#define DSI_DIRECT_CMD_STS_CTL_ACKNOWLEDGE_WITH_ERR_EN BIT(5)
> +#define DSI_DIRECT_CMD_STS_CTL_TRIGGER_RECEIVED_EN BIT(6)
> +#define DSI_DIRECT_CMD_STS_CTL_TE_RECEIVED_EN BIT(7)
> +#define DSI_DIRECT_CMD_STS_CTL_BTA_COMPLETED_EN BIT(8)
> +#define DSI_DIRECT_CMD_STS_CTL_BTA_FINISHED_EN BIT(9)
> +#define DSI_DIRECT_CMD_STS_CTL_READ_COMPLETED_WITH_ERR_EN BIT(10)
> +#define DSI_DIRECT_CMD_STS_CTL_CMD_TRANSMISSION_EDGE BIT(16)
> +#define DSI_DIRECT_CMD_STS_CTL_WRITE_COMPLETED_EDGE BIT(17)
> +#define DSI_DIRECT_CMD_STS_CTL_TRIGGER_COMPLETED_EDGE BIT(18)
> +#define DSI_DIRECT_CMD_STS_CTL_READ_COMPLETED_EDGE BIT(19)
> +#define DSI_DIRECT_CMD_STS_CTL_ACKNOWLEDGE_RECEIVED_EDGE BIT(20)
> +#define DSI_DIRECT_CMD_STS_CTL_ACKNOWLEDGE_WITH_ERR_EDGE BIT(21)
> +#define DSI_DIRECT_CMD_STS_CTL_TRIGGER_RECEIVED_EDGE BIT(22)
> +#define DSI_DIRECT_CMD_STS_CTL_TE_RECEIVED_EDGE BIT(23)
> +#define DSI_DIRECT_CMD_STS_CTL_BTA_COMPLETED_EDGE BIT(24)
> +#define DSI_DIRECT_CMD_STS_CTL_BTA_FINISHED_EDGE BIT(25)
> +#define DSI_DIRECT_CMD_STS_CTL_READ_COMPLETED_WITH_ERR_EDGE BIT(26)
> +
> +#define DSI_VID_MODE_STS_CTL 0x00000100
> +#define DSI_VID_MODE_STS_CTL_VSG_RUNNING BIT(0)
> +#define DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA BIT(1)
> +#define DSI_VID_MODE_STS_CTL_ERR_MISSING_HSYNC BIT(2)
> +#define DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC BIT(3)
> +#define DSI_VID_MODE_STS_CTL_REG_ERR_SMALL_LENGTH BIT(4)
> +#define DSI_VID_MODE_STS_CTL_REG_ERR_SMALL_HEIGHT BIT(5)
> +#define DSI_VID_MODE_STS_CTL_ERR_BURSTWRITE BIT(6)
> +#define DSI_VID_MODE_STS_CTL_ERR_LONGWRITE BIT(7)
> +#define DSI_VID_MODE_STS_CTL_ERR_LONGREAD BIT(8)
> +#define DSI_VID_MODE_STS_CTL_ERR_VRS_WRONG_LENGTH BIT(9)
> +#define DSI_VID_MODE_STS_CTL_VSG_RUNNING_EDGE BIT(16)
> +#define DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA_EDGE BIT(17)
> +#define DSI_VID_MODE_STS_CTL_ERR_MISSING_HSYNC_EDGE BIT(18)
> +#define DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC_EDGE BIT(19)
> +#define DSI_VID_MODE_STS_CTL_REG_ERR_SMALL_LENGTH_EDGE BIT(20)
> +#define DSI_VID_MODE_STS_CTL_REG_ERR_SMALL_HEIGHT_EDGE BIT(21)
> +#define DSI_VID_MODE_STS_CTL_ERR_BURSTWRITE_EDGE BIT(22)
> +#define DSI_VID_MODE_STS_CTL_ERR_LONGWRITE_EDGE BIT(23)
> +#define DSI_VID_MODE_STS_CTL_ERR_LONGREAD_EDGE BIT(24)
> +#define DSI_VID_MODE_STS_CTL_ERR_VRS_WRONG_LENGTH_EDGE BIT(25)
> +#define DSI_VID_MODE_STS_CTL_VSG_RECOVERY_EDGE BIT(26)
> +
> +#define DSI_TG_STS_CTL 0x00000104
> +#define DSI_MCTL_DHPY_ERR_CTL 0x00000108
> +#define DSI_MCTL_MAIN_STS_CLR 0x00000110
> +
> +#define DSI_CMD_MODE_STS_CLR 0x00000114
> +#define DSI_CMD_MODE_STS_CLR_ERR_NO_TE_CLR BIT(0)
> +#define DSI_CMD_MODE_STS_CLR_ERR_TE_MISS_CLR BIT(1)
> +#define DSI_CMD_MODE_STS_CLR_ERR_SDI1_UNDERRUN_CLR BIT(2)
> +#define DSI_CMD_MODE_STS_CLR_ERR_SDI2_UNDERRUN_CLR BIT(3)
> +#define DSI_CMD_MODE_STS_CLR_ERR_UNWANTED_RD_CLR BIT(4)
> +#define DSI_CMD_MODE_STS_CLR_CSM_RUNNING_CLR BIT(5)
> +
> +#define DSI_DIRECT_CMD_STS_CLR 0x00000118
> +#define DSI_DIRECT_CMD_STS_CLR_CMD_TRANSMISSION_CLR BIT(0)
> +#define DSI_DIRECT_CMD_STS_CLR_WRITE_COMPLETED_CLR BIT(1)
> +#define DSI_DIRECT_CMD_STS_CLR_TRIGGER_COMPLETED_CLR BIT(2)
> +#define DSI_DIRECT_CMD_STS_CLR_READ_COMPLETED_CLR BIT(3)
> +#define DSI_DIRECT_CMD_STS_CLR_ACKNOWLEDGE_RECEIVED_CLR BIT(4)
> +#define DSI_DIRECT_CMD_STS_CLR_ACKNOWLEDGE_WITH_ERR_RECEIVED_CLR BIT(5)
> +#define DSI_DIRECT_CMD_STS_CLR_TRIGGER_RECEIVED_CLR BIT(6)
> +#define DSI_DIRECT_CMD_STS_CLR_TE_RECEIVED_CLR BIT(7)
> +#define DSI_DIRECT_CMD_STS_CLR_BTA_COMPLETED_CLR BIT(8)
> +#define DSI_DIRECT_CMD_STS_CLR_BTA_FINISHED_CLR BIT(9)
> +#define DSI_DIRECT_CMD_STS_CLR_READ_COMPLETED_WITH_ERR_CLR BIT(10)
> +
> +#define DSI_DIRECT_CMD_RD_STS_CLR 0x0000011C
> +#define DSI_VID_MODE_STS_CLR 0x00000120
> +#define DSI_TG_STS_CLR 0x00000124
> +#define DSI_MCTL_DPHY_ERR_CLR 0x00000128
> +#define DSI_MCTL_MAIN_STS_FLAG 0x00000130
> +#define DSI_CMD_MODE_STS_FLAG 0x00000134
> +#define DSI_DIRECT_CMD_STS_FLAG 0x00000138
> +#define DSI_DIRECT_CMD_RD_STS_FLAG 0x0000013C
> +#define DSI_VID_MODE_STS_FLAG 0x00000140
> +#define DSI_TG_STS_FLAG 0x00000144
> +
> +#define DSI_DPHY_LANES_TRIM 0x00000150
> +#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_DAT1_SHIFT 0
> +#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_DAT1_MASK 0x00000003
> +#define DSI_DPHY_LANES_TRIM_DPHY_CD_OFF_DAT1 BIT(2)
> +#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_UP_DAT1 BIT(3)
> +#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_DOWN_DAT1 BIT(4)
> +#define DSI_DPHY_LANES_TRIM_DPHY_TEST_RESERVED_1_DAT1 BIT(5)
> +#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_CLK_SHIFT 6
> +#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_CLK_MASK 0x000000C0
> +#define DSI_DPHY_LANES_TRIM_DPHY_LP_RX_VIL_CLK_SHIFT 8
> +#define DSI_DPHY_LANES_TRIM_DPHY_LP_RX_VIL_CLK_MASK 0x00000300
> +#define DSI_DPHY_LANES_TRIM_DPHY_LP_TX_SLEWRATE_CLK_SHIFT 10
> +#define DSI_DPHY_LANES_TRIM_DPHY_LP_TX_SLEWRATE_CLK_MASK 0x00000C00
> +#define DSI_DPHY_LANES_TRIM_DPHY_SPECS_90_81B_0_81 0
> +#define DSI_DPHY_LANES_TRIM_DPHY_SPECS_90_81B_0_90 BIT(12)
> +#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_UP_CLK BIT(13)
> +#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_DOWN_CLK BIT(14)
> +#define DSI_DPHY_LANES_TRIM_DPHY_TEST_RESERVED_1_CLK BIT(15)
> +#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_DAT2 BIT(16)
> +#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_UP_DAT2 BIT(18)
> +#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_DOWN_DAT2 BIT(19)
> +#define DSI_DPHY_LANES_TRIM_DPHY_TEST_RESERVED_1_DAT2 BIT(20)
> +
> +#define DSI_ID_REG   0x00000FF0
> +
> +/* PRCMU DSI reset registers */
> +#define PRCM_DSI_SW_RESET 0x324
> +#define PRCM_DSI_SW_RESET_DSI0_SW_RESETN BIT(0)
> +#define PRCM_DSI_SW_RESET_DSI1_SW_RESETN BIT(1)
> +#define PRCM_DSI_SW_RESET_DSI2_SW_RESETN BIT(2)
Regs to other file?

> +
> +struct mcde_dsi {
> +     struct device *dev;
> +     struct mcde *mcde;
> +     struct drm_bridge bridge;
> +     struct drm_connector connector;
> +     struct drm_panel *panel;
> +     struct drm_bridge *bridge_out;
> +     struct mipi_dsi_host dsi_host;
> +     struct mipi_dsi_device *mdsi;
> +     struct clk *hs_clk;
> +     struct clk *lp_clk;
> +     unsigned long hs_freq;
> +     unsigned long lp_freq;
> +     bool unused;
> +
> +     void __iomem *regs;
> +     struct regmap *prcmu;
> +};

Consider regmap.

I did not read rest of driver, ran out af time...

        Sam
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to