All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/26] x86: video: Speed up the framebuffer
@ 2020-05-25  1:48 Simon Glass
  2020-05-25  1:48 ` [PATCH v2 01/26] x86: fsp: Reinit the FPU after FSP meminit Simon Glass
                   ` (25 more replies)
  0 siblings, 26 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Some architectures use a cached framebuffer and flush the cache as needed
so that changes are visible. This is supported by U-Boot.

However x86 uses an uncached framebuffer with a 'write-combining' feature
to speed up writes. Reads are permitted but they are extremely expensive.

Unfortunately, reading from the frame buffer is quite common, e.g. to
scroll it. This makes scrolling very slow.

This series adds a new feature which supports copying modified parts of
the frame buffer to the uncached hardware buffer. This speeds up scrolling
dramatically on x86 so the extra complexity cost seems worth it.

In an extreme case, the time to print the environment on minnowboard with
1280x1024 and CONFIG_CONSOLE_SCROLL_LINES disabled is reduced
significantly, from 13 seconds to 300ms.

Changes in v2:
- Simplify return sequence in vidconsole_memmove() since there is no logging

Simon Glass (26):
  x86: fsp: Reinit the FPU after FSP meminit
  console: Add a way to output to serial only
  video: Show an error when a vidconsole function fails
  sandbox: video: Allow selection of rotated console
  video: Split out expression parts into variables
  video: Adjust rotated console to start at right edge
  video: Drop unnecessary #ifdef around vid_console_color()
  video: Add a comment for struct video_uc_platdata
  video: Add support for copying to a hardware framebuffer
  video: Set up the copy framebuffer when enabled
  video: Clear the copy framebuffer when clearing the screen
  video: Add helpers for vidconsole for the copy framebuffer
  video: Update normal console to support copy buffer
  video: Update truetype console to support copy buffer
  video: Update rotated console to support copy buffer
  video: Update the copy framebuffer when writing bitmaps
  video: Add comments to struct sandbox_sdl_plat
  video: sandbox: Add support for the copy framebuffer
  video: pci: Set up the copy framebuffer
  x86: fsp: video: Allocate a frame buffer when needed
  video: Correctly handle multiple framebuffers
  x86: video: Support copy framebuffer with probed devices
  chromebook_samus: Enable the copy framebuffer
  chromebook_link: Enable the copy framebuffer
  minnowmax: Enable the copy framebuffer
  x86: minnowmax: Drop screen resolution to 1024x768

 arch/x86/cpu/i386/cpu.c            |   5 ++
 arch/x86/include/asm/u-boot-x86.h  |   8 +++
 arch/x86/lib/fsp/fsp_graphics.c    |  12 ++++
 arch/x86/lib/fsp2/fsp_meminit.c    |   1 +
 common/console.c                   |  28 ++++++--
 configs/chromebook_link_defconfig  |   2 +-
 configs/chromebook_samus_defconfig |   2 +-
 configs/minnowmax_defconfig        |   4 +-
 configs/sandbox_defconfig          |   1 +
 drivers/pci/pci_rom.c              |  22 +++++-
 drivers/video/Kconfig              |  31 +++++++++
 drivers/video/broadwell_igd.c      |  16 ++++-
 drivers/video/console_normal.c     |  26 +++++++-
 drivers/video/console_rotate.c     | 103 ++++++++++++++++++++---------
 drivers/video/console_truetype.c   |  43 ++++++++----
 drivers/video/ivybridge_igd.c      |  26 ++++++--
 drivers/video/sandbox_sdl.c        |  10 ++-
 drivers/video/vesa.c               |  30 ++++++++-
 drivers/video/vidconsole-uclass.c  |  40 ++++++++++-
 drivers/video/video-uclass.c       |  93 +++++++++++++++++++++++++-
 drivers/video/video_bmp.c          |  16 ++++-
 include/console.h                  |  13 ++++
 include/dm/test.h                  |  14 +++-
 include/video.h                    |  41 ++++++++++++
 include/video_console.h            |  51 +++++++++++++-
 test/dm/video.c                    |  60 ++++++++++-------
 26 files changed, 596 insertions(+), 102 deletions(-)

-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 01/26] x86: fsp: Reinit the FPU after FSP meminit
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 02/26] console: Add a way to output to serial only Simon Glass
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

The APL FSP appears to leave the FPU in a bad state in that it has
registers in use. This causes an error when the next FPU operation is
performed.

Work around this by re-resetting the FPU after calling FSP-M. This allows
the freetype console to work correctly.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/x86/cpu/i386/cpu.c           | 5 +++++
 arch/x86/include/asm/u-boot-x86.h | 8 ++++++++
 arch/x86/lib/fsp2/fsp_meminit.c   | 1 +
 3 files changed, 14 insertions(+)

diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index 435e50edad..d27324cb4e 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -363,6 +363,11 @@ static void setup_cpu_features(void)
 	: : "i" (em_rst), "i" (mp_ne_set) : "eax");
 }
 
+void cpu_reinit_fpu(void)
+{
+	asm ("fninit\n");
+}
+
 static void setup_identity(void)
 {
 	/* identify CPU via cpuid and store the decoded info into gd->arch */
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index 3e5d56d075..bd3f44014c 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -43,6 +43,14 @@ int x86_cpu_reinit_f(void);
  */
 int x86_cpu_init_tpl(void);
 
+/**
+ * cpu_reinit_fpu() - Reinit the FPU if something is wrong with it
+ *
+ * The FSP-M code can leave registers in use in the FPU. This functions reinits
+ * it so that the FPU can be used safely
+ */
+void cpu_reinit_fpu(void);
+
 int cpu_init_f(void);
 void setup_gdt(struct global_data *id, u64 *gdt_addr);
 /*
diff --git a/arch/x86/lib/fsp2/fsp_meminit.c b/arch/x86/lib/fsp2/fsp_meminit.c
index 1a758147b0..faf9c29aef 100644
--- a/arch/x86/lib/fsp2/fsp_meminit.c
+++ b/arch/x86/lib/fsp2/fsp_meminit.c
@@ -85,6 +85,7 @@ int fsp_memory_init(bool s3wake, bool use_spi_flash)
 	func = (fsp_memory_init_func)(hdr->img_base + hdr->fsp_mem_init);
 	ret = func(&upd, &hob);
 	bootstage_accum(BOOTSTAGE_ID_ACCUM_FSP_M);
+	cpu_reinit_fpu();
 	if (ret)
 		return log_msg_ret("SDRAM init fail\n", ret);
 
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 02/26] console: Add a way to output to serial only
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
  2020-05-25  1:48 ` [PATCH v2 01/26] x86: fsp: Reinit the FPU after FSP meminit Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 03/26] video: Show an error when a vidconsole function fails Simon Glass
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

In the video drivers it is useful to print errors while debugging but
doing so risks an infinite loop as the debugging info itself may go
through the video drivers.

Add a new console function that prints information only to the serial
device, thus making it safe for use in debugging.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/console.c  | 28 ++++++++++++++++++++++------
 include/console.h | 13 +++++++++++++
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/common/console.c b/common/console.c
index 1deca3cb78..31f46470d2 100644
--- a/common/console.c
+++ b/common/console.c
@@ -229,18 +229,34 @@ static void console_putc(int file, const char c)
 	}
 }
 
-static void console_puts_noserial(int file, const char *s)
+/**
+ * console_puts_select() - Output a string to all console devices
+ *
+ * @file: File number to output to (e,g, stdout, see stdio.h)
+ * @serial_only: true to output only to serial, false to output to everything
+ *	else
+ * @s: String to output
+ */
+static void console_puts_select(int file, bool serial_only, const char *s)
 {
 	int i;
 	struct stdio_dev *dev;
 
 	for (i = 0; i < cd_count[file]; i++) {
+		bool is_serial;
+
 		dev = console_devices[file][i];
-		if (dev->puts != NULL && !console_dev_is_serial(dev))
+		is_serial = console_dev_is_serial(dev);
+		if (dev->puts && serial_only == is_serial)
 			dev->puts(dev, s);
 	}
 }
 
+void console_puts_select_stderr(bool serial_only, const char *s)
+{
+	console_puts_select(stderr, serial_only, s);
+}
+
 static void console_puts(int file, const char *s)
 {
 	int i;
@@ -275,9 +291,9 @@ static inline void console_putc(int file, const char c)
 	stdio_devices[file]->putc(stdio_devices[file], c);
 }
 
-static inline void console_puts_noserial(int file, const char *s)
+void console_puts_select(int file, bool serial_only, const char *s)
 {
-	if (!console_dev_is_serial(stdio_devices[file]))
+	if (serial_only == console_dev_is_serial(stdio_devices[file]))
 		stdio_devices[file]->puts(stdio_devices[file], s);
 }
 
@@ -489,7 +505,7 @@ static void print_pre_console_buffer(int flushpoint)
 		puts(buf_out);
 		break;
 	case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
-		console_puts_noserial(stdout, buf_out);
+		console_puts_select(stdout, false, buf_out);
 		break;
 	}
 }
@@ -776,7 +792,7 @@ int console_announce_r(void)
 
 	display_options_get_banner(false, buf, sizeof(buf));
 
-	console_puts_noserial(stdout, buf);
+	console_puts_select(stdout, false, buf);
 #endif
 
 	return 0;
diff --git a/include/console.h b/include/console.h
index 74afe22b7e..4c6b8f2614 100644
--- a/include/console.h
+++ b/include/console.h
@@ -7,6 +7,8 @@
 #ifndef __CONSOLE_H
 #define __CONSOLE_H
 
+#include <stdbool.h>
+
 extern char console_buffer[];
 
 /* common/console.c */
@@ -72,6 +74,17 @@ int console_record_avail(void);
  */
 int console_announce_r(void);
 
