diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/lcd.c | 18 | ||||
-rw-r--r-- | common/lcd_console.c | 163 | ||||
-rw-r--r-- | common/lcd_console_rotation.c | 195 |
4 files changed, 296 insertions, 81 deletions
diff --git a/common/Makefile b/common/Makefile index 252fbf194b..e545458578 100644 --- a/common/Makefile +++ b/common/Makefile @@ -201,6 +201,7 @@ obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-y += splash.o obj-$(CONFIG_SPLASH_SOURCE) += splash_source.o obj-$(CONFIG_LCD) += lcd.o lcd_console.o +obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o obj-$(CONFIG_LYNXKDI) += lynxkdi.o obj-$(CONFIG_MENU) += menu.o diff --git a/common/lcd.c b/common/lcd.c index f33942c617..aab73d8a61 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -167,7 +167,6 @@ int drv_lcd_init(void) void lcd_clear(void) { - short console_rows, console_cols; int bg_color; char *s; ulong addr; @@ -211,16 +210,14 @@ void lcd_clear(void) } #endif #endif + /* setup text-console */ + debug("[LCD] setting up console...\n"); + lcd_init_console(lcd_base, + panel_info.vl_col, + panel_info.vl_row, + panel_info.vl_rot); /* Paint the logo and retrieve LCD base address */ debug("[LCD] Drawing the logo...\n"); -#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) - console_rows = (panel_info.vl_row - BMP_LOGO_HEIGHT); - console_rows /= VIDEO_FONT_HEIGHT; -#else - console_rows = panel_info.vl_row / VIDEO_FONT_HEIGHT; -#endif - console_cols = panel_info.vl_col / VIDEO_FONT_WIDTH; - lcd_init_console(lcd_base, console_rows, console_cols); if (do_splash) { s = getenv("splashimage"); if (s) { @@ -236,7 +233,8 @@ void lcd_clear(void) lcd_logo(); #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) addr = (ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length; - lcd_init_console((void *)addr, console_rows, console_cols); + lcd_init_console((void *)addr, panel_info.vl_row, + panel_info.vl_col, panel_info.vl_rot); #endif lcd_sync(); } diff --git a/common/lcd_console.c b/common/lcd_console.c index cac77be0a9..bb0d7c5485 100644 --- a/common/lcd_console.c +++ b/common/lcd_console.c @@ -1,7 +1,8 @@ /* - * (C) Copyright 2001-2014 + * (C) Copyright 2001-2015 * DENX Software Engineering -- wd@denx.de * Compulab Ltd - http://compulab.co.il/ + * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -9,27 +10,12 @@ #include <common.h> #include <lcd.h> #include <video_font.h> /* Get font data, width and height */ +#if defined(CONFIG_LCD_LOGO) +#include <bmp_logo.h> +#endif -#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length) -#define CONSOLE_ROW_FIRST cons.lcd_address -#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * cons.rows) - -struct console_t { - short curr_col, curr_row; - short cols, rows; - void *lcd_address; -}; static struct console_t cons; -void lcd_init_console(void *address, int rows, int cols) -{ - memset(&cons, 0, sizeof(cons)); - cons.cols = cols; - cons.rows = rows; - cons.lcd_address = address; - -} - void lcd_set_col(short col) { cons.curr_col = col; @@ -56,61 +42,50 @@ int lcd_get_screen_columns(void) return cons.cols; } -static void lcd_putc_xy(ushort x, ushort y, char c) +static void lcd_putc_xy0(struct console_t *pcons, ushort x, ushort y, char c) { - uchar *dest; - ushort row; int fg_color = lcd_getfgcolor(); int bg_color = lcd_getbgcolor(); - int i; - - dest = (uchar *)(cons.lcd_address + - y * lcd_line_length + x * NBITS(LCD_BPP) / 8); - - for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) { -#if LCD_BPP == LCD_COLOR16 - ushort *d = (ushort *)dest; -#elif LCD_BPP == LCD_COLOR32 - u32 *d = (u32 *)dest; -#else - uchar *d = dest; -#endif - uchar bits; - bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; - - for (i = 0; i < 8; ++i) { - *d++ = (bits & 0x80) ? fg_color : bg_color; + int i, row; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + y * pcons->lcdsizex + + x; + + for (row = 0; row < VIDEO_FONT_HEIGHT; row++) { + uchar bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; + for (i = 0; i < VIDEO_FONT_WIDTH; ++i) { + *dst++ = (bits & 0x80) ? fg_color : bg_color; bits <<= 1; } + dst += (pcons->lcdsizex - VIDEO_FONT_WIDTH); } } -static void console_scrollup(void) +static inline void console_setrow0(struct console_t *pcons, u32 row, int clr) { - const int rows = CONFIG_CONSOLE_SCROLL_LINES; - int bg_color = lcd_getbgcolor(); + int i; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + row * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; - /* Copy up rows ignoring those that will be overwritten */ - memcpy(CONSOLE_ROW_FIRST, - cons.lcd_address + CONSOLE_ROW_SIZE * rows, - CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows); + for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++) + *dst++ = clr; +} - /* Clear the last rows */ -#if (LCD_BPP != LCD_COLOR32) - memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows, - bg_color, CONSOLE_ROW_SIZE * rows); -#else - u32 *ppix = cons.lcd_address + - CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows; - u32 i; - for (i = 0; - i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix); - i++) { - *ppix++ = bg_color; - } -#endif - lcd_sync(); - cons.curr_row -= rows; +static inline void console_moverow0(struct console_t *pcons, + u32 rowdst, u32 rowsrc) +{ + int i; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + rowdst * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; + + fbptr_t *src = (fbptr_t *)pcons->fbbase + + rowsrc * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; + + for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++) + *dst++ = *src++; } static inline void console_back(void) @@ -121,19 +96,64 @@ static inline void console_back(void) cons.curr_row = 0; } - lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH, - cons.curr_row * VIDEO_FONT_HEIGHT, ' '); + cons.fp_putc_xy(&cons, + cons.curr_col * VIDEO_FONT_WIDTH, + cons.curr_row * VIDEO_FONT_HEIGHT, ' '); } static inline void console_newline(void) { + const int rows = CONFIG_CONSOLE_SCROLL_LINES; + int bg_color = lcd_getbgcolor(); + int i; + cons.curr_col = 0; /* Check if we need to scroll the terminal */ - if (++cons.curr_row >= cons.rows) - console_scrollup(); - else - lcd_sync(); + if (++cons.curr_row >= cons.rows) { + for (i = 0; i < cons.rows-rows; i++) + cons.fp_console_moverow(&cons, i, i+rows); + for (i = 0; i < rows; i++) + cons.fp_console_setrow(&cons, cons.rows-i-1, bg_color); + cons.curr_row -= rows; + } + lcd_sync(); +} + +void console_calc_rowcol(struct console_t *pcons, u32 sizex, u32 sizey) +{ + pcons->cols = sizex / VIDEO_FONT_WIDTH; +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) + pcons->rows = (pcons->lcdsizey - BMP_LOGO_HEIGHT); + pcons->rows /= VIDEO_FONT_HEIGHT; +#else + pcons->rows = sizey / VIDEO_FONT_HEIGHT; +#endif +} + +void __weak lcd_init_console_rot(struct console_t *pcons) +{ + return; +} + +void lcd_init_console(void *address, int vl_cols, int vl_rows, int vl_rot) +{ + memset(&cons, 0, sizeof(cons)); + cons.fbbase = address; + + cons.lcdsizex = vl_cols; + cons.lcdsizey = vl_rows; + cons.lcdrot = vl_rot; + + cons.fp_putc_xy = &lcd_putc_xy0; + cons.fp_console_moverow = &console_moverow0; + cons.fp_console_setrow = &console_setrow0; + console_calc_rowcol(&cons, cons.lcdsizex, cons.lcdsizey); + + lcd_init_console_rot(&cons); + + debug("lcd_console: have %d/%d col/rws on scr %dx%d (%d deg rotated)\n", + cons.cols, cons.rows, cons.lcdsizex, cons.lcdsizey, vl_rot); } void lcd_putc(const char c) @@ -165,8 +185,9 @@ void lcd_putc(const char c) return; default: - lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH, - cons.curr_row * VIDEO_FONT_HEIGHT, c); + cons.fp_putc_xy(&cons, + cons.curr_col * VIDEO_FONT_WIDTH, + cons.curr_row * VIDEO_FONT_HEIGHT, c); if (++cons.curr_col >= cons.cols) console_newline(); } diff --git a/common/lcd_console_rotation.c b/common/lcd_console_rotation.c new file mode 100644 index 0000000000..7aac521348 --- /dev/null +++ b/common/lcd_console_rotation.c @@ -0,0 +1,195 @@ +/* + * (C) Copyright 2015 + * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <lcd.h> +#include <video_font.h> /* Get font data, width and height */ + +static void lcd_putc_xy90(struct console_t *pcons, ushort x, ushort y, char c) +{ + int fg_color = lcd_getfgcolor(); + int bg_color = lcd_getbgcolor(); + int col, i; + + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + (x+1) * pcons->lcdsizex - + y; + + uchar msk = 0x80; + uchar *pfont = video_fontdata + c * VIDEO_FONT_HEIGHT; + for (col = 0; col < VIDEO_FONT_WIDTH; ++col) { + for (i = 0; i < VIDEO_FONT_HEIGHT; ++i) + *dst-- = (*(pfont + i) & msk) ? fg_color : bg_color; + msk >>= 1; + dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + } +} + +static inline void console_setrow90(struct console_t *pcons, u32 row, int clr) +{ + int i, j; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + pcons->lcdsizex - + row*VIDEO_FONT_HEIGHT+1; + + for (j = 0; j < pcons->lcdsizey; j++) { + for (i = 0; i < VIDEO_FONT_HEIGHT; i++) + *dst-- = clr; + dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + } +} + +static inline void console_moverow90(struct console_t *pcons, + u32 rowdst, u32 rowsrc) +{ + int i, j; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + pcons->lcdsizex - + (rowdst*VIDEO_FONT_HEIGHT+1); + + fbptr_t *src = (fbptr_t *)pcons->fbbase + + pcons->lcdsizex - + (rowsrc*VIDEO_FONT_HEIGHT+1); + + for (j = 0; j < pcons->lcdsizey; j++) { + for (i = 0; i < VIDEO_FONT_HEIGHT; i++) + *dst-- = *src--; + src += (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + } +} +static void lcd_putc_xy180(struct console_t *pcons, ushort x, ushort y, char c) +{ + int fg_color = lcd_getfgcolor(); + int bg_color = lcd_getbgcolor(); + int i, row; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + pcons->lcdsizex + + pcons->lcdsizey * pcons->lcdsizex - + y * pcons->lcdsizex - + (x+1); + + for (row = 0; row < VIDEO_FONT_HEIGHT; row++) { + uchar bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; + + for (i = 0; i < VIDEO_FONT_WIDTH; ++i) { + *dst-- = (bits & 0x80) ? fg_color : bg_color; + bits <<= 1; + } + dst -= (pcons->lcdsizex - VIDEO_FONT_WIDTH); + } +} + +static inline void console_setrow180(struct console_t *pcons, u32 row, int clr) +{ + int i; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + (pcons->rows-row-1) * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; + + for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++) + *dst++ = clr; +} + +static inline void console_moverow180(struct console_t *pcons, + u32 rowdst, u32 rowsrc) +{ + int i; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + (pcons->rows-rowdst-1) * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; + + fbptr_t *src = (fbptr_t *)pcons->fbbase + + (pcons->rows-rowsrc-1) * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; + + for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++) + *dst++ = *src++; +} + +static void lcd_putc_xy270(struct console_t *pcons, ushort x, ushort y, char c) +{ + int fg_color = lcd_getfgcolor(); + int bg_color = lcd_getbgcolor(); + int i, col; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + pcons->lcdsizey * pcons->lcdsizex - + (x+1) * pcons->lcdsizex + + y; + + uchar msk = 0x80; + uchar *pfont = video_fontdata + c * VIDEO_FONT_HEIGHT; + for (col = 0; col < VIDEO_FONT_WIDTH; ++col) { + for (i = 0; i < VIDEO_FONT_HEIGHT; ++i) + *dst++ = (*(pfont + i) & msk) ? fg_color : bg_color; + msk >>= 1; + dst -= (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + } +} + +static inline void console_setrow270(struct console_t *pcons, u32 row, int clr) +{ + int i, j; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + row*VIDEO_FONT_HEIGHT; + + for (j = 0; j < pcons->lcdsizey; j++) { + for (i = 0; i < VIDEO_FONT_HEIGHT; i++) + *dst++ = clr; + dst += (pcons->lcdsizex - VIDEO_FONT_HEIGHT); + } +} + +static inline void console_moverow270(struct console_t *pcons, + u32 rowdst, u32 rowsrc) +{ + int i, j; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + rowdst*VIDEO_FONT_HEIGHT; + + fbptr_t *src = (fbptr_t *)pcons->fbbase + + rowsrc*VIDEO_FONT_HEIGHT; + + for (j = 0; j < pcons->lcdsizey; j++) { + for (i = 0; i < VIDEO_FONT_HEIGHT; i++) + *dst++ = *src++; + src += (pcons->lcdsizex - VIDEO_FONT_HEIGHT); + dst += (pcons->lcdsizex - VIDEO_FONT_HEIGHT); + } +} + +static void console_calc_rowcol_rot(struct console_t *pcons) +{ + if (pcons->lcdrot == 1 || pcons->lcdrot == 3) + console_calc_rowcol(pcons, pcons->lcdsizey, pcons->lcdsizex); + else + console_calc_rowcol(pcons, pcons->lcdsizex, pcons->lcdsizey); +} + +void lcd_init_console_rot(struct console_t *pcons) +{ + if (pcons->lcdrot == 0) { + return; + } else if (pcons->lcdrot == 1) { + pcons->fp_putc_xy = &lcd_putc_xy90; + pcons->fp_console_moverow = &console_moverow90; + pcons->fp_console_setrow = &console_setrow90; + } else if (pcons->lcdrot == 2) { + pcons->fp_putc_xy = &lcd_putc_xy180; + pcons->fp_console_moverow = &console_moverow180; + pcons->fp_console_setrow = &console_setrow180; + } else if (pcons->lcdrot == 3) { + pcons->fp_putc_xy = &lcd_putc_xy270; + pcons->fp_console_moverow = &console_moverow270; + pcons->fp_console_setrow = &console_setrow270; + } else { + printf("%s: invalid framebuffer rotation (%d)!\n", + __func__, pcons->lcdrot); + return; + } + console_calc_rowcol_rot(pcons); +} |