[PATCH 16/27] ARM: pxa: add DEBUG_LL support
Sascha Hauer
s.hauer at pengutronix.de
Sun Aug 16 10:56:36 PDT 2026
The PXA UARTs are NS16550 compatible, so the generic ns16550 debug_ll
helpers can be reused. Two things differ from a plain ns16550: the
registers are 32bit wide and thus spaced four bytes apart, and the unit
has to be enabled explicitly with the UUE bit in the IER register.
The latter needs care as debug_ll_ns16550_init() clears IER to disable
the interrupts, which on PXA disables the unit as well, so UUE has to be
set again afterwards.
The UART clock is a fixed 14.857MHz on all PXA variants, so the divisor
can be calculated without any clock support.
Assisted-by: Claude Opus 5
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
arch/arm/Kconfig | 1 +
arch/arm/include/asm/debug_ll.h | 2 ++
common/Kconfig.debug_ll | 17 ++++++++++
include/mach/pxa/debug_ll.h | 74 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 94 insertions(+)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2f2ab5d76d..292b9cfe66 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -122,6 +122,7 @@ config ARCH_PXA
bool "Intel/Marvell PXA based"
depends on 32BIT
select GPIOLIB
+ select HAS_DEBUG_LL
config ARCH_SOCFPGA
bool "Altera SOCFPGA"
diff --git a/arch/arm/include/asm/debug_ll.h b/arch/arm/include/asm/debug_ll.h
index a645a6e910..e7e98ced0a 100644
--- a/arch/arm/include/asm/debug_ll.h
+++ b/arch/arm/include/asm/debug_ll.h
@@ -42,6 +42,8 @@
#include <mach/zynq/debug_ll.h>
#elif defined CONFIG_DEBUG_SOCFPGA_UART
#include <mach/socfpga/debug_ll.h>
+#elif defined CONFIG_DEBUG_PXA_UART
+#include <mach/pxa/debug_ll.h>
#endif
#endif
diff --git a/common/Kconfig.debug_ll b/common/Kconfig.debug_ll
index 8445b4be08..8ae3bbb172 100644
--- a/common/Kconfig.debug_ll
+++ b/common/Kconfig.debug_ll
@@ -393,6 +393,14 @@ config DEBUG_TEGRA_UART
bool "Tegra debug UART"
depends on ARCH_TEGRA
+config DEBUG_SOCFPGA_UART
+ bool "SoCFPGA debug UART"
+ depends on ARCH_SOCFPGA
+
+config DEBUG_PXA_UART
+ bool "PXA debug UART"
+ depends on ARCH_PXA
+
endchoice
config DEBUG_LL_NS16550
@@ -400,6 +408,15 @@ config DEBUG_LL_NS16550
help
Selected by RISC-V and PowerPC platforms that use ns16550 for debug_ll
+config DEBUG_PXA_UART_PORT
+ int "PXA Debug UART Port Selection" if DEBUG_PXA_UART
+ default 0
+ depends on ARCH_PXA
+ help
+ Choose UART port on which barebox low-level debug messages
+ should be output. Possible values are:
+ 0 - FFUART, 1 - BTUART, 2 - STUART
+
config DEBUG_IMX_UART_PORT
int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \
DEBUG_IMX21_UART || \
diff --git a/include/mach/pxa/debug_ll.h b/include/mach/pxa/debug_ll.h
new file mode 100644
index 0000000000..3a9ec3b6b6
--- /dev/null
+++ b/include/mach/pxa/debug_ll.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __MACH_PXA_DEBUG_LL_H__
+#define __MACH_PXA_DEBUG_LL_H__
+
+#include <io.h>
+#include <linux/bits.h>
+
+/*
+ * The PXA UARTs are NS16550 compatible, but the registers are 32bit
+ * wide and thus spaced four bytes apart. In addition to that the unit
+ * has to be enabled explicitly with the UUE bit in the IER register.
+ */
+#define PXA_UART_IER_UUE BIT(6)
+
+#define PXA_FFUART_BASE 0x40100000
+#define PXA_BTUART_BASE 0x40200000
+#define PXA_STUART_BASE 0x40700000
+
+#ifdef CONFIG_DEBUG_PXA_UART
+
+#if CONFIG_DEBUG_PXA_UART_PORT == 0
+#define PXA_DEBUG_UART_BASE PXA_FFUART_BASE
+#elif CONFIG_DEBUG_PXA_UART_PORT == 1
+#define PXA_DEBUG_UART_BASE PXA_BTUART_BASE
+#elif CONFIG_DEBUG_PXA_UART_PORT == 2
+#define PXA_DEBUG_UART_BASE PXA_STUART_BASE
+#else
+#error "Invalid CONFIG_DEBUG_PXA_UART_PORT"
+#endif
+
+static inline uint8_t debug_ll_read_reg(void __iomem *base, int reg)
+{
+ return readl(base + (reg << 2));
+}
+
+static inline void debug_ll_write_reg(void __iomem *base, int reg, uint8_t val)
+{
+ writel(val, base + (reg << 2));
+}
+
+#include <debug_ll/ns16550.h>
+
+static inline void pxa_debug_ll_init(void)
+{
+ void __iomem *base = IOMEM(PXA_DEBUG_UART_BASE);
+ uint16_t divisor;
+
+ /* The UART clock is a fixed 14.857MHz on all PXA variants */
+ divisor = debug_ll_ns16550_calc_divisor(14857000);
+ debug_ll_ns16550_init(base, divisor);
+
+ /*
+ * debug_ll_ns16550_init() has cleared IER to disable the
+ * interrupts, which on PXA also disabled the unit. Enable it
+ * again, interrupts stay disabled.
+ */
+ debug_ll_write_reg(base, NS16550_IER, PXA_UART_IER_UUE);
+}
+
+static inline void PUTC_LL(char c)
+{
+ debug_ll_ns16550_putc(IOMEM(PXA_DEBUG_UART_BASE), c);
+}
+
+#else
+
+static inline void pxa_debug_ll_init(void)
+{
+}
+
+#endif /* CONFIG_DEBUG_PXA_UART */
+
+#endif /* __MACH_PXA_DEBUG_LL_H__ */
--
2.47.3
More information about the barebox
mailing list