+/**
+ * console_puts_select_stderr() - Output a string to selected console devices
+ *
+ * This writes to stderr only. It is useful for outputting errors
+ *
+ * @serial_only: true to output only to serial, false to output to everything
+ *	else
+ * @s: String to output
+ */
+void console_puts_select_stderr(bool serial_only, const char *s);
+
 /*
  * CONSOLE multiplexing.
  */
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 03/26] video: Show an error when a vidconsole function fails
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
  2020-05-25  1:48 ` [PATCH v2 01/26] x86: fsp: Reinit the FPU after FSP meminit Simon Glass
  2020-05-25  1:48 ` [PATCH v2 02/26] console: Add a way to output to serial only Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 04/26] sandbox: video: Allow selection of rotated console Simon Glass
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

At present these functions fail silently even when debugging, which is not
very helpful. Add a way to print a message to the serial output when an
error is detected.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/vidconsole-uclass.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index d30e6db6f6..e06912cf36 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -9,12 +9,13 @@
 
 #include <common.h>
 #include <command.h>
+#include <console.h>
 #include <log.h>
-#include <linux/ctype.h>
 #include <dm.h>
 #include <video.h>
 #include <video_console.h>
 #include <video_font.h>		/* Bitmap font for code page 437 */
+#include <linux/ctype.h>
 
 /*
  * Structure to describe a console color
@@ -556,16 +557,31 @@ int vidconsole_put_string(struct udevice *dev, const char *str)
 static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
 {
 	struct udevice *dev = sdev->priv;
+	int ret;
 
-	vidconsole_put_char(dev, ch);
+	ret = vidconsole_put_char(dev, ch);
+	if (ret) {
+#ifdef DEBUG
+		console_puts_select_stderr(true, "[vc err: putc]");
+#endif
+	}
 	video_sync(dev->parent, false);
 }
 
 static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
 {
 	struct udevice *dev = sdev->priv;
+	int ret;
+
+	ret = vidconsole_put_string(dev, s);
+	if (ret) {
+#ifdef DEBUG
+		char str[30];
 
-	vidconsole_put_string(dev, s);
+		snprintf(str, sizeof(str), "[vc err: puts %d]", ret);
+		console_puts_select_stderr(true, str);
+#endif
+	}
 	video_sync(dev->parent, false);
 }
 
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 04/26] sandbox: video: Allow selection of rotated console
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (2 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 03/26] video: Show an error when a vidconsole function fails Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 05/26] video: Split out expression parts into variables Simon Glass
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Add a devicetree property to select a rotated console. This uses the same
encoding as vidconsole itself: 0=normal; 1=90 degrees clockwise, 2=upside
down, 3=90 degrees anticlockwise.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/sandbox_sdl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
index 20248e6607..c678e728db 100644
--- a/drivers/video/sandbox_sdl.c
+++ b/drivers/video/sandbox_sdl.c
@@ -53,6 +53,7 @@ static int sandbox_sdl_bind(struct udevice *dev)
 	plat->xres = dev_read_u32_default(dev, "xres", LCD_MAX_WIDTH);
 	plat->yres = dev_read_u32_default(dev, "yres", LCD_MAX_HEIGHT);
 	plat->bpix = dev_read_u32_default(dev, "log2-depth", VIDEO_BPP16);
+	plat->rot = dev_read_u32_default(dev, "rotate", 0);
 	uc_plat->size = plat->xres * plat->yres * (1 << plat->bpix) / 8;
 	debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
 
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 05/26] video: Split out expression parts into variables
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (3 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 04/26] sandbox: video: Allow selection of rotated console Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 06/26] video: Adjust rotated console to start at right edge Simon Glass
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

The functions in this file do similar things but not always in the same
way. To make the code easier to read and compare, use a separate 'linenum'
variable in every function. This is then multiplied by the line length to
get the offset within the frame buffer to modify. Also use an 'x' variable
to hold the pixel position within that line. This is multipled by the
pixel size and added to the offset.

Also move the pbytes declaration up a little with the other long lines.

A side effect of splitting out these variables is that they are promoted
to int, i.e. a signed type, from the unsigned short used in the
vidconsole_priv struct. This would be necessary should any of the
variables go negative. At present this can actually happen in
console_putc_xy_2(), if the display width is not a multiple of the
character size (see next patch).

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/console_rotate.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index b485255598..8bb05ae02c 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -59,9 +59,9 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
 			       uint count)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+	int pbytes = VNBYTES(vid_priv->bpix);
 	void *dst;
 	void *src;
-	int pbytes = VNBYTES(vid_priv->bpix);
 	int j;
 
 	dst = vid_priv->fb + vid_priv->line_length -
@@ -83,14 +83,15 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
+	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
 	int pbytes = VNBYTES(vid_priv->bpix);
-	int i, col;
+	int i, col, x, linenum;
 	int mask = 0x80;
 	void *line;
-	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
 
-	line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) *
-			vid_priv->line_length - (y + 1) * pbytes;
+	linenum = VID_TO_PIXEL(x_frac) + 1;
+	x = y + 1;
+	line = vid_priv->fb + linenum * vid_priv->line_length - x * pbytes;
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
 
@@ -204,16 +205,15 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
-	int i, row;
+	int pbytes = VNBYTES(vid_priv->bpix);
+	int i, row, x, linenum;
 	void *line;
 
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
-
-	line = vid_priv->fb + (vid_priv->ysize - y - 1) *
-			vid_priv->line_length +
-			(vid_priv->xsize - VID_TO_PIXEL(x_frac) -
-			VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix);
+	linenum = vid_priv->ysize - y - 1;
+	x = vid_priv->xsize - VID_TO_PIXEL(x_frac) - VIDEO_FONT_WIDTH - 1;
+	line = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
 
 	for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
 		unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
@@ -312,9 +312,9 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
 			       uint count)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+	int pbytes = VNBYTES(vid_priv->bpix);
 	void *dst;
 	void *src;
-	int pbytes = VNBYTES(vid_priv->bpix);
 	int j;
 
 	dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
@@ -334,16 +334,16 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
+	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
 	int pbytes = VNBYTES(vid_priv->bpix);
-	int i, col;
+	int i, col, x;
 	int mask = 0x80;
-	void *line = vid_priv->fb +
-		(vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) *
-		vid_priv->line_length + y * pbytes;
-	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
+	void *line;
 
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
+	x = vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1;
+	line = vid_priv->fb + x * vid_priv->line_length + y * pbytes;
 
 	for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
 		switch (vid_priv->bpix) {
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 06/26] video: Adjust rotated console to start at right edge
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (4 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 05/26] video: Split out expression parts into variables Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 07/26] video: Drop unnecessary #ifdef around vid_console_color() Simon Glass
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

At present when the console is rotated 180 degrees it starts almost a
whole character to the left of the right edge (typically 7 pixels with
an 8-pixel-wide font). On a display which aligns with the font width,
this just wastes space. On a display that does not this can result in
x_frac going negative for the final character (the one on the left
side) and the overflow -EAGAIN check at the start of the function
failing.

Change the function to start at the rightmost pixel to fix these
problems.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/console_rotate.c | 2 +-
 test/dm/video.c                | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index 8bb05ae02c..da0ce7b9ce 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -212,7 +212,7 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
 	linenum = vid_priv->ysize - y - 1;
-	x = vid_priv->xsize - VID_TO_PIXEL(x_frac) - VIDEO_FONT_WIDTH - 1;
+	x = vid_priv->xsize - VID_TO_PIXEL(x_frac) - 1;
 	line = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
 
 	for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
diff --git a/test/dm/video.c b/test/dm/video.c
index 0664e3f22b..68f5ba44e7 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -251,7 +251,7 @@ DM_TEST(dm_test_video_rotation1, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 /* Test rotated text output through the console uclass */
 static int dm_test_video_rotation2(struct unit_test_state *uts)
 {
-	ut_assertok(check_vidconsole_output(uts, 2, 785, 446));
+	ut_assertok(check_vidconsole_output(uts, 2, 783, 445));
 
 	return 0;
 }
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 07/26] video: Drop unnecessary #ifdef around vid_console_color()
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (5 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 06/26] video: Adjust rotated console to start at right edge Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 08/26] video: Add a comment for struct video_uc_platdata Simon Glass
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

All of the functions in this file only apply if DM_VIDEO is enabled. Drop
the #ifdef as it just clutters things up. Add the needed forward
declaration.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 include/video_console.h | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/include/video_console.h b/include/video_console.h
index 0936ceaaf1..d3bc063165 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -8,6 +8,8 @@
 
 #include <video.h>
 
+struct video_priv;
+
 #define VID_FRAC_DIV	256
 
 #define VID_TO_PIXEL(x)	((x) / VID_FRAC_DIV)
@@ -241,8 +243,6 @@ int vidconsole_put_string(struct udevice *dev, const char *str);
 void vidconsole_position_cursor(struct udevice *dev, unsigned col,
 				unsigned row);
 
