summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2015-04-20 09:13:52 -0400
committerTom Rini <trini@konsulko.com>2015-04-20 09:13:52 -0400
commit1733259d25015c28c47990ec11af99b3f62f811c (patch)
tree654c376440e5b01603e88dc22047d657f635def7
parent791a9f67f4f8db512cf59b40f47544fb335cd8db (diff)
parentfc1a79d95e9038e9cf53f99c1825005b4dfaf7f4 (diff)
downloadblackbird-obmc-uboot-1733259d25015c28c47990ec11af99b3f62f811c.tar.gz
blackbird-obmc-uboot-1733259d25015c28c47990ec11af99b3f62f811c.zip
Merge branch 'master' of git://git.denx.de/u-boot-video
-rw-r--r--README20
-rw-r--r--arch/arm/include/asm/imx-common/video.h1
-rw-r--r--common/Makefile1
-rw-r--r--common/lcd.c18
-rw-r--r--common/lcd_console.c203
-rw-r--r--common/lcd_console_rotation.c195
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/ipu.h1
-rw-r--r--drivers/video/ipu_common.c14
-rw-r--r--drivers/video/lg4573.c231
-rw-r--r--include/atmel_lcd.h3
-rw-r--r--include/exynos_lcd.h1
-rw-r--r--include/lcd.h9
-rw-r--r--include/lcd_console.h28
-rw-r--r--include/mpc823_lcd.h1
-rw-r--r--include/pxa_lcd.h1
-rw-r--r--include/video.h4
17 files changed, 618 insertions, 114 deletions
diff --git a/README b/README
index caba4602bc..fc1fd52f53 100644
--- 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.
diff --git a/arch/arm/include/asm/imx-common/video.h b/arch/arm/include/asm/imx-common/video.h
index 1a907d44e4..cad5f861cb 100644
--- a/arch/arm/include/asm/imx-common/video.h
+++ b/arch/arm/include/asm/imx-common/video.h
@@ -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
diff --git a/common/Makefile b/common/Makefile
index 978c33b24e..fba3830f1d 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 6982759e9e..055c366b19 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -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();
}
diff --git a/common/lcd_console.c b/common/lcd_console.c
index 8bf83b90d5..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,142 +10,150 @@
#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
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);
+}
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 22a316b536..f64918e6ba 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -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
diff --git a/drivers/video/ipu.h b/drivers/video/ipu.h
index 091b58fb47..348be58bf6 100644
--- a/drivers/video/ipu.h
+++ b/drivers/video/ipu.h
@@ -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
diff --git a/drivers/video/ipu_common.c b/drivers/video/ipu_common.c
index 5873531953..9f85102915 100644
--- a/drivers/video/ipu_common.c
+++ b/drivers/video/ipu_common.c
@@ -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
index 0000000000..43670fc320
--- /dev/null
+++ b/drivers/video/lg4573.c
@@ -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",
+ ""
+);
diff --git a/include/atmel_lcd.h b/include/atmel_lcd.h
index fa8aa29454..6993128b1b 100644
--- a/include/atmel_lcd.h
+++ b/include/atmel_lcd.h
@@ -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 */
diff --git a/include/exynos_lcd.h b/include/exynos_lcd.h
index cf389dac69..3969a6a066 100644
--- a/include/exynos_lcd.h
+++ b/include/exynos_lcd.h
@@ -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 */
diff --git a/include/lcd.h b/include/lcd.h
index f049fd3489..59202b7e59 100644
--- a/include/lcd.h
+++ b/include/lcd.h
@@ -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
diff --git a/include/lcd_console.h b/include/lcd_console.h
index 429214df80..2e0f56f990 100644
--- a/include/lcd_console.h
+++ b/include/lcd_console.h
@@ -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
*
@@ -16,11 +36,11 @@
* 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
*
diff --git a/include/mpc823_lcd.h b/include/mpc823_lcd.h
index 7e210e3296..cc72cde13f 100644
--- a/include/mpc823_lcd.h
+++ b/include/mpc823_lcd.h
@@ -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 */
diff --git a/include/pxa_lcd.h b/include/pxa_lcd.h
index 723f6ab766..1ea3717bf7 100644
--- a/include/pxa_lcd.h
+++ b/include/pxa_lcd.h
@@ -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 */
diff --git a/include/video.h b/include/video.h
index 673aa2ec56..65e4ec1e1a 100644
--- a/include/video.h
+++ b/include/video.h
@@ -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
OpenPOWER on IntegriCloud