]> git.sur5r.net Git - u-boot/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-video
authorTom Rini <trini@konsulko.com>
Mon, 20 Apr 2015 13:13:52 +0000 (09:13 -0400)
committerTom Rini <trini@konsulko.com>
Mon, 20 Apr 2015 13:13:52 +0000 (09:13 -0400)
17 files changed:
README
arch/arm/include/asm/imx-common/video.h
common/Makefile
common/lcd.c
common/lcd_console.c
common/lcd_console_rotation.c [new file with mode: 0644]
drivers/video/Makefile
drivers/video/ipu.h
drivers/video/ipu_common.c
drivers/video/lg4573.c [new file with mode: 0644]
include/atmel_lcd.h
include/exynos_lcd.h
include/lcd.h
include/lcd_console.h
include/mpc823_lcd.h
include/pxa_lcd.h
include/video.h

diff --git a/README b/README
index caba4602bc7253af33d49244e0901e791b6e8547..fc1fd52f53053268fe3bdb4d7040dffc855a53f4 100644 (file)
--- a/README
+++ b/README
@@ -1947,6 +1947,26 @@ CBFS (Coreboot Filesystem) support
                the console jump but can help speed up operation when scrolling
                is slow.
 
+               CONFIG_LCD_ROTATION
+
+               Sometimes, for example if the display is mounted in portrait
+               mode or even if it's mounted landscape but rotated by 180degree,
+               we need to rotate our content of the display relative to the
+               framebuffer, so that user can read the messages which are
+               printed out.
+               Once CONFIG_LCD_ROTATION is defined, the lcd_console will be
+               initialized with a given rotation from "vl_rot" out of
+               "vidinfo_t" which is provided by the board specific code.
+               The value for vl_rot is coded as following (matching to
+               fbcon=rotate:<n> linux-kernel commandline):
+               0 = no rotation respectively 0 degree
+               1 = 90 degree rotation
+               2 = 180 degree rotation
+               3 = 270 degree rotation
+
+               If CONFIG_LCD_ROTATION is not defined, the console will be
+               initialized with 0degree rotation.
+
                CONFIG_LCD_BMP_RLE8
 
                Support drawing of RLE8-compressed bitmaps on the LCD.
index 1a907d44e405a4a51898f9d3eab6da833101633b..cad5f861cb857ed91af00f5304c5ec7b9e73440b 100644 (file)
@@ -26,4 +26,5 @@ extern struct display_info_t const displays[];
 extern size_t display_count;
 #endif
 
+int ipu_set_ldb_clock(int rate);
 #endif
index 978c33b24e617b2ebe11c058647e4aa725c92af6..fba3830f1d2cf19788e42d09dc8ee8d124a39960 100644 (file)
@@ -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
index 6982759e9e2a34a9bd180ed27f949ccd72192ee2..055c366b191e32469c100c2d010fa9ba401526ef 100644 (file)
@@ -168,7 +168,6 @@ int drv_lcd_init(void)
 
 void lcd_clear(void)
 {
-       short console_rows, console_cols;
        int bg_color;
        char *s;
        ulong addr;
@@ -212,16 +211,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) {
@@ -237,7 +234,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();
 }
index 8bf83b90d5b1a30e4cd9eec79769d24bd42e6bee..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();
        }
 }
diff --git a/common/lcd_console_rotation.c b/common/lcd_console_rotation.c
new file mode 100644 (file)
index 0000000..7aac521
--- /dev/null
@@ -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);
+}
index 22a316b5366d7e303a719bb881491a29618e7b46..f64918e6bae41dbaead0d688fd81a1156fb31b60 100644 (file)
@@ -45,5 +45,6 @@ obj-$(CONFIG_VIDEO_TEGRA) += tegra.o
 obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
 obj-$(CONFIG_VIDEO_VESA) += vesa_fb.o
 obj-$(CONFIG_FORMIKE) += formike.o
+obj-$(CONFIG_LG4573) += lg4573.o
 obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
 obj-$(CONFIG_VIDEO_PARADE) += parade.o
index 091b58fb47bfccfa4bc30bfdd9e87006bbafa438..348be58bf6abaa729401d0db9744bdc0cf801c90 100644 (file)
@@ -265,5 +265,4 @@ int ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt,
 void ipu_dp_uninit(ipu_channel_t channel);
 void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap);
 ipu_color_space_t format_to_colorspace(uint32_t fmt);
