From: Thomas Zimmermann <tzimmermann@suse.de>
To: "Màxim Pedraza Padilla" <maximpedraza@gmail.com>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Ard Biesheuvel" <ardb@kernel.org>,
"Jonathan Corbet" <corbet@lwn.net>
Cc: Francesco Valla <francesco@valla.it>,
Jani Nikula <jani.nikula@linux.intel.com>,
Mario Limonciello <mario.limonciello@amd.com>,
Javier Martinez Canillas <javierm@redhat.com>,
Jocelyn Falempe <jfalempe@redhat.com>,
Sam Ravnborg <sam@ravnborg.org>,
Ilias Apalodimas <ilias.apalodimas@linaro.org>,
Shuah Khan <skhan@linuxfoundation.org>,
Randy Dunlap <rdunlap@infradead.org>,
dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
linux-efi@vger.kernel.org, linux-doc@vger.kernel.org,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v5 07/13] drm/client: splash: add a device tree image source
Date: Tue, 20 Oct 2026 13:04:22 +0200 [thread overview]
Message-ID: <9834b569-935c-484b-befb-b913acead9c1@suse.de> (raw)
In-Reply-To: <20261013093243.505776-8-maximpedraza@gmail.com>
Hi
Am 13.10.26 um 11:32 schrieb Màxim Pedraza Padilla:
> Embedded products often share one kernel image and one board support
> package across several models that differ in branding. The splash
> client can show the firmware's BGRT image or a BMP loaded as firmware,
> but a device tree system has no BGRT, and a BMP loaded as firmware is
> either built into the kernel, which means one kernel per logo, or read
> from a filesystem that is not there yet when the display comes up. With
> U-Boot's Falcon mode the SPL starts the kernel directly, and the device
> tree is the only thing that reaches it.
>
> Add a source that takes the image from a "boot-logo" node under /chosen.
> The BMP either sits in the node itself, in an "image" property that dtc
> fills in with /incbin/, or in a reserved memory region the bootloader
> loaded it into, named by "memory-region". Exactly one of the two must be
> present; a node with both or neither is ignored with a warning.
>
> The image in the node is used where it is: the device tree stays in
> memory, so there is nothing to copy or release. The region is mapped
> like the BGRT image, and the BMP header is checked against its size.
>
> A node is only there if someone put it there for that board, so the
> device tree goes first, then the BGRT, then the BMP loaded as firmware.
> The boolean that chose between the latter two becomes an enum naming
> the one source in use.
>
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Màxim Pedraza Padilla <maximpedraza@gmail.com>
> ---
> drivers/gpu/drm/clients/Kconfig | 15 +++
> drivers/gpu/drm/clients/drm_splash.c | 166 ++++++++++++++++++++++++---
> 2 files changed, 165 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/clients/Kconfig b/drivers/gpu/drm/clients/Kconfig
> index cbe271c3a23f..aef3781cc110 100644
> --- a/drivers/gpu/drm/clients/Kconfig
> +++ b/drivers/gpu/drm/clients/Kconfig
> @@ -108,6 +108,21 @@ config DRM_CLIENT_SPLASH_BACKGROUND_COLOR
> The color can be overridden through the drm_client_lib.splash_color
> kernel command line parameter.
>
> +config DRM_CLIENT_SPLASH_SRC_DT
> + bool "Device tree as splash source"
> + depends on DRM_CLIENT_SPLASH
> + depends on OF
> + select DRM_CLIENT_SPLASH_BMP_SUPPORT
> + help
> + Use a BMP image described by a "boot-logo" node under /chosen in
> + the device tree, either carried in the node itself or placed by the
> + bootloader in a reserved memory region. This lets one kernel image
> + show a different logo on each board or product, chosen by the
> + device tree it boots with.
> +
> + When present, the device tree image is preferred over the other
> + sources.
> +
> config DRM_CLIENT_SPLASH_SRC_BGRT
> bool "EFI BGRT as splash source"
> depends on DRM_CLIENT_SPLASH
> diff --git a/drivers/gpu/drm/clients/drm_splash.c b/drivers/gpu/drm/clients/drm_splash.c
> index a7d627954158..50842922a7f8 100644
> --- a/drivers/gpu/drm/clients/drm_splash.c
> +++ b/drivers/gpu/drm/clients/drm_splash.c
> @@ -9,9 +9,12 @@
> #include <linux/efi-bgrt.h>
> #include <linux/firmware.h>
> #include <linux/init.h>
> +#include <linux/io.h>
> #include <linux/iosys-map.h>
> #include <linux/kthread.h>
> #include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_reserved_mem.h>
> #include <linux/overflow.h>
> #include <linux/types.h>
> #include <linux/unaligned.h>
> @@ -71,6 +74,14 @@ struct bmp_dib_header {
> __le32 colors_important;
> } __packed;
>
> +/* Where the image comes from, in order of preference */
> +enum drm_splash_source {
> + DRM_SPLASH_SRC_NONE,
> + DRM_SPLASH_SRC_DT,
> + DRM_SPLASH_SRC_BGRT,
> + DRM_SPLASH_SRC_BMP,
> +};
The logic behind this enum deserves a separate patch, I think.
Best regards
Thomas
> +
> struct drm_splash_scanout {
> int id;
> /* Modesets scanning this buffer out, by position in the list */
> @@ -110,7 +121,7 @@ struct drm_splash {
> bool render_done;
> void *map_data;
>
> - bool use_bgrt;
> + enum drm_splash_source src;
> };
>
> static struct drm_splash *client_to_drm_splash(struct drm_client_dev *client)
> @@ -212,6 +223,114 @@ static int drm_splash_fw_request_bmp(struct drm_splash *splash)
> }
> #endif // CONFIG_DRM_CLIENT_SPLASH_SRC_BMP
>
> +#if IS_ENABLED(CONFIG_DRM_CLIENT_SPLASH_SRC_DT)
> +#define DRM_SPLASH_DT_COMPATIBLE "boot-logo"
> +
> +/*
> + * The boot logo node, if the device tree has a usable one. Only a child of
> + * /chosen is considered, not anything compatible anywhere in the tree: the
> + * image is configuration handed over by the firmware, not a device.
> + */
> +static struct device_node *drm_splash_dt_node(struct drm_splash *splash)
> +{
> + struct drm_client_dev *client = &splash->client;
> + struct device_node *np;
> + bool image, region;
> +
> + np = of_get_compatible_child(of_chosen, DRM_SPLASH_DT_COMPATIBLE);
> + if (!np)
> + return NULL;
> +
> + if (!of_device_is_available(np))
> + goto out_put;
> +
> + image = of_property_present(np, "image");
> + region = of_property_present(np, "memory-region");
> + if (image == region) {
> + drm_warn(client->dev,
> + "splash: %pOF needs exactly one of image or memory-region",
> + np);
> + goto out_put;
> + }
> +
> + return np;
> +
> +out_put:
> + of_node_put(np);
> + return NULL;
> +}
> +
> +static bool drm_splash_dt_available(struct drm_splash *splash)
> +{
> + struct device_node *np = drm_splash_dt_node(splash);
> +
> + of_node_put(np);
> +
> + return np;
> +}
> +
> +static int drm_splash_dt_load(struct drm_splash *splash, const u8 **data,
> + size_t *size)
> +{
> + struct drm_client_dev *client = &splash->client;
> + struct device_node *np;
> + struct resource res;
> + const void *prop;
> + int len, ret = 0;
> +
> + np = drm_splash_dt_node(splash);
> + if (!np)
> + return -ENOENT;
> +
> + /*
> + * An image in the node is used in place: the device tree stays in
> + * memory for as long as the system runs, so there is nothing to copy
> + * and nothing to release.
> + */
> + prop = of_get_property(np, "image", &len);
> + if (prop) {
> + *data = prop;
> + *size = len;
> + goto out_put;
> + }
> +
> + /* Otherwise the bootloader loaded it into a reserved region */
> + ret = of_reserved_mem_region_to_resource(np, 0, &res);
> + if (ret) {
> + drm_warn(client->dev, "splash: %pOF: no usable memory-region: %d",
> + np, ret);
> + goto out_put;
> + }
> +
> + splash->map_data = memremap(res.start, resource_size(&res),
> + MEMREMAP_WB);
> + if (!splash->map_data) {
> + drm_warn(client->dev, "splash: failed to map %pR", &res);
> + ret = -ENOMEM;
> + goto out_put;
> + }
> +
> + /* The BMP header, checked against this size, says how much is image */
> + *data = splash->map_data;
> + *size = resource_size(&res);
> +
> +out_put:
> + of_node_put(np);
> + return ret;
> +}
> +#else
> +static bool drm_splash_dt_available(struct drm_splash *splash)
> +{
> + return false;
> +}
> +
> +static int drm_splash_dt_load(struct drm_splash *splash,
> + const u8 **data, size_t *size)
> +{
> + return -EOPNOTSUPP;
> +}
> +#endif // CONFIG_DRM_CLIENT_SPLASH_SRC_DT
> +
> static bool drm_splash_bgrt_available(struct drm_splash *splash)
> {
> struct drm_client_dev *client = &splash->client;
> @@ -489,7 +608,7 @@ static int drm_splash_bmp_to_scanout(struct drm_splash *splash,
> return -EINVAL;
> }
>
> - if (splash->use_bgrt) {
> + if (splash->src == DRM_SPLASH_SRC_BGRT) {
> x_pad = efi_bgrt_image_offset_x();
> y_pad = efi_bgrt_image_offset_y();
>
> @@ -582,19 +701,34 @@ static int drm_splash_bmp_to_scanout(struct drm_splash *splash,
> static int drm_splash_image_load(struct drm_splash *splash, const u8 **img_data,
> size_t *img_data_len)
> {
> - int ret = 0;
> -
> - if (splash->use_bgrt) {
> - ret = drm_splash_bgrt_load(splash, img_data, img_data_len);
> - if (ret)
> - splash->use_bgrt = false;
> + switch (splash->src) {
> + case DRM_SPLASH_SRC_DT:
> + return drm_splash_dt_load(splash, img_data, img_data_len);
> + case DRM_SPLASH_SRC_BGRT:
> + return drm_splash_bgrt_load(splash, img_data, img_data_len);
> + case DRM_SPLASH_SRC_BMP:
> + return drm_splash_fw_load(splash, img_data, img_data_len);
> + default:
> + return -ENOENT;
> }
> +}
>
> - /* BGRT failed to load */
> - if (!splash->use_bgrt)
> - ret = drm_splash_fw_load(splash, img_data, img_data_len);
> -
> - return ret;
> +/*
> + * Pick the one source the image will come from. A device tree node is only
> + * there if someone put it there for this board, so it goes first; the BGRT
> + * is whatever the firmware shows, and the BMP loaded as firmware is the
> + * fallback. With none of them, only the background colour is drawn.
> + */
> +static enum drm_splash_source drm_splash_pick_source(struct drm_splash *splash)
> +{
> + if (drm_splash_dt_available(splash))
> + return DRM_SPLASH_SRC_DT;
> + if (drm_splash_bgrt_available(splash))
> + return DRM_SPLASH_SRC_BGRT;
> + if (IS_ENABLED(CONFIG_DRM_CLIENT_SPLASH_SRC_BMP))
> + return DRM_SPLASH_SRC_BMP;
> +
> + return DRM_SPLASH_SRC_NONE;
> }
>
> static void drm_splash_image_cleanup(struct drm_splash *splash)
> @@ -909,10 +1043,10 @@ static int drm_splash_client_hotplug(struct drm_client_dev *client)
> get_task_struct(thread);
> splash->thread = thread;
>
> - splash->use_bgrt = drm_splash_bgrt_available(splash);
> + splash->src = drm_splash_pick_source(splash);
>
> - /* If no other image has been loaded, try to load a BMP as firmware */
> - if (IS_ENABLED(CONFIG_DRM_CLIENT_SPLASH_SRC_BMP) && !splash->use_bgrt) {
> + /* The BMP loaded as firmware is the only source that arrives later */
> + if (splash->src == DRM_SPLASH_SRC_BMP) {
> WRITE_ONCE(splash->fw_pending, true);
> ret = drm_splash_fw_request_bmp(splash);
> splash->fw_requested = !ret;
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri, (HRB 36809, AG Nürnberg)
next prev parent reply other threads:[~2026-10-20 11:04 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-13 9:32 [PATCH v5 00/13] Add splash DRM client Màxim Pedraza Padilla
2026-10-13 9:32 ` [PATCH v5 01/13] drm/clients: Kconfig: indent DRM_CLIENT_DEFAULT with tabs Màxim Pedraza Padilla
2026-10-20 9:11 ` Thomas Zimmermann
2026-10-13 9:32 ` [PATCH v5 02/13] efi: bgrt: add accessors for the boot graphics Màxim Pedraza Padilla
2026-10-20 9:13 ` Thomas Zimmermann
2026-10-13 9:32 ` [PATCH v5 03/13] drm: client: add splash client Màxim Pedraza Padilla
2026-10-20 10:28 ` Thomas Zimmermann
2026-10-13 9:32 ` [PATCH v5 04/13] MAINTAINERS: add entry for DRM " Màxim Pedraza Padilla
2026-10-13 9:32 ` [PATCH v5 05/13] drm: docs: remove bootsplash from TODO Màxim Pedraza Padilla
2026-10-13 9:32 ` [PATCH v5 06/13] dt-bindings: display: add a boot logo node under /chosen Màxim Pedraza Padilla
2026-10-13 9:32 ` [PATCH v5 07/13] drm/client: splash: add a device tree image source Màxim Pedraza Padilla
2026-10-20 11:04 ` Thomas Zimmermann [this message]
2026-10-13 9:32 ` [PATCH v5 08/13] drm/client: splash: place the device tree image where it asks Màxim Pedraza Padilla
2026-10-13 9:32 ` [PATCH v5 09/13] drm/client: splash: turn the device tree image as " Màxim Pedraza Padilla
2026-10-13 9:32 ` [PATCH v5 10/13] drm/client: splash: take the background colour from the image source Màxim Pedraza Padilla
2026-10-13 9:32 ` [PATCH v5 11/13] drm/client: splash: turn the BGRT image on panels mounted turned Màxim Pedraza Padilla
2026-10-13 9:32 ` [PATCH v5 12/13] drm/client: splash: prefer what the command line asks for Màxim Pedraza Padilla
2026-10-13 9:32 ` [PATCH v5 13/13] drm/client: splash: document the image sources and parameters Màxim Pedraza Padilla
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=9834b569-935c-484b-befb-b913acead9c1@suse.de \
--to=tzimmermann@suse.de \
--cc=airlied@gmail.com \
--cc=ardb@kernel.org \
--cc=conor+dt@kernel.org \
--cc=corbet@lwn.net \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=francesco@valla.it \
--cc=ilias.apalodimas@linaro.org \
--cc=jani.nikula@linux.intel.com \
--cc=javierm@redhat.com \
--cc=jfalempe@redhat.com \
--cc=krzk+dt@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-embedded@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mario.limonciello@amd.com \
--cc=maximpedraza@gmail.com \
--cc=mripard@kernel.org \
--cc=rdunlap@infradead.org \
--cc=robh@kernel.org \
--cc=sam@ravnborg.org \
--cc=simona@ffwll.ch \
--cc=skhan@linuxfoundation.org \
/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
all inboxes | Powered by JetHome®