diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 109d49f57db7b4a409064fbb49fa5bc263c17f3c..8d05bb9ff95642f7475c6bc4163a6b8d23681e5d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -707,4 +707,6 @@ source "board/woodburn/Kconfig"
 source "board/xaeniax/Kconfig"
 source "board/zipitz2/Kconfig"
 
+source "arch/arm/Kconfig.debug"
+
 endmenu
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
new file mode 100644
index 0000000000000000000000000000000000000000..624bcf4682bd0ecbab9584f5598394f3170e929c
--- /dev/null
+++ b/arch/arm/Kconfig.debug
@@ -0,0 +1,64 @@
+menu "ARM debug"
+
+config DEBUG_LL
+	bool "Low-level debugging functions"
+	depends on !ARM64
+	help
+	  Say Y here to include definitions of printascii, printch, printhex
+	  in U-Boot.  This is helpful if you are debugging code that
+	  executes before the console is initialized.
+
+choice
+	prompt "Low-level debugging port"
+	depends on DEBUG_LL
+
+	config DEBUG_LL_UART_8250
+		bool "Low-level debugging via 8250 UART"
+		help
+		  Say Y here if you wish the debug print routes to direct
+		  their output to an 8250 UART.  You can use this option
+		  to provide the parameters for the 8250 UART rather than
+		  selecting one of the platform specific options above if
+		  you know the parameters for the port.
+
+		  This option is preferred over the platform specific
+		  options; the platform specific options are deprecated
+		  and will be soon removed.
+
+endchoice
+
+config DEBUG_LL_INCLUDE
+	string
+	depends on DEBUG_LL
+	default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250
+	default "mach/debug-macro.S"
+
+# Compatibility options for 8250
+config DEBUG_UART_8250
+	bool
+
+config DEBUG_UART_PHYS
+	hex "Physical base address of debug UART"
+	depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
+
+# This is not used in U-Boot
+config DEBUG_UART_VIRT
+	hex
+	default DEBUG_UART_PHYS
+	depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
+
+config DEBUG_UART_8250_SHIFT
+	int "Register offset shift for the 8250 debug UART"
+	depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
+	default 2
+
+config DEBUG_UART_8250_WORD
+	bool "Use 32-bit accesses for 8250 UART"
+	depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
+	depends on DEBUG_UART_8250_SHIFT >= 2
+
+config DEBUG_UART_8250_FLOW_CONTROL
+	bool "Enable flow control for 8250 UART"
+	depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
+
+endmenu
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 1ef240047f48d067748a42b08ed975ec96966e65..d74e4b8415f152061d50614185617749478a5e41 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -48,6 +48,8 @@ ifndef CONFIG_ARM64
 obj-y	+= cache-cp15.o
 endif
 
+obj-$(CONFIG_DEBUG_LL)	+= debug.o
+
 # For EABI conformant tool chains, provide eabi_compat()
 ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS)))
 extra-y	+= eabi_compat.o