All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation
@ 2015-03-27  7:01 Hannes Petermaier
  2015-03-27  7:01 ` [U-Boot] [PATCH v4 1/4] common/lcd_console: cleanup lcd_drawchars/lcd_putc_xy Hannes Petermaier
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Hannes Petermaier @ 2015-03-27  7:01 UTC (permalink / raw)
  To: u-boot

Sometimes, for example if the display is mounted in portrait mode or even if it
mounted landscape but rotated by 180 degree, we need to rotate our content of
the display respectively the framebuffer, so that user can read the messages who
are printed out.

For this we introduce the feature called "CONFIG_LCD_ROTATION", this may be
defined in the board-configuration if needed. After this 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
0 degrees rotation.

Patch 1-3 make preparations to the code.
Patch 4 implements the new feature

Changes in v4:
- cosmetic changes to README
- avoid code-duplication (reuse console_calc_rowcol within rotation code).

Changes in v3:
- rename lcd_address to fbbase for better readability.
- remove empty line lcd_console.c
- use printf instead puts to inform about invalid-fb rotation.
- avoid code-duplication (move define of fbptr_t into lcd.h)

Changes in v2:
- cleanup README text for feature
- don't make code cleanups (lcd_console.c) within this patch
- remove (unnary) comment in lcd_console.h
- update year to 2015 within copyright in lcd_console.c
- move rotation related code into separate file lcd_console_rotation.c
- rework rotation code
- change meaning of vl_rot to match fbcon=rotate:<n> from the linux-kernel

Hannes Petermaier (4):
  common/lcd_console: cleanup lcd_drawchars/lcd_putc_xy
  common/lcd_console: ask only one-time for bg/fg-color per call
  common/lcd_console: move single static variables into common (static)
    structure
  common/lcd_console: introduce display/framebuffer rotation

 README                        |   20 +++++
 common/Makefile               |    1 +
 common/lcd.c                  |   15 ++--
 common/lcd_console.c          |  200 +++++++++++++++++++++--------------------
 common/lcd_console_rotation.c |  195 ++++++++++++++++++++++++++++++++++++++++
 include/lcd.h                 |    9 ++
 include/lcd_console.h         |   28 +++++-
 7 files changed, 358 insertions(+), 110 deletions(-)
 create mode 100644 common/lcd_console_rotation.c

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v4 1/4] common/lcd_console: cleanup lcd_drawchars/lcd_putc_xy
  2015-03-27  7:01 [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
@ 2015-03-27  7:01 ` Hannes Petermaier
  2015-03-27  7:01 ` [U-Boot] [PATCH v4 2/4] common/lcd_console: ask only one-time for bg/fg-color per call Hannes Petermaier
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Hannes Petermaier @ 2015-03-27  7:01 UTC (permalink / raw)
  To: u-boot

From: Hannes Petermaier <hannes.petermaier@br-automation.com>

the capability of drawing some *str with count from lcd_drawchars is unnary.
It is always called from lcd_putc_xy with one character of and count = 1.

So we simply rename lcd_drawchars into lcd_putc_xy and remove the loops inside.

Signed-off-by: Hannes Petermaier <hannes.petermaier@br-automation.com>
Signed-off-by: Hannes Petermaier <oe5hpm@oevsv.at>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 common/lcd_console.c |   23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/common/lcd_console.c b/common/lcd_console.c
index 8bf83b9..243b7c5 100644
--- a/common/lcd_console.c
+++ b/common/lcd_console.c
@@ -55,18 +55,17 @@ int lcd_get_screen_columns(void)
 	return console_cols;
 }
 
-static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
+static void lcd_putc_xy(ushort x, ushort y, char c)
 {
 	uchar *dest;
 	ushort row;
 	int fg_color, bg_color;
+	int i;
 
 	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
@@ -77,25 +76,17 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
 
 		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];
+		uchar bits;
+		bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
 
-			for (c = 0; c < 8; ++c) {
-				*d++ = (bits & 0x80) ? fg_color : bg_color;
-				bits <<= 1;
-			}
+		for (i = 0; i < 8; ++i) {
+			*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;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v4 2/4] common/lcd_console: ask only one-time for bg/fg-color per call
  2015-03-27  7:01 [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
  2015-03-27  7:01 ` [U-Boot] [PATCH v4 1/4] common/lcd_console: cleanup lcd_drawchars/lcd_putc_xy Hannes Petermaier
