diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d58152abc7f..7d27dad327d 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -202,6 +202,21 @@ config VPL_DM_SERIAL
 	  implements serial_putc() etc. The uclass interface is
 	  defined in include/serial.h.
 
+config SERIAL_TERM_PRESENT
+	bool "Assume there is a serial terminal present on the serial line"
+	depends on DM_SERIAL
+	default y if EFI_LOADER
+	help
+	  In some cases boards are connected to a serial terminal and it is
+	  useful to emit ANSI codes or other characters to determine the
+	  properties of the terminal.
+
+	  Enable this if you wish to have these features.
+
+	  Note that enabling this for a board which is sending its output to
+	  a log will result in junk in the log. It also introduces a delay of
+	  up to 100ms on startup.
+
 config DEBUG_UART
 	bool "Enable an early debug UART for debugging"
 	help
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index a08678dde4e..1204fb5d4c4 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -13,6 +13,7 @@
 #include <os.h>
 #include <serial.h>
 #include <stdio_dev.h>
+#include <time.h>
 #include <watchdog.h>
 #include <asm/global_data.h>
 #include <dm/lists.h>
@@ -557,6 +558,123 @@ static int on_baudrate(const char *name, const char *value, enum env_op op,
 }
 U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
 
+/**
+ * term_get_char() - read a character from the console
+ *
+ * Wait for up to 100 ms to read a character from the console.
+ *
+ * @c:		pointer to the buffer to receive the character
+ * Return:	0 on success, -ETIMEDOUT if timed out
+ */
+static int term_get_char(s32 *c)
+{
+	u64 timeout;
+
+	/* Wait up to 100 ms for a character */
+	timeout = timer_get_us() + 100000;
+
+	while (!tstc())
+		if (timer_get_us() > timeout)
+			return -ETIMEDOUT;
+
+	*c = getchar();
+
+	return 0;
+}
+
+/**
+ * term_read_reply() - receive and parse a reply from the terminal
+ *
+ * @n:		array of return values
+ * @num:	number of return values expected
+ * @end_char:	character indicating end of terminal message
+ * Return:	non-zero indicates error
+ */
+static int term_read_reply(int *n, int num, char end_char)
+{
+	int ret, i = 0;
+	s32 c;
+
+	ret = term_get_char(&c);
+	if (ret)
+		return ret;
+	if (c != cESC)
+		return -EPROTO;
+
+	ret = term_get_char(&c);
+	if (ret)
+		return ret;
+	if (c != '[')
+		return -EPROTO;
+
+	n[0] = 0;
+	while (1) {
+		int ret;
+
+		ret = term_get_char(&c);
+		if (ret)
+			return ret;
+
+		if (c == ';') {
+			i++;
+			if (i >= num)
+				return -EPROTO;
+			n[i] = 0;
+			continue;
+		} else if (c == end_char) {
+			break;
+		} else if (c > '9' || c < '0') {
+			return -EPROTO;
+		}
+
+		/* Read one more decimal position */
+		n[i] *= 10;
+		n[i] += c - '0';
+	}
+	if (i != num - 1)
+		return -EPROTO;
+
+	return 0;
+}
+
+int serial_query_size(int *rowsp, int *colsp)
+{
+	int ret = 0;
+	int n[2];
+
+	if (!CONFIG_IS_ENABLED(SERIAL_TERM_PRESENT))
+		return -ENOENT;
+
+	/* Empty input buffer */
+	while (tstc())
+		getchar();
+
+	/*
+	 * Not all terminals understand CSI [18t for querying the console size.
+	 * We should adhere to escape sequences documented in the console_codes
+	 * man page and the ECMA-48 standard.
+	 *
+	 * So here we follow a different approach. We position the cursor to the
+	 * bottom right and query its position. Before leaving the function we
+	 * restore the original cursor position.
+	 */
+	puts(ESC "7"		/* Save cursor position */
+	     ESC "[r"		/* Set scrolling region to full window */
+	     ESC "[999;999H"	/* Move to bottom right corner */
+	     ESC "[6n");	/* Query cursor position */
+
+	/* Read {rows,cols} */
+	ret = term_read_reply(n, 2, 'R');
+	if (!ret) {
+		*colsp = n[1];
+		*rowsp = n[0];
+	}
+
+	printf(ESC "8");	/* Restore cursor position */
+
+	return ret;
+}
+
 #if CONFIG_IS_ENABLED(SERIAL_PRESENT)
 static int serial_post_probe(struct udevice *dev)
 {
diff --git a/include/serial.h b/include/serial.h
index e5f6d984d28..2aba4c313c2 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -3,6 +3,10 @@
 
 #include <post.h>
 
+/* Escape value */
+#define cESC	'\x1b'
+#define ESC	"\x1b"
+
 struct serial_device {
 	/* enough bytes to match alignment of following func pointer */
 	char	name[16];
@@ -382,4 +386,18 @@ static inline void serial_flush(void) {}
 int serial_getc(void);
 int serial_tstc(void);
 
+/**
+ * serial_query_size() - query serial console size
+ *
+ * When using a serial console or the net console we can only devise the
+ * terminal size by querying the terminal using ECMA-48 control sequences.
+ *
+ * @rowsp:	returns number of rows
+ * @colsp:	returns number of columns
+ * Returns:	0 on success, -NOENT if no terminal is present, -ETIMEDOUT if we
+ * checked for a terminal but didn't get a response in time, -EPROTO if the
+ * terminal did not respond as expected
+ */
+int serial_query_size(int *rowsp, int *colsp);
+
 #endif
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index ade44cb6e36..d2eabfdb07e 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -16,6 +16,7 @@
 #include <efi_loader.h>
 #include <env.h>
 #include <log.h>
+#include <serial.h>
 #include <stdio_dev.h>
 #include <video_console.h>
 #include <linux/delay.h>
@@ -59,9 +60,6 @@ const efi_guid_t efi_guid_text_input_protocol =
 const efi_guid_t efi_guid_text_output_protocol =
 			EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
 
-#define cESC '\x1b'
-#define ESC "\x1b"
-
 /*
  * efi_con_mode - mode information of the Simple Text Output Protocol
  *
@@ -77,76 +75,6 @@ static struct simple_text_output_mode efi_con_mode = {
 	.cursor_visible = 1,
 };
 
-/**
- * term_get_char() - read a character from the console
- *
- * Wait for up to 100 ms to read a character from the console.
- *
- * @c:		pointer to the buffer to receive the character
- * Return:	0 on success, 1 otherwise
- */
-static int term_get_char(s32 *c)
-{
-	u64 timeout;
-
-	/* Wait up to 100 ms for a character */
-	timeout = timer_get_us() + 100000;
-
-	while (!tstc())
-		if (timer_get_us() > timeout)
-			return 1;
-
-	*c = getchar();
-	return 0;
-}
-
-/**
- * term_read_reply() - receive and parse a reply from the terminal
- *
- * @n:		array of return values
- * @num:	number of return values expected
- * @end_char:	character indicating end of terminal message
- * Return:	non-zero indicates error
- */
-static int term_read_reply(int *n, int num, char end_char)
-{
-	s32 c;
-	int i = 0;
-
-	if (term_get_char(&c) || c != cESC)
-		return -1;
-
-	if (term_get_char(&c) || c != '[')
-		return -1;
-
-	n[0] = 0;
-	while (1) {
-		if (!term_get_char(&c)) {
-			if (c == ';') {
-				i++;
-				if (i >= num)
-					return -1;
-				n[i] = 0;
-				continue;
-			} else if (c == end_char) {
-				break;
-			} else if (c > '9' || c < '0') {
-				return -1;
-			}
-
-			/* Read one more decimal position */
-			n[i] *= 10;
-			n[i] += c - '0';
-		} else {
-			return -1;
-		}
-	}
-	if (i != num - 1)
-		return -1;
-
-	return 0;
-}
-
 /**
  * efi_cout_output_string() - write Unicode string to console
  *
@@ -272,52 +200,6 @@ static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
 	return (mode->rows == rows) && (mode->columns == cols);
 }
 
-/**
- * query_console_serial() - query serial console size
- *
- * When using a serial console or the net console we can only devise the
- * terminal size by querying the terminal using ECMA-48 control sequences.
- *
- * @rows:	pointer to return number of rows
- * @cols:	pointer to return number of columns
- * Returns:	0 on success
- */
-static int query_console_serial(int *rows, int *cols)
-{
-	int ret = 0;
-	int n[2];
-
-	/* Empty input buffer */
-	while (tstc())
-		getchar();
-
-	/*
-	 * Not all terminals understand CSI [18t for querying the console size.
-	 * We should adhere to escape sequences documented in the console_codes
-	 * man page and the ECMA-48 standard.
-	 *
-	 * So here we follow a different approach. We position the cursor to the
-	 * bottom right and query its position. Before leaving the function we
-	 * restore the original cursor position.
-	 */
-	printf(ESC "7"		/* Save cursor position */
-	       ESC "[r"		/* Set scrolling region to full window */
-	       ESC "[999;999H"	/* Move to bottom right corner */
-	       ESC "[6n");	/* Query cursor position */
-
-	/* Read {rows,cols} */
-	if (term_read_reply(n, 2, 'R')) {
-		ret = 1;
-		goto out;
-	}
-
-	*cols = n[1];
-	*rows = n[0];
-out:
-	printf(ESC "8");	/* Restore cursor position */
-	return ret;
-}
-
 /**
  * query_vidconsole() - query video console size
  *
@@ -363,8 +245,8 @@ void efi_setup_console_size(void)
 
 	if (IS_ENABLED(CONFIG_VIDEO))
 		ret = query_vidconsole(&rows, &cols);
-	if (ret)
-		ret = query_console_serial(&rows, &cols);
+	if (ret && IS_ENABLED(CONFIG_DM_SERIAL))
+		ret = serial_query_size(&rows, &cols);
 	if (ret)
 		return;
 
