[U-Boot] [PATCH 3/3] mpc8610: refactor DIU initialization code to use existing bitmap function

The Freescale MPC8610 DIU code has its own bitmap-drawing function, fsl_diu_display_bmp(), which is redundant. Instead, use the existing function video_display_bitmap(). Replacing fsl_diu_display_bmp() with video_display_bitmap() also requires refactoring the DIU initialization code.
Signed-off-by: Timur Tabi timur@freescale.com ---
This patch requires this other patch:
video: cfb_console: add support for 4bpp bitmaps with GDF_32BIT_X888RGB
board/freescale/common/fsl_diu_fb.c | 155 +++++++----------------- board/freescale/common/fsl_diu_fb.h | 7 +- board/freescale/mpc8610hpcd/mpc8610hpcd.c | 16 ++- board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c | 100 ++-------------- include/configs/MPC8610HPCD.h | 6 +- 5 files changed, 76 insertions(+), 208 deletions(-)
diff --git a/board/freescale/common/fsl_diu_fb.c b/board/freescale/common/fsl_diu_fb.c index e740ad8..e0ff466 100644 --- a/board/freescale/common/fsl_diu_fb.c +++ b/board/freescale/common/fsl_diu_fb.c @@ -27,6 +27,9 @@ #include <i2c.h> #include <malloc.h> #include <asm/io.h> +#include <bmp_layout.h> +#include <stdio_dev.h> +#include <video_fb.h>
#include "fsl_diu_fb.h"
@@ -359,10 +362,15 @@ int fsl_diu_init(int xres, fb_initialized = 1;
if (splash_bmp) { - info->logo_height = fsl_diu_display_bmp(splash_bmp, 0, 0, 0); + /* + * If we want a banner on top of the screen, we want to remember + * its size here, so that video_hw_init() can set the right + * display height. + */ + bmp_header_t *bmp = (bmp_header_t *)splash_bmp; + + info->logo_height = le32_to_cpu(bmp->height); info->logo_size = info->logo_height * info->line_length; - debug("logo height %d, logo_size 0x%x\n", - info->logo_height,info->logo_size); }
/* Enable the DIU */ @@ -486,117 +494,44 @@ static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align) return 0; }
-int fsl_diu_display_bmp(unsigned char *bmp, - int xoffset, - int yoffset, - int transpar) +/* + * The Graphic Device + */ +static GraphicDevice ctfb; + +/* Board-specific video initialization */ +void __board_diu_init(void) { - struct fb_info *info = &fsl_fb_info; - unsigned char r, g, b; - unsigned int *fb_t, val; - unsigned char *bitmap; - unsigned int palette[256]; - int width, height, bpp, ncolors, raster, offset, x, y, i, k, cpp; - - if (!bmp) { - printf("Must supply a bitmap address\n"); - return 0; - } +} +int board_diu_init(void) __attribute__((weak, alias("__board_diu_init")));
- raster = bmp[10] + (bmp[11] << 8) + (bmp[12] << 16) + (bmp[13] << 24); - width = (bmp[21] << 24) | (bmp[20] << 16) | (bmp[19] << 8) | bmp[18]; - height = (bmp[25] << 24) | (bmp[24] << 16) | (bmp[23] << 8) | bmp[22]; - bpp = (bmp[29] << 8) | (bmp[28]); - ncolors = bmp[46] + (bmp[47] << 8) + (bmp[48] << 16) + (bmp[49] << 24); - bitmap = bmp + raster; - cpp = info->var.bits_per_pixel / 8; - - debug("bmp = 0x%08x\n", (unsigned int)bmp); - debug("bitmap = 0x%08x\n", (unsigned int)bitmap); - debug("width = %d\n", width); - debug("height = %d\n", height); - debug("bpp = %d\n", bpp); - debug("ncolors = %d\n", ncolors); - - debug("xres = %d\n", info->var.xres); - debug("yres = %d\n", info->var.yres); - debug("Screen_base = 0x%x\n", (unsigned int)info->screen_base); - - if (((width+xoffset) > info->var.xres) || - ((height+yoffset) > info->var.yres)) { - printf("bitmap is out of range, image too large or too much offset\n"); - return 0; - } - if (bpp < 24) { - for (i = 0, offset = 54; i < ncolors; i++, offset += 4) - palette[i] = (bmp[offset+2] << 16) - + (bmp[offset+1] << 8) + bmp[offset]; - } +void *video_hw_init(void) +{ + struct fb_info *info;
- switch (bpp) { - case 1: - for (y = height - 1; y >= 0; y--) { - fb_t = (unsigned int *) ((unsigned int)info->screen_base + (((y+yoffset) * info->var.xres) + xoffset)*cpp); - for (x = 0; x < width; x += 8) { - b = *bitmap++; - for (k = 0; k < 8; k++) { - if (b & 0x80) - *fb_t++ = palette[1]; - else - *fb_t++ = palette[0]; - b = b << 1; - } - } - for (i = (width / 2) % 4; i > 0; i--) - bitmap++; - } - break; - case 4: - for (y = height - 1; y >= 0; y--) { - fb_t = (unsigned int *) ((unsigned int)info->screen_base + (((y+yoffset) * info->var.xres) + xoffset)*cpp); - for (x = 0; x < width; x += 2) { - b = *bitmap++; - r = (b >> 4) & 0x0F; - g = b & 0x0F; - *fb_t++ = palette[r]; - *fb_t++ = palette[g]; - } - for (i = (width / 2) % 4; i > 0; i--) - bitmap++; - } - break; - case 8: - for (y = height - 1; y >= 0; y--) { - fb_t = (unsigned int *) ((unsigned int)info->screen_base + (((y+yoffset) * info->var.xres) + xoffset)*cpp); - for (x = 0; x < width; x++) { - *fb_t++ = palette[ *bitmap++ ]; - } - for (i = (width / 2) % 4; i > 0; i--) - bitmap++; - } - break; - case 24: - for (y = height - 1; y >= 0; y--) { - fb_t = (unsigned int *) ((unsigned int)info->screen_base + (((y+yoffset) * info->var.xres) + xoffset)*cpp); - for (x = 0; x < width; x++) { - b = *bitmap++; - g = *bitmap++; - r = *bitmap++; - val = (r << 16) + (g << 8) + b; - *fb_t++ = val; - } - for (; (x % 4) != 0; x++) /* 4-byte alignment */ - bitmap++; - } - break; - } + board_diu_init();
- return height; -} + /* fill in Graphic device struct */ + ctfb.frameAdrs = (unsigned int)fsl_fb_open(&info); + ctfb.winSizeX = info->xres; + ctfb.winSizeY = info->yres - info->logo_height; + ctfb.plnSizeX = ctfb.winSizeX; + ctfb.plnSizeY = ctfb.winSizeY;
-void fsl_diu_clear_screen(void) -{ - struct fb_info *info = &fsl_fb_info; + ctfb.gdfBytesPP = 4; + ctfb.gdfIndex = GDF_32BIT_X888RGB;
- memset(info->screen_base, 0, info->smem_len); + ctfb.isaBase = 0; + ctfb.pciBase = 0; + ctfb.memSize = info->screen_size - info->logo_size; + + /* Cursor Start Address */ + ctfb.dprBase = 0; + ctfb.vprBase = 0; + ctfb.cprBase = 0; + + sprintf(ctfb.modeIdent, + "%dx%dx%d %ukHz %uHz", info->xres, info->yres, 32, 64, 60); + + return &ctfb; } diff --git a/board/freescale/common/fsl_diu_fb.h b/board/freescale/common/fsl_diu_fb.h index 6deba32..da5fa76 100644 --- a/board/freescale/common/fsl_diu_fb.h +++ b/board/freescale/common/fsl_diu_fb.h @@ -51,6 +51,8 @@ struct fb_info { unsigned int line_length; /* length of a line in bytes */
char *screen_base; + unsigned int xres; + unsigned int yres; unsigned long screen_size; int logo_height; unsigned int logo_size; @@ -62,8 +64,3 @@ extern int fsl_diu_init(int xres, unsigned int pixel_format, int gamma_fix, unsigned char *splash_bmp); -extern void fsl_diu_clear_screen(void); -extern int fsl_diu_display_bmp(unsigned char *bmp, - int xoffset, - int yoffset, - int transpar); diff --git a/board/freescale/mpc8610hpcd/mpc8610hpcd.c b/board/freescale/mpc8610hpcd/mpc8610hpcd.c index 6578f58..a172fd7 100644 --- a/board/freescale/mpc8610hpcd/mpc8610hpcd.c +++ b/board/freescale/mpc8610hpcd/mpc8610hpcd.c @@ -33,11 +33,13 @@ #include <fdt_support.h> #include <spd_sdram.h> #include <netdev.h> +#include <bmp_layout.h>
void sdram_init(void); phys_size_t fixed_sdram(void); -void mpc8610hpcd_diu_init(void);
+extern unsigned int FSL_Logo_BMP[]; +int video_display_bitmap(unsigned long, int, int);
/* called before any console output */ int board_early_init_f(void) @@ -54,6 +56,9 @@ int misc_init_r(void) { u8 tmp_val, version; u8 *pixis_base = (u8 *)PIXIS_BASE; +#ifdef CONFIG_VIDEO + bmp_header_t *bmp = (bmp_header_t *)FSL_Logo_BMP; +#endif
/*Do not use 8259PIC*/ tmp_val = in_8(pixis_base + PIXIS_BRDCFG0); @@ -84,8 +89,13 @@ int misc_init_r(void) i2c_read(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val)); debug("DVI Encoder Read: 0x%02lx\n",tmp_val);
-#ifdef CONFIG_FSL_DIU_FB - mpc8610hpcd_diu_init(); +#ifdef CONFIG_VIDEO + /* + * U-Boot has been told that the display is shorter than it really is, + * so we put the banner at a negative Y-axis. This draws it on the + * top of the screen, but it won't scroll off. + */ + video_display_bitmap((unsigned long)bmp, 0, -le32_to_cpu(bmp->height)); #endif
return 0; diff --git a/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c b/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c index 781a7c8..747f5c7 100644 --- a/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c +++ b/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c @@ -32,14 +32,10 @@ #include "../common/fsl_diu_fb.h"
#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) -#include <stdio_dev.h> -#include <video_fb.h> #endif
extern unsigned int FSL_Logo_BMP[];
-static int xres, yres; - void diu_set_pixel_clock(unsigned int pixclock) { volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; @@ -61,7 +57,7 @@ void diu_set_pixel_clock(unsigned int pixclock) debug("DIU: Modified value of CLKDVDR = 0x%08x\n", *guts_clkdvdr); }
-void mpc8610hpcd_diu_init(void) +void board_diu_init(void) { char *monitor_port; int gamma_fix; @@ -69,14 +65,17 @@ void mpc8610hpcd_diu_init(void) unsigned char tmp_val; unsigned char pixis_arch; u8 *pixis_base = (u8 *)PIXIS_BASE; + struct fb_info *info; + + fsl_fb_open(&info);
tmp_val = in_8(pixis_base + PIXIS_BRDCFG0); pixis_arch = in_8(pixis_base + PIXIS_VER);
monitor_port = getenv("monitor"); if (!strncmp(monitor_port, "0", 1)) { /* 0 - DVI */ - xres = 1280; - yres = 1024; + info->xres = 1280; + info->yres = 1024; if (pixis_arch == 0x01) pixel_format = 0x88882317; else @@ -85,102 +84,29 @@ void mpc8610hpcd_diu_init(void) out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x08);
} else if (!strncmp(monitor_port, "1", 1)) { /* 1 - Single link LVDS */ - xres = 1024; - yres = 768; + info->xres = 1024; + info->yres = 768; pixel_format = 0x88883316; gamma_fix = 0; out_8(pixis_base + PIXIS_BRDCFG0, (tmp_val & 0xf7) | 0x10);
} else if (!strncmp(monitor_port, "2", 1)) { /* 2 - Double link LVDS */ - xres = 1280; - yres = 1024; + info->xres = 1280; + info->yres = 1024; pixel_format = 0x88883316; gamma_fix = 1; out_8(pixis_base + PIXIS_BRDCFG0, tmp_val & 0xe7);
} else { /* DVI */ - xres = 1280; - yres = 1024; + info->xres = 1280; + info->yres = 1024; pixel_format = 0x88882317; gamma_fix = 0; out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x08); }
- fsl_diu_init(xres, pixel_format, gamma_fix, + fsl_diu_init(info->xres, pixel_format, gamma_fix, (unsigned char *)FSL_Logo_BMP); }
-int mpc8610diu_init_show_bmp(cmd_tbl_t *cmdtp, - int flag, int argc, char * const argv[]) -{ - unsigned int addr; - - if (argc < 2) - return cmd_usage(cmdtp); - - if (!strncmp(argv[1],"init",4)) { -#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) - fsl_diu_clear_screen(); - drv_video_init(); -#else - mpc8610hpcd_diu_init(); -#endif - } else { - addr = simple_strtoul(argv[1], NULL, 16); - fsl_diu_clear_screen(); - fsl_diu_display_bmp((unsigned char *)addr, 0, 0, 0); - } - - return 0; -} - -U_BOOT_CMD( - diufb, CONFIG_SYS_MAXARGS, 1, mpc8610diu_init_show_bmp, - "Init or Display BMP file", - "init\n - initialize DIU\n" - "addr\n - display bmp at address 'addr'" -); - - -#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) - -/* - * The Graphic Device - */ -GraphicDevice ctfb; -void *video_hw_init(void) -{ - GraphicDevice *pGD = (GraphicDevice *) &ctfb; - struct fb_info *info; - - mpc8610hpcd_diu_init(); - - /* fill in Graphic device struct */ - sprintf(pGD->modeIdent, - "%dx%dx%d %ldkHz %ldHz", - xres, yres, 32, 64, 60); - - pGD->frameAdrs = (unsigned int)fsl_fb_open(&info); - pGD->winSizeX = xres; - pGD->winSizeY = yres - info->logo_height; - pGD->plnSizeX = pGD->winSizeX; - pGD->plnSizeY = pGD->winSizeY; - - pGD->gdfBytesPP = 4; - pGD->gdfIndex = GDF_32BIT_X888RGB; - - pGD->isaBase = 0; - pGD->pciBase = 0; - pGD->memSize = info->screen_size - info->logo_size; - - /* Cursor Start Address */ - pGD->dprBase = 0; - pGD->vprBase = 0; - pGD->cprBase = 0; - - return (void *)pGD; -} - -#endif /* defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) */ - #endif /* CONFIG_FSL_DIU_FB */ diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h index 4d9606e..84979e4 100644 --- a/include/configs/MPC8610HPCD.h +++ b/include/configs/MPC8610HPCD.h @@ -22,9 +22,9 @@ #define CONFIG_FSL_DIU_FB 1 /* FSL DIU */
/* video */ -#undef CONFIG_VIDEO - -#if defined(CONFIG_VIDEO) +#define CONFIG_VIDEO +#ifdef CONFIG_VIDEO +#define CONFIG_CMD_BMP #define CONFIG_CFB_CONSOLE #define CONFIG_VGA_AS_SINGLE_DEVICE #endif

I'm rescinding this patch. I'll have v2 some time next week.
On Thu, Aug 26, 2010 at 3:59 PM, Timur Tabi timur@freescale.com wrote:
The Freescale MPC8610 DIU code has its own bitmap-drawing function, fsl_diu_display_bmp(), which is redundant. Instead, use the existing function video_display_bitmap(). Replacing fsl_diu_display_bmp() with video_display_bitmap() also requires refactoring the DIU initialization code.
Signed-off-by: Timur Tabi timur@freescale.com
participants (1)
-
Timur Tabi