diff options
-rw-r--r-- | include/asm-arm/arch-ns9xxx/uncompress.h | 143 |
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 961ca7dc9954..71066baceab7 100644 --- a/include/asm-arm/arch-ns9xxx/uncompress.h +++ b/include/asm-arm/arch-ns9xxx/uncompress.h | |||
@@ -11,20 +11,149 @@ | |||
11 | #ifndef __ASM_ARCH_UNCOMPRESS_H | 11 | #ifndef __ASM_ARCH_UNCOMPRESS_H |
12 | #define __ASM_ARCH_UNCOMPRESS_H | 12 | #define __ASM_ARCH_UNCOMPRESS_H |
13 | 13 | ||
14 | static void putc(char c) | 14 | #include <asm/io.h> |
15 | |||
16 | #define __REG(x) ((void __iomem __force *)(x)) | ||
17 | |||
18 | static void putc_dummy(char c, void __iomem *base) | ||
15 | { | 19 | { |
16 | volatile u8 *base = (volatile u8 *)0x40000000; | 20 | /* nothing */ |
17 | int t = 0x10000; | 21 | } |
18 | 22 | ||
23 | static void putc_ns9360(char c, void __iomem *base) | ||
24 | { | ||
25 | static int t = 0x10000; | ||
26 | do { | ||
27 | if (t) | ||
28 | --t; | ||
29 | |||
30 | if (__raw_readl(base + 8) & (1 << 3)) { | ||
31 | __raw_writeb(c, base + 16); | ||
32 | t = 0x10000; | ||
33 | break; | ||
34 | } | ||
35 | } while (t); | ||
36 | } | ||
37 | |||
38 | static void putc_a9m9750dev(char c, void __iomem *base) | ||
39 | { | ||
40 | static int t = 0x10000; | ||
41 | do { | ||
42 | if (t) | ||
43 | --t; | ||
44 | |||
45 | if (__raw_readb(base + 5) & (1 << 5)) { | ||
46 | __raw_writeb(c, base); | ||
47 | t = 0x10000; | ||
48 | break; | ||
49 | } | ||
50 | } while (t); | ||
51 | |||
52 | } | ||
53 | |||
54 | static void putc_ns921x(char c, void __iomem *base) | ||
55 | { | ||
56 | static int t = 0x10000; | ||
19 | do { | 57 | do { |
20 | if (base[5] & 0x20) { | 58 | if (t) |
21 | base[0] = c; | 59 | --t; |
60 | |||
61 | if (!(__raw_readl(base) & (1 << 11))) { | ||
62 | __raw_writeb(c, base + 0x0028); | ||
63 | t = 0x10000; | ||
22 | break; | 64 | break; |
23 | } | 65 | } |
24 | } while (--t); | 66 | } while (t); |
25 | } | 67 | } |
26 | 68 | ||
27 | #define arch_decomp_setup() | 69 | #define MSCS __REG(0xA0900184) |
70 | |||
71 | #define NS9360_UARTA __REG(0x90200040) | ||
72 | #define NS9360_UARTB __REG(0x90200000) | ||
73 | #define NS9360_UARTC __REG(0x90300000) | ||
74 | #define NS9360_UARTD __REG(0x90300040) | ||
75 | |||
76 | #define NS9360_UART_ENABLED(base) \ | ||
77 | (__raw_readl(NS9360_UARTA) & (1 << 31)) | ||
78 | |||
79 | #define A9M9750DEV_UARTA __REG(0x40000000) | ||
80 | |||
81 | #define NS921XSYS_CLOCK __REG(0xa090017c) | ||
82 | #define NS921X_UARTA __REG(0x90010000) | ||
83 | #define NS921X_UARTB __REG(0x90018000) | ||
84 | #define NS921X_UARTC __REG(0x90020000) | ||
85 | #define NS921X_UARTD __REG(0x90028000) | ||
86 | |||
87 | #define NS921X_UART_ENABLED(base) \ | ||
88 | (__raw_readl((base) + 0x1000) & (1 << 29)) | ||
89 | |||
90 | static void autodetect(void (**putc)(char, void __iomem *), void __iomem **base) | ||
91 | { | ||
92 | if (((__raw_readl(MSCS) >> 16) & 0xfe) == 0x00) { | ||
93 | /* ns9360 or ns9750 */ | ||
94 | if (NS9360_UART_ENABLED(NS9360_UARTA)) { | ||
95 | *putc = putc_ns9360; | ||
96 | *base = NS9360_UARTA; | ||
97 | return; | ||
98 | } else if (NS9360_UART_ENABLED(NS9360_UARTB)) { | ||
99 | *putc = putc_ns9360; | ||
100 | *base = NS9360_UARTB; | ||
101 | return; | ||
102 | } else if (NS9360_UART_ENABLED(NS9360_UARTC)) { | ||
103 | *putc = putc_ns9360; | ||
104 | *base = NS9360_UARTC; | ||
105 | return; | ||
106 | } else if (NS9360_UART_ENABLED(NS9360_UARTD)) { | ||
107 | *putc = putc_ns9360; | ||
108 | *base = NS9360_UARTD; | ||
109 | return; | ||
110 | } else if (__raw_readl(__REG(0xa09001f4)) == 0xfffff001) { | ||
111 | *putc = putc_a9m9750dev; | ||
112 | *base = A9M9750DEV_UARTA; | ||
113 | return; | ||
114 | } | ||
115 | } else if (((__raw_readl(MSCS) >> 16) & 0xfe) == 0x02) { | ||
116 | /* ns921x */ | ||
117 | u32 clock = __raw_readl(NS921XSYS_CLOCK); | ||
118 | |||
119 | if ((clock & (1 << 1)) && | ||
120 | NS921X_UART_ENABLED(NS921X_UARTA)) { | ||
121 | *putc = putc_ns921x; | ||
122 | *base = NS921X_UARTA; | ||
123 | return; | ||
124 | } else if ((clock & (1 << 2)) && | ||
125 | NS921X_UART_ENABLED(NS921X_UARTB)) { | ||
126 | *putc = putc_ns921x; | ||
127 | *base = NS921X_UARTB; | ||
128 | return; | ||
129 | } else if ((clock & (1 << 3)) && | ||
130 | NS921X_UART_ENABLED(NS921X_UARTC)) { | ||
131 | *putc = putc_ns921x; | ||
132 | *base = NS921X_UARTC; | ||
133 | return; | ||
134 | } else if ((clock & (1 << 4)) && | ||
135 | NS921X_UART_ENABLED(NS921X_UARTD)) { | ||
136 | *putc = putc_ns921x; | ||
137 | *base = NS921X_UARTD; | ||
138 | return; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | *putc = putc_dummy; | ||
143 | } | ||
144 | |||
145 | void (*myputc)(char, void __iomem *); | ||
146 | void __iomem *base; | ||
147 | |||
148 | static void putc(char c) | ||
149 | { | ||
150 | myputc(c, base); | ||
151 | } | ||
152 | |||
153 | static void arch_decomp_setup(void) | ||
154 | { | ||
155 | autodetect(&myputc, &base); | ||
156 | } | ||
28 | #define arch_decomp_wdog() | 157 | #define arch_decomp_wdog() |
29 | 158 | ||
30 | static void flush(void) | 159 | static void flush(void) |