[U-Boot] [PATCH 5/5] lcd: refactor lcd console stuff into its own file

Nikita Kiryanov
2014-11-20T16:13:48Z

common/lcd.c is a mix of code portions that do different but related
things. To improve modularity, the various code portions should be split
into their own modules. Separate lcd console code into its own file.

In the process of making this move, some minor changes are introduced:
CONSOLE_ROWS and CONSOLE_COLS macros are replaced with variables which
are assigned using a new function lcd_init_console().

Minor changes were done to facilitate communication between lcd code
and lcd_console code, specifically in the introduction of lcd_console
functions set_console_col(), set_console_row(), lcd_get_screen_rows(),
lcd_get_screen_columns(), and lcd funcitons lcd_getbgcolor(),
lcd_getfgcolor().

Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Simon Glass <sjg@chromium.org>
---
common/Makefile | 2 +-
common/lcd.c | 268 ++++++--------------------------------------------
common/lcd_console.c | 199 +++++++++++++++++++++++++++++++++++++
include/lcd.h | 3 +
include/lcd_console.h | 14 +++
5 files changed, 249 insertions(+), 237 deletions(-)
create mode 100644 common/lcd_console.c
create mode 100644 include/lcd_console.h

diff --git a/common/Makefile b/common/Makefile
index 6cc4de8..5f2350b 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -205,7 +205,7 @@ obj-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o
obj-$(CONFIG_I2C_EDID) += edid.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-y += splash.o
-obj-$(CONFIG_LCD) += lcd.o
+obj-$(CONFIG_LCD) += lcd.o lcd_console.o
obj-$(CONFIG_LYNXKDI) += lynxkdi.o
obj-$(CONFIG_MENU) += menu.o
obj-$(CONFIG_MODEM_SUPPORT) += modem.o
diff --git a/common/lcd.c b/common/lcd.c
index 4c86f6c..ea41ac2 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -72,42 +72,13 @@
#define CONFIG_LCD_ALIGNMENT PAGE_SIZE
#endif

-/* By default we scroll by a single line */
-#ifndef CONFIG_CONSOLE_SCROLL_LINES
-#define CONFIG_CONSOLE_SCROLL_LINES 1
-#endif
-
-/************************************************************************/
-/* ** 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
-
-#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_COLOR8) || (LCD_BPP == LCD_COLOR16) || \
- (LCD_BPP == LCD_COLOR32)
-# define COLOR_MASK(c) (c)
-#else
+#if (LCD_BPP != LCD_COLOR8) && (LCD_BPP != LCD_COLOR16) && \
+ (LCD_BPP != LCD_COLOR32)
# 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_putc_xy(ushort x, ushort y, uchar c);
-
static int lcd_init(void *lcdbase);

static void *lcd_logo(void);
@@ -121,16 +92,12 @@ int lcd_line_length;

char lcd_is_enabled = 0;

-static short console_col;
-static short console_row;
-
-static void *lcd_console_address;
static void *lcd_base; /* Start of framebuffer memory */

static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */

-/************************************************************************/

+/************************************************************************/
/* Flush LCD activity to the caches */
void lcd_sync(void)
{
@@ -160,186 +127,14 @@ void lcd_set_flush_dcache(int flush)
lcd_flush_dcache = (flush != 0);
}

