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 <s...@chromium.org>
---

 arch/arm/cpu/armv7/tegra2/board.c        |   48 ++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/board.h |   13 ++++++++
 include/configs/tegra2-common.h          |    4 ++
 3 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/armv7/tegra2/board.c 
b/arch/arm/cpu/armv7/tegra2/board.c
index c9a7520..54963d0 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,50 @@ 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[TEGRA_UART_COUNT] = {
+       NV_PA_APB_UARTA_BASE,
+       NV_PA_APB_UARTB_BASE,
+       0,
+       NV_PA_APB_UARTD_BASE,
+};
+
+void tegra_pre_console_panic(int uart_ids, unsigned clock_freq,
+                            unsigned multiplier, const char *str)
+{
+       int baudrate, divisor;
+       int i;
+
+       /* 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 (i = 0; i < TEGRA_UART_COUNT; i++) {
+               if (uart_ids & (1 << i)) {
+                       NS16550_t regs = (NS16550_t)uart_reg_addr[i];
+                       const char *s;
+
+                       if (!regs)
+                               continue;
+                       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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to