-#ifdef CONFIG_DM_VIDEO
-
 /**
  * vid_console_color() - convert a color code to a pixel's internal
  * representation
@@ -257,5 +257,3 @@ void vidconsole_position_cursor(struct udevice *dev, unsigned col,
 u32 vid_console_color(struct video_priv *priv, unsigned int idx);
 
 #endif
-
-#endif
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 08/26] video: Add a comment for struct video_uc_platdata
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (6 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 07/26] video: Drop unnecessary #ifdef around vid_console_color() Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 09/26] video: Add support for copying to a hardware framebuffer Simon Glass
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Add a few notes to explain the purpose of each member of this struct.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 include/video.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/video.h b/include/video.h
index e7c58e86cb..813b5653b0 100644
--- a/include/video.h
+++ b/include/video.h
@@ -19,6 +19,18 @@
 
 struct udevice;
 
+/**
+ * struct video_uc_platdata - uclass platform data for a video device
+ *
+ * This holds information that the uclass needs to know about each device. It
+ * is accessed using dev_get_uclass_platdata(dev). See 'Theory of operation' at
+ * the top of video-uclass.c for details on how this information is set.
+ *
+ * @align: Frame-buffer alignment, indicating the memory boundary the frame
+ *	buffer should start on. If 0, 1MB is assumed
+ * @size: Frame-buffer size, in bytes
+ * @base: Base address of frame buffer, 0 if not yet known
+ */
 struct video_uc_platdata {
 	uint align;
 	uint size;
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 09/26] video: Add support for copying to a hardware framebuffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (7 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 08/26] video: Add a comment for struct video_uc_platdata Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 10/26] video: Set up the copy framebuffer when enabled Simon Glass
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Some architectures use a cached framebuffer and flush the cache as needed
so that changes are visible. This is supported by U-Boot.

However x86 uses an uncached framebuffer with a 'write-combining' feature
to speed up writes.  Reads are permitted but they are extremely expensive.

Unfortunately, reading from the frame buffer is quite common, e.g. to
scroll it. This makes scrolling very slow.

Add a new feature which supports copying modified parts of the frame
buffer to the uncached hardware buffer. This speeds up scrolling by at
least 10x on x86 so the extra complexity cost seems worth it.

As a starting point, add the Kconfig, update the video structures to keep
track of the buffer and add a function to do the copy.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/Kconfig        | 12 ++++++++
 drivers/video/video-uclass.c | 54 ++++++++++++++++++++++++++++++++++++
 include/video.h              | 29 +++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 38123543a5..1cf63efd48 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -14,6 +14,18 @@ config DM_VIDEO
 	  option compiles in the video uclass and routes all LCD/video access
 	  through this.
 
+config VIDEO_COPY
+	bool "Enable copying the frame buffer to a hardware copy"
+	depends on DM_VIDEO
+	help
+	  On some machines (e.g. x86), reading from the frame buffer is very
+	  slow because it is uncached. To improve performance, this feature
+	  allows the frame buffer to be kept in cached memory (allocated by
+	  U-Boot) and then copied to the hardware frame-buffer as needed.
+
+	  To use this, your video driver must set @copy_base in
+	  struct video_uc_platdata.
+
 config BACKLIGHT_PWM
 	bool "Generic PWM based Backlight Driver"
 	depends on DM_VIDEO && DM_PWM
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index bf396d1091..9fbaa8db10 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <console.h>
 #include <cpu_func.h>
 #include <dm.h>
 #include <log.h>
@@ -200,6 +201,59 @@ int video_get_ysize(struct udevice *dev)
 	return priv->ysize;
 }
 
+#ifdef CONFIG_VIDEO_COPY
+int video_sync_copy(struct udevice *dev, void *from, void *to)
+{
+	struct video_priv *priv = dev_get_uclass_priv(dev);
+
+	if (priv->copy_fb) {
+		long offset, size;
+
+		/* Find the offset of the first byte to copy */
+		if ((ulong)to > (ulong)from) {
+			size = to - from;
+			offset = from - priv->fb;
+		} else {
+			size = from - to;
+			offset = to - priv->fb;
+		}
+
+		/*
+		 * Allow a bit of leeway for valid requests somewhere near the
+		 * frame buffer
+		 */
+		if (offset < -priv->fb_size || offset > 2 * priv->fb_size) {
+#ifdef DEBUG
+			char str[80];
+
+			snprintf(str, sizeof(str),
+				 "[sync_copy fb=%p, from=%p, to=%p, offset=%lx]",
+				 priv->fb, from, to, offset);
+			console_puts_select_stderr(true, str);
+#endif
+			return -EFAULT;
+		}
+
+		/*
+		 * Silently crop the memcpy. This allows callers to avoid doing
+		 * this themselves. It is common for the end pointer to go a
+		 * few lines after the end of the frame buffer, since most of
+		 * the update algorithms terminate a line after their last write
+		 */
+		if (offset + size > priv->fb_size) {
+			size = priv->fb_size - offset;
+		} else if (offset < 0) {
+			size += offset;
+			offset = 0;
+		}
+
+		memcpy(priv->copy_fb + offset, priv->fb + offset, size);
+	}
+
+	return 0;
+}
+#endif
+
 /* Set up the colour map */
 static int video_pre_probe(struct udevice *dev)
 {
diff --git a/include/video.h b/include/video.h
index 813b5653b0..1a0ffd8037 100644
--- a/include/video.h
+++ b/include/video.h
@@ -30,11 +30,14 @@ struct udevice;
  *	buffer should start on. If 0, 1MB is assumed
  * @size: Frame-buffer size, in bytes
  * @base: Base address of frame buffer, 0 if not yet known
+ * @copy_base: Base address of a hardware copy of the frame buffer. See
+ *	CONFIG_VIDEO_COPY.
  */
 struct video_uc_platdata {
 	uint align;
 	uint size;
 	ulong base;
+	ulong copy_base;
 };
 
 enum video_polarity {
@@ -75,6 +78,8 @@ enum video_log2_bpp {
  * @font_size:	Font size in pixels (0 to use a default value)
  * @fb:		Frame buffer
  * @fb_size:	Frame buffer size
+ * @copy_fb:	Copy of the frame buffer to keep up to date; see struct
+ *		video_uc_platdata
  * @line_length:	Length of each frame buffer line, in bytes. This can be
  *		set by the driver, but if not, the uclass will set it after
  *		probing
@@ -101,6 +106,7 @@ struct video_priv {
 	 */
 	void *fb;
 	int fb_size;
+	void *copy_fb;
 	int line_length;
 	u32 colour_fg;
 	u32 colour_bg;
@@ -214,6 +220,29 @@ void video_set_flush_dcache(struct udevice *dev, bool flush);
  */
 void video_set_default_colors(struct udevice *dev, bool invert);
 
+#ifdef CONFIG_VIDEO_COPY
+/**
+ * vidconsole_sync_copy() - Sync back to the copy framebuffer
+ *
+ * This ensures that the copy framebuffer has the same data as the framebuffer
+ * for a particular region. It should be called after the framebuffer is updated
+ *
+ * @from and @to can be in either order. The region between them is synced.
+ *
+ * @dev: Vidconsole device being updated
+ * @from: Start/end address within the framebuffer (->fb)
+ * @to: Other address within the frame buffer
+ * @return 0 if OK, -EFAULT if the start address is before the start of the
+ *	frame buffer start
+ */
+int video_sync_copy(struct udevice *dev, void *from, void *to);
+#else
+static inline int video_sync_copy(struct udevice *dev, void *from, void *to)
+{
+	return 0;
+}
+#endif
+
 #endif /* CONFIG_DM_VIDEO */
 
 #ifndef CONFIG_DM_VIDEO
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 10/26] video: Set up the copy framebuffer when enabled
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (8 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 09/26] video: Add support for copying to a hardware framebuffer Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 11/26] video: Clear the copy framebuffer when clearing the screen Simon Glass
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

This framebuffer is separately mapped. Update the video post-probe
function to set this up.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/video-uclass.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 9fbaa8db10..0c97377ea9 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -292,6 +292,9 @@ static int video_post_probe(struct udevice *dev)
 
 	priv->fb_size = priv->line_length * priv->ysize;
 
+	if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base)
+		priv->copy_fb = map_sysmem(plat->copy_base, plat->size);
+
 	/* Set up colors  */
 	video_set_default_colors(dev, false);
 
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 11/26] video: Clear the copy framebuffer when clearing the screen
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (9 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 10/26] video: Set up the copy framebuffer when enabled Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 12/26] video: Add helpers for vidconsole for the copy framebuffer Simon Glass
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Update video_clear() to also sync to the copy framebuffer.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/video-uclass.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 0c97377ea9..4d6f950eab 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -94,6 +94,7 @@ int video_reserve(ulong *addrp)
 int video_clear(struct udevice *dev)
 {
 	struct video_priv *priv = dev_get_uclass_priv(dev);
+	int ret;
 
 	switch (priv->bpix) {
 	case VIDEO_BPP16:
@@ -118,6 +119,9 @@ int video_clear(struct udevice *dev)
 		memset(priv->fb, priv->colour_bg, priv->fb_size);
 		break;
 	}
+	ret = video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size);
+	if (ret)
+		return ret;
 
 	return 0;
 }
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 12/26] video: Add helpers for vidconsole for the copy framebuffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (10 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 11/26] video: Clear the copy framebuffer when clearing the screen Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 13/26] video: Update normal console to support copy buffer Simon Glass
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Add a convenience function to call video_sync_copy() for a vidconsole.
Also add a memmove() helper, which does the memmove() as well as the sync.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2:
- Simplify return sequence in vidconsole_memmove() since there is no logging

 drivers/video/vidconsole-uclass.c | 18 ++++++++++++
 include/video_console.h           | 49 +++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index e06912cf36..406ec2334c 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -629,6 +629,24 @@ UCLASS_DRIVER(vidconsole) = {
 	.per_device_auto_alloc_size	= sizeof(struct vidconsole_priv),
 };
 