-/*----------------------------------------------------------------------*/
-
-static void console_scrollup(void)
-{
- const int rows = CONFIG_CONSOLE_SCROLL_LINES;
-
- /* Copy up rows ignoring those that will be overwritten */
- memcpy(CONSOLE_ROW_FIRST,
- lcd_console_address + CONSOLE_ROW_SIZE * rows,
- CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
-
- /* Clear the last rows */
-#if (LCD_BPP != LCD_COLOR32)
- memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
- COLOR_MASK(lcd_color_bg),
- CONSOLE_ROW_SIZE * rows);
-#else
- u32 *ppix = lcd_console_address +
- CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
- u32 i;
- for (i = 0;
- i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
- i++) {
- *ppix++ = COLOR_MASK(lcd_color_bg);
- }
-#endif
- lcd_sync();
- console_row -= rows;
-}
-
-/*----------------------------------------------------------------------*/
-
-static inline void console_back(void)
-{
- if (--console_col < 0) {
- console_col = CONSOLE_COLS-1 ;
- if (--console_row < 0)
- console_row = 0;
- }
-
- lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, ' ');
-}
-
-/*----------------------------------------------------------------------*/
-
-static inline void console_newline(void)
-{
- console_col = 0;
-
- /* Check if we need to scroll the terminal */
- if (++console_row >= CONSOLE_ROWS)
- console_scrollup();
- else
- lcd_sync();
-}
-
-/*----------------------------------------------------------------------*/
-
-static void lcd_stub_putc(struct stdio_dev *dev, const char c)
-{
- lcd_putc(c);
-}
-
-void lcd_putc(const char c)
-{
- if (!lcd_is_enabled) {
- serial_putc(c);
-
- return;
- }
-
- switch (c) {
- case '\r':
- console_col = 0;
-
- return;
- case '\n':
- console_newline();
-
- return;
- case '\t': /* Tab (8 chars alignment) */
- console_col += 8;
- console_col &= ~7;
-
- if (console_col >= CONSOLE_COLS)
- console_newline();
-
- return;
- case '\b':
- console_back();
-
- return;
- default:
- lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, c);
- if (++console_col >= CONSOLE_COLS)
- console_newline();
- }
-}
-
-/*----------------------------------------------------------------------*/
-
static void lcd_stub_puts(struct stdio_dev *dev, const char *s)
{
lcd_puts(s);
}

-void lcd_puts(const char *s)
-{
- if (!lcd_is_enabled) {
- serial_puts(s);
-
- return;
- }
-
- while (*s)
- lcd_putc(*s++);
-
- lcd_sync();
-}
-
-/*----------------------------------------------------------------------*/
-
-void lcd_printf(const char *fmt, ...)
-{
- va_list args;
- char buf[CONFIG_SYS_PBSIZE];
-
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
-
- lcd_puts(buf);
-}
-
-/************************************************************************/
-/* ** Low-Level Graphics Routines */
-/************************************************************************/
-
-static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
-{
- uchar *dest;
- ushort row;
-
-#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
- y += BMP_LOGO_HEIGHT;
-#endif
-
- dest = (uchar *)(lcd_base + y * lcd_line_length + x * NBITS(LCD_BPP)/8);
-
- for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
- uchar *s = str;
- int i;
-#if LCD_BPP == LCD_COLOR16
- ushort *d = (ushort *)dest;
-#elif LCD_BPP == LCD_COLOR32
- u32 *d = (u32 *)dest;
-#else
- uchar *d = dest;
-#endif
-
- for (i = 0; i < count; ++i) {
- uchar c, bits;
-
- c = *s++;
- bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
-
- for (c = 0; c < 8; ++c) {
- *d++ = (bits & 0x80) ?
- lcd_color_fg : lcd_color_bg;
- bits <<= 1;
- }
- }
- }
-}
-
-static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
+static void lcd_stub_putc(struct stdio_dev *dev, const char c)
{
- lcd_drawchars(x, y, &c, 1);
+ lcd_putc(c);
}

/************************************************************************/
@@ -420,6 +215,8 @@ int drv_lcd_init(void)
/*----------------------------------------------------------------------*/
void lcd_clear(void)
{
+ short console_rows, console_cols;
+
#if LCD_BPP == LCD_COLOR8
/* Setting the palette */
lcd_setcolreg(CONSOLE_COLOR_BLACK, 0, 0, 0);
@@ -447,7 +244,7 @@ void lcd_clear(void)
/* set framebuffer to background color */
#if (LCD_BPP != LCD_COLOR32)
memset((char *)lcd_base,
- COLOR_MASK(lcd_color_bg),
+ lcd_color_bg,
lcd_line_length * panel_info.vl_row);
#else
u32 *ppix = lcd_base;
@@ -455,16 +252,21 @@ void lcd_clear(void)
for (i = 0;
i < (lcd_line_length * panel_info.vl_row)/NBYTES(panel_info.vl_bpix);
i++) {
- *ppix++ = COLOR_MASK(lcd_color_bg);
+ *ppix++ = lcd_color_bg;
}
#endif
#endif
/* Paint the logo and retrieve LCD base address */
debug("[LCD] Drawing the logo...\n");
- lcd_console_address = lcd_logo();
+#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;

- console_col = 0;
- console_row = 0;
+ lcd_init_console(lcd_logo(), console_rows, console_cols);
lcd_sync();
}

@@ -507,11 +309,11 @@ static int lcd_init(void *lcdbase)
lcd_enable();

