From: sashiko-bot@kernel.org
To: "Laurentiu Palcu" <laurentiu.palcu@oss.nxp.com>
Cc: imx@lists.linux.dev, robh@kernel.org, conor+dt@kernel.org,
dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
linux-clk@vger.kernel.org, Frank.Li@kernel.org
Subject: Re: [PATCH v10 5/9] drm/imx: Add support for i.MX94 DCIF
Date: Tue, 06 Oct 2026 12:39:06 +0000 [thread overview]
Message-ID: <20261006123906.AA3D01F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20261006-dcif-upstreaming-v10-5-bcfb28de0aae@oss.nxp.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] drm/imx/dcif: unpowered MMIO access crash if PM resume fails in atomic_enable
- [High] drm/imx/dcif: vblank refcount underflow and memory leak via manual event caching
- [High] drm/imx/dcif: NULL pointer dereference in IRQ handler during probe
- [Medium] drm/imx/dcif: premature vblank event delivery exposes race with plane updates
- [Medium] drm/imx/dcif: back-to-back software reset may cause incomplete hardware reset
--
commit 5b82f4222050053f161ded1c655289268046892b
Author: Sandor Yu <sandor.yu@nxp.com>
drm/imx: Add support for i.MX94 DCIF
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;
> diff --git a/drivers/gpu/drm/imx/dcif/dcif-crtc.c b/drivers/gpu/drm/imx/dcif/dcif-crtc.c
> index 0000000000000..07016b5fc700d 100644
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dcif/dcif-crtc.c
> @@ -0,0 +1,763 @@
[ ... ]
> +static void dcif_reset_block(struct dcif_dev *dcif)
> +{
> + regmap_set_bits(dcif->regmap, DCIF_DISP_CTRL, DCIF_DISP_CTRL_SW_RST);
> +
> + regmap_clear_bits(dcif->regmap, DCIF_DISP_CTRL, DCIF_DISP_CTRL_SW_RST);
[Severity: Medium]
Will this 1-cycle reset pulse be sufficient for full pipeline resets across
all clock domains? Since this toggles the bit via back-to-back regmap
writes without any delay or status polling, the hardware might remain in an
indeterminate state.
> +}
[ ... ]
> +static void dcif_crtc_queue_state_event(struct drm_crtc *crtc)
> +{
> + struct dcif_dev *dcif = crtc_to_dcif_dev(crtc);
> +
> + scoped_guard(spinlock_irq, &crtc->dev->event_lock) {
> + if (crtc->state->event) {
> + WARN_ON(drm_crtc_vblank_get(crtc));
> + WARN_ON(dcif->event);
> + dcif->event = crtc->state->event;
> + crtc->state->event = NULL;
[Severity: High]
Does this code leak the vblank event and underflow the refcount if
drm_crtc_vblank_get() fails? Even if the WARN_ON triggers, the event is
manually cached and the loop continues. Later, dcif_irq_handler() will
blindly call drm_crtc_vblank_put(), underflowing the refcount.
If the hardware times out and no VSYNC fires, the event is leaked when
overwritten or ignored during disable. Could this use
drm_crtc_arm_vblank_event() instead of manual caching?
> + }
> + }
> +}
[ ... ]
> +static void dcif_crtc_atomic_enable(struct drm_crtc *crtc,
> + struct drm_atomic_commit *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;
> + int ret;
> +
> + dev_dbg(drm->dev, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
> +
> + /* enable power when we start to set mode for CRTC */
> + ret = pm_runtime_resume_and_get(drm->dev);
> + if (ret < 0) {
> + drm_err(drm, "failed to resume DCIF, ret = %d\n", ret);
> +
> + /* Don't leave the commit waiting for a flip done that never comes. */
> + scoped_guard(spinlock_irq, &drm->event_lock) {
> + if (crtc->state->event) {
> + drm_crtc_send_vblank_event(crtc, crtc->state->event);
> + crtc->state->event = NULL;
> + }
> + }
> + return;
[Severity: High]
If this returns early, will the DRM atomic helpers proceed to call
dcif_plane_atomic_update() anyway? Since the helpers ignore this void
return, plane updates will write to unpowered registers (e.g.,
DCIF_CTRLDESC1) and the subsequent dcif_crtc_atomic_disable() will call
dcif_disable_controller() which also accesses registers, causing a kernel
panic from unpowered MMIO access.
> + }
> + dcif->crtc_pm_enabled = true;
> +
> + dcif_crtc_mode_set_nofb(crtc_state, plane_state);
> +
> + drm_crtc_vblank_on(crtc);
> +
> + 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);
[Severity: Medium]
Since the controller is already enabled at this point, could a VSYNC
interrupt fire and deliver the event to userspace prematurely? Userspace
might receive the completion event before drm_atomic_helper_commit_planes()
finishes calling atomic_update on overlay planes, potentially causing
framebuffers to be released too early.
> +
> + if (dcif->has_crc && dcif_crtc_state->crc.source != DCIF_CRC_SRC_NONE) {
> + struct drm_rect roi;
> +
> + dcif_crtc_get_crc_roi(crtc_state, &roi);
> + dcif_crc_source_enable(dcif, dcif_crtc_state->crc.source, &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);
> + regmap_write(dcif->regmap, DCIF_IS0(domain), stat0);
> + regmap_write(dcif->regmap, DCIF_IS1(domain), stat1);
> +
> + if (stat0 & DCIF_INT0_VS_BLANK) {
> + drm_crtc_handle_vblank(&dcif->crtc);
[Severity: High]
Could this dereference a NULL crtc->dev? In dcif_probe(),
devm_request_irq() is called before the CRTC is initialized by
dcif_kms_prepare(). If the bootloader left the display active, a pending
VSYNC interrupt could fire immediately, passing the uninitialized CRTC to
drm_crtc_handle_vblank().
> +
> + scoped_guard(spinlock_irqsave, &drm->event_lock) {
> + if (dcif->event) {
[ ... ]
> diff --git a/drivers/gpu/drm/imx/dcif/dcif-drv.c b/drivers/gpu/drm/imx/dcif/dcif-drv.c
> index 0000000000000..ddc2614656a79 100644
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dcif/dcif-drv.c
> @@ -0,0 +1,238 @@
[ ... ]
> +static int dcif_probe(struct platform_device *pdev)
> +{
> + struct dcif_dev *dcif;
> + struct drm_device *drm;
> + int ret;
> + int i;
[ ... ]
> + ret = devm_request_irq(drm->dev, dcif->irq[dcif->cpu_domain],
> + dcif_irq_handler, 0, drm->driver->name, drm);
> + if (ret < 0)
> + return dev_err_probe(drm->dev, ret, "failed to install IRQ handler\n");
> +
> + dcif_read_chip_info(dcif);
> +
> + ret = dcif_kms_prepare(dcif);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261006-dcif-upstreaming-v10-0-bcfb28de0aae@oss.nxp.com?part=5
next prev parent reply other threads:[~2026-10-06 12:39 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-06 12:21 [PATCH v10 0/9] Add support for i.MX94 DCIF Laurentiu Palcu
2026-10-06 12:21 ` [PATCH v10 1/9] dt-bindings: display: fsl,ldb: Add i.MX94 LDB Laurentiu Palcu
2026-10-06 12:21 ` [PATCH v10 2/9] drm/bridge: fsl-ldb: Get the next non-panel bridge Laurentiu Palcu
2026-10-06 12:30 ` sashiko-bot
2026-10-06 12:21 ` [PATCH v10 3/9] drm/bridge: fsl-ldb: Add support for i.MX94 Laurentiu Palcu
2026-10-06 12:21 ` [PATCH v10 4/9] dt-bindings: display: imx: Add i.MX94 DCIF Laurentiu Palcu
2026-10-06 12:22 ` [PATCH v10 5/9] drm/imx: Add support for " Laurentiu Palcu
2026-10-06 12:39 ` sashiko-bot [this message]
2026-10-06 12:22 ` [PATCH v10 6/9] dt-bindings: clock: nxp,imx95-blk-ctl: Add ldb child node Laurentiu Palcu
2026-10-06 12:34 ` sashiko-bot
2026-10-07 13:11 ` Conor Dooley
2026-10-07 13:12 ` Conor Dooley
2026-10-07 13:57 ` Laurentiu Palcu
2026-10-07 14:02 ` Conor Dooley
2026-10-06 12:22 ` [PATCH v10 7/9] arm64: dts: imx94: Add display pipeline nodes Laurentiu Palcu
2026-10-06 12:22 ` [PATCH v10 8/9] arm64: dts: imx943-evk: Add display support using IT6263 Laurentiu Palcu
2026-10-06 12:22 ` [PATCH v10 9/9] MAINTAINERS: Add entry for i.MX94 DCIF driver Laurentiu Palcu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261006123906.AA3D01F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=imx@lists.linux.dev \
--cc=laurentiu.palcu@oss.nxp.com \
--cc=linux-clk@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox