Merge tag 'efi-next-20230313' of https://source.denx.de/u-boot/custodians/u-boot-efi into next

Pull request efi-next-20230313

UEFI:

* Improve graphics support in EFI app

Others:

* x86: Add a few more items to bdinfo
* video: Remove duplicate cursor-positioning function
* video: Clear the vidconsole rather than the video
diff --git a/arch/x86/dts/efi-x86_app.dts b/arch/x86/dts/efi-x86_app.dts
index 6d843a9..59e2e40 100644
--- a/arch/x86/dts/efi-x86_app.dts
+++ b/arch/x86/dts/efi-x86_app.dts
@@ -27,6 +27,7 @@
 	};
 	efi-fb {
 		compatible = "efi-fb";
+		bootph-some-ram;
 	};
 
 };
diff --git a/arch/x86/lib/bdinfo.c b/arch/x86/lib/bdinfo.c
index 0cb79b0..1539007 100644
--- a/arch/x86/lib/bdinfo.c
+++ b/arch/x86/lib/bdinfo.c
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <efi.h>
 #include <init.h>
+#include <asm/cpu.h>
 #include <asm/efi.h>
 #include <asm/global_data.h>
 
@@ -16,6 +17,11 @@
 void arch_print_bdinfo(void)
 {
 	bdinfo_print_num_l("prev table", gd->arch.table);
+	bdinfo_print_num_l("clock_rate", gd->arch.clock_rate);
+	bdinfo_print_num_l("tsc_base", gd->arch.tsc_base);
+	bdinfo_print_num_l("vendor", gd->arch.x86_vendor);
+	bdinfo_print_str(" name", cpu_vendor_name(gd->arch.x86_vendor));
+	bdinfo_print_num_l("model", gd->arch.x86_model);
 
 	if (IS_ENABLED(CONFIG_EFI_STUB))
 		efi_show_bdinfo();
diff --git a/arch/x86/lib/fsp/fsp_graphics.c b/arch/x86/lib/fsp/fsp_graphics.c
index b07c666..2bcc49f 100644
--- a/arch/x86/lib/fsp/fsp_graphics.c
+++ b/arch/x86/lib/fsp/fsp_graphics.c
@@ -106,7 +106,7 @@
 	vesa->phys_base_ptr = dm_pci_read_bar32(dev, 2);
 	gd->fb_base = vesa->phys_base_ptr;
 
-	ret = vesa_setup_video_priv(vesa, uc_priv, plat);
+	ret = vesa_setup_video_priv(vesa, vesa->phys_base_ptr, uc_priv, plat);
 	if (ret)
 		goto err;
 
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index bf002f8..f709904 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -26,6 +26,11 @@
 	print_size(size, "\n");
 }
 
+void bdinfo_print_str(const char *name, const char *str)
+{
+	printf("%-12s= %s\n", name, str);
+}
+
 void bdinfo_print_num_l(const char *name, ulong value)
 {
 	printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value);
@@ -83,11 +88,15 @@
 		       device_active(dev) ? "" : "in");
 		if (device_active(dev)) {
 			struct video_priv *upriv = dev_get_uclass_priv(dev);
+			struct video_uc_plat *plat = dev_get_uclass_plat(dev);
 
 			bdinfo_print_num_ll("FB base", (ulong)upriv->fb);
-			if (upriv->copy_fb)
+			if (upriv->copy_fb) {
 				bdinfo_print_num_ll("FB copy",
 						    (ulong)upriv->copy_fb);
+				bdinfo_print_num_l(" copy size",
+						   plat->copy_size);
+			}
 			printf("%-12s= %dx%dx%d\n", "FB size", upriv->xsize,
 			       upriv->ysize, 1 << upriv->bpix);
 		}
diff --git a/cmd/cls.c b/cmd/cls.c
index 40a32ee..1125a3f 100644
--- a/cmd/cls.c
+++ b/cmd/cls.c
@@ -8,7 +8,7 @@
 #include <common.h>
 #include <command.h>
 #include <dm.h>
-#include <video.h>
+#include <video_console.h>
 
 #define CSI "\x1b["
 
