mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-24 04:34:22 +08:00
Merge branch 'master' of git://git.denx.de/u-boot-video
This commit is contained in:
commit
1733259d25
20
README
20
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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
18
common/lcd.c
18
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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
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
|
||||
|
||||
fg_color = lcd_getfgcolor();
|
||||
bg_color = lcd_getbgcolor();
|
||||
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) ? fg_color : bg_color;
|
||||
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;
|
||||
int fg_color = lcd_getfgcolor();
|
||||
int bg_color = lcd_getbgcolor();
|
||||
int i, row;
|
||||
fbptr_t *dst = (fbptr_t *)pcons->fbbase +
|
||||
y * pcons->lcdsizex +
|
||||
x;
|
||||
|
||||
/* 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,
|
||||
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;
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
lcd_sync();
|
||||
console_curr_row -= rows;
|
||||
}
|
||||
|
||||
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 (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
|
||||
*dst++ = clr;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (--console_curr_col < 0) {
|
||||
console_curr_col = console_cols - 1;
|
||||
if (--console_curr_row < 0)
|
||||
console_curr_row = 0;
|
||||
if (--cons.curr_col < 0) {
|
||||
cons.curr_col = cons.cols - 1;
|
||||
if (--cons.curr_row < 0)
|
||||
cons.curr_row = 0;
|
||||
}
|
||||
|
||||
lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
|
||||
console_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)
|
||||
{
|
||||
console_curr_col = 0;
|
||||
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 (++console_curr_row >= console_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)
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
195
common/lcd_console_rotation.c
Normal file
195
common/lcd_console_rotation.c
Normal file
@ -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);
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
231
drivers/video/lg4573.c
Normal file
231
drivers/video/lg4573.c
Normal file
@ -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",
|
||||
""
|
||||
);
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user