mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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)



  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®