+#ifdef CONFIG_VIDEO_COPY
+int vidconsole_sync_copy(struct udevice *dev, void *from, void *to)
+{
+	struct udevice *vid = dev_get_parent(dev);
+
+	return video_sync_copy(vid, from, to);
+}
+
+int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
+		       int size)
+{
+	int ret;
+
+	memmove(dst, src, size);
+	return vidconsole_sync_copy(dev, dst, dst + size);
+}
+#endif
+
 void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row)
 {
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
diff --git a/include/video_console.h b/include/video_console.h
index d3bc063165..06b798ef10 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -256,4 +256,53 @@ void vidconsole_position_cursor(struct udevice *dev, unsigned col,
  */
 u32 vid_console_color(struct video_priv *priv, unsigned int idx);
 
+#ifdef CONFIG_VIDEO_COPY
+/**
+ * vidconsole_sync_copy() - Sync back to the copy framebuffer
+ *
+ * This ensures that the copy framebuffer has the same data as the framebuffer
+ * for a particular region. It should be called after the framebuffer is updated
+ *
+ * @from and @to can be in either order. The region between them is synced.
+ *
+ * @dev: Vidconsole device being updated
+ * @from: Start/end address within the framebuffer (->fb)
+ * @to: Other address within the frame buffer
+ * @return 0 if OK, -EFAULT if the start address is before the start of the
+ *	frame buffer start
+ */
+int vidconsole_sync_copy(struct udevice *dev, void *from, void *to);
+
+/**
+ * vidconsole_memmove() - Perform a memmove() within the frame buffer
+ *
+ * This handles a memmove(), e.g. for scrolling. It also updates the copy
+ * framebuffer.
+ *
+ * @dev: Vidconsole device being updated
+ * @dst: Destination address within the framebuffer (->fb)
+ * @src: Source address within the framebuffer (->fb)
+ * @size: Number of bytes to transfer
+ * @return 0 if OK, -EFAULT if the start address is before the start of the
+ *	frame buffer start
+ */
+int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
+		       int size);
+#else
+static inline int vidconsole_sync_copy(struct udevice *dev, void *from,
+				       void *to)
+{
+	return 0;
+}
+
+static inline int vidconsole_memmove(struct udevice *dev, void *dst,
+				     const void *src, int size)
+{
+	memmove(dst, src, size);
+
+	return 0;
+}
+
+#endif
+
 #endif
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 13/26] video: Update normal console to support copy buffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (11 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 12/26] video: Add helpers for vidconsole for the copy framebuffer Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 14/26] video: Update truetype " Simon Glass
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Update the implementation to keep a track of what it changes in the frame
buffer and then tell the copy buffer about it. Use the special
vidconsole_memmove() helper so that memmove() operations are also
reflected in the copy buffer.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/console_normal.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index c3f7ef8add..04f022491e 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -16,8 +16,9 @@
 static int console_normal_set_row(struct udevice *dev, uint row, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
-	void *line;
+	void *line, *end;
 	int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
+	int ret;
 	int i;
 
 	line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
@@ -28,6 +29,7 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	case VIDEO_BPP16:
@@ -36,6 +38,7 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	case VIDEO_BPP32:
@@ -44,11 +47,15 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	default:
 		return -ENOSYS;
 	}
+	ret = vidconsole_sync_copy(dev, line, end);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -59,10 +66,15 @@ static int console_normal_move_rows(struct udevice *dev, uint rowdst,
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
 	void *dst;
 	void *src;
+	int size;
+	int ret;
 
 	dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * vid_priv->line_length;
 	src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * vid_priv->line_length;
-	memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
+	size = VIDEO_FONT_HEIGHT * vid_priv->line_length * count;
+	ret = vidconsole_memmove(dev, dst, src, size);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -74,8 +86,13 @@ static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
 	int i, row;
-	void *line = vid_priv->fb + y * vid_priv->line_length +
+	void *start;
+	void *line;
+	int ret;
+
+	start = vid_priv->fb + y * vid_priv->line_length +
 		VID_TO_PIXEL(x_frac) * VNBYTES(vid_priv->bpix);
+	line = start;
 
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
@@ -126,6 +143,9 @@ static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
 		}
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 
 	return VID_TO_POS(VIDEO_FONT_WIDTH);
 }
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 14/26] video: Update truetype console to support copy buffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (12 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 13/26] video: Update normal console to support copy buffer Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 15/26] video: Update rotated " Simon Glass
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Update the implementation to keep a track of what it changes in the frame
buffer and then tell the copy buffer about it. Use the special
vidconsole_memmove() helper so that memmove() operations are also
reflected in the copy buffer.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/console_truetype.c | 43 +++++++++++++++++++++++---------
 1 file changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 5f7f03904b..22b2ea7191 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -127,9 +127,9 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
 	struct console_tt_priv *priv = dev_get_priv(dev);
-	void *line;
+	void *end, *line;
 	int pixels = priv->font_size * vid_priv->line_length;
-	int i;
+	int i, ret;
 
 	line = vid_priv->fb + row * priv->font_size * vid_priv->line_length;
 	switch (vid_priv->bpix) {
@@ -139,6 +139,7 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
 
 		for (i = 0; i < pixels; i++)
 			*dst++ = clr;
+		end = dst;
 		break;
 	}
 #endif
@@ -148,6 +149,7 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
 
 		for (i = 0; i < pixels; i++)
 			*dst++ = clr;
+		end = dst;
 		break;
 	}
 #endif
@@ -157,12 +159,16 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
 
 		for (i = 0; i < pixels; i++)
 			*dst++ = clr;
+		end = dst;
 		break;
 	}
 #endif
 	default:
 		return -ENOSYS;
 	}
+	ret = vidconsole_sync_copy(dev, line, end);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -174,11 +180,14 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst,
 	struct console_tt_priv *priv = dev_get_priv(dev);
 	void *dst;
 	void *src;
-	int i, diff;
+	int i, diff, ret;
 
 	dst = vid_priv->fb + rowdst * priv->font_size * vid_priv->line_length;
 	src = vid_priv->fb + rowsrc * priv->font_size * vid_priv->line_length;
-	memmove(dst, src, priv->font_size * vid_priv->line_length * count);
+	ret = vidconsole_memmove(dev, dst, src, priv->font_size *
+				 vid_priv->line_length * count);
+	if (ret)
+		return ret;
 
 	/* Scroll up our position history */
 	diff = (rowsrc - rowdst) * priv->font_size;
@@ -203,8 +212,8 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
 	struct pos_info *pos;
 	u8 *bits, *data;
 	int advance;
-	void *line;
-	int row;
+	void *start, *end, *line;
+	int row, ret;
 
 	/* First get some basic metrics about this character */
 	stbtt_GetCodepointHMetrics(font, ch, &advance, &lsb);
@@ -253,11 +262,12 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
 
 	/* Figure out where to write the character in the frame buffer */
 	bits = data;
-	line = vid_priv->fb + y * vid_priv->line_length +
+	start = vid_priv->fb + y * vid_priv->line_length +
 		VID_TO_PIXEL(x) * VNBYTES(vid_priv->bpix);
 	linenum = priv->baseline + yoff;
 	if (linenum > 0)
-		line += linenum * vid_priv->line_length;
+		start += linenum * vid_priv->line_length;
+	line = start;
 
 	/*
 	 * Write a row at a time, converting the 8bpp image into the colour
@@ -286,6 +296,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
 					*dst++ &= out;
 				bits++;
 			}
+			end = dst;
 			break;
 		}
 #endif
@@ -307,6 +318,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
 					*dst++ &= out;
 				bits++;
 			}
+			end = dst;
 			break;
 		}
 #endif
@@ -317,6 +329,9 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
 
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 	free(data);
 
 	return width_frac;
@@ -340,12 +355,13 @@ static int console_truetype_erase(struct udevice *dev, int xstart, int ystart,
 				  int xend, int yend, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
-	void *line;
+	void *start, *line;
 	int pixels = xend - xstart;
-	int row, i;
+	int row, i, ret;
 
-	line = vid_priv->fb + ystart * vid_priv->line_length;
-	line += xstart * VNBYTES(vid_priv->bpix);
+	start = vid_priv->fb + ystart * vid_priv->line_length;
+	start += xstart * VNBYTES(vid_priv->bpix);
+	line = start;
 	for (row = ystart; row < yend; row++) {
 		switch (vid_priv->bpix) {
 #ifdef CONFIG_VIDEO_BPP8
@@ -380,6 +396,9 @@ static int console_truetype_erase(struct udevice *dev, int xstart, int ystart,
 		}
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 
 	return 0;
 }
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 15/26] video: Update rotated console to support copy buffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (13 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 14/26] video: Update truetype " Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 16/26] video: Update the copy framebuffer when writing bitmaps Simon Glass
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Update the implementation to keep a track of what it changes in the frame
buffer and then tell the copy buffer about it. Use the special
vidconsole_memmove() helper so that memmove() operations are also
reflected in the copy buffer.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/console_rotate.c | 83 ++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 23 deletions(-)

diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index da0ce7b9ce..36c8d0609d 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -15,11 +15,13 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
 	int pbytes = VNBYTES(vid_priv->bpix);
-	void *line;
+	void *start, *line;
 	int i, j;
+	int ret;
 
-	line = vid_priv->fb + vid_priv->line_length -
+	start = vid_priv->fb + vid_priv->line_length -
 		(row + 1) * VIDEO_FONT_HEIGHT * pbytes;
+	line = start;
 	for (j = 0; j < vid_priv->ysize; j++) {
 		switch (vid_priv->bpix) {
 		case VIDEO_BPP8:
@@ -51,6 +53,9 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
 		}
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -62,7 +67,7 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
 	int pbytes = VNBYTES(vid_priv->bpix);
 	void *dst;
 	void *src;
-	int j;
+	int j, ret;
 
 	dst = vid_priv->fb + vid_priv->line_length -
 		(rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
@@ -70,7 +75,10 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
 		(rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
 
 	for (j = 0; j < vid_priv->ysize; j++) {
-		memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
+		ret = vidconsole_memmove(dev, dst, src,
+					 VIDEO_FONT_HEIGHT * pbytes * count);
+		if (ret)
+			return ret;
 		src += vid_priv->line_length;
 		dst += vid_priv->line_length;
 	}
@@ -85,13 +93,14 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
 	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
 	int pbytes = VNBYTES(vid_priv->bpix);
-	int i, col, x, linenum;
+	int i, col, x, linenum, ret;
 	int mask = 0x80;
-	void *line;
+	void *start, *line;
 
 	linenum = VID_TO_PIXEL(x_frac) + 1;
 	x = y + 1;
-	line = vid_priv->fb + linenum * vid_priv->line_length - x * pbytes;
+	start = vid_priv->fb + linenum * vid_priv->line_length - x * pbytes;
+	line = start;
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
 
@@ -136,6 +145,10 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
 		line += vid_priv->line_length;
 		mask >>= 1;
 	}
+	/* We draw backwards from 'start, so account for the first line */
+	ret = vidconsole_sync_copy(dev, start - vid_priv->line_length, line);
+	if (ret)
+		return ret;
 
 	return VID_TO_POS(VIDEO_FONT_WIDTH);
 }