-
 #endif
index 5873531953316a25799c020206328bd84280b97d..9f851029157624605e8ae4450432accf283f3bdc 100644 (file)
@@ -210,9 +210,13 @@ static struct clk ipu_clk = {
        .usecount = 0,
 };
 
+#if !defined CONFIG_SYS_LDB_CLOCK
+#define CONFIG_SYS_LDB_CLOCK 65000000
+#endif
+
 static struct clk ldb_clk = {
        .name = "ldb_clk",
-       .rate = 65000000,
+       .rate = CONFIG_SYS_LDB_CLOCK,
        .usecount = 0,
 };
 
@@ -1194,3 +1198,11 @@ ipu_color_space_t format_to_colorspace(uint32_t fmt)
        }
        return RGB;
 }
+
+/* should be removed when clk framework is availiable */
+int ipu_set_ldb_clock(int rate)
+{
+       ldb_clk.rate = rate;
+
+       return 0;
+}
diff --git a/drivers/video/lg4573.c b/drivers/video/lg4573.c
new file mode 100644 (file)
index 0000000..43670fc
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * LCD: LG4573, TFT 4.3", 480x800, RGB24
+ * LCD initialization via SPI
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ *
+ */
+#include <common.h>
+#include <errno.h>
+#include <spi.h>
+
+#define PWR_ON_DELAY_MSECS  120
+
+static int lb043wv_spi_write_u16(struct spi_slave *spi, u16 val)
+{
+       unsigned long flags = SPI_XFER_BEGIN;
+       unsigned short buf16 = htons(val);
+       int ret = 0;
+
+       flags |= SPI_XFER_END;
+
+       ret = spi_xfer(spi, 16, &buf16, NULL, flags);
+       if (ret)
+               debug("%s: Failed to send: %d\n", __func__, ret);
+
+       return ret;
+}
+
+static void lb043wv_spi_write_u16_array(struct spi_slave *spi, u16 *buff,
+                                       int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++)
+               lb043wv_spi_write_u16(spi, buff[i]);
+}
+
+static void lb043wv_display_mode_settings(struct spi_slave *spi)
+{
+       static u16 display_mode_settings[] = {
+         0x703A,
+         0x7270,
+         0x70B1,
+         0x7208,
+         0x723B,
+         0x720F,
+         0x70B2,
+         0x7200,
+         0x72C8,
+         0x70B3,
+         0x7200,
+         0x70B4,
+         0x7200,
+         0x70B5,
+         0x7242,
+         0x7210,
+         0x7210,
+         0x7200,
+         0x7220,
+         0x70B6,
+         0x720B,
+         0x720F,
+         0x723C,
+         0x7213,
+         0x7213,
+         0x72E8,
+         0x70B7,
+         0x7246,
+         0x7206,
+         0x720C,
+         0x7200,
+         0x7200,
+       };
+
+       debug("transfer display mode settings\n");
+       lb043wv_spi_write_u16_array(spi, display_mode_settings,
+                                   ARRAY_SIZE(display_mode_settings));
+}
+
+static void lb043wv_power_settings(struct spi_slave *spi)
+{
+       static u16 power_settings[] = {
+         0x70C0,
+         0x7201,
+         0x7211,
+         0x70C3,
+         0x7207,
+         0x7203,
+         0x7204,
+         0x7204,
+         0x7204,
+         0x70C4,
+         0x7212,
+         0x7224,
+         0x7218,
+         0x7218,
+         0x7202,
+         0x7249,
+         0x70C5,
+         0x726F,
+         0x70C6,
+         0x7241,
+         0x7263,
+       };
+
+       debug("transfer power settings\n");
+       lb043wv_spi_write_u16_array(spi, power_settings,
+                                   ARRAY_SIZE(power_settings));
+}
+
+static void lb043wv_gamma_settings(struct spi_slave *spi)
+{
+       static u16 gamma_settings[] = {
+         0x70D0,
+         0x7203,
+         0x7207,
+         0x7273,
+         0x7235,
+         0x7200,
+         0x7201,
+         0x7220,
+         0x7200,
+         0x7203,
+         0x70D1,
+         0x7203,
+         0x7207,
+         0x7273,
+         0x7235,
+         0x7200,
+         0x7201,
+         0x7220,
+         0x7200,
+         0x7203,
+         0x70D2,
+         0x7203,
+         0x7207,
+         0x7273,
+         0x7235,
+         0x7200,
+         0x7201,
+         0x7220,
+         0x7200,
+         0x7203,
+         0x70D3,
+         0x7203,
+         0x7207,
+         0x7273,
+         0x7235,
+         0x7200,
+         0x7201,
+         0x7220,
+         0x7200,
+         0x7203,
+         0x70D4,
+         0x7203,
+         0x7207,
+         0x7273,
+         0x7235,
+         0x7200,
+         0x7201,
+         0x7220,
+         0x7200,
+         0x7203,
+         0x70D5,
+         0x7203,
+         0x7207,
+         0x7273,
+         0x7235,
+         0x7200,
+         0x7201,
+         0x7220,
+         0x7200,
+         0x7203,
+       };
+
+       debug("transfer gamma settings\n");
+       lb043wv_spi_write_u16_array(spi, gamma_settings,
+                                   ARRAY_SIZE(gamma_settings));
+}
+
+static void lb043wv_display_on(struct spi_slave *spi)
+{
+       static u16 sleep_out = 0x7011;
+       static u16 display_on = 0x7029;
+
+       lb043wv_spi_write_u16(spi, sleep_out);
+       mdelay(PWR_ON_DELAY_MSECS);
+       lb043wv_spi_write_u16(spi, display_on);
+}
+
+int lg4573_spi_startup(unsigned int bus, unsigned int cs,
+       unsigned int max_hz, unsigned int spi_mode)
+{
+       struct spi_slave *spi;
+       int ret;
+
+       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+       if (!spi) {
+               debug("%s: Failed to set up slave\n", __func__);
+               return -1;
+       }
+
+       ret = spi_claim_bus(spi);
+       if (ret) {
+               debug("%s: Failed to claim SPI bus: %d\n", __func__, ret);
+               goto err_claim_bus;
+       }
+
+       lb043wv_display_mode_settings(spi);
+       lb043wv_power_settings(spi);
+       lb043wv_gamma_settings(spi);
+
+       lb043wv_display_on(spi);
+       return 0;
+err_claim_bus:
+       spi_free_slave(spi);
+       return -1;
+}
+
+static int do_lgset(cmd_tbl_t *cmdtp, int flag, int argc,
+                      char * const argv[])
+{
+       lg4573_spi_startup(0, 0, 10000000, SPI_MODE_0);
+       return 0;
+}
+
+U_BOOT_CMD(
+       lgset,  2,      1,      do_lgset,
+       "set lgdisplay",
+       ""
+);
index fa8aa294542f60e2af44a723417e6ec6183507ee..6993128b1b4c37df8d6c544cb2e06e0f220269c0 100644 (file)
@@ -13,7 +13,8 @@
 typedef struct vidinfo {
        ushort vl_col;          /* Number of columns (i.e. 640) */
        ushort vl_row;          /* Number of rows (i.e. 480) */
-       u_long vl_clk;  /* pixel clock in ps    */
+       ushort vl_rot;          /* Rotation of Display (0, 1, 2, 3) */
+       u_long vl_clk;          /* pixel clock in ps    */
 
        /* LCD configuration register */
        u_long vl_sync;         /* Horizontal / vertical sync */
index cf389dac692f603698f5639814480cebd8118b91..3969a6a06662408482aa06b521a5a619ef8ffa16 100644 (file)
@@ -25,6 +25,7 @@ enum exynos_fb_rgb_mode_t {
 typedef struct vidinfo {
        ushort vl_col;          /* Number of columns (i.e. 640) */
        ushort vl_row;          /* Number of rows (i.e. 480) */
+       ushort vl_rot;          /* Rotation of Display (0, 1, 2, 3) */
        ushort vl_width;        /* Width of display area in millimeters */
        ushort vl_height;       /* Height of display area in millimeters */
 
index f049fd3489e201fbd0f275930bc59729668b1b0b..59202b7e59de8ddf7f4fb4321bf1886b47a7d2fd 100644 (file)
@@ -51,6 +51,7 @@ void lcd_set_flush_dcache(int flush);
 typedef struct vidinfo {
        ushort  vl_col;         /* Number of columns (i.e. 160) */
        ushort  vl_row;         /* Number of rows (i.e. 100) */
+       ushort  vl_rot;         /* Rotation of Display (0, 1, 2, 3) */
        u_char  vl_bpix;        /* Bits per pixel, 0 = 1 */
        ushort  *cmap;          /* Pointer to the colormap */
        void    *priv;          /* Pointer to driver-specific data */
@@ -196,6 +197,14 @@ void lcd_sync(void);
 #define CONSOLE_COLOR_WHITE    0xffff          /* Must remain last / highest */
 #endif /* color definitions */
 
+#if LCD_BPP == LCD_COLOR16
+#define fbptr_t ushort
+#elif LCD_BPP == LCD_COLOR32
+#define fbptr_t u32
+#else
+#define fbptr_t uchar
+#endif
+
 #ifndef PAGE_SIZE
 #define PAGE_SIZE      4096
 #endif
index 429214df80943ebf142a326ac1e2221dbec911ae..2e0f56f9903a24259c18b58e151206cd02fda941 100644 (file)
@@ -9,6 +9,26 @@
 #define CONFIG_CONSOLE_SCROLL_LINES 1
 #endif
 
+struct console_t {
+       short curr_col, curr_row;
+       short cols, rows;
+       void *fbbase;
+       u32 lcdsizex, lcdsizey, lcdrot;
+       void (*fp_putc_xy)(struct console_t *pcons, ushort x, ushort y, char c);
+       void (*fp_console_moverow)(struct console_t *pcons,
+                                  u32 rowdst, u32 rowsrc);
+       void (*fp_console_setrow)(struct console_t *pcons, u32 row, int clr);
+};
+
+/**
+ * console_calc_rowcol() - calculate available rows / columns wihtin a given
+ * screen-size based on used VIDEO_FONT.
+ *
+ * @pcons: Pointer to struct console_t
+ * @sizex: size X of the screen in pixel
+ * @sizey: size Y of the screen in pixel
+ */
+void console_calc_rowcol(struct console_t *pcons, u32 sizex, u32 sizey);
 /**
  * lcd_init_console() - Initialize lcd console parameters
  *
  * console has.
  *
  * @address: Console base address
- * @rows: Number of rows in the console
- * @cols: Number of columns in the console
+ * @vl_rows: Number of rows in the console
+ * @vl_cols: Number of columns in the console
+ * @vl_rot: Rotation of display in degree (0 - 90 - 180 - 270) counterlockwise
  */
-void lcd_init_console(void *address, int rows, int cols);
-
+void lcd_init_console(void *address, int vl_cols, int vl_rows, int vl_rot);
 /**
  * lcd_set_col() - Set the number of the current lcd console column
  *
index 7e210e329602f09515d0d1d0b8e0405760ee3596..cc72cde13f05ae69caeb06fd2679294d03982bc9 100644 (file)
@@ -16,6 +16,7 @@
 typedef struct vidinfo {
        ushort  vl_col;         /* Number of columns (i.e. 640) */
        ushort  vl_row;         /* Number of rows (i.e. 480) */
+       ushort  vl_rot;         /* Rotation of Display (0, 1, 2, 3) */
        ushort  vl_width;       /* Width of display area in millimeters */
        ushort  vl_height;      /* Height of display area in millimeters */
 
index 723f6ab76670e4a0a229f831a00b84821aaf2eda..1ea3717bf74283fcd53ab476318505324b7104b8 100644 (file)
@@ -48,6 +48,7 @@ struct pxafb_info {
 typedef struct vidinfo {
        ushort  vl_col;         /* Number of columns (i.e. 640) */
        ushort  vl_row;         /* Number of rows (i.e. 480) */
+       ushort  vl_rot;         /* Rotation of Display (0, 1, 2, 3) */
        ushort  vl_width;       /* Width of display area in millimeters */
        ushort  vl_height;      /* Height of display area in millimeters */
 
index 673aa2ec56fb4ef8cb5379472f00e4a8d2b6b193..65e4ec1e1a3df81ed83562914b902a18530b6fe3 100644 (file)
@@ -69,4 +69,8 @@ void video_clear(void);
 int kwh043st20_f01_spi_startup(unsigned int bus, unsigned int cs,
        unsigned int max_hz, unsigned int spi_mode);
 #endif
+#if defined(CONFIG_LG4573)
+int lg4573_spi_startup(unsigned int bus, unsigned int cs,
+       unsigned int max_hz, unsigned int spi_mode);
+#endif
 #endif