/* Initialize the console */
- console_col = 0;
+ set_console_col(0);
#ifdef CONFIG_LCD_INFO_BELOW_LOGO
- console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;
+ set_console_row(7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT);
#else
- console_row = 1; /* leave 1 blank line below logo */
+ set_console_col(1); /* leave 1 blank line below logo */
#endif

return 0;
@@ -558,6 +360,11 @@ static void lcd_setfgcolor(int color)
lcd_color_fg = color;
}

+int lcd_getfgcolor(void)
+{
+ return lcd_color_fg;
+}
+
/*----------------------------------------------------------------------*/

static void lcd_setbgcolor(int color)
@@ -565,6 +372,11 @@ static void lcd_setbgcolor(int color)
lcd_color_bg = color;
}

+int lcd_getbgcolor(void)
+{
+ return lcd_color_bg;
+}
+
/************************************************************************/
/* ** Chipset depending Bitmap / Logo stuff... */
/************************************************************************/
@@ -1061,8 +873,8 @@ static void *lcd_logo(void)
bitmap_plot(0, 0);

#ifdef CONFIG_LCD_INFO
- console_col = LCD_INFO_X / VIDEO_FONT_WIDTH;
- console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT;
+ set_console_col(LCD_INFO_X / VIDEO_FONT_WIDTH);
+ set_console_row(LCD_INFO_Y / VIDEO_FONT_HEIGHT);
lcd_show_board_info();
#endif /* CONFIG_LCD_INFO */