@@ -17,14 +17,24 @@
 {
 	__maybe_unused struct udevice *dev;
 
-	/*  Send clear screen and home */
+	/*
+	 * Send clear screen and home
+	 *
+	 * FIXME(Heinrich Schuchardt <xypron.glpk@gmx.de>): This should go
+	 * through an API and only be written to serial terminals, not video
+	 * displays
+	 */
 	printf(CSI "2J" CSI "1;1H");
-	if (IS_ENABLED(CONFIG_VIDEO) && !IS_ENABLED(CONFIG_VIDEO_ANSI)) {
-		if (uclass_first_device_err(UCLASS_VIDEO, &dev))
+	if (IS_ENABLED(CONFIG_VIDEO_ANSI))
+		return 0;
+
+	if (IS_ENABLED(CONFIG_VIDEO)) {
+		if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
 			return CMD_RET_FAILURE;
-		if (video_clear(dev))
+		if (vidconsole_clear_and_reset(dev))
 			return CMD_RET_FAILURE;
 	}
+
 	return CMD_RET_SUCCESS;
 }
 
diff --git a/configs/efi-x86_app64_defconfig b/configs/efi-x86_app64_defconfig
index 605d49f..dae4884 100644
--- a/configs/efi-x86_app64_defconfig
+++ b/configs/efi-x86_app64_defconfig
@@ -22,6 +22,7 @@
 # CONFIG_CMD_BOOTM is not set
 CONFIG_CMD_PART=y
 # CONFIG_CMD_NET is not set
+CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_EXT4=y
@@ -39,7 +40,9 @@
 CONFIG_USE_ROOTPATH=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_CONSOLE_SCROLL_LINES=5
 # CONFIG_REGEX is not set
+CONFIG_CMD_DHRYSTONE=y
 # CONFIG_GZIP is not set
 CONFIG_EFI=y
 CONFIG_EFI_APP_64BIT=y
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index 47b6e6e..f0dfe63 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -325,7 +325,7 @@
 	return ret;
 }
 
-int vesa_setup_video_priv(struct vesa_mode_info *vesa,
+int vesa_setup_video_priv(struct vesa_mode_info *vesa, u64 fb,
 			  struct video_priv *uc_priv,
 			  struct video_uc_plat *plat)
 {
@@ -348,9 +348,9 @@
 
 	/* Use double buffering if enabled */
 	if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->base)
-		plat->copy_base = vesa->phys_base_ptr;
+		plat->copy_base = fb;
 	else
-		plat->base = vesa->phys_base_ptr;
+		plat->base = fb;
 	log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
 	plat->size = vesa->bytes_per_scanline * vesa->y_resolution;
 
@@ -377,7 +377,9 @@
 		return ret;
 	}
 
