On Wed, Aug 06, 2025 at 06:05:12PM +0300, Laurentiu Palcu wrote:
> From: Sandor Yu <sandor...@nxp.com>
>
> The i.MX94 Display Control Interface features:
>  * Up to maximum 3 layers of alpha blending:
>     - 1 background layer(Layer 0);
>     - 1 foreground layer(Layer 1);
>     - A programmable constant color behind the background layer;
>  * Each layer supports:
>     - programmable plane size;
>     - programmable background color;
>     - embedded alpha and global alpha;
>  * Data output with CRC checksum for 4 programmable regions;
>
> Signed-off-by: Sandor Yu <sandor...@nxp.com>
> Signed-off-by: Laurentiu Palcu <laurentiu.pa...@oss.nxp.com>
> ---
>  drivers/gpu/drm/imx/Kconfig           |   1 +
>  drivers/gpu/drm/imx/Makefile          |   1 +
>  drivers/gpu/drm/imx/dcif/Kconfig      |  15 +
>  drivers/gpu/drm/imx/dcif/Makefile     |   5 +
>  drivers/gpu/drm/imx/dcif/dcif-crc.c   | 211 ++++++++
>  drivers/gpu/drm/imx/dcif/dcif-crc.h   |  52 ++
>  drivers/gpu/drm/imx/dcif/dcif-crtc.c  | 694 ++++++++++++++++++++++++++
>  drivers/gpu/drm/imx/dcif/dcif-drv.c   | 226 +++++++++
>  drivers/gpu/drm/imx/dcif/dcif-drv.h   |  84 ++++
>  drivers/gpu/drm/imx/dcif/dcif-kms.c   | 100 ++++
>  drivers/gpu/drm/imx/dcif/dcif-plane.c | 269 ++++++++++
>  drivers/gpu/drm/imx/dcif/dcif-reg.h   | 266 ++++++++++
>  12 files changed, 1924 insertions(+)
>  create mode 100644 drivers/gpu/drm/imx/dcif/Kconfig
>  create mode 100644 drivers/gpu/drm/imx/dcif/Makefile
>  create mode 100644 drivers/gpu/drm/imx/dcif/dcif-crc.c
>  create mode 100644 drivers/gpu/drm/imx/dcif/dcif-crc.h
>  create mode 100644 drivers/gpu/drm/imx/dcif/dcif-crtc.c
>  create mode 100644 drivers/gpu/drm/imx/dcif/dcif-drv.c
>  create mode 100644 drivers/gpu/drm/imx/dcif/dcif-drv.h
>  create mode 100644 drivers/gpu/drm/imx/dcif/dcif-kms.c
>  create mode 100644 drivers/gpu/drm/imx/dcif/dcif-plane.c
>  create mode 100644 drivers/gpu/drm/imx/dcif/dcif-reg.h
>
> diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
> index 3e8c6edbc17c2..1b6ced5c60b51 100644
> --- a/drivers/gpu/drm/imx/Kconfig
> +++ b/drivers/gpu/drm/imx/Kconfig
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>
...
> +static int
> +dcif_crc_parse_source(const char *source_name, enum dcif_crc_source *s,
> +                   struct drm_rect *roi)
> +{
> +     static const char roi_prefix[] = "roi:";
> +
> +     if (!source_name) {
> +             *s = DCIF_CRC_SRC_NONE;
> +     } else if (!strcmp(source_name, "auto")) {
> +             *s = DCIF_CRC_SRC_FRAME;
> +     } else if (strstarts(source_name, roi_prefix)) {
> +             char *options __free(kfree), *opt;

need set opt to NULL here

> +             int len = strlen(roi_prefix);
> +             int params[4];
> +             int i = 0, ret;
> +
> +             options = kstrdup(source_name + len, GFP_KERNEL);
> +
...
> +
> +static void dcif_crtc_atomic_enable(struct drm_crtc *crtc,
> +                                 struct drm_atomic_state *state)
> +{
> +     struct drm_crtc_state *crtc_state = 
> drm_atomic_get_new_crtc_state(state, crtc);
> +     struct drm_plane_state *plane_state = 
> drm_atomic_get_new_plane_state(state, crtc->primary);
> +     struct dcif_crtc_state *dcif_crtc_state = 
> to_dcif_crtc_state(crtc_state);
> +     struct drm_display_mode *adj = &crtc_state->adjusted_mode;
> +     struct dcif_dev *dcif = crtc_to_dcif_dev(crtc);
> +     struct drm_device *drm = crtc->dev;
> +     dma_addr_t baseaddr;
> +
> +     dev_dbg(drm->dev, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
> +
> +     /* enable power when we start to set mode for CRTC */
> +     pm_runtime_get_sync(drm->dev);

Need check return value here.

> +
> +     drm_crtc_vblank_on(crtc);
> +
> +     dcif_crtc_mode_set_nofb(crtc_state, plane_state);
> +
> +     baseaddr = drm_fb_dma_get_gem_addr(plane_state->fb, plane_state, 0);
> +     if (baseaddr)
> +             regmap_write(dcif->regmap, DCIF_CTRLDESC4(0), baseaddr);
> +
> +     dcif_enable_plane_panic(dcif);
> +     dcif_enable_controller(dcif);
> +
> +     dcif_crtc_queue_state_event(crtc);
> +
> +     if (dcif->has_crc && dcif_crtc_state->crc.source != DCIF_CRC_SRC_NONE)
> +             dcif_crtc_enable_crc_source(dcif, dcif_crtc_state->crc.source,
> +                                         &dcif_crtc_state->crc.roi, 0);
> +}
> +
...
> +irqreturn_t dcif_irq_handler(int irq, void *data)
> +{
> +     struct drm_device *drm = data;
> +     struct dcif_dev *dcif = to_dcif_dev(drm);
> +     int domain = dcif->cpu_domain;
> +     u32 stat0, stat1, crc;
> +
> +     regmap_read(dcif->regmap, DCIF_IS0(domain), &stat0);
> +     regmap_read(dcif->regmap, DCIF_IS1(domain), &stat1);
> +
> +     if (stat0 & DCIF_INT0_VS_BLANK) {
> +             drm_crtc_handle_vblank(&dcif->crtc);
> +
> +             scoped_guard(spinlock_irqsave, &drm->event_lock) {
> +                     if (dcif->event) {
> +                             drm_crtc_send_vblank_event(&dcif->crtc, 
> dcif->event);
> +                             dcif->event = NULL;
> +                             drm_crtc_vblank_put(&dcif->crtc);
> +                     }
> +                     if (dcif->crc_is_enabled) {
> +                             regmap_read(dcif->regmap, DCIF_CRC_VAL_R(0), 
> &crc);
> +                             drm_crtc_add_crc_entry(&dcif->crtc, false, 0, 
> &crc);
> +                             dev_dbg(drm->dev, "crc=0x%x\n",  crc);
> +                     }
> +             }
> +     }
> +
> +     if (stat1 & (DCIF_INT1_FIFO_PANIC0 | DCIF_INT1_FIFO_PANIC1)) {
> +             u32 panic = stat1 & (DCIF_INT1_FIFO_PANIC0 | 
> DCIF_INT1_FIFO_PANIC1);
> +
> +             dev_dbg_ratelimited(drm->dev, "FIFO panic on %s\n",
> +                                 panic == (DCIF_INT1_FIFO_PANIC0 | 
> DCIF_INT1_FIFO_PANIC1) ?
> +                                 "layers 0 & 1" : panic == 
> DCIF_INT1_FIFO_PANIC0 ? "layer 0" :
> +                                 "layer 1");
> +     }
> +
> +     /* W1C */
> +     regmap_write(dcif->regmap, DCIF_IS0(domain), stat0);
> +     regmap_write(dcif->regmap, DCIF_IS1(domain), stat1);

Need move above two lines to just after read it to avoid lost irq.

> +
> +     return IRQ_HANDLED;
> +}
> +
> +int dcif_crtc_init(struct dcif_dev *dcif)
> +{
> +     int ret;
> +
> +     ret = dcif_plane_init(dcif);
> +     if (ret)
> +             return ret;
> +
> +     drm_crtc_helper_add(&dcif->crtc, &dcif_crtc_helper_funcs);
> +     ret = drm_crtc_init_with_planes(&dcif->drm, &dcif->crtc, 
> &dcif->planes.primary, NULL,
> +                                     &dcif_crtc_funcs, NULL);
> +     if (ret) {
> +             drm_err(&dcif->drm, "failed to initialize CRTC: %d\n", ret);
> +             return ret;
> +     }
> +
> +     return 0;
> +}
...
> +
> +static void dcif_read_chip_info(struct dcif_dev *dcif)
> +{
> +     struct drm_device *drm = &dcif->drm;
> +     u32 val, vmin, vmaj;
> +
> +     pm_runtime_get_sync(drm->dev);
> +
> +     regmap_read(dcif->regmap, DCIF_VER, &val);
> +
> +     dcif->has_crc = val & 0x2;

0x2 need register field define macro for it

> +
> +     vmin = DCIF_VER_GET_MINOR(val);
> +     vmaj = DCIF_VER_GET_MAJOR(val);
> +     DRM_DEV_DEBUG(drm->dev, "DCIF version is %d.%d\n", vmaj, vmin);
> +
> +     pm_runtime_put_sync(drm->dev);
> +}
> +
...
> +
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_device.h>
> +#include <drm/drm_encoder.h>
> +#include <drm/drm_plane.h>
> +#include <drm/drm_vblank.h>
> +
> +struct dcif_dev {
> +     struct drm_device drm;
> +     void __iomem *reg_base;
> +
> +     struct regmap *regmap;
> +     int irq[3];

3 need define MAX_IRQ_NUMS macro for it.

Frank
> +
> +     unsigned int num_clks;
> +     struct clk_bulk_data *clks;
> +
> +     struct drm_crtc crtc;
> +     struct {
> +             struct drm_plane primary;
> +             struct drm_plane overlay;
> +     } planes;
> +     struct drm_encoder encoder;
> +
> +     struct drm_pending_vblank_event *event;
> +
> +     /* Implement crc */
> +     bool has_crc;
> +     bool crc_is_enabled;
> +
> +     /* CPU domain for interrupt control */
> +     int cpu_domain;
> +};
> +
> +enum dcif_crc_source {
> +     DCIF_CRC_SRC_NONE,
> +     DCIF_CRC_SRC_FRAME,
> +     DCIF_CRC_SRC_FRAME_ROI,
> +};
> +
> +struct dcif_crc {
> +     enum dcif_crc_source    source;
> +     struct drm_rect         roi;
> +};
> +
> +struct dcif_crtc_state {
> +     struct drm_crtc_state   base;
> +     struct dcif_crc         crc;
> +     u32                     bus_format;
> +     u32                     bus_flags;
> +};
> +
> +static inline struct dcif_dev *to_dcif_dev(struct drm_device *drm_dev)
> +{
> +     return container_of(drm_dev, struct dcif_dev, drm);
> +}
> +
> +static inline struct dcif_dev *crtc_to_dcif_dev(struct drm_crtc *crtc)
> +{
> +     return to_dcif_dev(crtc->dev);
> +}
> +
> +static inline struct dcif_crtc_state *to_dcif_crtc_state(struct 
> drm_crtc_state *s)
> +{
> +     return container_of(s, struct dcif_crtc_state, base);
> +}
> +
> +irqreturn_t dcif_irq_handler(int irq, void *data);
> +int dcif_crtc_init(struct dcif_dev *dcif);
> +int dcif_plane_init(struct dcif_dev *dcif);
> +int dcif_kms_prepare(struct dcif_dev *dcif);
> +
> +#endif
> diff --git a/drivers/gpu/drm/imx/dcif/dcif-kms.c 
> b/drivers/gpu/drm/imx/dcif/dcif-kms.c
> new file mode 100644
> index 0000000000000..69d999d178b0b
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dcif/dcif-kms.c
> @@ -0,0 +1,100 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Copyright 2025 NXP
> + */
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_bridge_connector.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_probe_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
> +
> +#include "dcif-drv.h"
> +
> +static int dcif_kms_init(struct dcif_dev *dcif)
> +{
> +     struct drm_device *drm = &dcif->drm;
> +     struct device_node *np = drm->dev->of_node;
> +     struct drm_connector *connector;
> +     struct drm_bridge *bridge;
> +     int ret;
> +
> +     ret = dcif_crtc_init(dcif);
> +     if (ret)
> +             return ret;
> +
> +     bridge = devm_drm_of_get_bridge(drm->dev, np, 0, 0);
> +     if (IS_ERR(bridge))
> +             return dev_err_probe(drm->dev, PTR_ERR(bridge), "Failed to find 
> bridge\n");
> +
> +     dcif->encoder.possible_crtcs = drm_crtc_mask(&dcif->crtc);
> +     ret = drm_simple_encoder_init(drm, &dcif->encoder, 
> DRM_MODE_ENCODER_NONE);
> +     if (ret) {
> +             drm_err(drm, "failed to initialize encoder: %d\n", ret);
> +             return ret;
> +     }
> +
> +     ret = drm_bridge_attach(&dcif->encoder, bridge, NULL, 
> DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +     if (ret) {
> +             drm_err(drm, "failed to attach bridge to encoder: %d\n", ret);
> +             return ret;
> +     }
> +
> +     connector = drm_bridge_connector_init(drm, &dcif->encoder);
> +     if (IS_ERR(connector)) {
> +             drm_err(drm, "failed to initialize bridge connector: %d\n", 
> ret);
> +             return PTR_ERR(connector);
> +     }
> +
> +     ret = drm_connector_attach_encoder(connector, &dcif->encoder);
> +     if (ret)
> +             drm_err(drm, "failed to attach encoder to connector: %d\n", 
> ret);
> +
> +     return ret;
> +}
> +
> +static const struct drm_mode_config_funcs dcif_mode_config_funcs = {
> +     .fb_create     = drm_gem_fb_create,
> +     .atomic_check  = drm_atomic_helper_check,
> +     .atomic_commit = drm_atomic_helper_commit,
> +};
> +
> +static const struct drm_mode_config_helper_funcs dcif_mode_config_helpers = {
> +     .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
> +};
> +
> +int dcif_kms_prepare(struct dcif_dev *dcif)
> +{
> +     struct drm_device *drm = &dcif->drm;
> +     int ret;
> +
> +     ret = drmm_mode_config_init(drm);
> +     if (ret)
> +             return ret;
> +
> +     ret = dcif_kms_init(dcif);
> +     if (ret)
> +             return ret;
> +
> +     drm->mode_config.min_width      = 1;
> +     drm->mode_config.min_height     = 1;
> +     drm->mode_config.max_width      = 1920;
> +     drm->mode_config.max_height     = 1920;
> +     drm->mode_config.funcs          = &dcif_mode_config_funcs;
> +     drm->mode_config.helper_private = &dcif_mode_config_helpers;
> +
> +     ret = drm_vblank_init(drm, 1);
> +     if (ret < 0) {
> +             drm_err(drm, "failed to initialize vblank: %d\n", ret);
> +             return ret;
> +     }
> +
> +     drm_mode_config_reset(drm);
> +
> +     drmm_kms_helper_poll_init(drm);
> +
> +     return 0;
> +}
> diff --git a/drivers/gpu/drm/imx/dcif/dcif-plane.c 
> b/drivers/gpu/drm/imx/dcif/dcif-plane.c
> new file mode 100644
> index 0000000000000..54ab8edd11e0c
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dcif/dcif-plane.c
> @@ -0,0 +1,269 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Copyright 2025 NXP
> + */
> +
> +#include <linux/regmap.h>
> +
> +#include <drm/drm_atomic.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_blend.h>
> +#include <drm/drm_fb_dma_helper.h>
> +#include <drm/drm_fourcc.h>
> +#include <drm/drm_framebuffer.h>
> +#include <drm/drm_gem_atomic_helper.h>
> +#include <drm/drm_gem_dma_helper.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_rect.h>
> +
> +#include "dcif-drv.h"
> +#include "dcif-reg.h"
> +
> +static const u32 dcif_primary_plane_formats[] = {
> +     /* RGB */
> +     DRM_FORMAT_RGB565,
> +     DRM_FORMAT_RGB888,
> +     DRM_FORMAT_XBGR8888,
> +     DRM_FORMAT_XRGB1555,
> +     DRM_FORMAT_XRGB4444,
> +     DRM_FORMAT_XRGB8888,
> +
> +     /* Packed YCbCr */
> +     DRM_FORMAT_YUYV,
> +     DRM_FORMAT_YVYU,
> +     DRM_FORMAT_UYVY,
> +     DRM_FORMAT_VYUY,
> +};
> +
> +static const u32 dcif_overlay_plane_formats[] = {
> +     /* RGB */
> +     DRM_FORMAT_RGB565,
> +     DRM_FORMAT_RGB888,
> +     DRM_FORMAT_XBGR8888,
> +     DRM_FORMAT_XRGB1555,
> +     DRM_FORMAT_XRGB4444,
> +     DRM_FORMAT_XRGB8888,
> +};
> +
> +static inline struct dcif_dev *plane_to_dcif_dev(struct drm_plane *plane)
> +{
> +     return to_dcif_dev(plane->dev);
> +}
> +
> +static inline dma_addr_t drm_plane_state_to_baseaddr(struct drm_plane_state 
> *state)
> +{
> +     struct drm_framebuffer *fb = state->fb;
> +     struct drm_gem_dma_object *dma_obj;
> +     unsigned int x = state->src.x1 >> 16;
> +     unsigned int y = state->src.y1 >> 16;
> +
> +     dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
> +
> +     return dma_obj->dma_addr + fb->offsets[0] + fb->pitches[0] * y + 
> fb->format->cpp[0] * x;
> +}
> +
> +static int dcif_plane_get_layer_id(struct drm_plane *plane)
> +{
> +     return (plane->type == DRM_PLANE_TYPE_PRIMARY) ? 0 : 1;
> +}
> +
> +static int dcif_plane_atomic_check(struct drm_plane *plane, struct 
> drm_atomic_state *state)
> +{
> +     struct drm_plane_state *new_plane_state = 
> drm_atomic_get_new_plane_state(state, plane);
> +     struct drm_plane_state *old_plane_state = 
> drm_atomic_get_old_plane_state(state, plane);
> +     struct dcif_dev *dcif = plane_to_dcif_dev(plane);
> +     struct drm_framebuffer *fb = new_plane_state->fb;
> +     struct drm_framebuffer *old_fb = old_plane_state->fb;
> +     struct drm_crtc_state *crtc_state;
> +
> +     if (!fb)
> +             return 0;
> +
> +     crtc_state = drm_atomic_get_new_crtc_state(state, &dcif->crtc);
> +     if (WARN_ON(!crtc_state))
> +             return -EINVAL;
> +
> +     /*
> +      * Force CRTC mode change if framebuffer stride or pixel format have 
> changed.
> +      */
> +     if (plane->type == DRM_PLANE_TYPE_PRIMARY && old_fb &&
> +         (fb->pitches[0] != old_fb->pitches[0] || fb->format->format != 
> old_fb->format->format))
> +             crtc_state->mode_changed = true;
> +
> +     return drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
> +                                                DRM_PLANE_NO_SCALING, 
> DRM_PLANE_NO_SCALING, true,
> +                                                true);
> +}
> +
> +static void dcif_plane_atomic_update(struct drm_plane *plane, struct 
> drm_atomic_state *state)
> +{
> +     struct drm_plane_state *new_state = 
> drm_atomic_get_new_plane_state(state, plane);
> +     struct dcif_dev *dcif = plane_to_dcif_dev(plane);
> +     int layer_id = dcif_plane_get_layer_id(plane);
> +     struct drm_framebuffer *fb = new_state->fb;
> +     u32 crtc_x, crtc_y, crtc_h, crtc_w;
> +     u32 layer_fmt = 0, yuv_fmt = 0;
> +     dma_addr_t baseaddr;
> +     u32 reg;
> +
> +     if (!fb)
> +             return;
> +
> +     crtc_x = new_state->crtc_x;
> +     crtc_y = new_state->crtc_y;
> +     crtc_h = new_state->crtc_h;
> +     crtc_w = new_state->crtc_w;
> +
> +     /* visible portion of plane on crtc */
> +     regmap_write(dcif->regmap, DCIF_CTRLDESC1(layer_id),
> +                  DCIF_CTRLDESC1_POSX(crtc_x) | DCIF_CTRLDESC1_POSY(crtc_y));
> +     regmap_write(dcif->regmap, DCIF_CTRLDESC2(layer_id),
> +                  DCIF_CTRLDESC2_WIDTH(crtc_w) | 
> DCIF_CTRLDESC2_HEIGHT(crtc_h));
> +
> +     /* pitch size */
> +     reg = DCIF_CTRLDESC3_P_SIZE(2) | DCIF_CTRLDESC3_T_SIZE(2) |
> +           DCIF_CTRLDESC3_PITCH(fb->pitches[0]);
> +     regmap_write(dcif->regmap, DCIF_CTRLDESC3(layer_id), reg);
> +
> +     /*  address */
> +     baseaddr = drm_fb_dma_get_gem_addr(new_state->fb, new_state, 0);
> +
> +     drm_dbg_kms(plane->dev, "[PLANE:%d:%s] fb address %pad, pitch 0x%08x\n",
> +                 plane->base.id, plane->name, &baseaddr, fb->pitches[0]);
> +
> +     regmap_write(dcif->regmap, DCIF_CTRLDESC4(layer_id), baseaddr);
> +
> +     /* Format */
> +     switch (fb->format->format) {
> +     /* RGB Formats */
> +     case DRM_FORMAT_RGB565:
> +             layer_fmt = CTRLDESCL0_FORMAT_RGB565;
> +             break;
> +     case DRM_FORMAT_RGB888:
> +             layer_fmt = CTRLDESCL0_FORMAT_RGB888;
> +             break;
> +     case DRM_FORMAT_XRGB1555:
> +             layer_fmt = CTRLDESCL0_FORMAT_ARGB1555;
> +             break;
> +     case DRM_FORMAT_XRGB4444:
> +             layer_fmt = CTRLDESCL0_FORMAT_ARGB4444;
> +             break;
> +     case DRM_FORMAT_XBGR8888:
> +             layer_fmt = CTRLDESCL0_FORMAT_ABGR8888;
> +             break;
> +     case DRM_FORMAT_XRGB8888:
> +             layer_fmt = CTRLDESCL0_FORMAT_ARGB8888;
> +             break;
> +
> +     /* YUV Formats */
> +     case DRM_FORMAT_YUYV:
> +             layer_fmt = CTRLDESCL0_FORMAT_YCBCR422;
> +             yuv_fmt = CTRLDESCL0_YUV_FORMAT_VY2UY1;
> +             break;
> +     case DRM_FORMAT_YVYU:
> +             layer_fmt = CTRLDESCL0_FORMAT_YCBCR422;
> +             yuv_fmt = CTRLDESCL0_YUV_FORMAT_UY2VY1;
> +             break;
> +     case DRM_FORMAT_UYVY:
> +             layer_fmt = CTRLDESCL0_FORMAT_YCBCR422;
> +             yuv_fmt = CTRLDESCL0_YUV_FORMAT_Y2VY1U;
> +             break;
> +     case DRM_FORMAT_VYUY:
> +             layer_fmt = CTRLDESCL0_FORMAT_YCBCR422;
> +             yuv_fmt = CTRLDESCL0_YUV_FORMAT_Y2UY1V;
> +             break;
> +
> +     default:
> +             dev_err(dcif->drm.dev, "Unknown pixel format 0x%x\n", 
> fb->format->format);
> +             break;
> +     }
> +
> +     if (plane->type == DRM_PLANE_TYPE_OVERLAY && yuv_fmt == 
> CTRLDESCL0_YUV_FORMAT_Y2UY1V) {
> +             dev_err(dcif->drm.dev, "Overlay plane could not support YUV 
> format\n");
> +             return;
> +     }
> +
> +     reg = DCIF_CTRLDESC0_EN | DCIF_CTRLDESC0_SHADOW_LOAD_EN |
> +           DCIF_CTRLDESC0_FORMAT(layer_fmt) | 
> DCIF_CTRLDESC0_YUV_FORMAT(yuv_fmt);
> +
> +     /* Alpha */
> +     reg |= DCIF_CTRLDESC0_GLOBAL_ALPHA(new_state->alpha >> 8) | 
> ALPHA_GLOBAL;
> +
> +     regmap_write(dcif->regmap, DCIF_CTRLDESC0(layer_id), reg);
> +}
> +
> +static void dcif_overlay_plane_atomic_disable(struct drm_plane *plane,
> +                                           struct drm_atomic_state *state)
> +{
> +     struct dcif_dev *dcif = plane_to_dcif_dev(plane);
> +
> +     regmap_update_bits(dcif->regmap, DCIF_CTRLDESC0(1),
> +                        DCIF_CTRLDESC0_EN | DCIF_CTRLDESC0_SHADOW_LOAD_EN,
> +                        DCIF_CTRLDESC0_SHADOW_LOAD_EN);
> +}
> +
> +static const struct drm_plane_helper_funcs dcif_primary_plane_helper_funcs = 
> {
> +     .prepare_fb     = drm_gem_plane_helper_prepare_fb,
> +     .atomic_check   = dcif_plane_atomic_check,
> +     .atomic_update  = dcif_plane_atomic_update,
> +};
> +
> +static const struct drm_plane_helper_funcs dcif_overlay_plane_helper_funcs = 
> {
> +     .atomic_check   = dcif_plane_atomic_check,
> +     .atomic_update  = dcif_plane_atomic_update,
> +     .atomic_disable = dcif_overlay_plane_atomic_disable,
> +};
> +
> +static const struct drm_plane_funcs dcif_plane_funcs = {
> +     .update_plane           = drm_atomic_helper_update_plane,
> +     .disable_plane          = drm_atomic_helper_disable_plane,
> +     .destroy                = drm_plane_cleanup,
> +     .reset                  = drm_atomic_helper_plane_reset,
> +     .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
> +     .atomic_destroy_state   = drm_atomic_helper_plane_destroy_state,
> +};
> +
> +int dcif_plane_init(struct dcif_dev *dcif)
> +{
> +     const u32 supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) |
> +                                     BIT(DRM_COLOR_YCBCR_BT709) |
> +                                     BIT(DRM_COLOR_YCBCR_BT2020);
> +     const u32 supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
> +                                  BIT(DRM_COLOR_YCBCR_FULL_RANGE);
> +     int ret;
> +
> +     /* primary plane */
> +     drm_plane_helper_add(&dcif->planes.primary, 
> &dcif_primary_plane_helper_funcs);
> +     ret = drm_universal_plane_init(&dcif->drm, &dcif->planes.primary, 1, 
> &dcif_plane_funcs,
> +                                    dcif_primary_plane_formats,
> +                                    ARRAY_SIZE(dcif_primary_plane_formats), 
> NULL,
> +                                    DRM_PLANE_TYPE_PRIMARY, NULL);
> +     if (ret) {
> +             drm_err(&dcif->drm, "failed to initialize primary plane: %d\n", 
> ret);
> +             return ret;
> +     }
> +
> +     ret = drm_plane_create_color_properties(&dcif->planes.primary, 
> supported_encodings,
> +                                             supported_ranges, 
> DRM_COLOR_YCBCR_BT601,
> +                                             DRM_COLOR_YCBCR_LIMITED_RANGE);
> +     if (ret)
> +             return ret;
> +
> +     ret = drm_plane_create_alpha_property(&dcif->planes.primary);
> +     if (ret)
> +             return ret;
> +
> +     /* overlay plane */
> +     drm_plane_helper_add(&dcif->planes.overlay, 
> &dcif_overlay_plane_helper_funcs);
> +     ret = drm_universal_plane_init(&dcif->drm, &dcif->planes.overlay, 1, 
> &dcif_plane_funcs,
> +                                    dcif_overlay_plane_formats,
> +                                    ARRAY_SIZE(dcif_overlay_plane_formats), 
> NULL,
> +                                    DRM_PLANE_TYPE_OVERLAY, NULL);
> +     if (ret) {
> +             drm_err(&dcif->drm, "failed to initialize overlay plane: %d\n", 
> ret);
> +             return ret;
> +     }
> +
> +     return drm_plane_create_alpha_property(&dcif->planes.overlay);
> +}
> diff --git a/drivers/gpu/drm/imx/dcif/dcif-reg.h 
> b/drivers/gpu/drm/imx/dcif/dcif-reg.h
> new file mode 100644
> index 0000000000000..f918bbb6d2d15
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dcif/dcif-reg.h
> @@ -0,0 +1,266 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +/*
> + * Copyright 2025 NXP
> + */
> +#ifndef __DCIF_REG_H__
> +#define __DCIF_REG_H__
> +
> +#include <linux/bits.h>
> +
> +/* Version ID Register */
> +#define DCIF_VER                             0x0
> +#define   DCIF_VER_GET_FEATURE(x)            FIELD_GET(GENMASK(15, 0), x)
> +#define   DCIF_VER_GET_MINOR(x)                      FIELD_GET(GENMASK(23, 
> 16), x)
> +#define   DCIF_VER_GET_MAJOR(x)                      FIELD_GET(GENMASK(31, 
> 24), x)
> +
> +/* Parameter Registers */
> +#define DCIF_PAR_0                           0x4
> +#define   DCIF_PAR_0_LAYER_NUM(x)            FIELD_PREP(GENMASK(3, 0), x)
> +#define   DCIF_PAR_0_DOMAIN_NUM(x)           FIELD_PREP(GENMASK(5, 4), x)
> +#define   DCIF_PAR_0_AXI_DATA_WIDTH(x)               FIELD_PREP(GENMASK(7, 
> 6), x)
> +#define   DCIF_PAR_0_CLUT_RAM_NUM(x)         FIELD_PREP(GENMASK(11, 8), x)
> +#define   DCIF_PAR_0_CSC_NUM(x)                      FIELD_PREP(GENMASK(13, 
> 12), x)
> +#define   DCIF_PAR_0_CRC_REGION_NUM(x)               FIELD_PREP(GENMASK(18, 
> 16), x)
> +#define   DCIF_PAR_0_BACKUP(x)                       FIELD_PREP(GENMASK(31, 
> 28), x)
> +
> +#define DCIF_PAR_1                           0x8
> +#define   DCIF_PAR_1_LAYER0_FIFO_SIZE(x)     FIELD_PREP(GENMASK(3, 0), x)
> +#define   DCIF_PAR_1_LAYER1_FIFO_SIZE(x)     FIELD_PREP(GENMASK(7, 4), x)
> +
> +/* Display Control and Parameter Registers */
> +#define DCIF_DISP_CTRL                               0x10
> +#define   DCIF_DISP_CTRL_DISP_ON             BIT(0)
> +#define   DCIF_DISP_CTRL_AXI_RD_HOLD         BIT(30)
> +#define   DCIF_DISP_CTRL_SW_RST                      BIT(31)
> +#define DCIF_DISP_PAR                                0x14
> +#define   DCIF_DISP_PAR_BGND_B(x)            FIELD_PREP(GENMASK(7, 0), x)
> +#define   DCIF_DISP_PAR_BGND_G(x)            FIELD_PREP(GENMASK(15, 8), x)
> +#define   DCIF_DISP_PAR_BGND_R(x)            FIELD_PREP(GENMASK(23, 16), x)
> +#define DCIF_DISP_SIZE                               0x18
> +#define   DCIF_DISP_SIZE_DISP_WIDTH(x)               FIELD_PREP(GENMASK(11, 
> 0), x)
> +#define   DCIF_DISP_SIZE_DISP_HEIGHT(x)              FIELD_PREP(GENMASK(27, 
> 16), x)
> +
> +/* Display Status Registers */
> +#define DCIF_DISP_SR0                                0x1C
> +#define   DCIF_DISP_SR0_AXI_RD_PEND(x)               FIELD_PREP(GENMASK(4, 
> 0), x)
> +#define   DCIF_DISP_SR0_DPI_BUSY(x)          FIELD_PREP(GENMASK(14, 14), x)
> +#define   DCIF_DISP_SR0_AXI_RD_BUSY(x)               FIELD_PREP(GENMASK(15, 
> 15), x)
> +#define DCIF_DISP_SR0_TXFIFO_CNT(x)          FIELD_PREP(GENMASK(23, 16), x)
> +
> +#define DCIF_DISP_SR1                                0x20
> +#define   DCIF_DISP_SR1_H_CNT(x)             FIELD_PREP(GENMASK(11, 0), x)
> +#define   DCIF_DISP_SR1_V_CNT(x)             FIELD_PREP(GENMASK(27, 16), x)
> +
> +/* Interrupt Enable and Status Registers, n=0-2*/
> +#define DCIF_IE0(n)                          (0x24 + (n) * 0x10000)
> +#define DCIF_IS0(n)                          (0x28 + (n) * 0x10000)
> +#define   DCIF_INT0_VSYNC                    BIT(0)
> +#define   DCIF_INT0_UNDERRUN                 BIT(1)
> +#define   DCIF_INT0_VS_BLANK                 BIT(2)
> +#define   DCIF_INT0_HIST_DONE                        BIT(5)
> +#define   DCIF_INT0_CRC_ERR                  BIT(6)
> +#define   DCIF_INT0_CRC_ERR_SAT                      BIT(7)
> +
> +#define DCIF_IE1(n)                          (0x2C + (n) * 0x10000)
> +#define DCIF_IS1(n)                          (0x30 + (n) * 0x10000)
> +#define   DCIF_INT1_FIFO_PANIC0                      BIT(0)
> +#define   DCIF_INT1_FIFO_PANIC1                      BIT(1)
> +#define   DCIF_INT1_DMA_ERR0                 BIT(8)
> +#define   DCIF_INT1_DMA_ERR1                 BIT(9)
> +#define   DCIF_INT1_DMA_DONE0                        BIT(16)
> +#define   DCIF_INT1_DMA_DONE1                        BIT(17)
> +#define   DCIF_INT1_FIFO_EMPTY0                      BIT(24)
> +#define   DCIF_INT1_FIFO_EMPTY1                      BIT(25)
> +
> +/* DPI Control and Sync Parameter Registers */
> +#define DCIF_DPI_CTRL                                0x40
> +#define   DCIF_DPI_CTRL_HSYNC_POL_LOW                BIT(0)
> +#define   DCIF_DPI_CTRL_VSYNC_POL_LOW                BIT(1)
> +#define   DCIF_DPI_CTRL_DE_POL_LOW           BIT(2)
> +#define   DCIF_DPI_CTRL_PCLK_EDGE_FALLING    BIT(3)
> +#define   DCIF_DPI_CTRL_POL_MASK             GENMASK(3, 0)
> +#define   DCIF_DPI_CTRL_DATA_INV(x)          FIELD_PREP(GENMASK(4, 4), x)
> +#define   DCIF_DPI_CTRL_DEF_BGND_EN(x)               FIELD_PREP(GENMASK(5, 
> 5), x)
> +#define   DCIF_DPI_CTRL_FETCH_OPT(x)         FIELD_PREP(GENMASK(9, 8), x)
> +#define   DCIF_DPI_CTRL_DISP_MODE(x)         FIELD_PREP(GENMASK(13, 12), x)
> +#define   DCIF_DPI_CTRL_DATA_PATTERN_MASK    GENMASK(18, 16)
> +#define   DCIF_DPI_CTRL_DATA_PATTERN(x)              FIELD_PREP(GENMASK(18, 
> 16), x)
> +#define   PATTERN_RGB888                     0
> +#define   PATTERN_RBG888                     1
> +#define   PATTERN_GBR888                     2
> +#define   PATTERN_GRB888                     3
> +#define   PATTERN_BRG888                     4
> +#define   PATTERN_BGR888                     5
> +#define   PATTERN_RGB555                     6
> +#define   PATTERN_RGB565                     7
> +
> +#define DCIF_DPI_HSYN_PAR                    0x44
> +#define   DCIF_DPI_HSYN_PAR_FP_H(x)          FIELD_PREP(GENMASK(11, 0), x)
> +#define   DCIF_DPI_HSYN_PAR_BP_H(x)          FIELD_PREP(GENMASK(27, 16), x)
> +
> +#define DCIF_DPI_VSYN_PAR                    0x48
> +#define   DCIF_DPI_VSYN_PAR_FP_V(x)          FIELD_PREP(GENMASK(11, 0), x)
> +#define   DCIF_DPI_VSYN_PAR_BP_V(x)          FIELD_PREP(GENMASK(27, 16), x)
> +
> +#define DCIF_DPI_VSYN_HSYN_WIDTH             0x4C
> +#define   DCIF_DPI_VSYN_HSYN_WIDTH_PW_H(x)   FIELD_PREP(GENMASK(11, 0), x)
> +#define   DCIF_DPI_VSYN_HSYN_WIDTH_PW_V(x)   FIELD_PREP(GENMASK(27, 16), x)
> +
> +/* Control Descriptor Registers, n=0-1*/
> +#define DCIF_CTRLDESC0(n)                    (0x10000 + (n) * 0x10000)
> +#define   DCIF_CTRLDESC0_AB_MODE(x)          FIELD_PREP(GENMASK(1, 0), x)
> +#define   ALPHA_EMBEDDED                     0
> +#define   ALPHA_GLOBAL                               1
> +#define   DCIF_CTRLDESC0_YUV_FORMAT_MASK     GENMASK(15, 14)
> +#define   DCIF_CTRLDESC0_YUV_FORMAT(x)               FIELD_PREP(GENMASK(15, 
> 14), x)
> +#define   CTRLDESCL0_YUV_FORMAT_Y2VY1U               0x0
> +#define   CTRLDESCL0_YUV_FORMAT_Y2UY1V               0x1
> +#define   CTRLDESCL0_YUV_FORMAT_VY2UY1               0x2
> +#define   CTRLDESCL0_YUV_FORMAT_UY2VY1               0x3
> +#define   DCIF_CTRLDESC0_GLOBAL_ALPHA(x)     FIELD_PREP(GENMASK(23, 16), x)
> +#define   DCIF_CTRLDESC0_FORMAT_MASK         GENMASK(27, 24)
> +#define   DCIF_CTRLDESC0_FORMAT(x)           FIELD_PREP(GENMASK(27, 24), x)
> +#define   CTRLDESCL0_FORMAT_RGB565           0x4
> +#define   CTRLDESCL0_FORMAT_ARGB1555         0x5
> +#define   CTRLDESCL0_FORMAT_ARGB4444         0x6
> +#define   CTRLDESCL0_FORMAT_YCBCR422         0x7
> +#define   CTRLDESCL0_FORMAT_RGB888           0x8
> +#define   CTRLDESCL0_FORMAT_ARGB8888         0x9
> +#define   CTRLDESCL0_FORMAT_ABGR8888         0xa
> +#define   DCIF_CTRLDESC0_SHADOW_LOAD_EN              BIT(30)
> +#define   DCIF_CTRLDESC0_EN                  BIT(31)
> +
> +#define DCIF_CTRLDESC1(n)                    (0x10004 + (n) * 0x10000)
> +#define   DCIF_CTRLDESC1_POSX(x)             FIELD_PREP(GENMASK(11, 0), x)
> +#define   DCIF_CTRLDESC1_POSY(x)             FIELD_PREP(GENMASK(27, 16), x)
> +
> +#define DCIF_CTRLDESC2(n)                    (0x10008 + (n) * 0x10000)
> +#define   DCIF_CTRLDESC2_WIDTH(x)            FIELD_PREP(GENMASK(11, 0), x)
> +#define   DCIF_CTRLDESC2_HEIGHT(x)           FIELD_PREP(GENMASK(27, 16), x)
> +
> +#define DCIF_CTRLDESC3(n)                    (0x1000C + (n) * 0x10000)
> +#define   DCIF_CTRLDESC3_PITCH(x)            FIELD_PREP(GENMASK(15, 0), x)
> +#define   DCIF_CTRLDESC3_T_SIZE(x)           FIELD_PREP(GENMASK(17, 16), x)
> +#define   DCIF_CTRLDESC3_P_SIZE(x)           FIELD_PREP(GENMASK(22, 20), x)
> +
> +#define DCIF_CTRLDESC4(n)                    (0x10010 + (n) * 0x10000)
> +#define   DCIF_CTRLDESC4_ADDR(x)             FIELD_PREP(GENMASK(31, 0), x)
> +
> +#define DCIF_CTRLDESC5(n)                    (0x10014 + (n) * 0x10000)
> +#define DCIF_CTRLDESC6(n)                    (0x10018 + (n) * 0x10000)
> +#define   DCIF_CTRLDESC6_BCLR_B(x)           FIELD_PREP(GENMASK(7, 0), x)
> +#define   DCIF_CTRLDESC6_BCLR_G(x)           FIELD_PREP(GENMASK(15, 8), x)
> +#define   DCIF_CTRLDESC6_BCLR_R(x)           FIELD_PREP(GENMASK(23, 16), x)
> +#define   DCIF_CTRLDESC6_BCLR_A(x)           FIELD_PREP(GENMASK(31, 24), x)
> +
> +/* CLUT control Register */
> +#define DCIF_CLUT_CTRL                               0x1003C
> +#define   DCIF_CLUT_CTRL_CLUT0_SEL(x)                FIELD_PREP(GENMASK(0, 
> 0), x)
> +#define   DCIF_CLUT_CTRL_CLUT1_SEL(x)                FIELD_PREP(GENMASK(3, 
> 3), x)
> +#define   DCIF_CLUT_CTRL_CLUT_MUX(x)         FIELD_PREP(GENMASK(29, 28), x)
> +#define   DCIF_CLUT_CTRL_CLUT_SHADOW_LOAD_EN(x)      FIELD_PREP(GENMASK(31, 
> 31), x)
> +
> +/* FIFO Panic Threshold Register, n=0-1 */
> +#define DCIF_PANIC_THRES(n)                  (0x10040 + (n) * 0x10000)
> +#define   DCIF_PANIC_THRES_LOW_MASK          GENMASK(11, 0)
> +#define   DCIF_PANIC_THRES_LOW(x)            FIELD_PREP(GENMASK(11, 00), x)
> +#define   DCIF_PANIC_THRES_HIGH_MASK         GENMASK(27, 16)
> +#define   DCIF_PANIC_THRES_HIGH(x)           FIELD_PREP(GENMASK(27, 16), x)
> +#define   DCIF_PANIC_THRES_REQ_EN            BIT(31)
> +#define   PANIC0_THRES_MAX                   511
> +
> +/* Layer Status Register 0, n=0-1 */
> +#define DCIF_LAYER_SR0(n)                    (0x10044 + (n) * 0x10000)
> +#define   DCIF_LAYER_SR0_L0_FIFO_CNT_MASK    GENMASK(9, 0)
> +#define   DCIF_LAYER_SR0_L0_FIFO_CNT(x)              FIELD_PREP(GENMASK(9, 
> 0), x)
> +
> +/* Color Space Conversion Control and Coefficient Registers for Layer 0 */
> +#define DCIF_CSC_CTRL_L0                     0x10050
> +#define   DCIF_CSC_CTRL_L0_CSC_EN            BIT(0)
> +#define   DCIF_CSC_CTRL_L0_CSC_MODE_YCBCR2RGB        BIT(1)
> +
> +#define DCIF_CSC_COEF0_L0                    0x10054
> +#define   DCIF_CSC_COEF0_L0_A1(x)            FIELD_PREP_CONST(GENMASK(10, 
> 0), x)
> +#define   DCIF_CSC_COEF0_L0_A2(x)            FIELD_PREP_CONST(GENMASK(26, 
> 16), x)
> +
> +#define DCIF_CSC_COEF1_L0                    0x10058
> +#define   DCIF_CSC_COEF1_L0_A3(x)            FIELD_PREP_CONST(GENMASK(10, 
> 0), x)
> +#define   DCIF_CSC_COEF1_L0_B1(x)            FIELD_PREP_CONST(GENMASK(26, 
> 16), x)
> +
> +#define DCIF_CSC_COEF2_L0                    0x1005C
> +#define   DCIF_CSC_COEF2_L0_B2(x)            FIELD_PREP_CONST(GENMASK(10, 
> 0), x)
> +#define   DCIF_CSC_COEF2_L0_B3(x)            FIELD_PREP_CONST(GENMASK(26, 
> 16), x)
> +
> +#define DCIF_CSC_COEF3_L0                    0x10060
> +#define   DCIF_CSC_COEF3_L0_C1(x)            FIELD_PREP_CONST(GENMASK(10, 
> 0), x)
> +#define   DCIF_CSC_COEF3_L0_C2(x)            FIELD_PREP_CONST(GENMASK(26, 
> 16), x)
> +
> +#define DCIF_CSC_COEF4_L0                    0x10064
> +#define   DCIF_CSC_COEF4_L0_C3(x)            FIELD_PREP_CONST(GENMASK(10, 
> 0), x)
> +#define   DCIF_CSC_COEF4_L0_D1(x)            FIELD_PREP_CONST(GENMASK(24, 
> 16), x)
> +
> +#define DCIF_CSC_COEF5_L0                    0x10068
> +#define   DCIF_CSC_COEF5_L0_D2(x)            FIELD_PREP_CONST(GENMASK(8, 0), 
> x)
> +#define   DCIF_CSC_COEF5_L0_D3(x)            FIELD_PREP_CONST(GENMASK(24, 
> 16), x)
> +
> +/* CRC Control, Threshold, and Histogram Coefficient Registers */
> +#define DCIF_CRC_CTRL                                0x20100
> +#define   DCIF_CRC_CTRL_CRC_EN(x)            (1 << (x))
> +#define   DCIF_CRC_CTRL_HIST_REGION_SEL(x)   FIELD_PREP(GENMASK(17, 16), x)
> +#define   DCIF_CRC_CTRL_HIST_MODE            BIT(21)
> +#define   DCIF_CRC_CTRL_HIST_TRIG            BIT(22)
> +#define   DCIF_CRC_CTRL_HIST_EN                      BIT(23)
> +#define   DCIF_CRC_CTRL_CRC_MODE             BIT(28)
> +#define   DCIF_CRC_CTRL_CRC_TRIG             BIT(29)
> +#define   DCIF_CRC_CTRL_CRC_ERR_CNT_RST              BIT(30)
> +#define   DCIF_CRC_CTRL_CRC_SHADOW_LOAD_EN   BIT(31)
> +
> +#define DCIF_CRC_THRES                               0x20104
> +#define   DCIF_CRC_THRES_CRC_THRESHOLD_MASK  GENMASK(31, 0)
> +#define   DCIF_CRC_THRES_CRC_THRESHOLD(x)    FIELD_PREP(GENMASK(31, 0), x)
> +
> +#define DCIF_CRC_HIST_COEF                   0x20108
> +#define   DCIF_CRC_HIST_COEF_HIST_WB_MASK    GENMASK(7, 0)
> +#define   DCIF_CRC_HIST_COEF_HIST_WB(x)              FIELD_PREP(GENMASK(7, 
> 0), x)
> +#define   DCIF_CRC_HIST_COEF_HIST_WG_MASK    GENMASK(15, 8)
> +#define   DCIF_CRC_HIST_COEF_HIST_WG(x)              FIELD_PREP(GENMASK(15, 
> 8), x)
> +#define   DCIF_CRC_HIST_COEF_HIST_WR_MASK    GENMASK(23, 16)
> +#define   DCIF_CRC_HIST_COEF_HIST_WR(x)              FIELD_PREP(GENMASK(23, 
> 16), x)
> +
> +#define DCIF_CRC_ERR_CNT                     0x2010C
> +#define   DCIF_CRC_ERR_CNT_CRC_ERR_CNT_MASK  GENMASK(31, 0)
> +#define   DCIF_CRC_ERR_CNT_CRC_ERR_CNT(x)    FIELD_PREP(GENMASK(31, 0), x)
> +
> +#define DCIF_CRC_SR                          0x20110
> +#define   DCIF_CRC_SR_HIST_CNT_SAT_MASK              BIT(13)
> +#define   DCIF_CRC_SR_HIST_CNT_SAT(x)                FIELD_PREP(GENMASK(13, 
> 13), x)
> +#define   DCIF_CRC_SR_HIST_SAT_MASK          BIT(14)
> +#define   DCIF_CRC_SR_HIST_SAT(x)            FIELD_PREP(GENMASK(14, 14), x)
> +#define   DCIF_CRC_SR_HIST_BUSY_MASK         BIT(15)
> +#define   DCIF_CRC_SR_HIST_BUSY(x)           FIELD_PREP(GENMASK(15, 15), x)
> +#define   DCIF_CRC_SR_CRC_STATUS_MASK                BIT(31)
> +#define   DCIF_CRC_SR_CRC_STATUS(x)          FIELD_PREP(GENMASK(31, 31), x)
> +
> +#define DCIF_CRC_HIST_CNT_B(n)                       (0x20114 + (n) * 4)
> +#define   DCIF_B_BIN_CNT_MASK                        GENMASK(20, 0)
> +#define   DCIF_B_BIN_CNT(x)                  FIELD_PREP(GENMASK(20, 0), x)
> +
> +/* CRC Region Position, Size, Value, and Expected Value Registers, n=0-3 */
> +#define DCIF_CRC_POS_R(n)                    (0x20214 + (n) * 0x10)
> +#define   DCIF_CRC_POS_CRC_HOR_POS(x)                FIELD_PREP(GENMASK(11, 
> 0), x)
> +#define   DCIF_CRC_POS_CRC_VER_POS(x)                FIELD_PREP(GENMASK(27, 
> 16), x)
> +
> +#define DCIF_CRC_SIZE_R(n)                   (0x20218 + (n) * 0x10)
> +#define   DCIF_CRC_SIZE_CRC_HOR_SIZE(x)              FIELD_PREP(GENMASK(11, 
> 0), x)
> +#define   DCIF_CRC_SIZE_CRC_VER_SIZE(x)              FIELD_PREP(GENMASK(27, 
> 16), x)
> +
> +#define DCIF_CRC_VAL_R(n)                    (0x2021C + (n) * 0x10)
> +#define   DCIF_CRC_VAL_CRC_VAL_MASK          GENMASK(31, 0)
> +#define   DCIF_CRC_VAL_CRC_VAL(x)            FIELD_PREP(GENMASK(31, 0), x)
> +
> +#define DCIF_CRC_EXP_VAL_R(n)                        (0x20220 + (n) * 0x10)
> +#define   DCIF_CRC_EXP_VAL_CRC_EXP_VAL_MASK  GENMASK(31, 0)
> +#define   DCIF_CRC_EXP_VAL_CRC_EXP_VAL(x)    FIELD_PREP(GENMASK(31, 0), x)
> +
> +#endif /* __DCIF_REG_H__ */
> --
> 2.49.0
>

Reply via email to