diff options
Diffstat (limited to 'common/lcd.c')
-rw-r--r-- | common/lcd.c | 143 |
1 files changed, 86 insertions, 57 deletions
diff --git a/common/lcd.c b/common/lcd.c index 77914ad..edae835 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -83,9 +83,35 @@ #define CONFIG_CONSOLE_SCROLL_LINES 1 #endif -DECLARE_GLOBAL_DATA_PTR; +/************************************************************************/ +/* ** CONSOLE DEFINITIONS & FUNCTIONS */ +/************************************************************************/ +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) +# define CONSOLE_ROWS ((panel_info.vl_row-BMP_LOGO_HEIGHT) \ + / VIDEO_FONT_HEIGHT) +#else +# define CONSOLE_ROWS (panel_info.vl_row / VIDEO_FONT_HEIGHT) +#endif -ulong lcd_setmem (ulong addr); +#define CONSOLE_COLS (panel_info.vl_col / VIDEO_FONT_WIDTH) +#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length) +#define CONSOLE_ROW_FIRST lcd_console_address +#define CONSOLE_ROW_SECOND (lcd_console_address + CONSOLE_ROW_SIZE) +#define CONSOLE_ROW_LAST (lcd_console_address + CONSOLE_SIZE \ + - CONSOLE_ROW_SIZE) +#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS) +#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE) + +#if LCD_BPP == LCD_MONOCHROME +# define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \ + (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7) +#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) +# define COLOR_MASK(c) (c) +#else +# error Unsupported LCD BPP. +#endif + +DECLARE_GLOBAL_DATA_PTR; static void lcd_drawchars(ushort x, ushort y, uchar *str, int count); static inline void lcd_puts_xy(ushort x, ushort y, uchar *s); @@ -93,22 +119,25 @@ static inline void lcd_putc_xy(ushort x, ushort y, uchar c); static int lcd_init(void *lcdbase); -static void *lcd_logo (void); +static void *lcd_logo(void); static int lcd_getbgcolor(void); static void lcd_setfgcolor(int color); static void lcd_setbgcolor(int color); +static int lcd_color_fg; +static int lcd_color_bg; +int lcd_line_length; + char lcd_is_enabled = 0; -static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ +static short console_col; +static short console_row; +static void *lcd_console_address; +static void *lcd_base; /* Start of framebuffer memory */ -#ifdef NOT_USED_SO_FAR -static void lcd_getcolreg(ushort regno, - ushort *red, ushort *green, ushort *blue); -static int lcd_getfgcolor(void); -#endif /* NOT_USED_SO_FAR */ +static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ /************************************************************************/ @@ -148,7 +177,7 @@ static void console_scrollup(void) /* Clear the last rows */ memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows, COLOR_MASK(lcd_color_bg), - CONSOLE_ROW_SIZE * rows); + CONSOLE_ROW_SIZE * rows); lcd_sync(); console_row -= rows; @@ -160,9 +189,8 @@ static inline void console_back(void) { if (--console_col < 0) { console_col = CONSOLE_COLS-1 ; - if (--console_row < 0) { + if (--console_row < 0) console_row = 0; - } } lcd_putc_xy(console_col * VIDEO_FONT_WIDTH, @@ -173,16 +201,13 @@ static inline void console_back(void) static inline void console_newline(void) { - ++console_row; console_col = 0; /* Check if we need to scroll the terminal */ - if (console_row >= CONSOLE_ROWS) { - /* Scroll everything up */ + if (++console_row >= CONSOLE_ROWS) console_scrollup(); - } else { + else lcd_sync(); - } } /*----------------------------------------------------------------------*/ @@ -234,9 +259,9 @@ void lcd_puts(const char *s) return; } - while (*s) { + while (*s) lcd_putc(*s++); - } + lcd_sync(); } @@ -283,7 +308,7 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count) #endif #if LCD_BPP == LCD_MONOCHROME - uchar rest = *d & -(1 << (8-off)); + uchar rest = *d & -(1 << (8 - off)); uchar sym; #endif for (i = 0; i < count; ++i) { @@ -313,7 +338,7 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count) #endif } #if LCD_BPP == LCD_MONOCHROME - *d = rest | (*d & ((1 << (8-off)) - 1)); + *d = rest | (*d & ((1 << (8 - off)) - 1)); #endif } } @@ -340,7 +365,7 @@ static inline void lcd_putc_xy(ushort x, ushort y, uchar c) #define N_BLK_VERT 2 #define N_BLK_HOR 3 -static int test_colors[N_BLK_HOR*N_BLK_VERT] = { +static int test_colors[N_BLK_HOR * N_BLK_VERT] = { CONSOLE_COLOR_RED, CONSOLE_COLOR_GREEN, CONSOLE_COLOR_YELLOW, CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN, }; @@ -361,7 +386,7 @@ static void test_pattern(void) for (v = 0; v < v_max; ++v) { uchar iy = v / v_step; for (h = 0; h < h_max; ++h) { - uchar ix = N_BLK_HOR * iy + (h/h_step); + uchar ix = N_BLK_HOR * iy + h / h_step; *pix++ = test_colors[ix]; } } @@ -379,12 +404,12 @@ int lcd_get_size(int *line_length) return *line_length * panel_info.vl_row; } -int drv_lcd_init (void) +int drv_lcd_init(void) { struct stdio_dev lcddev; int rc; - lcd_base = (void *)(gd->fb_base); + lcd_base = (void *) gd->fb_base; lcd_init(lcd_base); /* LCD initialization */ @@ -397,7 +422,7 @@ int drv_lcd_init (void) lcddev.putc = lcd_putc; /* 'putc' function */ lcddev.puts = lcd_puts; /* 'puts' function */ - rc = stdio_register (&lcddev); + rc = stdio_register(&lcddev); return (rc == 0) ? 1 : rc; } @@ -436,11 +461,11 @@ void lcd_clear(void) /* set framebuffer to background color */ memset((char *)lcd_base, COLOR_MASK(lcd_getbgcolor()), - lcd_line_length*panel_info.vl_row); + lcd_line_length * panel_info.vl_row); #endif /* Paint the logo and retrieve LCD base address */ debug("[LCD] Drawing the logo...\n"); - lcd_console_address = lcd_logo (); + lcd_console_address = lcd_logo(); console_col = 0; console_row = 0; @@ -468,11 +493,23 @@ static int lcd_init(void *lcdbase) debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase); lcd_ctrl_init(lcdbase); + + /* + * lcd_ctrl_init() of some drivers (i.e. bcm2835 on rpi_b) ignores + * the 'lcdbase' argument and uses custom lcd base address + * by setting up gd->fb_base. Check for this condition and fixup + * 'lcd_base' address. + */ + if ((unsigned long)lcdbase != gd->fb_base) + lcd_base = (void *)gd->fb_base; + + debug("[LCD] Using LCD frambuffer at %p\n", lcd_base); + lcd_get_size(&lcd_line_length); lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; lcd_is_enabled = 1; lcd_clear(); - lcd_enable (); + lcd_enable(); /* Initialize the console */ console_col = 0; @@ -513,7 +550,8 @@ ulong lcd_setmem(ulong addr) /* Allocate pages for the frame buffer. */ addr -= size; - debug("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr); + debug("Reserving %ldk for LCD Framebuffer at: %08lx\n", + size >> 10, addr); return addr; } @@ -534,12 +572,10 @@ static void lcd_setbgcolor(int color) /*----------------------------------------------------------------------*/ -#ifdef NOT_USED_SO_FAR -static int lcd_getfgcolor(void) +int lcd_getfgcolor(void) { return lcd_color_fg; } -#endif /* NOT_USED_SO_FAR */ /*----------------------------------------------------------------------*/ @@ -548,8 +584,6 @@ static int lcd_getbgcolor(void) return lcd_color_bg; } -/*----------------------------------------------------------------------*/ - /************************************************************************/ /* ** Chipset depending Bitmap / Logo stuff... */ /************************************************************************/ @@ -566,13 +600,11 @@ static inline ushort *configuration_get_cmap(void) return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); #elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) return panel_info.cmap; -#else -#if defined(CONFIG_LCD_LOGO) +#elif defined(CONFIG_LCD_LOGO) return bmp_logo_palette; #else return NULL; #endif -#endif } #ifdef CONFIG_LCD_LOGO @@ -591,15 +623,16 @@ void bitmap_plot(int x, int y) immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; cpm8xx_t *cp = &(immr->im_cpm); #endif + unsigned bpix = NBITS(panel_info.vl_bpix); debug("Logo: width %d height %d colors %d cmap %d\n", BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS, ARRAY_SIZE(bmp_logo_palette)); bmap = &bmp_logo_bitmap[0]; - fb = (uchar *)(lcd_base + y * lcd_line_length + x); + fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8); - if (NBITS(panel_info.vl_bpix) < 12) { + if (bpix < 12) { /* Leave room for default color map * default case: generic system with no cmap (most likely 16bpp) * cmap was set to the source palette, so no change is done. @@ -645,12 +678,12 @@ void bitmap_plot(int x, int y) for (i = 0; i < BMP_LOGO_HEIGHT; ++i) { memcpy(fb, bmap, BMP_LOGO_WIDTH); bmap += BMP_LOGO_WIDTH; - fb += panel_info.vl_col; + fb += panel_info.vl_col; } } else { /* true color mode */ u16 col16; - fb16 = (ushort *)(lcd_base + y * lcd_line_length + x); + fb16 = (ushort *)fb; for (i = 0; i < BMP_LOGO_HEIGHT; ++i) { for (j = 0; j < BMP_LOGO_WIDTH; j++) { col16 = bmp_logo_palette[(bmap[j]-16)]; @@ -736,12 +769,11 @@ static void draw_encoded_bitmap(ushort **fbp, ushort c, int cnt) *fb++ = c; cnt--; } - (*fbp) = fb; + *fbp = fb; } /* - * Do not call this function directly, must be called from - * lcd_display_bitmap. + * Do not call this function directly, must be called from lcd_display_bitmap. */ static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, int x_off, int y_off) @@ -868,8 +900,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) unsigned long pwidth = panel_info.vl_col; unsigned colors, bpix, bmp_bpix; - if (!bmp || !((bmp->header.signature[0] == 'B') && - (bmp->header.signature[1] == 'M'))) { + if (!bmp || !(bmp->header.signature[0] == 'B' && + bmp->header.signature[1] == 'M')) { printf("Error: no valid bmp image at %lx\n", bmp_image); return 1; @@ -882,7 +914,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) bpix = NBITS(panel_info.vl_bpix); - if ((bpix != 1) && (bpix != 8) && (bpix != 16) && (bpix != 32)) { + if (bpix != 1 && bpix != 8 && bpix != 16 && bpix != 32) { printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n", bpix, bmp_bpix); @@ -950,7 +982,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } #endif - padded_width = (width&0x3) ? ((width&~0x3)+4) : (width); + padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width); #ifdef CONFIG_SPLASH_SCREEN_ALIGN splash_align_axis(&x, pwidth, width); @@ -962,7 +994,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) if ((y + height) > panel_info.vl_row) height = panel_info.vl_row - y; - bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset); + bmap = (uchar *) bmp + le32_to_cpu(bmp->header.data_offset); fb = (uchar *) (lcd_base + (y + height - 1) * lcd_line_length + x * bpix / 8); @@ -997,7 +1029,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } } bmap += (padded_width - width); - fb -= (byte_width + lcd_line_length); + fb -= byte_width + lcd_line_length; } break; @@ -1009,7 +1041,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) fb_put_word(&fb, &bmap); bmap += (padded_width - width) * 2; - fb -= (width * 2 + lcd_line_length); + fb -= width * 2 + lcd_line_length; } break; #endif /* CONFIG_BMP_16BPP */ @@ -1023,7 +1055,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) *(fb++) = *(bmap++); *(fb++) = *(bmap++); } - fb -= (lcd_line_length + width * (bpix / 8)); + fb -= lcd_line_length + width * (bpix / 8); } break; #endif /* CONFIG_BMP_32BPP */ @@ -1098,7 +1130,7 @@ static void *lcd_logo(void) return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length); #else return (void *)lcd_base; -#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */ +#endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */ } #ifdef CONFIG_SPLASHIMAGE_GUARD @@ -1150,6 +1182,3 @@ int lcd_get_screen_columns(void) { return CONSOLE_COLS; } - -/************************************************************************/ -/************************************************************************/ |