-	ret = vesa_setup_video_priv(&mode_info.vesa, uc_priv, plat);
+	ret = vesa_setup_video_priv(&mode_info.vesa,
+				    mode_info.vesa.phys_base_ptr, uc_priv,
+				    plat);
 	if (ret) {
 		if (ret == -ENFILE) {
 			/*
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index 192c7b7..f86a0b8 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -404,6 +404,15 @@
 	if (!gd->arch.clock_rate) {
 		unsigned long fast_calibrate;
 
+		/**
+		 * There is no obvious way to obtain this information from EFI
+		 * boot services. This value was measured on a Framework Laptop
+		 * which has a 12th Gen Intel Core
+		 */
+		if (IS_ENABLED(CONFIG_EFI_APP)) {
+			fast_calibrate = 2750;
+			goto done;
+		}
 		fast_calibrate = native_calibrate_tsc();
 		if (fast_calibrate)
 			goto done;
diff --git a/drivers/video/coreboot.c b/drivers/video/coreboot.c
index d2d87c7..c586475 100644
--- a/drivers/video/coreboot.c
+++ b/drivers/video/coreboot.c
@@ -57,7 +57,7 @@
 		goto err;
 	}
 
-	ret = vesa_setup_video_priv(vesa, uc_priv, plat);
+	ret = vesa_setup_video_priv(vesa, vesa->phys_base_ptr, uc_priv, plat);
 	if (ret) {
 		ret = log_msg_ret("setup", ret);
 		goto err;
diff --git a/drivers/video/efi.c b/drivers/video/efi.c
index b11e42c..28ac15f 100644
--- a/drivers/video/efi.c
+++ b/drivers/video/efi.c
@@ -5,6 +5,8 @@
  * EFI framebuffer driver based on GOP
  */
 
+#define LOG_CATEGORY LOGC_EFI
+
 #include <common.h>
 #include <dm.h>
 #include <efi_api.h>
@@ -50,7 +52,19 @@
 	*size = len;
 }
 
-static int get_mode_info(struct vesa_mode_info *vesa)
+/**
+ * get_mode_info() - Ask EFI for the mode information
+ *
+ * Gets info from the graphics-output protocol
+ *
+ * @vesa: Place to put the mode information
+ * @fbp: Returns the address of the frame buffer
+ * @infop: Returns a pointer to the mode info
+ * Returns: 0 if OK, -ENOSYS if boot services are not available, -ENOTSUPP if
+ * the protocol is not supported by EFI
+ */
+static int get_mode_info(struct vesa_mode_info *vesa, u64 *fbp,
+			 struct efi_gop_mode_info **infop)
 {
 	efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
 	struct efi_boot_services *boot = efi_get_boot();
@@ -63,41 +77,70 @@
 	ret = boot->locate_protocol(&efi_gop_guid, NULL, (void **)&gop);
 	if (ret)
 		return log_msg_ret("prot", -ENOTSUPP);
-
 	mode = gop->mode;
+	log_debug("maxmode %u, mode %u, info %p, size %lx, fb %lx, fb_size %lx\n",
+		  mode->max_mode, mode->mode, mode->info, mode->info_size,
+		  (ulong)mode->fb_base, (ulong)mode->fb_size);
+
 	vesa->phys_base_ptr = mode->fb_base;
+	*fbp = mode->fb_base;
 	vesa->x_resolution = mode->info->width;
 	vesa->y_resolution = mode->info->height;
+	*infop = mode->info;
 
 	return 0;
 }
 
-static int save_vesa_mode(struct vesa_mode_info *vesa)
+/**
+ * get_mode_from_entry() - Obtain fb info from the EFIET_GOP_MODE payload entry
+ *
+ * This gets the mode information provided by the stub to the payload and puts
+ * it into a vesa structure. It also returns the mode information.
+ *
+ * @vesa: Place to put the mode information
+ * @fbp: Returns the address of the frame buffer
+ * @infop: Returns a pointer to the mode info
+ * Returns: 0 if OK, -ve on error
+ */
+static int get_mode_from_entry(struct vesa_mode_info *vesa, u64 *fbp,
+			       struct efi_gop_mode_info **infop)
 {
-	struct efi_entry_gopmode *mode;
-	const struct efi_framebuffer *fbinfo;
+	struct efi_gop_mode *mode;
 	int size;
 	int ret;
 
-	if (IS_ENABLED(CONFIG_EFI_APP)) {
-		ret = get_mode_info(vesa);
-		if (ret) {
-			printf("EFI graphics output protocol not found\n");
-			return -ENXIO;
-		}
-	} else {
-		ret = efi_info_get(EFIET_GOP_MODE, (void **)&mode, &size);
-		if (ret == -ENOENT) {
-			printf("EFI graphics output protocol mode not found\n");
-			return -ENXIO;
-		}
-		vesa->phys_base_ptr = mode->fb_base;
-		vesa->x_resolution = mode->info->width;
-		vesa->y_resolution = mode->info->height;
+	ret = efi_info_get(EFIET_GOP_MODE, (void **)&mode, &size);
+	if (ret) {
+		printf("EFI graphics output entry not found\n");
+		return ret;
+	}
+	vesa->phys_base_ptr = mode->fb_base;
+	*fbp = mode->fb_base;
+	vesa->x_resolution = mode->info->width;
+	vesa->y_resolution = mode->info->height;
+	*infop = mode->info;
+
+	return 0;
+}
+
+static int save_vesa_mode(struct vesa_mode_info *vesa, u64 *fbp)
+{
+	const struct efi_framebuffer *fbinfo;
+	struct efi_gop_mode_info *info;
+	int ret;
+
+	if (IS_ENABLED(CONFIG_EFI_APP))
+		ret = get_mode_info(vesa, fbp, &info);
+	else
+		ret = get_mode_from_entry(vesa, fbp, &info);
+	if (ret) {
+		printf("EFI graphics output protocol not found (err=%dE)\n",
+		       ret);
+		return ret;
 	}
 
-	if (mode->info->pixel_format < EFI_GOT_BITMASK) {
-		fbinfo = &efi_framebuffer_format_map[mode->info->pixel_format];
+	if (info->pixel_format < EFI_GOT_BITMASK) {
+		fbinfo = &efi_framebuffer_format_map[info->pixel_format];
 		vesa->red_mask_size = fbinfo->red.size;
 		vesa->red_mask_pos = fbinfo->red.pos;
 		vesa->green_mask_size = fbinfo->green.size;
@@ -108,29 +151,28 @@
 		vesa->reserved_mask_pos = fbinfo->rsvd.pos;
 
 		vesa->bits_per_pixel = 32;
-		vesa->bytes_per_scanline = mode->info->pixels_per_scanline * 4;
-	} else if (mode->info->pixel_format == EFI_GOT_BITMASK) {
-		efi_find_pixel_bits(mode->info->pixel_bitmask[0],
+		vesa->bytes_per_scanline = info->pixels_per_scanline * 4;
+	} else if (info->pixel_format == EFI_GOT_BITMASK) {
+		efi_find_pixel_bits(info->pixel_bitmask[0],
 				    &vesa->red_mask_pos,
 				    &vesa->red_mask_size);
-		efi_find_pixel_bits(mode->info->pixel_bitmask[1],
+		efi_find_pixel_bits(info->pixel_bitmask[1],
 				    &vesa->green_mask_pos,
 				    &vesa->green_mask_size);
-		efi_find_pixel_bits(mode->info->pixel_bitmask[2],
+		efi_find_pixel_bits(info->pixel_bitmask[2],
 				    &vesa->blue_mask_pos,
 				    &vesa->blue_mask_size);
-		efi_find_pixel_bits(mode->info->pixel_bitmask[3],
+		efi_find_pixel_bits(info->pixel_bitmask[3],
 				    &vesa->reserved_mask_pos,
 				    &vesa->reserved_mask_size);
 		vesa->bits_per_pixel = vesa->red_mask_size +
 				       vesa->green_mask_size +
 				       vesa->blue_mask_size +
 				       vesa->reserved_mask_size;
-		vesa->bytes_per_scanline = (mode->info->pixels_per_scanline *
+		vesa->bytes_per_scanline = (info->pixels_per_scanline *
 					    vesa->bits_per_pixel) / 8;
 	} else {
-		debug("efi set unknown framebuffer format: %d\n",
-		      mode->info->pixel_format);
+		log_err("Unknown framebuffer format: %d\n", info->pixel_format);
 		return -EINVAL;
 	}
 
@@ -142,19 +184,20 @@
 	struct video_uc_plat *plat = dev_get_uclass_plat(dev);
 	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct vesa_mode_info *vesa = &mode_info.vesa;
+	u64 fb;
 	int ret;
 
 	/* Initialize vesa_mode_info structure */
-	ret = save_vesa_mode(vesa);
+	ret = save_vesa_mode(vesa, &fb);
 	if (ret)
 		goto err;
 
-	ret = vesa_setup_video_priv(vesa, uc_priv, plat);
+	ret = vesa_setup_video_priv(vesa, fb, uc_priv, plat);
 	if (ret)
 		goto err;
 
-	printf("Video: %dx%dx%d\n", uc_priv->xsize, uc_priv->ysize,
-	       vesa->bits_per_pixel);
+	printf("Video: %dx%dx%d @ %lx\n", uc_priv->xsize, uc_priv->ysize,
+	       vesa->bits_per_pixel, (ulong)fb);
 
 	return 0;
 
@@ -163,6 +206,30 @@
 	return ret;
 }
 
+static int efi_video_bind(struct udevice *dev)
+{
+	if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
+		struct video_uc_plat *plat = dev_get_uclass_plat(dev);
+		struct vesa_mode_info vesa;
+		int ret;
+		u64 fb;
+
+		/*
+		 * Initialise vesa_mode_info structure so we can figure out the
+		 * required framebuffer size. If something goes wrong, just do
+		 * without a copy framebuffer
+		 */
+		ret = save_vesa_mode(&vesa, &fb);
+		if (!ret) {
+			/* this is not reached if the EFI call failed */
+			plat->copy_size = vesa.bytes_per_scanline *
+				vesa.y_resolution;
+		}
+	}
+
+	return 0;
+}
+
 static const struct udevice_id efi_video_ids[] = {
 	{ .compatible = "efi-fb" },
 	{ }
@@ -172,5 +239,6 @@
 	.name	= "efi_video",
 	.id	= UCLASS_VIDEO,
 	.of_match = efi_video_ids,
+	.bind	= efi_video_bind,
 	.probe	= efi_video_probe,
 };
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index a5f2350..61f4216 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -126,26 +126,14 @@
 	priv->ycur = y;
 }
 
-/**
- * set_cursor_position() - set cursor position
- *
- * @priv:	private data of the video console
- * @row:	new row
- * @col:	new column
- */
-static void set_cursor_position(struct vidconsole_priv *priv, int row, int col)
+void vidconsole_position_cursor(struct udevice *dev, uint col, uint row)
 {
-	/*
-	 * Ensure we stay in the bounds of the screen.
-	 */
-	if (row >= priv->rows)
-		row = priv->rows - 1;
-	if (col >= priv->cols)
-		col = priv->cols - 1;
+	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+	short x, y;
 
-	priv->ycur = row * priv->y_charsize;
-	priv->xcur_frac = priv->xstart_frac +
-			  VID_TO_POS(col * priv->x_charsize);
+	x = min_t(short, col, priv->cols - 1) * priv->x_charsize;
+	y = min_t(short, row, priv->rows - 1) * priv->y_charsize;
+	vidconsole_set_cursor_pos(dev, x, y);
 }
 
 /**
@@ -192,7 +180,7 @@
 			int row = priv->row_saved;
 			int col = priv->col_saved;
 
-			set_cursor_position(priv, row, col);
+			vidconsole_position_cursor(dev, col, row);
 			priv->escape = 0;
 			return;
 		}
@@ -254,7 +242,7 @@
 		if (row < 0)
 			row = 0;
 		/* Right and bottom overflows are handled in the callee. */
-		set_cursor_position(priv, row, col);
+		vidconsole_position_cursor(dev, col, row);
 		break;
 	}
 	case 'H':
@@ -278,7 +266,7 @@
 		if (col)
 			--col;
 
-		set_cursor_position(priv, row, col);
+		vidconsole_position_cursor(dev, col, row);
 
 		break;
 	}
@@ -656,14 +644,14 @@
 }
 #endif
 
-void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row)
+int vidconsole_clear_and_reset(struct udevice *dev)
 {
-	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
-	struct udevice *vid_dev = dev->parent;
-	struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
-	short x, y;
+	int ret;
 
-	x = min_t(short, col * priv->x_charsize, vid_priv->xsize - 1);
-	y = min_t(short, row * priv->y_charsize, vid_priv->ysize - 1);
-	vidconsole_set_cursor_pos(dev, x, y);
+	ret = video_clear(dev_get_parent(dev));
+	if (ret)
+		return ret;
+	vidconsole_position_cursor(dev, 0, 0);
+
+	return 0;
 }
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index ab482f1..da89f43 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -78,24 +78,40 @@
 	priv->flush_dcache = flush;
 }
 
+static ulong alloc_fb_(ulong align, ulong size, ulong *addrp)
+{
+	ulong base;
+
+	align = align ? align : 1 << 20;
+	base = *addrp - size;
+	base &= ~(align - 1);
+	size = *addrp - base;
+	*addrp = base;
+
+	return size;
+}
+
 static ulong alloc_fb(struct udevice *dev, ulong *addrp)
 {
 	struct video_uc_plat *plat = dev_get_uclass_plat(dev);
-	ulong base, align, size;
+	ulong size;
 
-	if (!plat->size)
+	if (!plat->size) {
+		if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_size) {
+			size = alloc_fb_(plat->align, plat->copy_size, addrp);
+			plat->copy_base = *addrp;
+			return size;
+		}
+
 		return 0;
+	}
 
 	/* Allow drivers to allocate the frame buffer themselves */
 	if (plat->base)
 		return 0;
 
-	align = plat->align ? plat->align : 1 << 20;
-	base = *addrp - plat->size;
-	base &= ~(align - 1);
-	plat->base = base;
-	size = *addrp - base;
-	*addrp = base;
+	size = alloc_fb_(plat->align, plat->size, addrp);
+	plat->base = *addrp;
 
 	return size;
 }
