]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/lcd_console.c
mmc: omap_hsmmc: enable 8bit interface for eMMC for AM43xx
[karo-tx-uboot.git] / common / lcd_console.c
index 74c388a0cadccb06a4e9ba935310b78d2206ec3a..bb0d7c54858a3291feca8edc4bba8697a5bf2c0f 100644 (file)
@@ -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+
  */
 #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      lcd_console_address
-#define CONSOLE_SIZE           (CONSOLE_ROW_SIZE * console_rows)
-
-static short console_curr_col;
-static short console_curr_row;
-static short console_cols;
-static short console_rows;
-static void *lcd_console_address;
-
-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;
-}
+static struct console_t cons;
 
 void lcd_set_col(short col)
 {
-       console_curr_col = col;
+       cons.curr_col = col;
 }
 
 void lcd_set_row(short row)
 {
-       console_curr_row = row;
+       cons.curr_row = row;
 }
 
 void lcd_position_cursor(unsigned col, unsigned row)
 {
-       console_curr_col = min_t(short, col, console_cols - 1);
-       console_curr_row = min_t(short, row, console_rows - 1);
+       cons.curr_col = min_t(short, col, cons.cols - 1);
+       cons.curr_row = min_t(short, row, cons.rows - 1);
 }
 
 int lcd_get_screen_rows(void)
 {
-       return console_rows;
+       return cons.rows;
 }
 
 int lcd_get_screen_columns(void)
 {
-       return console_cols;
+       return cons.cols;
 }
 
-static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
+static void lcd_putc_xy0(struct console_t *pcons, ushort x, ushort y, char c)
 {
-       uchar *dest;
-       ushort row;
-       int fg_color, bg_color;
+       int fg_color = lcd_getfgcolor();
+       int bg_color = lcd_getbgcolor();
+       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);
+       }
+}
 
-       dest = (uchar *)(lcd_console_address +
-                        y * lcd_line_length + x * NBITS(LCD_BPP) / 8);
+static inline void console_setrow0(struct console_t *pcons, u32 row, int clr)
+{
+       int i;
+       fbptr_t *dst = (fbptr_t *)pcons->fbbase +
+                                 row * VIDEO_FONT_HEIGHT *
+                                 pcons->lcdsizex;
 
-       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 < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
+               *dst++ = clr;
+}
 
-               fg_color = lcd_getfgcolor();
-               bg_color = lcd_getbgcolor();
-               for (i = 0; i < count; ++i) {
-                       uchar c, bits;
+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;
 
-                       c = *s++;
-                       bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
+       fbptr_t *src = (fbptr_t *)pcons->fbbase +
+                                 rowsrc * VIDEO_FONT_HEIGHT *
+                                 pcons->lcdsizex;
 
-                       for (c = 0; c < 8; ++c) {
-                               *d++ = (bits & 0x80) ? fg_color : bg_color;
-                               bits <<= 1;
-                       }
-               }
-       }
+       for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
+               *dst++ = *src++;
 }
 
-static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
+static inline void console_back(void)
 {
-       lcd_drawchars(x, y, &c, 1);
+       if (--cons.curr_col < 0) {
+               cons.curr_col = cons.cols - 1;
+               if (--cons.curr_row < 0)
+                       cons.curr_row = 0;
+       }
+
+       cons.fp_putc_xy(&cons,
+                       cons.curr_col * VIDEO_FONT_WIDTH,
+                       cons.curr_row * VIDEO_FONT_HEIGHT, ' ');
 }
 
-static void console_scrollup(void)
+static inline void console_newline(void)
 {
        const int rows = CONFIG_CONSOLE_SCROLL_LINES;
        int bg_color = lcd_getbgcolor();
+       int i;
 
-       /* 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);
+       cons.curr_col = 0;
 
-       /* 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 = 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++ = bg_color;
+       /* Check if we need to scroll the terminal */
+       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;
        }
-#endif
        lcd_sync();
-       console_curr_row -= rows;
 }
 
-static inline void console_back(void)
+void console_calc_rowcol(struct console_t *pcons, u32 sizex, u32 sizey)
 {
-       if (--console_curr_col < 0) {
-               console_curr_col = console_cols - 1;
-               if (--console_curr_row < 0)
-                       console_curr_row = 0;
-       }
+       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
+}
 
-       lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
-                   console_curr_row * VIDEO_FONT_HEIGHT, ' ');
+void __weak lcd_init_console_rot(struct console_t *pcons)
+{
+       return;
 }
 
-static inline void console_newline(void)
+void lcd_init_console(void *address, int vl_cols, int vl_rows, int vl_rot)
 {
-       console_curr_col = 0;
+       memset(&cons, 0, sizeof(cons));
+       cons.fbbase = address;
 
-       /* Check if we need to scroll the terminal */
-       if (++console_curr_row >= console_rows)
-               console_scrollup();
-       else
-               lcd_sync();
+       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)
@@ -157,18 +166,17 @@ void lcd_putc(const char c)
 
        switch (c) {
        case '\r':
-               console_curr_col = 0;
-
+               cons.curr_col = 0;
                return;
        case '\n':
                console_newline();
 
                return;
        case '\t':      /* Tab (8 chars alignment) */
-               console_curr_col +=  8;
-               console_curr_col &= ~7;
+               cons.curr_col +=  8;
+               cons.curr_col &= ~7;
 
-               if (console_curr_col >= console_cols)
+               if (cons.curr_col >= cons.cols)
                        console_newline();
 
                return;
@@ -177,9 +185,10 @@ void lcd_putc(const char c)
 
                return;
        default:
-               lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
-                           console_curr_row * VIDEO_FONT_HEIGHT, c);
-               if (++console_curr_col >= console_cols)
+               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();
        }
 }
@@ -209,3 +218,42 @@ void lcd_printf(const char *fmt, ...)
 
        lcd_puts(buf);
 }
+
+static int do_lcd_setcursor(cmd_tbl_t *cmdtp, int flag, int argc,
+                           char *const argv[])
+{
+       unsigned int col, row;
+
+       if (argc != 3)
+               return CMD_RET_USAGE;
+
+       col = simple_strtoul(argv[1], NULL, 10);
+       row = simple_strtoul(argv[2], NULL, 10);
+       lcd_position_cursor(col, row);
+
+       return 0;
+}
+
+static int do_lcd_puts(cmd_tbl_t *cmdtp, int flag, int argc,
+                      char *const argv[])
+{
+       if (argc != 2)
+               return CMD_RET_USAGE;
+
+       lcd_puts(argv[1]);
+
+       return 0;
+}
+
+U_BOOT_CMD(
+       setcurs, 3,     1,      do_lcd_setcursor,
+       "set cursor position within screen",
+       "    <col> <row> in character"
+);
+
+U_BOOT_CMD(
+       lcdputs, 2,     1,      do_lcd_puts,
+       "print string on lcd-framebuffer",
+       "    <string>"
+);
+