aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-arm
diff options
context:
space:
mode:
authorUwe Kleine-König <Uwe.Kleine-Koenig@digi.com>2008-02-06 15:10:41 +0100
committerUwe Kleine-König <Uwe.Kleine-Koenig@digi.com>2008-03-31 08:17:01 +0200
commita287453e37a11a128ee0761e1db2e79d7faacdb3 (patch)
treeeef8ae184404db195d3d8e6fc122991a705e8062 /include/asm-arm
parent724ce5ee15ff4c4f3035110b683b990a3b33c832 (diff)
downloadkernel_samsung_smdk4412-a287453e37a11a128ee0761e1db2e79d7faacdb3.zip
kernel_samsung_smdk4412-a287453e37a11a128ee0761e1db2e79d7faacdb3.tar.gz
kernel_samsung_smdk4412-a287453e37a11a128ee0761e1db2e79d7faacdb3.tar.bz2
ns9xxx: let putc autodetect where to write
Now putc writes to the first enabled internal UART. If there is none the external UART on the a9m9750dev board is used (if enabled). Otherwise there is no output. Signed-off-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Diffstat (limited to 'include/asm-arm')
-rw-r--r--include/asm-arm/arch-ns9xxx/uncompress.h143
1 files changed, 136 insertions, 7 deletions
diff --git a/include/asm-arm/arch-ns9xxx/uncompress.h b/include/asm-arm/arch-ns9xxx/uncompress.h
index 961ca7d..71066ba 100644
--- a/include/asm-arm/arch-ns9xxx/uncompress.h
+++ b/include/asm-arm/arch-ns9xxx/uncompress.h
@@ -11,20 +11,149 @@
#ifndef __ASM_ARCH_UNCOMPRESS_H
#define __ASM_ARCH_UNCOMPRESS_H
-static void putc(char c)
+#include <asm/io.h>
+
+#define __REG(x) ((void __iomem __force *)(x))
+
+static void putc_dummy(char c, void __iomem *base)
{
- volatile u8 *base = (volatile u8 *)0x40000000;
- int t = 0x10000;
+ /* nothing */
+}
+static void putc_ns9360(char c, void __iomem *base)
+{
+ static int t = 0x10000;
+ do {
+ if (t)
+ --t;
+
+ if (__raw_readl(base + 8) & (1 << 3)) {
+ __raw_writeb(c, base + 16);
+ t = 0x10000;
+ break;
+ }
+ } while (t);
+}
+
+static void putc_a9m9750dev(char c, void __iomem *base)
+{
+ static int t = 0x10000;
+ do {
+ if (t)
+ --t;
+
+ if (__raw_readb(base + 5) & (1 << 5)) {
+ __raw_writeb(c, base);
+ t = 0x10000;
+ break;
+ }
+ } while (t);
+
+}
+
+static void putc_ns921x(char c, void __iomem *base)
+{
+ static int t = 0x10000;
do {
- if (base[5] & 0x20) {
- base[0] = c;
+ if (t)
+ --t;
+
+ if (!(__raw_readl(base) & (1 << 11))) {
+ __raw_writeb(c, base + 0x0028);
+ t = 0x10000;
break;
}
- } while (--t);
+ } while (t);
}
-#define arch_decomp_setup()
+#define MSCS __REG(0xA0900184)
+
+#define NS9360_UARTA __REG(0x90200040)
+#define NS9360_UARTB __REG(0x90200000)
+#define NS9360_UARTC __REG(0x90300000)
+#define NS9360_UARTD __REG(0x90300040)
+
+#define NS9360_UART_ENABLED(base) \
+ (__raw_readl(NS9360_UARTA) & (1 << 31))
+
+#define A9M9750DEV_UARTA __REG(0x40000000)
+
+#define NS921XSYS_CLOCK __REG(0xa090017c)
+#define NS921X_UARTA __REG(0x90010000)
+#define NS921X_UARTB __REG(0x90018000)
+#define NS921X_UARTC __REG(0x90020000)
+#define NS921X_UARTD __REG(0x90028000)
+
+#define NS921X_UART_ENABLED(base) \
+ (__raw_readl((base) + 0x1000) & (1 << 29))
+
+static void autodetect(void (**putc)(char, void __iomem *), void __iomem **base)
+{
+ if (((__raw_readl(MSCS) >> 16) & 0xfe) == 0x00) {
+ /* ns9360 or ns9750 */
+ if (NS9360_UART_ENABLED(NS9360_UARTA)) {
+ *putc = putc_ns9360;
+ *base = NS9360_UARTA;
+ return;
+ } else if (NS9360_UART_ENABLED(NS9360_UARTB)) {
+ *putc = putc_ns9360;
+ *base = NS9360_UARTB;
+ return;
+ } else if (NS9360_UART_ENABLED(NS9360_UARTC)) {
+ *putc = putc_ns9360;
+ *base = NS9360_UARTC;
+ return;
+ } else if (NS9360_UART_ENABLED(NS9360_UARTD)) {
+ *putc = putc_ns9360;
+ *base = NS9360_UARTD;
+ return;
+ } else if (__raw_readl(__REG(0xa09001f4)) == 0xfffff001) {
+ *putc = putc_a9m9750dev;
+ *base = A9M9750DEV_UARTA;
+ return;
+ }
+ } else if (((__raw_readl(MSCS) >> 16) & 0xfe) == 0x02) {
+ /* ns921x */
+ u32 clock = __raw_readl(NS921XSYS_CLOCK);
+
+ if ((clock & (1 << 1)) &&
+ NS921X_UART_ENABLED(NS921X_UARTA)) {
+ *putc = putc_ns921x;
+ *base = NS921X_UARTA;
+ return;
+ } else if ((clock & (1 << 2)) &&
+ NS921X_UART_ENABLED(NS921X_UARTB)) {
+ *putc = putc_ns921x;
+ *base = NS921X_UARTB;
+ return;
+ } else if ((clock & (1 << 3)) &&
+ NS921X_UART_ENABLED(NS921X_UARTC)) {
+ *putc = putc_ns921x;
+ *base = NS921X_UARTC;
+ return;
+ } else if ((clock & (1 << 4)) &&
+ NS921X_UART_ENABLED(NS921X_UARTD)) {
+ *putc = putc_ns921x;
+ *base = NS921X_UARTD;
+ return;
+ }
+ }
+
+ *putc = putc_dummy;
+}
+
+void (*myputc)(char, void __iomem *);
+void __iomem *base;
+
+static void putc(char c)
+{
+ myputc(c, base);
+}
+
+static void arch_decomp_setup(void)
+{
+ autodetect(&myputc, &base);
+}
#define arch_decomp_wdog()
static void flush(void)