@@ -144,12 +157,13 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
 static int console_set_row_2(struct udevice *dev, uint row, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
-	void *line;
+	void *start, *line, *end;
 	int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
-	int i;
+	int i, ret;
 
-	line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
+	start = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
 		(row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
+	line = start;
 	switch (vid_priv->bpix) {
 	case VIDEO_BPP8:
 		if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
@@ -157,6 +171,7 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	case VIDEO_BPP16:
@@ -165,6 +180,7 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	case VIDEO_BPP32:
@@ -173,11 +189,15 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	default:
 		return -ENOSYS;
 	}
+	ret = vidconsole_sync_copy(dev, start, end);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -195,7 +215,8 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
 		vid_priv->line_length;
 	src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
 		vid_priv->line_length;
-	memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
+	vidconsole_memmove(dev, dst, src,
+			   VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
 
 	return 0;
 }
@@ -206,14 +227,15 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
 	int pbytes = VNBYTES(vid_priv->bpix);
-	int i, row, x, linenum;
-	void *line;
+	int i, row, x, linenum, ret;
+	void *start, *line;
 
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
 	linenum = vid_priv->ysize - y - 1;
 	x = vid_priv->xsize - VID_TO_PIXEL(x_frac) - 1;
-	line = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
+	start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
+	line = start;
 
 	for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
 		unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
@@ -261,6 +283,10 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
 		}
 		line -= vid_priv->line_length;
 	}
+	/* Add 4 bytes to allow for the first pixel writen */
+	ret = vidconsole_sync_copy(dev, start + 4, line);
+	if (ret)
+		return ret;
 
 	return VID_TO_POS(VIDEO_FONT_WIDTH);
 }
@@ -269,10 +295,11 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
 	int pbytes = VNBYTES(vid_priv->bpix);
-	void *line;
-	int i, j;
+	void *start, *line;
+	int i, j, ret;
 
-	line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
+	start = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
+	line = start;
 	for (j = 0; j < vid_priv->ysize; j++) {
 		switch (vid_priv->bpix) {
 		case VIDEO_BPP8:
@@ -304,6 +331,9 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
 		}
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -315,13 +345,16 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
 	int pbytes = VNBYTES(vid_priv->bpix);
 	void *dst;
 	void *src;
-	int j;
+	int j, ret;
 
 	dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
 	src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
 
 	for (j = 0; j < vid_priv->ysize; j++) {
-		memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
+		ret = vidconsole_memmove(dev, dst, src,
+					 VIDEO_FONT_HEIGHT * pbytes * count);
+		if (ret)
+			return ret;
 		src += vid_priv->line_length;
 		dst += vid_priv->line_length;
 	}
@@ -336,15 +369,15 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
 	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
 	int pbytes = VNBYTES(vid_priv->bpix);
-	int i, col, x;
+	int i, col, x, ret;
 	int mask = 0x80;
-	void *line;
+	void *start, *line;
 
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
 	x = vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1;
-	line = vid_priv->fb + x * vid_priv->line_length + y * pbytes;
-
+	start = vid_priv->fb + x * vid_priv->line_length + y * pbytes;
+	line = start;
 	for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
 		switch (vid_priv->bpix) {
 		case VIDEO_BPP8:
@@ -386,6 +419,10 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
 		line -= vid_priv->line_length;
 		mask >>= 1;
 	}
+	/* Add a line to allow for the first pixels writen */
+	ret = vidconsole_sync_copy(dev, start + vid_priv->line_length, line);
+	if (ret)
+		return ret;
 
 	return VID_TO_POS(VIDEO_FONT_WIDTH);
 }
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 16/26] video: Update the copy framebuffer when writing bitmaps
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (14 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 15/26] video: Update rotated " Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 17/26] video: Add comments to struct sandbox_sdl_plat Simon Glass
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Adjust the bitmap code to sync to the copy framebuffer when done.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/video_bmp.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
index eb9636541d..732ce3bcc1 100644
--- a/drivers/video/video_bmp.c
+++ b/drivers/video/video_bmp.c
@@ -192,7 +192,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
 	struct video_priv *priv = dev_get_uclass_priv(dev);
 	ushort *cmap_base = NULL;
 	int i, j;
-	uchar *fb;
+	uchar *start, *fb;
 	struct bmp_image *bmp = map_sysmem(bmp_image, 0);
 	uchar *bmap;
 	ushort padded_width;
@@ -201,6 +201,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
 	unsigned colours, bpix, bmp_bpix;
 	struct bmp_color_table_entry *palette;
 	int hdr_size;
+	int ret;
 
 	if (!bmp || !(bmp->header.signature[0] == 'B' &&
 	    bmp->header.signature[1] == 'M')) {
@@ -259,8 +260,11 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
 		height = priv->ysize - y;
 
 	bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
-	fb = (uchar *)(priv->fb +
-		(y + height - 1) * priv->line_length + x * bpix / 8);
+	start = (uchar *)(priv->fb +
+		(y + height) * priv->line_length + x * bpix / 8);
+
+	/* Move back to the final line to be drawn */
+	fb = start - priv->line_length;
 
 	switch (bmp_bpix) {
 	case 1:
@@ -354,6 +358,12 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
 		break;
 	};
 
+	/* Find the position of the top left of the image in the framebuffer */
+	fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8);
+	ret = video_sync_copy(dev, start, fb);
+	if (ret)
+		return log_ret(ret);
+
 	video_sync(dev, false);
 
 	return 0;
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 17/26] video: Add comments to struct sandbox_sdl_plat
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (15 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 16/26] video: Update the copy framebuffer when writing bitmaps Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 18/26] video: sandbox: Add support for the copy framebuffer Simon Glass
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

This struct is not commented but needs it. Also fix the comment in
check_vidconsole_output() about the encoding for the rotation value.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 include/dm/test.h | 14 +++++++++++++-
 test/dm/video.c   |  3 ++-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/include/dm/test.h b/include/dm/test.h
