Re: [PATCH v2 0/6] Boot logo supplied by the device tree

Màxim Pedraza Padilla <[email protected]> Thu, 6 Aug 2026 03:29:35 +0200
Newsgroups gmane.linux.drivers.devicetree,gmane.comp.video.dri.devel,gmane.linux.kernel
Message-ID <CAEUXW=HQA7Hwo7m1s5=6mNsbLg3doc4rgg+_+6tTPD2sUxTQdA@mail.gmail.com>
El mié, 5 ago 2026 a las 16:09, Rob Herring (<[email protected]>) escribió:
> Why is this linux specific? Don't people want to do a splash screen in
> u-boot or other firmware?

You are right, and I had not questioned the name. Looking at chosen.yaml,
the split is clear: the "linux," properties are kernel-internal structures
(initrd, kexec handover, the UEFI memory map), while anything a second
implementation could reasonably consume has no prefix at all -- bootargs,
bootsource, stdout-path, kaslr-seed. A boot logo is squarely in the second
group, and simple-framebuffer, which this sits next to, carries no vendor
prefix either.

There is a second Linux-ism in there that your question made me notice:
the 224 in the format. That is 256 minus the 32 palette entries fbcon
reserves for the console, which means nothing outside Linux. The 32 entry
offset itself is already applied by the kernel rather than by the binding,
so it is only the limit that leaks.

Rather than guess at the shape you would want, I would rather ask, since
both the name and the format follow from your answer.

On the name: dropping the prefix would give something like
"boot-logo-clut224", or "boot-logo" with the format named by a property.
Is a bare, unprefixed compatible acceptable here, the way
simple-framebuffer is, or would you rather see this described some other
way entirely?

On the format, two options that I can see:

  a) Keep a palette, but allow the full 256 entries, so that the limit
     Linux applies is a kernel limitation rather than part of the binding.

  b) Reuse the simple-framebuffer vocabulary, format = "r5g6b5" and so on,
     with raw pixels.

I lean towards (a), because the palette is what makes carrying the image
in the device tree viable at all: our own 800x480 logo is 17 KiB paletted
and 768 KiB raw. But (b) reuses an existing vocabulary instead of adding
one, and if you prefer it the reserved memory form still covers our case,
so the in-tree image could go entirely.

I will follow whichever you think is right; I would just rather not
respin the binding twice.

> What does /options/oem-logo look like? Why can't that be used?

Two reasons, and the second is the real one.

It is fixed at 64x64 monochrome (IEEE 1275-1994), stored in NVRAM. As a
precedent for "firmware may carry a logo" it is exactly right, which is
why the binding cites it, but it cannot express a product logo on a
modern panel.

More importantly, /options is the wrong node for something the kernel
reads. Its own schema in dt-schema says it is "for passing data into and
between firmware components" and that "it is ignored by operating
systems", while /chosen is firmware to OS. So the oem-logo precedent
argues for the idea and /chosen for the location, which is where Geert
pointed the node in v2.

> If you are going to put it in memory, why not just draw it into the
> simple-framebuffer?

I did not know about simplefb, and that is worth saying plainly: this
started as a patch against 4.19 for a product, simpledrm did not exist
then (5.14), and I never went looking for what the alternative would be
today. So thank you for the question.

I spent today testing it on the board rather than arguing about it. The
result is that it does not work here, and I could not make it work:

  - Added a simple-framebuffer node under /chosen pointing at U-Boot's
    framebuffer, with the region declared in reserved-memory. simpledrm
    binds cleanly at 0.62s and registers fb0. Nothing is visible.

  - The panel is dark for that entire window. The backlight is a
    pwm-backlight owned by the panel, and it is drm_panel_enable() that
    calls backlight_enable() (drm_panel.c), which only happens at the
    native driver's modeset, around 2.2s. So for as long as
    simple-framebuffer is the only driver, there is no light.

  - Forced the backlight on from probe with a local hack to pwm_bl.c, so
    the panel is lit from about 1s. The image is still not there.

  - Disabled the LCDC target module in the device tree entirely and booted
    with clk_ignore_unused, so that nothing in Linux touches the
    controller and it keeps whatever U-Boot left. Still nothing.

  - Repeated all of it with simplefb instead of simpledrm. Same result.

  - Read back the framebuffer memory through fb0 after boot: all zeros.

So the pixels are gone by the time Linux can show them, and I have not
found what clears them. I can say what it is not: not the choice of
driver, not the modeset, and not the backlight. Somewhere between U-Boot
jumping to the kernel and simpledrm probing, this platform stops
displaying that memory.

One smaller thing I noticed on the way: tilcdc came up as card1 and
simpledrm stayed on card0, with no conflicting-framebuffer removal
between them. Two DRM devices with the real one second is not a state I
would want to ship either.

There is also a case against this that does not depend on our hardware at
all. U-Boot's Falcon mode boots the kernel straight from SPL, skipping
U-Boot proper, and display initialisation normally lives in U-Boot proper
rather than in SPL. On a Falcon boot there is therefore no firmware splash
to hand over and nothing for a simple-framebuffer node to point at. That is
not an obscure corner either: Falcon mode exists to shorten boot time,
which is the same reason one cares about how early the logo appears in the
first place. A logo the kernel can draw itself works the same way in both
cases.

I am not claiming the experimental result above generalises. It may well be
specific to AM335x, or to how our U-Boot hands over. But on the hardware
this series exists for, a firmware-drawn splash does not survive into the
kernel, and the logo has to be drawn again once the native driver owns the
display. That is the gap the series fills, and the reserved memory region
is what gives the kernel the pixels to do it with.

Max