@ 2015-03-27  7:01 ` Hannes Petermaier
  2015-03-27  7:01 ` [U-Boot] [PATCH v4 3/4] common/lcd_console: move single static variables into common (static) structure Hannes Petermaier
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Hannes Petermaier @ 2015-03-27  7:01 UTC (permalink / raw)
  To: u-boot

From: Hannes Petermaier <hannes.petermaier@br-automation.com>

Don't call the lcd_getfgcolor and lcd_getbgcolor within the "draw-loop", this
only wastes time.

Signed-off-by: Hannes Petermaier <hannes.petermaier@br-automation.com>
Signed-off-by: Hannes Petermaier <oe5hpm@oevsv.at>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 common/lcd_console.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/common/lcd_console.c b/common/lcd_console.c
index 243b7c5..b7dda7a 100644
--- a/common/lcd_console.c
+++ b/common/lcd_console.c
@@ -59,7 +59,8 @@ static void lcd_putc_xy(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;
 
 	dest = (uchar *)(lcd_console_address +
@@ -73,10 +74,6 @@ static void lcd_putc_xy(ushort x, ushort y, char c)
 #else
 		uchar *d = dest;
 #endif
-
-		fg_color = lcd_getfgcolor();
-		bg_color = lcd_getbgcolor();
-
 		uchar bits;
 		bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v4 3/4] common/lcd_console: move single static variables into common (static) structure
  2015-03-27  7:01 [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
  2015-03-27  7:01 ` [U-Boot] [PATCH v4 1/4] common/lcd_console: cleanup lcd_drawchars/lcd_putc_xy Hannes Petermaier
  2015-03-27  7:01 ` [U-Boot] [PATCH v4 2/4] common/lcd_console: ask only one-time for bg/fg-color per call Hannes Petermaier
@ 2015-03-27  7:01 ` Hannes Petermaier
  2015-03-27  7:01 ` [U-Boot] [PATCH v4 4/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Hannes Petermaier @ 2015-03-27  7:01 UTC (permalink / raw)
  To: u-boot

From: Hannes Petermaier <hannes.petermaier@br-automation.com>

For coming implementation of lcd_console rotation, we will need some more
variables for holding information about framebuffer size, rotation, ...

For better readability we catch all them into a common structure.

Signed-off-by: Hannes Petermaier <hannes.petermaier@br-automation.com>
Signed-off-by: Hannes Petermaier <oe5hpm@oevsv.at>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 common/lcd_console.c |   76 +++++++++++++++++++++++++-------------------------
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/common/lcd_console.c b/common/lcd_console.c
index b7dda7a..cac77be 100644
--- a/common/lcd_console.c
+++ b/common/lcd_console.c
@@ -11,48 +11,49 @@
 #include <video_font.h>		/* Get font data, width and height */
 
 #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)
+#define CONSOLE_ROW_FIRST	cons.lcd_address
+#define CONSOLE_SIZE		(CONSOLE_ROW_SIZE * cons.rows)
 
-static short console_curr_col;
-static short console_curr_row;
-static short console_cols;
-static short console_rows;
-static void *lcd_console_address;
+struct console_t {
+	short curr_col, curr_row;
+	short cols, rows;
+	void *lcd_address;
+};
+static struct console_t cons;
 
 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;
+	memset(&cons, 0, sizeof(cons));
+	cons.cols = cols;
+	cons.rows = rows;
+	cons.lcd_address = address;
+
 }
 
 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_putc_xy(ushort x, ushort y, char c)
@@ -63,7 +64,7 @@ static void lcd_putc_xy(ushort x, ushort y, char c)
 	int bg_color = lcd_getbgcolor();
 	int i;
 
-	dest = (uchar *)(lcd_console_address +
+	dest = (uchar *)(cons.lcd_address +
 			 y * lcd_line_length + x * NBITS(LCD_BPP) / 8);
 
 	for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
@@ -91,7 +92,7 @@ static void console_scrollup(void)
 
 	/* Copy up rows ignoring those that will be overwritten */
 	memcpy(CONSOLE_ROW_FIRST,
-	       lcd_console_address + CONSOLE_ROW_SIZE * rows,
+	       cons.lcd_address + CONSOLE_ROW_SIZE * rows,
 	       CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
 
 	/* Clear the last rows */
@@ -99,7 +100,7 @@ static void console_scrollup(void)
 	memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
 	       bg_color, CONSOLE_ROW_SIZE * rows);
 #else
-	u32 *ppix = lcd_console_address +
+	u32 *ppix = cons.lcd_address +
 		    CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
 	u32 i;
 	for (i = 0;
@@ -109,27 +110,27 @@ static void console_scrollup(void)
 	}
 #endif
 	lcd_sync();
-	console_curr_row -= rows;
+	cons.curr_row -= rows;
 }
 
 static inline void console_back(void)
 {
-	if (--console_curr_col < 0) {
-		console_curr_col = console_cols - 1;
-		if (--console_curr_row < 0)
-			console_curr_row = 0;
+	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, ' ');
+	lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH,
+		    cons.curr_row * VIDEO_FONT_HEIGHT, ' ');
 }
 
 static inline void console_newline(void)
 {
-	console_curr_col = 0;
+	cons.curr_col = 0;
 
 	/* Check if we need to scroll the terminal */
-	if (++console_curr_row >= console_rows)
+	if (++cons.curr_row >= cons.rows)
 		console_scrollup();
 	else
 		lcd_sync();
@@ -145,18 +146,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;
@@ -165,9 +165,9 @@ 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)
+		lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH,
+			    cons.curr_row * VIDEO_FONT_HEIGHT, c);
+		if (++cons.curr_col >= cons.cols)
 			console_newline();
 	}
 }
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v4 4/4] common/lcd_console: introduce display/framebuffer rotation
  2015-03-27  7:01 [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
                   ` (2 preceding siblings ...)
  2015-03-27  7:01 ` [U-Boot] [PATCH v4 3/4] common/lcd_console: move single static variables into common (static) structure Hannes Petermaier
@ 2015-03-27  7:01 ` Hannes Petermaier
  2015-03-30 10:48 ` [U-Boot] [PATCH v4 0/4] " Nikita Kiryanov
  2015-04-18 17:03 ` Anatolij Gustschin
  5 siblings, 0 replies; 7+ messages in thread
From: Hannes Petermaier @ 2015-03-27  7:01 UTC (permalink / raw)
  To: u-boot

From: Hannes Petermaier <hannes.petermaier@br-automation.com>

Sometimes, for example if the display is mounted in portrait mode or even if it
mounted landscape but rotated by 180 degrees, we need to rotate our content of
the display respectively the framebuffer, so that user can read the messages
who are printed out.

For this we introduce the feature called "CONFIG_LCD_ROTATION", this may be
defined in the board-configuration if needed. After this 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.

If CONFIG_LCD_ROTATION is not defined, the console will be initialized with
0 degrees rotation.

Signed-off-by: Hannes Petermaier <hannes.petermaier@br-automation.com>
Signed-off-by: Hannes Petermaier <oe5hpm@oevsv.at>
---

Changes in v4:
- cosmetic changes to README
- avoid code-duplication (reuse console_calc_rowcol within rotation code).

Changes in v3:
- rename lcd_address to fbbase for better readability.
- remove empty line lcd_console.c
- use printf instead puts to inform about invalid-fb rotation.
- avoid code-duplication (move define of fbptr_t into lcd.h)

Changes in v2:
- cleanup README text for feature
- don't make code cleanups (lcd_console.c) within this patch
- remove (unnary) comment in lcd_console.h
- update year to 2015 within copyright in lcd_console.c
- move rotation related code into separate file lcd_console_rotation.c
- rework rotation code
- change meaning of vl_rot to match fbcon=rotate:<n> from the linux-kernel

 README                        |   20 +++++
 common/Makefile               |    1 +
 common/lcd.c                  |   15 ++--
 common/lcd_console.c          |  160 ++++++++++++++++++---------------
 common/lcd_console_rotation.c |  195 +++++++++++++++++++++++++++++++++++++++++
 include/lcd.h                 |    9 ++
 include/lcd_console.h         |   28 +++++-
 7 files changed, 344 insertions(+), 84 deletions(-)
 create mode 100644 common/lcd_console_rotation.c

diff --git a/README b/README
index b0124d6..317c380 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/common/Makefile b/common/Makefile
index 7216a13..a1b3c09 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -200,6 +200,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 f33942c..d1b4ca7 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -167,7 +167,6 @@ int drv_lcd_init(void)
 
 void lcd_clear(void)
 {
-	short console_rows, console_cols;
 	int bg_color;
 	char *s;
 	ulong addr;
@@ -211,16 +210,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) {
diff --git a/common/lcd_console.c b/common/lcd_console.c
index cac77be..7d3f00f 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 at denx.de
  * Compulab Ltd - http://compulab.co.il/
+ * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -10,26 +11,8 @@
 #include <lcd.h>
 #include <video_font.h>		/* Get font data, width and height */
 
-#define CONSOLE_ROW_SIZE	(VIDEO_FONT_HEIGHT * lcd_line_length)
-#define CONSOLE_ROW_FIRST	cons.lcd_address
-#define CONSOLE_SIZE		(CONSOLE_ROW_SIZE * cons.rows)
-
-struct console_t {
-	short curr_col, curr_row;
-	short cols, rows;
-	void *lcd_address;
-};
 static struct console_t cons;
 
-void lcd_init_console(void *address, int rows, int cols)
-{
-	memset(&cons, 0, sizeof(cons));
-	cons.cols = cols;
-	cons.rows = rows;
-	cons.lcd_address = address;
-
-}
-
 void lcd_set_col(short col)
 {
 	cons.curr_col = col;
@@ -56,61 +39,50 @@ int lcd_get_screen_columns(void)
 	return cons.cols;
 }
 
-static void lcd_putc_xy(ushort x, ushort y, char c)
+static void lcd_putc_xy0(struct console_t *pcons, ushort x, ushort y, char c)
 {
-	uchar *dest;
-	ushort row;
 	int fg_color = lcd_getfgcolor();
 	int bg_color = lcd_getbgcolor();
-	int i;
-
-	dest = (uchar *)(cons.lcd_address +
-			 y * lcd_line_length + x * NBITS(LCD_BPP) / 8);
-
-	for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
-#if LCD_BPP == LCD_COLOR16
-		ushort *d = (ushort *)dest;
-#elif LCD_BPP == LCD_COLOR32
-		u32 *d = (u32 *)dest;
-#else
-		uchar *d = dest;
-#endif
-		uchar bits;
-		bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
-
-		for (i = 0; i < 8; ++i) {
-			*d++ = (bits & 0x80) ? fg_color : bg_color;
+	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);
 	}
 }
 
-static void console_scrollup(void)
+static inline void console_setrow0(struct console_t *pcons, u32 row, int clr)
 {
-	const int rows = CONFIG_CONSOLE_SCROLL_LINES;
-	int bg_color = lcd_getbgcolor();
+	int i;
+	fbptr_t *dst = (fbptr_t *)pcons->fbbase +
+				  row * VIDEO_FONT_HEIGHT *
+				  pcons->lcdsizex;
 
-	/* Copy up rows ignoring those that will be overwritten */
-	memcpy(CONSOLE_ROW_FIRST,
-	       cons.lcd_address + CONSOLE_ROW_SIZE * rows,
-	       CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
+	for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
+		*dst++ = clr;
+}
 
-	/* 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 = cons.lcd_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;
-	}
-#endif
-	lcd_sync();
-	cons.curr_row -= rows;
+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)
@@ -121,19 +93,64 @@ static inline void console_back(void)
 			cons.curr_row = 0;
 	}
 
-	lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH,
-		    cons.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)
 {
+	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 (++cons.curr_row >= cons.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)
@@ -165,8 +182,9 @@ void lcd_putc(const char c)
 
 		return;
 	default:
-		lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH,
-			    cons.curr_row * VIDEO_FONT_HEIGHT, c);
+		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 0000000..7aac521
--- /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/include/lcd.h b/include/lcd.h
index f049fd3..59202b7 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 429214d..2e0f56f 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
  *
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation
  2015-03-27  7:01 [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
                   ` (3 preceding siblings ...)
  2015-03-27  7:01 ` [U-Boot] [PATCH v4 4/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
@ 2015-03-30 10:48 ` Nikita Kiryanov
  2015-04-18 17:03 ` Anatolij Gustschin
  5 siblings, 0 replies; 7+ messages in thread
From: Nikita Kiryanov @ 2015-03-30 10:48 UTC (permalink / raw)
  To: u-boot

On 03/27/2015 10:01 AM, Hannes Petermaier wrote:
> Sometimes, for example if the display is mounted in portrait mode or even if it
> mounted landscape but rotated by 180 degree, we need to rotate our content of
> the display respectively the framebuffer, so that user can read the messages who
> are printed out.
>
> For this we introduce the feature called "CONFIG_LCD_ROTATION", this may be
> defined in the board-configuration if needed. After this 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
> 0 degrees rotation.
>
> Patch 1-3 make preparations to the code.
> Patch 4 implements the new feature
>

Whole series:
Acked-by: Nikita Kiryanov <nikita@compulab.co.il>

-- 
Regards,
Nikita Kiryanov

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation
  2015-03-27  7:01 [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
                   ` (4 preceding siblings ...)
  2015-03-30 10:48 ` [U-Boot] [PATCH v4 0/4] " Nikita Kiryanov
@ 2015-04-18 17:03 ` Anatolij Gustschin
  5 siblings, 0 replies; 7+ messages in thread
From: Anatolij Gustschin @ 2015-04-18 17:03 UTC (permalink / raw)
  To: u-boot

On Fri, 27 Mar 2015 08:01:34 +0100
Hannes Petermaier <oe5hpm@oevsv.at> wrote:
...
> Hannes Petermaier (4):
>   common/lcd_console: cleanup lcd_drawchars/lcd_putc_xy
>   common/lcd_console: ask only one-time for bg/fg-color per call
>   common/lcd_console: move single static variables into common (static)
>     structure
>   common/lcd_console: introduce display/framebuffer rotation
> 
>  README                        |   20 +++++
>  common/Makefile               |    1 +
>  common/lcd.c                  |   15 ++--
>  common/lcd_console.c          |  200 +++++++++++++++++++++--------------------
>  common/lcd_console_rotation.c |  195 ++++++++++++++++++++++++++++++++++++++++
>  include/lcd.h                 |    9 ++
>  include/lcd_console.h         |   28 +++++-
>  7 files changed, 358 insertions(+), 110 deletions(-)
>  create mode 100644 common/lcd_console_rotation.c

series applied after fixing build issues with some boards.

Thanks,

Anatolij

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-04-18 17:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-27  7:01 [U-Boot] [PATCH v4 0/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
2015-03-27  7:01 ` [U-Boot] [PATCH v4 1/4] common/lcd_console: cleanup lcd_drawchars/lcd_putc_xy Hannes Petermaier
2015-03-27  7:01 ` [U-Boot] [PATCH v4 2/4] common/lcd_console: ask only one-time for bg/fg-color per call Hannes Petermaier
2015-03-27  7:01 ` [U-Boot] [PATCH v4 3/4] common/lcd_console: move single static variables into common (static) structure Hannes Petermaier
2015-03-27  7:01 ` [U-Boot] [PATCH v4 4/4] common/lcd_console: introduce display/framebuffer rotation Hannes Petermaier
2015-03-30 10:48 ` [U-Boot] [PATCH v4 0/4] " Nikita Kiryanov
2015-04-18 17:03 ` Anatolij Gustschin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.