index f0f36624ce..d39686cde2 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -159,7 +159,19 @@ enum {
 /* Declare a new driver model test */
 #define DM_TEST(_name, _flags)	UNIT_TEST(_name, _flags, dm_test)
 
-/* This platform data is needed in tests, so declare it here */
+/*
+ * struct sandbox_sdl_plat - Platform data for the SDL video driver
+ *
+ * This platform data is needed in tests, so declare it here
+ *
+ * @xres: Width of display in pixels
+ * @yres: Height of display in pixels
+ * @bpix: Log2 of bits per pixel (enum video_log2_bpp)
+ * @rot: Console rotation (0=normal orientation, 1=90 degrees clockwise,
+ *	2=upside down, 3=90 degree counterclockwise)
+ * @vidconsole_drv_name: Name of video console driver (set by tests)
+ * @font_size: Console font size to select (set by tests)
+ */
 struct sandbox_sdl_plat {
 	int xres;
 	int yres;
diff --git a/test/dm/video.c b/test/dm/video.c
index 68f5ba44e7..729c31b47d 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -188,7 +188,8 @@ DM_TEST(dm_test_video_ansi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  * check_vidconsole_output() - Run a text console test
  *
  * @uts:	Test state
- * @rot:	Console rotation (0, 90, 180, 270)
+ * @rot:	Console rotation (0=normal orientation, 1=90 degrees clockwise,
+ *		2=upside down, 3=90 degree counterclockwise)
  * @wrap_size:	Expected size of compressed frame buffer for the wrap test
  * @scroll_size: Same for the scroll test
  * @return 0 on success
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 18/26] video: sandbox: Add support for the copy framebuffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (16 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 17/26] video: Add comments to struct sandbox_sdl_plat Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 19/26] video: pci: Set up " Simon Glass
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

Enable this feature on sandbox by updating the SDL driver to have two
framebuffers.

Update the video tests to check that the copy framebuffer is kept in sync.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 configs/sandbox_defconfig   |  1 +
 drivers/video/sandbox_sdl.c |  9 +++++-
 test/dm/video.c             | 55 +++++++++++++++++++++++--------------
 3 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 9445d78118..ea567506e5 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -215,6 +215,7 @@ CONFIG_DM_USB=y
 CONFIG_USB_EMUL=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_DM_VIDEO=y
+CONFIG_VIDEO_COPY=y
 CONFIG_CONSOLE_ROTATION=y
 CONFIG_CONSOLE_TRUETYPE=y
 CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
index c678e728db..f529a350fb 100644
--- a/drivers/video/sandbox_sdl.c
+++ b/drivers/video/sandbox_sdl.c
@@ -23,6 +23,7 @@ enum {
 
 static int sandbox_sdl_probe(struct udevice *dev)
 {
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
 	struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
 	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct sandbox_state *state = state_get_current();
@@ -40,6 +41,8 @@ static int sandbox_sdl_probe(struct udevice *dev)
 	uc_priv->rot = plat->rot;
 	uc_priv->vidconsole_drv_name = plat->vidconsole_drv_name;
 	uc_priv->font_size = plat->font_size;
+	if (IS_ENABLED(CONFIG_VIDEO_COPY))
+		uc_plat->copy_base = uc_plat->base - uc_plat->size / 2;
 
 	return 0;
 }
@@ -55,7 +58,11 @@ static int sandbox_sdl_bind(struct udevice *dev)
 	plat->bpix = dev_read_u32_default(dev, "log2-depth", VIDEO_BPP16);
 	plat->rot = dev_read_u32_default(dev, "rotate", 0);
 	uc_plat->size = plat->xres * plat->yres * (1 << plat->bpix) / 8;
-	debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+	/* Allow space for two buffers, the lower one being the copy buffer */
+	log_debug("Frame buffer size %x\n", uc_plat->size);
+	if (IS_ENABLED(CONFIG_VIDEO_COPY))
+		uc_plat->size *= 2;
 
 	return ret;
 }
diff --git a/test/dm/video.c b/test/dm/video.c
index 729c31b47d..19f78b6239 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -51,12 +51,18 @@ DM_TEST(dm_test_video_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  * size of the compressed data. This provides a pretty good level of
  * certainty and the resulting tests need only check a single value.
  *
+ * If the copy framebuffer is enabled, this compares it to the main framebuffer
+ * too.
+ *
+ * @uts:	Test state
  * @dev:	Video device
  * @return compressed size of the frame buffer, or -ve on error
  */
-static int compress_frame_buffer(struct udevice *dev)
+static int compress_frame_buffer(struct unit_test_state *uts,
+				 struct udevice *dev)
 {
 	struct video_priv *priv = dev_get_uclass_priv(dev);
+	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
 	uint destlen;
 	void *dest;
 	int ret;
@@ -72,6 +78,13 @@ static int compress_frame_buffer(struct udevice *dev)
 	if (ret)
 		return ret;
 
+	/* Check here that the copy frame buffer is working correctly */
+	if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
+		ut_assertf(!memcmp(uc_priv->fb, uc_priv->copy_fb,
+				   uc_priv->fb_size),
+				   "Copy framebuffer does not match fb");
+	}
+
 	return destlen;
 }
 
@@ -110,25 +123,25 @@ static int dm_test_video_text(struct unit_test_state *uts)
 
 	ut_assertok(select_vidconsole(uts, "vidconsole0"));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_putc_xy(con, 0, 0, 'a');
-	ut_asserteq(79, compress_frame_buffer(dev));
+	ut_asserteq(79, compress_frame_buffer(uts, dev));
 
 	vidconsole_putc_xy(con, 0, 0, ' ');
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	for (i = 0; i < 20; i++)
 		vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
-	ut_asserteq(273, compress_frame_buffer(dev));
+	ut_asserteq(273, compress_frame_buffer(uts, dev));
 
 	vidconsole_set_row(con, 0, WHITE);
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	for (i = 0; i < 20; i++)
 		vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
-	ut_asserteq(273, compress_frame_buffer(dev));
+	ut_asserteq(273, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -144,7 +157,7 @@ static int dm_test_video_chars(struct unit_test_state *uts)
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_put_string(con, test_string);
-	ut_asserteq(466, compress_frame_buffer(dev));
+	ut_asserteq(466, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -164,20 +177,20 @@ static int dm_test_video_ansi(struct unit_test_state *uts)
 	/* reference clear: */
 	video_clear(con->parent);
 	video_sync(con->parent, false);
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	/* test clear escape sequence: [2J */
 	vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	/* test set-cursor: [%d;%df */
 	vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
-	ut_asserteq(143, compress_frame_buffer(dev));
+	ut_asserteq(143, compress_frame_buffer(uts, dev));
 
 	/* test colors (30-37 fg color, 40-47 bg color) */
 	vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
 	vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
-	ut_asserteq(272, compress_frame_buffer(dev));
+	ut_asserteq(272, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -208,24 +221,24 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot,
 
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	/* Check display wrap */
 	for (i = 0; i < 120; i++)
 		vidconsole_put_char(con, 'A' + i % 50);
-	ut_asserteq(wrap_size, compress_frame_buffer(dev));
+	ut_asserteq(wrap_size, compress_frame_buffer(uts, dev));
 
 	/* Check display scrolling */
 	for (i = 0; i < SCROLL_LINES; i++) {
 		vidconsole_put_char(con, 'A' + i % 50);
 		vidconsole_put_char(con, '\n');
 	}
-	ut_asserteq(scroll_size, compress_frame_buffer(dev));
+	ut_asserteq(scroll_size, compress_frame_buffer(uts, dev));
 
 	/* If we scroll enough, the screen becomes blank again */
 	for (i = 0; i < SCROLL_LINES; i++)
 		vidconsole_put_char(con, '\n');
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -299,7 +312,7 @@ static int dm_test_video_bmp(struct unit_test_state *uts)
 	ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
 
 	ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
-	ut_asserteq(1368, compress_frame_buffer(dev));
+	ut_asserteq(1368, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -315,7 +328,7 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts)
 	ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
 
 	ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
-	ut_asserteq(1368, compress_frame_buffer(dev));
+	ut_asserteq(1368, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -330,7 +343,7 @@ static int dm_test_video_truetype(struct unit_test_state *uts)
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_put_string(con, test_string);
-	ut_asserteq(12237, compress_frame_buffer(dev));
+	ut_asserteq(12237, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -351,7 +364,7 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_put_string(con, test_string);
-	ut_asserteq(35030, compress_frame_buffer(dev));
+	ut_asserteq(35030, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -372,7 +385,7 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts)
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_put_string(con, test_string);
-	ut_asserteq(29018, compress_frame_buffer(dev));
+	ut_asserteq(29018, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 19/26] video: pci: Set up the copy framebuffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (17 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 18/26] video: sandbox: Add support for the copy framebuffer Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 20/26] x86: fsp: video: Allocate a frame buffer when needed Simon Glass
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

When using a copy framebuffer we need to tell the video subsystem its
address. U-Boot's normally allocated framebuffer is used as the working
buffer, but nothing is displayed until it is copied to the copy
framebuffer.

For this to work the video driver must request that a framebuffer be
allocated separately from the hardware framebuffer, so add a check for
that.

Also add a log category so that logging appears correctly.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/pci/pci_rom.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index 6a9bc49978..fa29d69e85 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -22,6 +22,8 @@
  * Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  */
 
+#define LOG_CATEGORY UCLASS_PCI
+
 #include <common.h>
 #include <bios_emul.h>
 #include <bootstage.h>
@@ -344,7 +346,16 @@ int vbe_setup_video_priv(struct vesa_mode_info *vesa,
 	default:
 		return -EPROTONOSUPPORT;
 	}
-	plat->base = vesa->phys_base_ptr;
+
+	/* Use double buffering if enabled */
+	if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
+		if (!plat->base)
+			return log_msg_ret("copy", -ENFILE);
+		plat->copy_base = vesa->phys_base_ptr;
+	} else {
+		plat->base = vesa->phys_base_ptr;
+	}
+	log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
 	plat->size = vesa->bytes_per_scanline * vesa->y_resolution;
 
 	return 0;
@@ -372,6 +383,15 @@ int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void))
 
 	ret = vbe_setup_video_priv(&mode_info.vesa, uc_priv, plat);
 	if (ret) {
+		if (ret == -ENFILE) {
+			/*
+			 * See video-uclass.c for how to set up reserved memory
+			 * in your video driver
+			 */
+			log_err("CONFIG_VIDEO_COPY enabled but driver '%s' set up no reserved memory\n",
+				dev->driver->name);
+		}
+
 		debug("No video mode configured\n");
 		return ret;
 	}
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 20/26] x86: fsp: video: Allocate a frame buffer when needed
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (18 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 19/26] video: pci: Set up " Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 21/26] video: Correctly handle multiple framebuffers Simon Glass
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

When the copy framebuffer is in use, we must also have the standard U-Boot
framebuffer available. Update the FSP driver to support this.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 arch/x86/lib/fsp/fsp_graphics.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/x86/lib/fsp/fsp_graphics.c b/arch/x86/lib/fsp/fsp_graphics.c
index 70224c1a48..4eaa4fa6d4 100644
--- a/arch/x86/lib/fsp/fsp_graphics.c
+++ b/arch/x86/lib/fsp/fsp_graphics.c
@@ -116,6 +116,16 @@ err:
 	return ret;
 }
 
