From: Max Pedraza <maximpedraza@gmail.com>
To: Helge Deller <deller@gmx.de>,
Thomas Zimmermann <tzimmermann@suse.de>,
Simona Vetter <simona@ffwll.ch>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Maxime Ripard <mripard@kernel.org>
Cc: linux-fbdev@vger.kernel.org, devicetree@vger.kernel.org,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
Max Pedraza <maximpedraza@gmail.com>
Subject: [PATCH v3 1/7] fbdev: describe where the boot logo goes in one place
Date: Wed, 23 Sep 2026 22:10:29 +0200 [thread overview]
Message-ID: <20260923201035.51007-2-maximpedraza@gmail.com> (raw)
In-Reply-To: <20260923201035.51007-1-maximpedraza@gmail.com>
fb_prepare_logo() works out how many rows to keep clear for the logo and
fb_show_logo_line() works out where to draw it, and both of them open code
the same decision: centred if fb_center_logo, top left otherwise. The two
calculations have to agree, because fbcon erases whatever falls outside the
rows that were reserved, and nothing makes them.
Give the position a small structure of its own, with -1 on an axis meaning
centre on that axis, and have both callers ask for it. fb_center_logo
becomes {-1, -1} rather than a second path, and the arithmetic lives in one
function that both use, so they cannot end up disagreeing.
The structure and logo_place_axis() go in linux_logo.h rather than in the
frame buffer code, since where a logo goes is a property of the logo, not
of the one thing that draws it today.
logo_place_axis() also clamps, which the open coded version did not: the
result is now always a position at which the logo lies entirely on screen.
That is not reachable today, since the only positions are the two the
console offers, but it stops being something the next caller has to
remember.
No functional change intended.
Signed-off-by: Max Pedraza <maximpedraza@gmail.com>
---
drivers/video/fbdev/core/fb_logo.c | 58 +++++++++++++++++++-----------
include/linux/linux_logo.h | 29 +++++++++++++++
2 files changed, 67 insertions(+), 20 deletions(-)
diff --git a/drivers/video/fbdev/core/fb_logo.c b/drivers/video/fbdev/core/fb_logo.c
index 0bab8352b6..5ec9f9554f 100644
--- a/drivers/video/fbdev/core/fb_logo.c
+++ b/drivers/video/fbdev/core/fb_logo.c
@@ -8,6 +8,17 @@
bool fb_center_logo __read_mostly;
int fb_logo_count __read_mostly = -1;
+/*
+ * The placement in effect, as asked for on the console command line.
+ */
+static const struct logo_placement *fb_logo_placement(void)
+{
+ static const struct logo_placement centred = { .x = -1, .y = -1 };
+ static const struct logo_placement top_left = { };
+
+ return fb_center_logo ? ¢red : &top_left;
+}
+
static inline unsigned int safe_shift(unsigned int d, int n)
{
return n < 0 ? d >> -n : d << n;
@@ -281,7 +292,11 @@ static int fb_show_logo_line(struct fb_info *info, int rotate,
{
u32 *palette = NULL, *saved_pseudo_palette = NULL;
unsigned char *logo_new = NULL, *logo_rotate = NULL;
+ const struct logo_placement *p;
+ unsigned int xres = info->var.xres;
+ unsigned int yres = info->var.yres;
struct fb_image image;
+ unsigned int block;
/* Return if the frame buffer is not mapped or suspended */
if (logo == NULL || info->state != FBINFO_STATE_RUNNING ||
@@ -322,26 +337,22 @@ static int fb_show_logo_line(struct fb_info *info, int rotate,
fb_set_logo(info, logo, logo_new, fb_logo.depth);
}
- if (fb_center_logo) {
- int xres = info->var.xres;
- int yres = info->var.yres;
+ image.width = logo->width;
+ image.height = logo->height;
- if (rotate == FB_ROTATE_CW || rotate == FB_ROTATE_CCW) {
- xres = info->var.yres;
- yres = info->var.xres;
- }
+ if (rotate == FB_ROTATE_CW || rotate == FB_ROTATE_CCW)
+ swap(xres, yres);
- while (n && (n * (logo->width + 8) - 8 > xres))
- --n;
- image.dx = (xres - (n * (logo->width + 8) - 8)) / 2;
- image.dy = y ?: (yres - logo->height) / 2;
- } else {
- image.dx = 0;
- image.dy = y;
- }
+ while (n && (n * (logo->width + 8) - 8 > xres))
+ --n;
- image.width = logo->width;
- image.height = logo->height;
+ /* The copies are drawn in a row, so they are centred as one block */
+ block = n ? n * (logo->width + 8) - 8 : logo->width;
+
+ p = fb_logo_placement();
+ image.dx = logo_place_axis(p->x, xres, block);
+ /* A stacked logo goes where the caller put it */
+ image.dy = y ? y : logo_place_axis(p->y, yres, image.height);
if (rotate) {
logo_rotate = kmalloc_array(logo->width, logo->height,
@@ -418,6 +429,7 @@ static int fb_show_extra_logos(struct fb_info *info, int y, int rotate)
int fb_prepare_logo(struct fb_info *info, int rotate)
{
int depth = fb_get_color_depth(&info->var, &info->fix);
+ const struct logo_placement *p;
unsigned int yres;
int height;
@@ -480,9 +492,15 @@ int fb_prepare_logo(struct fb_info *info, int rotate)
}
}
- height = fb_logo.logo->height;
- if (fb_center_logo)
- height += (yres - fb_logo.logo->height) / 2;
+ /*
+ * fbcon only leaves the first @height rows of the screen alone, so a
+ * logo placed further down would be drawn and then immediately
+ * cleared. Ask the same placement fb_show_logo_line() will use, so
+ * that the two cannot disagree.
+ */
+ p = fb_logo_placement();
+ height = logo_place_axis(p->y, yres, fb_logo.logo->height) +
+ fb_logo.logo->height;
#ifdef CONFIG_FB_LOGO_EXTRA
height = fb_prepare_extra_logos(info, height, yres);
#endif
diff --git a/include/linux/linux_logo.h b/include/linux/linux_logo.h
index 1e727a2cb4..b3b15d3800 100644
--- a/include/linux/linux_logo.h
+++ b/include/linux/linux_logo.h
@@ -13,6 +13,8 @@
*/
#include <linux/init.h>
+#include <linux/minmax.h>
+#include <linux/types.h>
#define LINUX_LOGO_MONO 1 /* monochrome black/white */
@@ -36,6 +38,33 @@ extern const struct linux_logo logo_linux_clut224;
extern const struct linux_logo logo_spe_clut224;
extern const struct linux_logo *fb_find_logo(int depth);
+
+/*
+ * Where a boot logo goes. A coordinate of -1 centres the logo on that axis.
+ * Whatever draws the logo describes its placement this way and computes it
+ * with logo_place_axis(), so that no two places can end up disagreeing about
+ * where the logo is.
+ */
+struct logo_placement {
+ s32 x, y;
+};
+
+/*
+ * Place a logo along one axis. @pos is the coordinate asked for, or -1 to
+ * centre on that axis. The result is clamped so that the logo always lies
+ * entirely within the screen: the drawing code does not clip, so asking for
+ * more than that would otherwise scribble past the end of the frame buffer.
+ */
+static inline int logo_place_axis(s32 pos, unsigned int span, unsigned int size)
+{
+ int last = (int)span - (int)size;
+
+ if (size > span)
+ return 0;
+
+ return pos == -1 ? last / 2 : clamp(pos, 0, last);
+}
+
#ifdef CONFIG_FB_LOGO_EXTRA
extern void fb_append_extra_logo(const struct linux_logo *logo,
unsigned int n);
--
2.39.5
next prev parent reply other threads:[~2026-09-23 20:11 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-23 20:10 [PATCH v3 0/7] Boot logo supplied by the device tree Max Pedraza
2026-09-23 20:10 ` Max Pedraza [this message]
2026-09-24 12:05 ` [PATCH v3 1/7] fbdev: describe where the boot logo goes in one place Thomas Zimmermann
2026-09-23 20:10 ` [PATCH v3 2/7] dt-bindings: display: add a device tree supplied boot logo Max Pedraza
2026-09-24 11:49 ` Rob Herring (Arm)
2026-09-23 20:10 ` [PATCH v3 3/7] video: logo: allow the boot logo to come from the device tree Max Pedraza
2026-09-23 20:10 ` [PATCH v3 4/7] fbdev: honour the device tree boot logo placement properties Max Pedraza
2026-09-23 20:10 ` [PATCH v3 5/7] dt-bindings: display: allow the boot logo in a reserved memory region Max Pedraza
2026-09-23 20:10 ` [PATCH v3 6/7] video: logo: allow the boot logo to come from " Max Pedraza
2026-09-23 20:10 ` [PATCH v3 7/7] video: logo: add ppmtodtlogo host tool Max Pedraza
2026-09-24 12:21 ` [PATCH v3 0/7] Boot logo supplied by the device tree Thomas Zimmermann
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=20260923201035.51007-2-maximpedraza@gmail.com \
--to=maximpedraza@gmail.com \
--cc=conor+dt@kernel.org \
--cc=deller@gmx.de \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=krzk+dt@kernel.org \
--cc=linux-fbdev@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mripard@kernel.org \
--cc=robh@kernel.org \
--cc=simona@ffwll.ch \
--cc=tzimmermann@suse.de \
/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®