diff --git a/arch/arm/mach-socfpga/include/mach/debug_ll.h b/arch/arm/mach-socfpga/include/mach/debug_ll.h index f378435..4e906ea 100644 --- a/arch/arm/mach-socfpga/include/mach/debug_ll.h +++ b/arch/arm/mach-socfpga/include/mach/debug_ll.h @@ -2,24 +2,33 @@ #define __MACH_DEBUG_LL_H__ #include +#include -#define UART_BASE 0xffc02000 +#ifdef CONFIG_DEBUG_LL +#define UART_BASE CONFIG_DEBUG_SOCFPGA_UART_PHYS_ADDR +#endif #define LSR_THRE 0x20 /* Xmit holding register empty */ -#define LSR (5 << 2) -#define THR (0 << 2) +#define LSR_TEMT 0x40 #define LCR_BKSE 0x80 /* Bank select enable */ -#define LSR (5 << 2) -#define THR (0 << 2) -#define DLL (0 << 2) -#define IER (1 << 2) -#define DLM (1 << 2) -#define FCR (2 << 2) -#define LCR (3 << 2) -#define MCR (4 << 2) -#define MDR (8 << 2) +#define LCRVAL 0x3 +#define MCRVAL 0x3 +#define FCRVAL 0xc1 +#define RBR 0x0 +#define DLL 0x0 +#define IER 0x4 +#define DLM 0x4 +#define FCR 0x8 +#define LCR 0xc +#define MCR 0x10 +#define LSR 0x14 +#define MSR 0x18 +#define SCR 0x1c +#define THR 0x30 + +#ifdef CONFIG_DEBUG_LL static inline unsigned int ns16550_calc_divisor(unsigned int clk, unsigned int baudrate) { @@ -28,19 +37,20 @@ static inline void INIT_LL(void) { - unsigned int clk = 100000000; - unsigned int divisor = clk / 16 / 115200; + unsigned int div = ns16550_calc_divisor(CONFIG_DEBUG_SOCFPGA_UART_CLOCK, + 115200); - writeb(0x00, UART_BASE + LCR); - writeb(0x00, UART_BASE + IER); - writeb(0x07, UART_BASE + MDR); - writeb(LCR_BKSE, UART_BASE + LCR); - writeb(divisor & 0xff, UART_BASE + DLL); - writeb(divisor >> 8, UART_BASE + DLM); - writeb(0x03, UART_BASE + LCR); - writeb(0x03, UART_BASE + MCR); - writeb(0x07, UART_BASE + FCR); - writeb(0x00, UART_BASE + MDR); + while ((readl(UART_BASE + LSR) & LSR_TEMT) == 0); + + writel(0x00, UART_BASE + IER); + + writel(LCR_BKSE, UART_BASE + LCR); + writel(div & 0xff, UART_BASE + DLL); + writel((div >> 8) & 0xff, UART_BASE + DLM); + writel(LCRVAL, UART_BASE + LCR); + + writel(MCRVAL, UART_BASE + MCR); + writel(FCRVAL, UART_BASE + FCR); } static inline void PUTC_LL(char c) @@ -52,4 +62,13 @@ /* Wait to make sure it hits the line, in case we die too soon. */ while ((readb(UART_BASE + LSR) & LSR_THRE) == 0); } + +#else +static inline unsigned int ns16550_calc_divisor(unsigned int clk, + unsigned int baudrate) { + return -ENOSYS; +} +static inline void INIT_LL(void) {} +static inline void PUTC_LL(char c) {} +#endif #endif diff --git a/common/Kconfig b/common/Kconfig index 8dd40db..4c7a2d2 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -1122,6 +1122,14 @@ Say Y here if you want kernel low-level debugging support on RK3XXX. +config DEBUG_SOCFPGA_UART0 + bool "Use SOCFPGA UART0 for low-level debug" + depends on ARCH_SOCFPGA + help + Say Y here if you want kernel low-level debugging support + on SOCFPGA(Cyclone 5 and Arria 5) based platforms. + + endchoice config DEBUG_IMX_UART_PORT @@ -1164,6 +1172,18 @@ Choose UART port on which kernel low-level debug messages should be output. +config DEBUG_SOCFPGA_UART_PHYS_ADDR + hex "Physical base address of debug UART" if DEBUG_LL + default 0xffc02000 if DEBUG_SOCFPGA_UART0 + depends on ARCH_SOCFPGA + +config DEBUG_SOCFPGA_UART_CLOCK + int "SoCFPGA UART debug clock" if DEBUG_LL + default 100000000 + depends on ARCH_SOCFPGA + help + Choose UART root clock. + config DEBUG_INITCALLS bool "Trace initcalls" help