+static int fsp_video_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+
+	/* Set the maximum supported resolution */
+	plat->size = 2560 * 1600 * 4;
+
+	return 0;
+}
+
 static const struct udevice_id fsp_video_ids[] = {
 	{ .compatible = "fsp-fb" },
 	{ }
@@ -125,7 +135,9 @@ U_BOOT_DRIVER(fsp_video) = {
 	.name	= "fsp_video",
 	.id	= UCLASS_VIDEO,
 	.of_match = fsp_video_ids,
+	.bind	= fsp_video_bind,
 	.probe	= fsp_video_probe,
+	.flags	= DM_FLAG_PRE_RELOC,
 };
 
 static struct pci_device_id fsp_video_supported[] = {
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 21/26] video: Correctly handle multiple framebuffers
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (19 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 20/26] x86: fsp: video: Allocate a frame buffer when needed Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:48 ` [PATCH v2 22/26] x86: video: Support copy framebuffer with probed devices Simon Glass
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

At present video_bottom is set to the bottom of each framebuffer when it
is allocated. This is not correct, since it should hold the bottom of the
entire area available for framebuffers.

Fix this by adding a private address in the uclass which keeps track of
the next available spot for a framebuffer.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/video-uclass.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 4d6f950eab..aa543cb5df 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -46,6 +46,19 @@
  */
 DECLARE_GLOBAL_DATA_PTR;
 
+/**
+ * struct video_uc_priv - Information for the video uclass
+ *
+ * @video_ptr: Current allocation position of the video framebuffer pointer.
+ *	While binding devices after relocation, this points to the next
+ *	available address to use for a device's framebuffer. It starts at
+ *	gd->video_top and works downwards, running out of space when it hits
+ *	gd->video_bottom.
+ */
+struct video_uc_priv {
+	ulong video_ptr;
+};
+
 void video_set_flush_dcache(struct udevice *dev, bool flush)
 {
 	struct video_priv *priv = dev_get_uclass_priv(dev);
@@ -350,12 +363,21 @@ static int video_post_probe(struct udevice *dev)
 /* Post-relocation, allocate memory for the frame buffer */
 static int video_post_bind(struct udevice *dev)
 {
-	ulong addr = gd->video_top;
+	struct video_uc_priv *uc_priv;
+	ulong addr;
 	ulong size;
 
 	/* Before relocation there is nothing to do here */
 	if (!(gd->flags & GD_FLG_RELOC))
 		return 0;
+
+	/* Set up the video pointer, if this is the first device */
+	uc_priv = dev->uclass->priv;
+	if (!uc_priv->video_ptr)
+		uc_priv->video_ptr = gd->video_top;
+
+	/* Allocate framebuffer space for this device */
+	addr = uc_priv->video_ptr;
 	size = alloc_fb(dev, &addr);
 	if (addr < gd->video_bottom) {
 		/* Device tree node may need the 'u-boot,dm-pre-reloc' or
@@ -367,7 +389,7 @@ static int video_post_bind(struct udevice *dev)
 	}
 	debug("%s: Claiming %lx bytes at %lx for video device '%s'\n",
 	      __func__, size, addr, dev->name);
-	gd->video_bottom = addr;
+	uc_priv->video_ptr = addr;
 
 	return 0;
 }
@@ -380,6 +402,7 @@ UCLASS_DRIVER(video) = {
 	.pre_probe	= video_pre_probe,
 	.post_probe	= video_post_probe,
 	.pre_remove	= video_pre_remove,
+	.priv_auto_alloc_size	= sizeof(struct video_uc_priv),
 	.per_device_auto_alloc_size	= sizeof(struct video_priv),
 	.per_device_platdata_auto_alloc_size = sizeof(struct video_uc_platdata),
 };
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 22/26] x86: video: Support copy framebuffer with probed devices
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (20 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 21/26] video: Correctly handle multiple framebuffers Simon Glass
@ 2020-05-25  1:48 ` Simon Glass
  2020-05-25  1:49 ` [PATCH v2 23/26] chromebook_samus: Enable the copy framebuffer Simon Glass
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:48 UTC (permalink / raw)
  To: u-boot

For PCI video devices that are not mentioned in the devicetree, U-Boot
does not bind a driver before relocation, since PCI is not fully probed
at that point. Furthermore it is possible for the video device to be on
a secondary bus which is not even scanned.

This is fine if the framebuffer is allocated in fixed memory, as it
normally is on x86. But when using this as a copy framebuffer, we also
need U-Boot to allocate its own cached framebuffer for working in. Since
the video driver is never bound before relocation, the framebuffer size
is never set and U-Boot does no allocation.

Add a new CONFIG option to reserve 16MB of memory for this eventuality.
This allows vesa devices to use the copy framebuffer.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 drivers/video/Kconfig        | 19 +++++++++++++++++++
 drivers/video/video-uclass.c |  5 +++++
 2 files changed, 24 insertions(+)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 1cf63efd48..3e65052359 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -14,6 +14,25 @@ config DM_VIDEO
 	  option compiles in the video uclass and routes all LCD/video access
 	  through this.
 
+config VIDEO_PCI_DEFAULT_FB_SIZE
+	hex "Default framebuffer size to use if no drivers request it"
+	depends on DM_VIDEO
+	default 0x1000000 if X86 && PCI
+	default 0 if !(X86 && PCI)
+	help
+	  Generally, video drivers request the amount of memory they need for
+	  the frame buffer when they are bound, by setting the size field in
+	  struct video_uc_platdata. That memory is then reserved for use after
+	  relocation. But PCI drivers cannot be bound before relocation unless
+	  they are mentioned in the devicetree.
+
+	  With this value set appropriately, it is possible for PCI video
+	  devices to have a framebuffer allocated by U-Boot.
+
+	  Note: the framebuffer needs to be large enough to store all pixels at
+	  maximum resolution. For example, at 1920 x 1200 with 32 bits per
+	  pixel, 2560 * 1600 * 32 / 8 = 0xfa0000 bytes are needed.
+
 config VIDEO_COPY
 	bool "Enable copying the frame buffer to a hardware copy"
 	depends on DM_VIDEO
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index aa543cb5df..b5a03042c2 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -97,6 +97,11 @@ int video_reserve(ulong *addrp)
 		debug("%s: Reserving %lx bytes at %lx for video device '%s'\n",
 		      __func__, size, *addrp, dev->name);
 	}
+
+	/* Allocate space for PCI video devices in case there were not bound */
+	if (*addrp == gd->video_top)
+		*addrp -= CONFIG_VIDEO_PCI_DEFAULT_FB_SIZE;
+
 	gd->video_bottom = *addrp;
 	debug("Video frame buffers from %lx to %lx\n", gd->video_bottom,
 	      gd->video_top);
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 23/26] chromebook_samus: Enable the copy framebuffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (21 preceding siblings ...)
  2020-05-25  1:48 ` [PATCH v2 22/26] x86: video: Support copy framebuffer with probed devices Simon Glass
@ 2020-05-25  1:49 ` Simon Glass
  2020-05-25  1:49 ` [PATCH v2 24/26] chromebook_link: " Simon Glass
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:49 UTC (permalink / raw)
  To: u-boot

Update the video driver to support this feature and enable it on samus.
Also remove the multi-line scrolling since normal scrolling is fast enough
now.

With this change, the time taken to print the environment to the display
without CONFIG_CONSOLE_SCROLL_LINES is reduced from about 430ms to 12ms.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 configs/chromebook_samus_defconfig |  2 +-
 drivers/video/broadwell_igd.c      | 16 +++++++++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/configs/chromebook_samus_defconfig b/configs/chromebook_samus_defconfig
index fb4d88028c..13058ea7d7 100644
--- a/configs/chromebook_samus_defconfig
+++ b/configs/chromebook_samus_defconfig
@@ -67,7 +67,7 @@ CONFIG_SPI=y
 CONFIG_TPM_TIS_LPC=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_VIDEO_COPY=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
-CONFIG_CONSOLE_SCROLL_LINES=5
 CONFIG_TPM=y
diff --git a/drivers/video/broadwell_igd.c b/drivers/video/broadwell_igd.c
index 8e8fe9d9b3..df6a761d2d 100644
--- a/drivers/video/broadwell_igd.c
+++ b/drivers/video/broadwell_igd.c
@@ -664,6 +664,7 @@ static int broadwell_igd_probe(struct udevice *dev)
 	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
 	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
 	bool is_broadwell;
+	ulong fbbase;
 	int ret;
 
 	if (!ll_boot_init()) {
@@ -690,7 +691,8 @@ static int broadwell_igd_probe(struct udevice *dev)
 		return ret;
 
 	/* Use write-combining for the graphics memory, 256MB */
-	ret = mtrr_add_request(MTRR_TYPE_WRCOMB, plat->base, 256 << 20);
+	fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
+	ret = mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
 	if (!ret)
 		ret = mtrr_commit(true);
 	if (ret && ret != -ENOSYS) {
@@ -752,6 +754,17 @@ static int broadwell_igd_ofdata_to_platdata(struct udevice *dev)
 	return 0;
 }
 
+static int broadwell_igd_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	/* Set the maximum supported resolution */
+	uc_plat->size = 2560 * 1600 * 4;
+	log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+	return 0;
+}
+
 static const struct video_ops broadwell_igd_ops = {
 };
 
@@ -766,6 +779,7 @@ U_BOOT_DRIVER(broadwell_igd) = {
 	.of_match = broadwell_igd_ids,
 	.ops	= &broadwell_igd_ops,
 	.ofdata_to_platdata = broadwell_igd_ofdata_to_platdata,
+	.bind	= broadwell_igd_bind,
 	.probe	= broadwell_igd_probe,
 	.priv_auto_alloc_size	= sizeof(struct broadwell_igd_priv),
 	.platdata_auto_alloc_size	= sizeof(struct broadwell_igd_plat),
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 24/26] chromebook_link: Enable the copy framebuffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (22 preceding siblings ...)
  2020-05-25  1:49 ` [PATCH v2 23/26] chromebook_samus: Enable the copy framebuffer Simon Glass
@ 2020-05-25  1:49 ` Simon Glass
  2020-05-25  1:49 ` [PATCH v2 25/26] minnowmax: " Simon Glass
  2020-05-25  1:49 ` [PATCH v2 26/26] x86: minnowmax: Drop screen resolution to 1024x768 Simon Glass
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:49 UTC (permalink / raw)
  To: u-boot

Update the video driver to support this feature and enable it on link.
Also remove the multi-line scrolling since normal scrolling is fast enough
now.

With this change, the time taken to print the environment to the display
without CONFIG_CONSOLE_SCROLL_LINES is reduced from about 930ms to 29ms.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 configs/chromebook_link_defconfig |  2 +-
 drivers/video/ivybridge_igd.c     | 26 ++++++++++++++++++++------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig
index de4186cdf2..215185c974 100644
--- a/configs/chromebook_link_defconfig
+++ b/configs/chromebook_link_defconfig
@@ -62,10 +62,10 @@ CONFIG_SPI=y
 CONFIG_TPM_TIS_LPC=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_VIDEO_COPY=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
 CONFIG_VIDEO_IVYBRIDGE_IGD=y
-CONFIG_CONSOLE_SCROLL_LINES=5
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_TPM=y
 # CONFIG_EFI_LOADER is not set
diff --git a/drivers/video/ivybridge_igd.c b/drivers/video/ivybridge_igd.c
index 4c57e311d1..2587f53ac1 100644
--- a/drivers/video/ivybridge_igd.c
+++ b/drivers/video/ivybridge_igd.c
@@ -11,6 +11,7 @@
 #include <log.h>
 #include <pci_rom.h>
 #include <vbe.h>
+#include <video.h>
 #include <asm/intel_regs.h>
 #include <asm/io.h>
 #include <asm/mtrr.h>
@@ -722,7 +723,6 @@ static int gma_func0_init(struct udevice *dev)
 {
 	struct udevice *nbridge;
 	void *gtt_bar;
-	ulong base;
 	u32 reg32;
 	int ret;
 	int rev;
@@ -742,11 +742,6 @@ static int gma_func0_init(struct udevice *dev)
 	reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
 	dm_pci_write_config32(dev, PCI_COMMAND, reg32);
 
-	/* Use write-combining for the graphics memory, 256MB */
-	base = dm_pci_read_bar32(dev, 2);
-	mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20);
-	mtrr_commit(true);
-
 	gtt_bar = (void *)(ulong)dm_pci_read_bar32(dev, 0);
 	debug("GT bar %p\n", gtt_bar);
 	ret = gma_pm_init_pre_vbios(gtt_bar, rev);
@@ -758,6 +753,8 @@ static int gma_func0_init(struct udevice *dev)
 
 static int bd82x6x_video_probe(struct udevice *dev)
 {
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+	ulong fbbase;
 	void *gtt_bar;
 	int ret, rev;
 
@@ -774,6 +771,22 @@ static int bd82x6x_video_probe(struct udevice *dev)
 	if (ret)
 		return ret;
 
+	/* Use write-combining for the graphics memory, 256MB */
+	fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
+	mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
+	mtrr_commit(true);
+
+	return 0;
+}
+
+static int bd82x6x_video_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	/* Set the maximum supported resolution */
+	uc_plat->size = 2560 * 1600 * 4;
+	log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
 	return 0;
 }
 