diff --git a/include/init.h b/include/init.h
index 699dc24..8873081 100644
--- a/include/init.h
+++ b/include/init.h
@@ -353,6 +353,9 @@
 void bdinfo_print_num_l(const char *name, ulong value);
 void bdinfo_print_num_ll(const char *name, unsigned long long value);
 
+/* Print a string value (for use in arch_print_bdinfo()) */
+void bdinfo_print_str(const char *name, const char *str);
+
 /* Print a clock speed in MHz */
 void bdinfo_print_mhz(const char *name, unsigned long hz);
 
diff --git a/include/vesa.h b/include/vesa.h
index a42c179..9285bfa 100644
--- a/include/vesa.h
+++ b/include/vesa.h
@@ -108,7 +108,21 @@
 
 struct video_priv;
 struct video_uc_plat;
-int vesa_setup_video_priv(struct vesa_mode_info *vesa,
+
+/**
+ * vesa_setup_video_priv() - Set up a video device using VESA information
+ *
+ * The vesa struct is used by various x86 drivers, so this is a common function
+ * to use it to set up the video.
+ *
+ * @vesa: Vesa information to use (vesa->phys_base_ptr is ignored)
+ * @fb: Frame buffer address (since vesa->phys_base_ptr is only 32 bits)
+ * @uc_priv: Video device's uclass-private information
+ * @plat: Video devices's uclass-private platform data
+ * Returns: 0 if OK, -ENXIO if the x resolution is 0, -EEPROTONOSUPPORT if the
+ * pixel format is not supported
+ */
+int vesa_setup_video_priv(struct vesa_mode_info *vesa, u64 fb,
 			  struct video_priv *uc_priv,
 			  struct video_uc_plat *plat);
 int vesa_setup_video(struct udevice *dev, int (*int15_handler)(void));
diff --git a/include/video.h b/include/video.h
index 3f67a93..4d99e5d 100644
--- a/include/video.h
+++ b/include/video.h
@@ -24,6 +24,7 @@
  * @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.
+ * @copy_size: Size of copy framebuffer, used if @size is 0
  * @hide_logo: Hide the logo (used for testing)
  */
 struct video_uc_plat {
@@ -31,6 +32,7 @@
 	uint size;
 	ulong base;
 	ulong copy_base;
+	ulong copy_size;
 	bool hide_logo;
 };
 
diff --git a/include/video_console.h b/include/video_console.h
index 7701032..3db9a7e 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -286,6 +286,15 @@
 				unsigned row);
 
 /**
+ * vidconsole_clear_and_reset() - Clear the console and reset the cursor
+ *
+ * The cursor is placed at the start of the console
+ *
+ * @dev:	vidconsole device to adjust
+ */
+int vidconsole_clear_and_reset(struct udevice *dev);
+
+/**
  * vidconsole_set_cursor_pos() - set cursor position
  *
  * The cursor is set to the new position and the start-of-line information is
diff --git a/scripts/build-efi.sh b/scripts/build-efi.sh
index bc9aeeb..46c2880 100755
--- a/scripts/build-efi.sh
+++ b/scripts/build-efi.sh
@@ -96,6 +96,8 @@
 	fi
 	if [[ -n "${serial}" ]]; then
 		extra="-display none -serial mon:stdio"
+	else
+		extra="-serial mon:stdio"
 	fi
 	echo "Running ${qemu}"
 	# Use 512MB since U-Boot EFI likes to have 256MB to play with