@@ -1097,12 +909,6 @@ static int on_splashimage(const char *name, const char *value, enum env_op op,
U_BOOT_ENV_CALLBACK(splashimage, on_splashimage);
#endif

-void lcd_position_cursor(unsigned col, unsigned row)
-{
- console_col = min(col, CONSOLE_COLS - 1);
- console_row = min(row, CONSOLE_ROWS - 1);
-}
-
int lcd_get_pixel_width(void)
{
return panel_info.vl_col;
@@ -1113,16 +919,6 @@ int lcd_get_pixel_height(void)
return panel_info.vl_row;
}

-int lcd_get_screen_rows(void)
-{
- return CONSOLE_ROWS;
-}
-
-int lcd_get_screen_columns(void)
-{
- return CONSOLE_COLS;
-}
-
#if defined(CONFIG_LCD_DT_SIMPLEFB)
static int lcd_dt_simplefb_configure_node(void *blob, int off)
{
diff --git a/common/lcd_console.c b/common/lcd_console.c
new file mode 100644
index 0000000..e6e1887
--- /dev/null
+++ b/common/lcd_console.c
@@ -0,0 +1,199 @@
+#include <common.h>
+#include <lcd.h>
+#include <video_font.h> /* Get font data, width and height */
+
+static short console_cols;
+static short console_rows;
+static short console_curr_col;
+static short console_curr_row;
+static void *lcd_console_address;
+
+#define CONSOLE_ROW_FIRST lcd_console_address
+#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)
+#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * console_rows)
+
+static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
+{
+ uchar *dest;
+ ushort row;
+
+ dest = (uchar *)(lcd_console_address +
+ y * lcd_line_length + x * NBITS(LCD_BPP) / 8);
+ for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
+ uchar *s = str;
+ int i;
+#if LCD_BPP == LCD_COLOR16
+ ushort *d = (ushort *)dest;
+#elif LCD_BPP == LCD_COLOR32
+ u32 *d = (u32 *)dest;
+#else
+ uchar *d = dest;
+#endif
+
+ for (i = 0; i < count; ++i) {
+ uchar c, bits;
+
+ c = *s++;
+ bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
+
+ for (c = 0; c < 8; ++c) {
+ *d++ = (bits & 0x80) ?
+ lcd_getfgcolor() : lcd_getbgcolor();
+ bits <<= 1;
+ }
+ }
+ }
+}
+
+static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
+{
+ lcd_drawchars(x, y, &c, 1);
+}
+
+static void console_scrollup(void)
+{
+ const int rows = CONFIG_CONSOLE_SCROLL_LINES;
+
+ /* Copy up rows ignoring those that will be overwritten */
+ memcpy(CONSOLE_ROW_FIRST,
+ lcd_console_address + CONSOLE_ROW_SIZE * rows,
+ CONSOLE_ROW_SIZE - CONSOLE_ROW_SIZE * rows);
+
+ /* Clear the last rows */
+#if (LCD_BPP != LCD_COLOR32)
+ memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
+ lcd_getbgcolor(), CONSOLE_ROW_SIZE * rows);
+#else
+ u32 *ppix = lcd_console_address +
+ CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
+ u32 i;
+ for (i = 0;
+ i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
+ i++) {
+ *ppix++ = lcd_getbgcolor();
+ }
+#endif
+ lcd_sync();
+ console_curr_row -= rows;
+}
+
+static inline void console_back(void)
+{
+ if (--console_curr_col < 0) {
+ console_curr_col = console_cols - 1;
+ if (--console_curr_row < 0)
+ console_curr_row = 0;
+ }
+
+ lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
+ console_curr_row * VIDEO_FONT_HEIGHT, ' ');
+}
+
+static inline void console_newline(void)
+{
+ console_curr_col = 0;
+
+ /* Check if we need to scroll the terminal */
+ if (++console_curr_row >= console_rows)
+ console_scrollup();
+ else
+ lcd_sync();
+}
+
+void lcd_init_console(void *address, int rows, int cols)
+{
+ console_curr_col = 0;
+ console_curr_row = 0;
+ console_cols = cols;
+ console_rows = rows;
+ lcd_console_address = address;
+}
+
+void set_console_col(short col)
+{
+ console_curr_col = col;
+}
+
+void set_console_row(short row)
+{
+ console_curr_row = row;
+}
+
+void lcd_position_cursor(unsigned col, unsigned row)
+{
+ set_console_col(min(col, console_cols - 1));
+ set_console_row(min(row, console_rows - 1));
+}
+
+int lcd_get_screen_rows(void)
+{
+ return console_rows;
+}
+
+int lcd_get_screen_columns(void)
+{
+ return console_cols;
+}
+
+void lcd_putc(const char c)
+{
+ if (!lcd_is_enabled) {
+ serial_putc(c);
+
+ return;
+ }
+
+ switch (c) {
+ case '\r':
+ console_curr_col = 0;
+
+ return;
+ case '\n':
+ console_newline();
+
+ return;
+ case '\t': /* Tab (8 chars alignment) */
+ console_curr_col += 8;
+ console_curr_col &= ~7;
+
+ if (console_curr_col >= console_cols)
+ console_newline();
+
+ return;
+ case '\b':
+ console_back();
+
+ return;
+ default:
+ lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
+ console_curr_row * VIDEO_FONT_HEIGHT, c);
+ if (++console_curr_col >= console_cols)
+ console_newline();
+ }
+}
+
+void lcd_puts(const char *s)
+{
+ if (!lcd_is_enabled) {
+ serial_puts(s);
+
+ return;
+ }
+
+ while (*s)
+ lcd_putc(*s++);
+
+ lcd_sync();
+}
+
+void lcd_printf(const char *fmt, ...)
+{
+ va_list args;
+ char buf[CONFIG_SYS_PBSIZE];
+
+ va_start(args, fmt);
+ vsprintf(buf, fmt, args);
+ va_end(args);
+
+ lcd_puts(buf);
+}
diff --git a/include/lcd.h b/include/lcd.h
index 01609ac..8960b7a 100644
--- a/include/lcd.h
+++ b/include/lcd.h
@@ -12,6 +12,7 @@

#ifndef _LCD_H_
#define _LCD_H_
+#include <lcd_console.h>

extern char lcd_is_enabled;

@@ -290,6 +291,8 @@ int lcd_get_screen_rows(void);
*/
int lcd_get_screen_columns(void);

+int lcd_getbgcolor(void);
+int lcd_getfgcolor(void);
/**
* Set the position of the text cursor
*
diff --git a/include/lcd_console.h b/include/lcd_console.h
new file mode 100644
index 0000000..928173d
--- /dev/null
+++ b/include/lcd_console.h
@@ -0,0 +1,14 @@
+/* By default we scroll by a single line */
+#ifndef CONFIG_CONSOLE_SCROLL_LINES
+#define CONFIG_CONSOLE_SCROLL_LINES 1
+#endif
+
+void lcd_init_console(void *address, int rows, int cols);
+void set_console_col(short col);
+void set_console_row(short row);
+void lcd_position_cursor(unsigned col, unsigned row);
+int lcd_get_screen_rows(void);
+int lcd_get_screen_columns(void);
+void lcd_putc(const char c);
+void lcd_puts(const char *s);
+void lcd_printf(const char *fmt, ...);
--
1.9.1