aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini2022-03-14 18:39:26 -0400
committerTom Rini2022-03-14 18:39:26 -0400
commitf43e892f51d7ecca8c8bd1b0850120db92f7caed (patch)
treee01a92bf6789c0e42012f85c3e3bb384cd3d3afa /drivers
parentc149bf41404e34014e37de32fac332892b11bd4a (diff)
parentd6213e206c441a3b2b83c0588954c851c3610d97 (diff)
Merge tag 'video-20220314' of https://source.denx.de/u-boot/custodians/u-boot-video
- fix display of the u-boot logo on Apple devices - convert Nokia RX-51 to CONFIG_DM_VIDEO
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/video-uclass.c7
-rw-r--r--drivers/video/video_bmp.c70
2 files changed, 62 insertions, 15 deletions
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 7d499bcec51..88797d4a21c 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -33,7 +33,8 @@
* information represents the requires size and alignment of the frame buffer
* for the device. The values can be an over-estimate but cannot be too
* small. The actual values will be suppled (in the same manner) by the bind()
- * method after relocation.
+ * method after relocation. Additionally driver can allocate frame buffer
+ * itself by setting plat->base.
*
* This information is then picked up by video_reserve() which works out how
* much memory is needed for all devices. This is allocated between
@@ -78,6 +79,10 @@ static ulong alloc_fb(struct udevice *dev, ulong *addrp)
if (!plat->size)
return 0;
+ /* Allow drivers to allocate the frame buffer themselves */
+ if (plat->base)
+ return 0;
+
align = plat->align ? plat->align : 1 << 20;
base = *addrp - plat->size;
base &= ~(align - 1);
diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
index c8c3fd3549d..4d2d961696a 100644
--- a/drivers/video/video_bmp.c
+++ b/drivers/video/video_bmp.c
@@ -31,6 +31,18 @@ static uint get_bmp_col_16bpp(struct bmp_color_table_entry cte)
}
/**
+ * get_bmp_col_x2r10g10b10() - Convert a colour-table entry into a x2r10g10b10 pixel value
+ *
+ * Return: value to write to the x2r10g10b10 frame buffer for this palette entry
+ */
+static u32 get_bmp_col_x2r10g10b10(struct bmp_color_table_entry *cte)
+{
+ return ((cte->red << 22U) |
+ (cte->green << 12U) |
+ (cte->blue << 2U));
+}
+
+/**
* write_pix8() - Write a pixel from a BMP image into the framebuffer
*
* This handles frame buffers with 8, 16, 24 or 32 bits per pixel
@@ -42,8 +54,8 @@ static uint get_bmp_col_16bpp(struct bmp_color_table_entry cte)
* which is either written directly (bpix == 8) or used to look up the
* palette to get a colour to write
*/
-static void write_pix8(u8 *fb, uint bpix, struct bmp_color_table_entry *palette,
- u8 *bmap)
+static void write_pix8(u8 *fb, uint bpix, enum video_format eformat,
+ struct bmp_color_table_entry *palette, u8 *bmap)
{
if (bpix == 8) {
*fb++ = *bmap;
@@ -57,6 +69,8 @@ static void write_pix8(u8 *fb, uint bpix, struct bmp_color_table_entry *palette,
*fb++ = cte->red;
*fb++ = cte->green;
*fb++ = cte->blue;
+ } else if (eformat == VIDEO_X2R10G10B10) {
+ *(u32 *)fb = get_bmp_col_x2r10g10b10(cte);
} else {
*fb++ = cte->blue;
*fb++ = cte->green;
@@ -66,28 +80,29 @@ static void write_pix8(u8 *fb, uint bpix, struct bmp_color_table_entry *palette,
}
}
-static void draw_unencoded_bitmap(u8 **fbp, uint bpix, uchar *bmap,
+static void draw_unencoded_bitmap(u8 **fbp, uint bpix,
+ enum video_format eformat, uchar *bmap,
struct bmp_color_table_entry *palette,
int cnt)
{
u8 *fb = *fbp;
while (cnt > 0) {
- write_pix8(fb, bpix, palette, bmap++);
+ write_pix8(fb, bpix, eformat, palette, bmap++);
fb += bpix / 8;
cnt--;
}
*fbp = fb;
}
-static void draw_encoded_bitmap(u8 **fbp, uint bpix,
+static void draw_encoded_bitmap(u8 **fbp, uint bpix, enum video_format eformat,
struct bmp_color_table_entry *palette, u8 *bmap,
int cnt)
{
u8 *fb = *fbp;
while (cnt > 0) {
- write_pix8(fb, bpix, palette, bmap);
+ write_pix8(fb, bpix, eformat, palette, bmap);
fb += bpix / 8;
cnt--;
}
@@ -106,6 +121,7 @@ static void video_display_rle8_bitmap(struct udevice *dev,
int x, y;
int decode = 1;
uint bytes_per_pixel = bpix / 8;
+ enum video_format eformat = priv->format;
debug("%s\n", __func__);
bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
@@ -148,7 +164,7 @@ static void video_display_rle8_bitmap(struct udevice *dev,
else
cnt = runlen;
draw_unencoded_bitmap(
- &fb, bpix,
+ &fb, bpix, eformat,
bmap, palette, cnt);
}
x += runlen;
@@ -173,8 +189,9 @@ static void video_display_rle8_bitmap(struct udevice *dev,
cnt = width - x;
else
cnt = runlen;
- draw_encoded_bitmap(&fb, bpix, palette,
- &bmap[1], cnt);
+ draw_encoded_bitmap(&fb, bpix, eformat,
+ palette, &bmap[1],
+ cnt);
}
x += runlen;
}
@@ -224,6 +241,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
unsigned long width, height, byte_width;
unsigned long pwidth = priv->xsize;
unsigned colours, bpix, bmp_bpix;
+ enum video_format eformat;
struct bmp_color_table_entry *palette;
int hdr_size;
int ret;
@@ -245,6 +263,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
colours = 1 << bmp_bpix;
bpix = VNBITS(priv->bpix);
+ eformat = priv->format;
if (bpix != 1 && bpix != 8 && bpix != 16 && bpix != 32) {
printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
@@ -312,7 +331,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
for (i = 0; i < height; ++i) {
WATCHDOG_RESET();
for (j = 0; j < width; j++) {
- write_pix8(fb, bpix, palette, bmap);
+ write_pix8(fb, bpix, eformat, palette, bmap);
bmap++;
fb += bpix / 8;
}
@@ -345,6 +364,16 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
(bmap[0] >> 3);
bmap += 3;
fb += 2;
+ } else if (eformat == VIDEO_X2R10G10B10) {
+ u32 pix;
+
+ pix = *bmap++ << 2U;
+ pix |= *bmap++ << 12U;
+ pix |= *bmap++ << 22U;
+ *fb++ = pix & 0xff;
+ *fb++ = (pix >> 8) & 0xff;
+ *fb++ = (pix >> 16) & 0xff;
+ *fb++ = pix >> 24;
} else {
*fb++ = *bmap++;
*fb++ = *bmap++;
@@ -361,10 +390,23 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
if (IS_ENABLED(CONFIG_BMP_32BPP)) {
for (i = 0; i < height; ++i) {
for (j = 0; j < width; j++) {
- *fb++ = *bmap++;
- *fb++ = *bmap++;
- *fb++ = *bmap++;
- *fb++ = *bmap++;
+ if (eformat == VIDEO_X2R10G10B10) {
+ u32 pix;
+
+ pix = *bmap++ << 2U;
+ pix |= *bmap++ << 12U;
+ pix |= *bmap++ << 22U;
+ pix |= (*bmap++ >> 6) << 30U;
+ *fb++ = pix & 0xff;
+ *fb++ = (pix >> 8) & 0xff;
+ *fb++ = (pix >> 16) & 0xff;
+ *fb++ = pix >> 24;
+ } else {
+ *fb++ = *bmap++;
+ *fb++ = *bmap++;
+ *fb++ = *bmap++;
+ *fb++ = *bmap++;
+ }
}
fb -= priv->line_length + width * (bpix / 8);
}