diff options
Diffstat (limited to 'arch/arm/mach-at91/include/mach/uncompress.h')
-rw-r--r-- | arch/arm/mach-at91/include/mach/uncompress.h | 170 |
1 files changed, 145 insertions, 25 deletions
diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h index d985af7c94bd..6f6118d1576a 100644 --- a/arch/arm/mach-at91/include/mach/uncompress.h +++ b/arch/arm/mach-at91/include/mach/uncompress.h | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-at91/include/mach/uncompress.h | 2 | * arch/arm/mach-at91/include/mach/uncompress.h |
3 | * | 3 | * |
4 | * Copyright (C) 2003 SAN People | 4 | * Copyright (C) 2003 SAN People |
5 | * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -25,32 +26,149 @@ | |||
25 | #include <linux/atmel_serial.h> | 26 | #include <linux/atmel_serial.h> |
26 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
27 | 28 | ||
28 | #if defined(CONFIG_AT91_EARLY_DBGU0) | 29 | #include <mach/at91_dbgu.h> |
29 | #define UART_OFFSET AT91_BASE_DBGU0 | 30 | #include <mach/cpu.h> |
30 | #elif defined(CONFIG_AT91_EARLY_DBGU1) | ||
31 | #define UART_OFFSET AT91_BASE_DBGU1 | ||
32 | #elif defined(CONFIG_AT91_EARLY_USART0) | ||
33 | #define UART_OFFSET AT91_USART0 | ||
34 | #elif defined(CONFIG_AT91_EARLY_USART1) | ||
35 | #define UART_OFFSET AT91_USART1 | ||
36 | #elif defined(CONFIG_AT91_EARLY_USART2) | ||
37 | #define UART_OFFSET AT91_USART2 | ||
38 | #elif defined(CONFIG_AT91_EARLY_USART3) | ||
39 | #define UART_OFFSET AT91_USART3 | ||
40 | #elif defined(CONFIG_AT91_EARLY_USART4) | ||
41 | #define UART_OFFSET AT91_USART4 | ||
42 | #elif defined(CONFIG_AT91_EARLY_USART5) | ||
43 | #define UART_OFFSET AT91_USART5 | ||
44 | #endif | ||
45 | 31 | ||
46 | void __iomem *at91_uart; | 32 | void __iomem *at91_uart; |
47 | 33 | ||
34 | #if !defined(CONFIG_ARCH_AT91X40) | ||
35 | static const u32 uarts_rm9200[] = { | ||
36 | AT91_BASE_DBGU0, | ||
37 | AT91RM9200_BASE_US0, | ||
38 | AT91RM9200_BASE_US1, | ||
39 | AT91RM9200_BASE_US2, | ||
40 | AT91RM9200_BASE_US3, | ||
41 | 0, | ||
42 | }; | ||
43 | |||
44 | static const u32 uarts_sam9260[] = { | ||
45 | AT91_BASE_DBGU0, | ||
46 | AT91SAM9260_BASE_US0, | ||
47 | AT91SAM9260_BASE_US1, | ||
48 | AT91SAM9260_BASE_US2, | ||
49 | AT91SAM9260_BASE_US3, | ||
50 | AT91SAM9260_BASE_US4, | ||
51 | AT91SAM9260_BASE_US5, | ||
52 | 0, | ||
53 | }; | ||
54 | |||
55 | static const u32 uarts_sam9261[] = { | ||
56 | AT91_BASE_DBGU0, | ||
57 | AT91SAM9261_BASE_US0, | ||
58 | AT91SAM9261_BASE_US1, | ||
59 | AT91SAM9261_BASE_US2, | ||
60 | 0, | ||
61 | }; | ||
62 | |||
63 | static const u32 uarts_sam9263[] = { | ||
64 | AT91_BASE_DBGU1, | ||
65 | AT91SAM9263_BASE_US0, | ||
66 | AT91SAM9263_BASE_US1, | ||
67 | AT91SAM9263_BASE_US2, | ||
68 | 0, | ||
69 | }; | ||
70 | |||
71 | static const u32 uarts_sam9g45[] = { | ||
72 | AT91_BASE_DBGU1, | ||
73 | AT91SAM9G45_BASE_US0, | ||
74 | AT91SAM9G45_BASE_US1, | ||
75 | AT91SAM9G45_BASE_US2, | ||
76 | AT91SAM9G45_BASE_US3, | ||
77 | 0, | ||
78 | }; | ||
79 | |||
80 | static const u32 uarts_sam9rl[] = { | ||
81 | AT91_BASE_DBGU0, | ||
82 | AT91SAM9RL_BASE_US0, | ||
83 | AT91SAM9RL_BASE_US1, | ||
84 | AT91SAM9RL_BASE_US2, | ||
85 | AT91SAM9RL_BASE_US3, | ||
86 | 0, | ||
87 | }; | ||
88 | |||
89 | static const u32 uarts_sam9x5[] = { | ||
90 | AT91_BASE_DBGU0, | ||
91 | AT91SAM9X5_BASE_USART0, | ||
92 | AT91SAM9X5_BASE_USART1, | ||
93 | AT91SAM9X5_BASE_USART2, | ||
94 | 0, | ||
95 | }; | ||
96 | |||
97 | static inline const u32* decomp_soc_detect(u32 dbgu_base) | ||
98 | { | ||
99 | u32 cidr, socid; | ||
100 | |||
101 | cidr = __raw_readl(dbgu_base + AT91_DBGU_CIDR); | ||
102 | socid = cidr & ~AT91_CIDR_VERSION; | ||
103 | |||
104 | switch (socid) { | ||
105 | case ARCH_ID_AT91RM9200: | ||
106 | return uarts_rm9200; | ||
107 | |||
108 | case ARCH_ID_AT91SAM9G20: | ||
109 | case ARCH_ID_AT91SAM9260: | ||
110 | return uarts_sam9260; | ||
111 | |||
112 | case ARCH_ID_AT91SAM9261: | ||
113 | return uarts_sam9261; | ||
114 | |||
115 | case ARCH_ID_AT91SAM9263: | ||
116 | return uarts_sam9263; | ||
117 | |||
118 | case ARCH_ID_AT91SAM9G45: | ||
119 | return uarts_sam9g45; | ||
120 | |||
121 | case ARCH_ID_AT91SAM9RL64: | ||
122 | return uarts_sam9rl; | ||
123 | |||
124 | case ARCH_ID_AT91SAM9X5: | ||
125 | return uarts_sam9x5; | ||
126 | } | ||
127 | |||
128 | /* at91sam9g10 */ | ||
129 | if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { | ||
130 | return uarts_sam9261; | ||
131 | } | ||
132 | /* at91sam9xe */ | ||
133 | else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) { | ||
134 | return uarts_sam9260; | ||
135 | } | ||
136 | |||
137 | return NULL; | ||
138 | } | ||
139 | |||
48 | static inline void arch_decomp_setup(void) | 140 | static inline void arch_decomp_setup(void) |
49 | { | 141 | { |
50 | #ifdef UART_OFFSET | 142 | int i = 0; |
51 | at91_uart = (void __iomem *) UART_OFFSET; /* physical address */ | 143 | const u32* usarts; |
52 | #endif | 144 | |
145 | usarts = decomp_soc_detect(AT91_BASE_DBGU0); | ||
146 | |||
147 | if (!usarts) | ||
148 | usarts = decomp_soc_detect(AT91_BASE_DBGU1); | ||
149 | if (!usarts) { | ||
150 | at91_uart = NULL; | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | do { | ||
155 | /* physical address */ | ||
156 | at91_uart = (void __iomem *)usarts[i]; | ||
157 | |||
158 | if (__raw_readl(at91_uart + ATMEL_US_BRGR)) | ||
159 | return; | ||
160 | i++; | ||
161 | } while (usarts[i]); | ||
162 | |||
163 | at91_uart = NULL; | ||
53 | } | 164 | } |
165 | #else | ||
166 | static inline void arch_decomp_setup(void) | ||
167 | { | ||
168 | at91_uart = NULL; | ||
169 | } | ||
170 | #endif | ||
171 | |||
54 | /* | 172 | /* |
55 | * The following code assumes the serial port has already been | 173 | * The following code assumes the serial port has already been |
56 | * initialized by the bootloader. If you didn't setup a port in | 174 | * initialized by the bootloader. If you didn't setup a port in |
@@ -60,20 +178,22 @@ static inline void arch_decomp_setup(void) | |||
60 | */ | 178 | */ |
61 | static void putc(int c) | 179 | static void putc(int c) |
62 | { | 180 | { |
63 | #ifdef UART_OFFSET | 181 | if (!at91_uart) |
182 | return; | ||
183 | |||
64 | while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXRDY)) | 184 | while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXRDY)) |
65 | barrier(); | 185 | barrier(); |
66 | __raw_writel(c, at91_uart + ATMEL_US_THR); | 186 | __raw_writel(c, at91_uart + ATMEL_US_THR); |
67 | #endif | ||
68 | } | 187 | } |
69 | 188 | ||
70 | static inline void flush(void) | 189 | static inline void flush(void) |
71 | { | 190 | { |
72 | #ifdef UART_OFFSET | 191 | if (!at91_uart) |
192 | return; | ||
193 | |||
73 | /* wait for transmission to complete */ | 194 | /* wait for transmission to complete */ |
74 | while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXEMPTY)) | 195 | while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXEMPTY)) |
75 | barrier(); | 196 | barrier(); |
76 | #endif | ||
77 | } | 197 | } |
78 | 198 | ||
79 | #define arch_decomp_wdog() | 199 | #define arch_decomp_wdog() |