[U-Boot] [PATCH 4/5] tegra: Provide tegra_pre_console_panic() for early panics

Simon Glass sjg at chromium.org
Mon Mar 19 21:27:03 CET 2012


This function is made available to board which want to display a message
when a panic() occurs before the console is set up. This would otherwise
result in a silent hang or reboot.

Boards should call tegra_pre_console_panic() and pass the UARTs which
are available and safe for a message, as well as the selected clock and
serial multiplier values. Defaults are available as
CONFIG_DEFAULT_NS16550_CLK and CONFIG_DEFAULT_NS16550_MULT.

Signed-off-by: Simon Glass <sjg at chromium.org>
---
 arch/arm/cpu/armv7/tegra2/board.c        |   44 ++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/board.h |   13 +++++++++
 include/configs/tegra2-common.h          |    4 +++
 3 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c
index c9a7520..6e76dbe 100644
--- a/arch/arm/cpu/armv7/tegra2/board.c
+++ b/arch/arm/cpu/armv7/tegra2/board.c
@@ -22,6 +22,7 @@
  */
 
 #include <common.h>
+#include <ns16550.h>
 #include <asm/io.h>
 #include "ap20.h"
 #include <asm/arch/board.h>
@@ -137,3 +138,46 @@ void enable_caches(void)
 	dcache_enable();
 }
 #endif
+
+/*
+ * Possible UART locations: we ignore UARTC at 0x70006200 and UARTE at
+ * 0x70006400, since we don't have code to init them
+ */
+static const u32 uart_reg_addr[] = {
+	NV_PA_APB_UARTA_BASE,
+	NV_PA_APB_UARTB_BASE,
+	NV_PA_APB_UARTD_BASE,
+	0
+};
+
+void tegra_pre_console_panic(int uart_ids, unsigned clock_freq,
+			     unsigned multiplier, const char *str)
+{
+	int baudrate, divisor;
+	const u32 *uart_addr;
+
+	/* Enable all permitted UARTs */
+	tegra_setup_uarts(uart_ids);
+
+	/*
+	 * Now send the string out all the selected  UARTs. We don't try all
+	 * possible configurations, but this could be added if required.
+	 */
+	baudrate = CONFIG_BAUDRATE;
+	divisor = (clock_freq + (baudrate * (multiplier / 2))) /
+			(multiplier * baudrate);
+
+	for (uart_addr = uart_reg_addr; *uart_addr; uart_addr++) {
+		NS16550_t regs = (NS16550_t)*uart_addr;
+		const char *s;
+
+		NS16550_init(regs, divisor);
+		for (s = str; *s; s++) {
+			NS16550_putc(regs, *s);
+			if (*s == '\n')
+				NS16550_putc(regs, '\r');
+		}
+		NS16550_putc(regs, '\n');
+		NS16550_putc(regs, '\r');
+	}
+}
diff --git a/arch/arm/include/asm/arch-tegra2/board.h b/arch/arm/include/asm/arch-tegra2/board.h
index fb88517..fd2489f 100644
--- a/arch/arm/include/asm/arch-tegra2/board.h
+++ b/arch/arm/include/asm/arch-tegra2/board.h
@@ -41,6 +41,19 @@ enum {
  */
 void tegra_setup_uarts(int uart_ids);
 
+/**
+ * Display a panic message on selected UARTs.
+ *
+ * This is called when we have no console yet but have hit a panic(). It
+ * is normally called from board_pre_console_panic(), which passes in the
+ * UARTs that we are permitted to output to.
+ *
+ * We display a message on each UART in the hope that one will reach the
+ * user.
+ */
+void tegra_pre_console_panic(int uart_ids, unsigned clock_freq,
+			     unsigned multiplier, const char *str);
+
 /* Setup UARTs for the board according to the selected config */
 void board_init_uart_f(void);
 
diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h
index 837f859..14d7602 100644
--- a/include/configs/tegra2-common.h
+++ b/include/configs/tegra2-common.h
@@ -84,6 +84,10 @@
 #define CONFIG_SYS_BAUDRATE_TABLE	{4800, 9600, 19200, 38400, 57600,\
 					115200}
 
+/* Default serial clock and multiplier */
+#define CONFIG_DEFAULT_NS16550_CLK	V_NS16550_CLK
+#define CONFIG_DEFAULT_NS16550_MULT	16
+
 /*
  * This parameter affects a TXFILLTUNING field that controls how much data is
  * sent to the latency fifo before it is sent to the wire. Without this
-- 
1.7.7.3



More information about the U-Boot mailing list