diff options
author | Tom Rini <trini@konsulko.com> | 2022-03-28 12:36:49 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-03-28 12:36:49 -0400 |
commit | 34d2b7f20369d62c0f091d6572a8c0ea4655cf14 (patch) | |
tree | 0591ee99c118e0e196730b6ec6582986200e6313 /drivers/video | |
parent | 7f0826c169ff14d62e92d02f85d33d0030d45c12 (diff) | |
parent | e893e8ea6a5d3af312747d00f93587559193a426 (diff) | |
download | u-boot-34d2b7f20369d62c0f091d6572a8c0ea4655cf14.tar.gz |
Merge tag 'v2022.04-rc5' into next
Prepare v2022.04-rc5
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/stm32/stm32_ltdc.c | 11 | ||||
-rw-r--r-- | drivers/video/video-uclass.c | 7 | ||||
-rw-r--r-- | drivers/video/video_bmp.c | 70 |
3 files changed, 68 insertions, 20 deletions
diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c index 87e5fd54d9..e741e74739 100644 --- a/drivers/video/stm32/stm32_ltdc.c +++ b/drivers/video/stm32/stm32_ltdc.c @@ -338,6 +338,7 @@ static int stm32_ltdc_probe(struct udevice *dev) struct display_timing timings; struct clk pclk; struct reset_ctl rst; + ulong rate; int ret; priv->regs = (void *)dev_read_addr(dev); @@ -375,13 +376,13 @@ static int stm32_ltdc_probe(struct udevice *dev) } } - ret = clk_set_rate(&pclk, timings.pixelclock.typ); - if (ret) - dev_warn(dev, "fail to set pixel clock %d hz\n", - timings.pixelclock.typ); + rate = clk_set_rate(&pclk, timings.pixelclock.typ); + if (IS_ERR_VALUE(rate)) + dev_warn(dev, "fail to set pixel clock %d hz, ret=%ld\n", + timings.pixelclock.typ, rate); dev_dbg(dev, "Set pixel clock req %d hz get %ld hz\n", - timings.pixelclock.typ, clk_get_rate(&pclk)); + timings.pixelclock.typ, rate); ret = reset_get_by_index(dev, 0, &rst); if (ret) { diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index 5215114b2d..9ae032e9c2 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 c8c3fd3549..4d2d961696 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); } |