@@ -786,5 +799,6 @@ U_BOOT_DRIVER(bd82x6x_video) = {
 	.name	= "bd82x6x_video",
 	.id	= UCLASS_VIDEO,
 	.of_match = bd82x6x_video_ids,
+	.bind	= bd82x6x_video_bind,
 	.probe	= bd82x6x_video_probe,
 };
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 25/26] minnowmax: Enable the copy framebuffer
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (23 preceding siblings ...)
  2020-05-25  1:49 ` [PATCH v2 24/26] chromebook_link: " Simon Glass
@ 2020-05-25  1:49 ` Simon Glass
  2020-05-25  1:49 ` [PATCH v2 26/26] x86: minnowmax: Drop screen resolution to 1024x768 Simon Glass
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:49 UTC (permalink / raw)
  To: u-boot

Update the video driver to support this feature and enable it on
minnowmax to speed up the display.

With this change, the time taken to print the environment to the display
without CONFIG_CONSOLE_SCROLL_LINES is reduced from over 13 seconds to
300ms, at 1280x1024.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
---

Changes in v2: None

 configs/minnowmax_defconfig |  2 +-
 drivers/video/vesa.c        | 30 +++++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig
index 127fd5d53e..19528c4641 100644
--- a/configs/minnowmax_defconfig
+++ b/configs/minnowmax_defconfig
@@ -59,6 +59,6 @@ CONFIG_RTL8169=y
 CONFIG_SPI=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_VIDEO_COPY=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11B=y
-CONFIG_CONSOLE_SCROLL_LINES=5
diff --git a/drivers/video/vesa.c b/drivers/video/vesa.c
index 6c03611e80..9656326bdb 100644
--- a/drivers/video/vesa.c
+++ b/drivers/video/vesa.c
@@ -5,12 +5,39 @@
 
 #include <common.h>
 #include <dm.h>
+#include <log.h>
 #include <pci.h>
 #include <vbe.h>
+#include <video.h>
+#include <asm/mtrr.h>
 
 static int vesa_video_probe(struct udevice *dev)
 {
-	return vbe_setup_video(dev, NULL);
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+	ulong fbbase;
+	int ret;
+
+	ret = vbe_setup_video(dev, NULL);
+	if (ret)
+		return log_ret(ret);
+
+	/* Use write-combining for the graphics memory, 256MB */
+	fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
+	mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
+	mtrr_commit(true);
+
+	return 0;
+}
+
+static int vesa_video_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	/* Set the maximum supported resolution */
+	uc_plat->size = 2560 * 1600 * 4;
+	log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+	return 0;
 }
 
 static const struct udevice_id vesa_video_ids[] = {
@@ -22,6 +49,7 @@ U_BOOT_DRIVER(vesa_video) = {
 	.name	= "vesa_video",
 	.id	= UCLASS_VIDEO,
 	.of_match = vesa_video_ids,
+	.bind	= vesa_video_bind,
 	.probe	= vesa_video_probe,
 };
 
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

* [PATCH v2 26/26] x86: minnowmax: Drop screen resolution to 1024x768
  2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
                   ` (24 preceding siblings ...)
  2020-05-25  1:49 ` [PATCH v2 25/26] minnowmax: " Simon Glass
@ 2020-05-25  1:49 ` Simon Glass
  25 siblings, 0 replies; 27+ messages in thread
From: Simon Glass @ 2020-05-25  1:49 UTC (permalink / raw)
  To: u-boot

This seems like a more reasonable resolution for this board, since it is
quite slow. It also allows it to work with a 5" LCD display in my lab.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 configs/minnowmax_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig
index 19528c4641..cce9ee6fea 100644
--- a/configs/minnowmax_defconfig
+++ b/configs/minnowmax_defconfig
@@ -61,4 +61,4 @@ CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_VIDEO_COPY=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
-CONFIG_FRAMEBUFFER_VESA_MODE_11B=y
+CONFIG_FRAMEBUFFER_VESA_MODE_118=y
-- 
2.27.0.rc0.183.gde8f92d652-goog

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

end of thread, other threads:[~2020-05-25  1:49 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-25  1:48 [PATCH v2 00/26] x86: video: Speed up the framebuffer Simon Glass
2020-05-25  1:48 ` [PATCH v2 01/26] x86: fsp: Reinit the FPU after FSP meminit Simon Glass
2020-05-25  1:48 ` [PATCH v2 02/26] console: Add a way to output to serial only Simon Glass
2020-05-25  1:48 ` [PATCH v2 03/26] video: Show an error when a vidconsole function fails Simon Glass
2020-05-25  1:48 ` [PATCH v2 04/26] sandbox: video: Allow selection of rotated console Simon Glass
2020-05-25  1:48 ` [PATCH v2 05/26] video: Split out expression parts into variables Simon Glass
2020-05-25  1:48 ` [PATCH v2 06/26] video: Adjust rotated console to start at right edge Simon Glass
2020-05-25  1:48 ` [PATCH v2 07/26] video: Drop unnecessary #ifdef around vid_console_color() Simon Glass
2020-05-25  1:48 ` [PATCH v2 08/26] video: Add a comment for struct video_uc_platdata Simon Glass
2020-05-25  1:48 ` [PATCH v2 09/26] video: Add support for copying to a hardware framebuffer Simon Glass
2020-05-25  1:48 ` [PATCH v2 10/26] video: Set up the copy framebuffer when enabled Simon Glass
2020-05-25  1:48 ` [PATCH v2 11/26] video: Clear the copy framebuffer when clearing the screen Simon Glass
2020-05-25  1:48 ` [PATCH v2 12/26] video: Add helpers for vidconsole for the copy framebuffer Simon Glass
2020-05-25  1:48 ` [PATCH v2 13/26] video: Update normal console to support copy buffer Simon Glass
2020-05-25  1:48 ` [PATCH v2 14/26] video: Update truetype " Simon Glass
2020-05-25  1:48 ` [PATCH v2 15/26] video: Update rotated " Simon Glass
2020-05-25  1:48 ` [PATCH v2 16/26] video: Update the copy framebuffer when writing bitmaps Simon Glass
2020-05-25  1:48 ` [PATCH v2 17/26] video: Add comments to struct sandbox_sdl_plat Simon Glass
2020-05-25  1:48 ` [PATCH v2 18/26] video: sandbox: Add support for the copy framebuffer Simon Glass
2020-05-25  1:48 ` [PATCH v2 19/26] video: pci: Set up " Simon Glass
2020-05-25  1:48 ` [PATCH v2 20/26] x86: fsp: video: Allocate a frame buffer when needed Simon Glass
2020-05-25  1:48 ` [PATCH v2 21/26] video: Correctly handle multiple framebuffers Simon Glass
2020-05-25  1:48 ` [PATCH v2 22/26] x86: video: Support copy framebuffer with probed devices Simon Glass
2020-05-25  1:49 ` [PATCH v2 23/26] chromebook_samus: Enable the copy framebuffer Simon Glass
2020-05-25  1:49 ` [PATCH v2 24/26] chromebook_link: " Simon Glass
2020-05-25  1:49 ` [PATCH v2 25/26] minnowmax: " Simon Glass
2020-05-25  1:49 ` [PATCH v2 26/26] x86: minnowmax: Drop screen resolution to 1024x768 Simon Glass

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.