From: Michael Grzeschik <mgr@kernel.org>
To: Lucas Stach <l.stach@pengutronix.de>
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>,
Johannes Schneider <johannes.schneider@leica-geosystems.com>,
barebox@lists.infradead.org,
thomas.haemmerle@leica-geosystems.com
Subject: Re: [PATCH 6/6] video: imx-lcdif: drain write-combine buffer before LCDIF DMA reads pixels
Date: Tue, 2 Jun 2026 17:17:40 +0200 [thread overview]
Message-ID: <ah70FFDnP_O2RYr-@pengutronix.de> (raw)
In-Reply-To: <9bf1b5920ca2c986533c5f17d10aa774aa60c895.camel@pengutronix.de>
Hi Johannes
On Tue, Jun 02, 2026 at 02:12:43PM +0200, Lucas Stach wrote:
> Am Dienstag, dem 02.06.2026 um 11:37 +0200 schrieb Ahmad Fatoum:
> >
> > On 6/2/26 10:12 AM, Lucas Stach wrote:
> > > Am Dienstag, dem 02.06.2026 um 04:09 +0000 schrieb Johannes Schneider:
> > > > From: Thomas Haemmerle <thomas.haemmerle@leica-geosystems.com>
> > > >
> > > > The LCDIF framebuffer is allocated as Normal Non-Cacheable (write-combine)
> > > > memory. After the splash command calls gu_screen_blit(), which copies the
> > > > decoded PNG via memcpy() from a cached shadow buffer into the hardware
> > > > framebuffer, writes may still reside in the CPU write buffer and not yet
> > > > be visible to the LCDIF DMA engine. On hardware this manifests as
> > > > partial or corrupted rendering — the bottom portion of the splash image
> > > > renders black or shows garbage.
> > > >
> > > > Implement fb_damage() to execute a DSB SY barrier after each blit,
> > > > ensuring all pending write-combine writes are committed to DRAM before
> > > > the LCDIF reads the pixel data.
> > > >
> > > > Assisted-by: Claude:claude-sonnet-4-6
> > > > Signed-of-by: Thomas Haemmerle <thomas.haemmerle@leica-geosystems.com>
> > > > ---
> > > > drivers/video/imx-lcdif.c | 13 +++++++++++++
> > > > 1 file changed, 13 insertions(+)
> > > >
> > > > diff --git a/drivers/video/imx-lcdif.c b/drivers/video/imx-lcdif.c
> > > > index ae5976c771..8d9b40be0f 100644
> > > > --- a/drivers/video/imx-lcdif.c
> > > > +++ b/drivers/video/imx-lcdif.c
> > > > @@ -20,6 +20,7 @@
> > > > #include <of_graph.h>
> > > > #include <video/media-bus-format.h>
> > > > #include <video/vpl.h>
> > > > +#include <asm/system.h>
> > > >
> > > > /* LCDIF V8 register map */
> > > > #define LCDC_V8_CTRL 0x00
> > > > @@ -262,9 +263,21 @@ static void lcdif_fb_disable(struct fb_info *info)
> > > > clk_disable_unprepare(priv->clk_axi);
> > > > }
> > > >
> > > > +static void lcdif_fb_damage(struct fb_info *info, struct fb_rect *rect)
> > > > +{
> > > > + /*
> > > > + * The hardware framebuffer is Normal Non-Cacheable (write-combine).
> > > > + * Writes from the shadow-buffer memcpy may sit in the CPU write buffer
> > > > + * and not yet be visible to the LCDIF DMA engine. Execute DSB SY to
> > > > + * drain the write buffer to DRAM before the LCDIF reads the pixels.
> > > > + */
> > > > + dsb();
> > >
> > > This will probably work in practice, but it doesn't exactly do what the
> > > comment above states. A dsb does not drain the write combine buffers,
> > > it just makes sure that they are drained before the next instruction is
> > > executed.
> > > So if the fb_damage is the last thing that gets executed, this will not
> > > ensure that the writes will actually become visible to external agents.
> > >
> > > A more robust way to drain the write combine buffers is to execute a
> > > readback of a memory location within the WC region.
> >
> > Would that on its own suffice though? If we have just the single buffer,
> > flushing the write buffer only reduces the race window, but doesn't
> > remove it as the framebuffer write may still happen in parallel to the
> > scanout.
>
> Updating the (front-)framebuffer will always be racy against the
> scanout. The flushes just ensure that the writes eventually reach
> memory visible to the scanout DMA master. Without any flushes there is
> nothing in the memory model which would prohibit writes from being
> stuck in the write buffers indefinitely.
I wonder why this all is actually necessary. The driver has an shadowed
buffer which can be flushed when ready.
Your implementation already has this comment.
+ /* 32bpp XRGB8888 → ARGB8888 pixel format.
+ * SHADOW_LOAD_EN causes the descriptor registers (address, format, pitch)
+ * to be latched into the active registers on the next VSYNC, which is
+ * required for the initial descriptor load in barebox's single-enable
+ * sequence (no DRM page-flip mechanism). EN is ORed in later by
+ * lcdif_enable() after DISP_ON. */
Look into mine and you will find the function flush function, which will
exactly do this after every frame write.
> > > > +}
> > > > +
> > > > static struct fb_ops lcdif_fb_ops = {
> > > > .fb_enable = lcdif_fb_enable,
> > > > .fb_disable = lcdif_fb_disable,
> > > > + .fb_damage = lcdif_fb_damage,
> > > > };
> > > >
> > > > static int lcdif_probe(struct device *dev)
> > >
> > >
Regards,
Michael
next prev parent reply other threads:[~2026-06-02 15:20 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-02 4:09 [PATCH 0/7] video: enable boot splash on i.MX8MP with LVDS panel Johannes Schneider
2026-06-02 4:09 ` [PATCH 1/6] clk: imx8mp: add 700 MHz rate entry for VIDEO_PLL1 Johannes Schneider
2026-06-02 7:04 ` Ahmad Fatoum
2026-06-02 4:09 ` [PATCH 2/6] pmdomain: imx8mp-blk-ctrl: add media blk-ctrl power domain support Johannes Schneider
2026-06-02 7:34 ` Ahmad Fatoum
2026-06-02 4:09 ` [PATCH 3/6] video: backlight-pwm: make power-supply and enable-gpio optional Johannes Schneider
2026-06-02 7:22 ` Ahmad Fatoum
2026-06-02 4:09 ` [PATCH 4/6] video: add i.MX8MP LCDIF2 V8 framebuffer driver Johannes Schneider
2026-06-02 7:16 ` Ahmad Fatoum
2026-06-04 3:34 ` SCHNEIDER Johannes
2026-06-02 4:09 ` [PATCH 5/6] video: add generic panel-lvds driver Johannes Schneider
2026-06-02 7:12 ` Ahmad Fatoum
2026-06-02 4:09 ` [PATCH 6/6] video: imx-lcdif: drain write-combine buffer before LCDIF DMA reads pixels Johannes Schneider
2026-06-02 8:12 ` Lucas Stach
2026-06-02 9:37 ` Ahmad Fatoum
2026-06-02 12:12 ` Lucas Stach
2026-06-02 15:17 ` Michael Grzeschik [this message]
2026-06-02 17:10 ` Michael Grzeschik
2026-06-04 3:42 ` SCHNEIDER Johannes
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=ah70FFDnP_O2RYr-@pengutronix.de \
--to=mgr@kernel.org \
--cc=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
--cc=johannes.schneider@leica-geosystems.com \
--cc=l.stach@pengutronix.de \
--cc=thomas.haemmerle@leica-geosystems.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.