diff options
Diffstat (limited to 'arch/arm/mach-at91/setup.c')
-rw-r--r-- | arch/arm/mach-at91/setup.c | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c new file mode 100644 index 000000000000..aa64294c7db3 --- /dev/null +++ b/arch/arm/mach-at91/setup.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Atmel Corporation. | ||
3 | * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | ||
4 | * | ||
5 | * Under GPLv2 | ||
6 | */ | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include <linux/io.h> | ||
10 | #include <linux/mm.h> | ||
11 | |||
12 | #include <asm/mach/map.h> | ||
13 | |||
14 | #include <mach/hardware.h> | ||
15 | #include <mach/cpu.h> | ||
16 | #include <mach/at91_dbgu.h> | ||
17 | #include <mach/at91_pmc.h> | ||
18 | |||
19 | #include "soc.h" | ||
20 | #include "generic.h" | ||
21 | |||
22 | struct at91_init_soc __initdata at91_boot_soc; | ||
23 | |||
24 | struct at91_socinfo at91_soc_initdata; | ||
25 | EXPORT_SYMBOL(at91_soc_initdata); | ||
26 | |||
27 | void __init at91rm9200_set_type(int type) | ||
28 | { | ||
29 | if (type == ARCH_REVISON_9200_PQFP) | ||
30 | at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA; | ||
31 | else | ||
32 | at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP; | ||
33 | } | ||
34 | |||
35 | void __init at91_init_irq_default(void) | ||
36 | { | ||
37 | at91_init_interrupts(at91_boot_soc.default_irq_priority); | ||
38 | } | ||
39 | |||
40 | void __init at91_init_interrupts(unsigned int *priority) | ||
41 | { | ||
42 | /* Initialize the AIC interrupt controller */ | ||
43 | at91_aic_init(priority); | ||
44 | |||
45 | /* Enable GPIO interrupts */ | ||
46 | at91_gpio_irq_setup(); | ||
47 | } | ||
48 | |||
49 | static struct map_desc sram_desc[2] __initdata; | ||
50 | |||
51 | void __init at91_init_sram(int bank, unsigned long base, unsigned int length) | ||
52 | { | ||
53 | struct map_desc *desc = &sram_desc[bank]; | ||
54 | |||
55 | desc->virtual = AT91_IO_VIRT_BASE - length; | ||
56 | if (bank > 0) | ||
57 | desc->virtual -= sram_desc[bank - 1].length; | ||
58 | |||
59 | desc->pfn = __phys_to_pfn(base); | ||
60 | desc->length = length; | ||
61 | desc->type = MT_DEVICE; | ||
62 | |||
63 | pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n", | ||
64 | base, length, desc->virtual); | ||
65 | |||
66 | iotable_init(desc, 1); | ||
67 | } | ||
68 | |||
69 | static struct map_desc at91_io_desc __initdata = { | ||
70 | .virtual = AT91_VA_BASE_SYS, | ||
71 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | ||
72 | .length = SZ_16K, | ||
73 | .type = MT_DEVICE, | ||
74 | }; | ||
75 | |||
76 | void __iomem *at91_ioremap(unsigned long p, size_t size, unsigned int type) | ||
77 | { | ||
78 | if (p >= AT91_BASE_SYS && p <= (AT91_BASE_SYS + SZ_16K - 1)) | ||
79 | return (void __iomem *)AT91_IO_P2V(p); | ||
80 | |||
81 | return __arm_ioremap_caller(p, size, type, __builtin_return_address(0)); | ||
82 | } | ||
83 | EXPORT_SYMBOL(at91_ioremap); | ||
84 | |||
85 | void at91_iounmap(volatile void __iomem *addr) | ||
86 | { | ||
87 | unsigned long virt = (unsigned long)addr; | ||
88 | |||
89 | if (virt >= VMALLOC_START && virt < VMALLOC_END) | ||
90 | __iounmap(addr); | ||
91 | } | ||
92 | EXPORT_SYMBOL(at91_iounmap); | ||
93 | |||
94 | #define AT91_DBGU0 0xfffff200 | ||
95 | #define AT91_DBGU1 0xffffee00 | ||
96 | |||
97 | static void __init soc_detect(u32 dbgu_base) | ||
98 | { | ||
99 | u32 cidr, socid; | ||
100 | |||
101 | cidr = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_CIDR); | ||
102 | socid = cidr & ~AT91_CIDR_VERSION; | ||
103 | |||
104 | switch (socid) { | ||
105 | case ARCH_ID_AT91CAP9: { | ||
106 | #ifdef CONFIG_AT91_PMC_UNIT | ||
107 | u32 pmc_ver = at91_sys_read(AT91_PMC_VER); | ||
108 | |||
109 | if (pmc_ver == ARCH_REVISION_CAP9_B) | ||
110 | at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_B; | ||
111 | else if (pmc_ver == ARCH_REVISION_CAP9_C) | ||
112 | at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_C; | ||
113 | #endif | ||
114 | at91_soc_initdata.type = AT91_SOC_CAP9; | ||
115 | at91_boot_soc = at91cap9_soc; | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | case ARCH_ID_AT91RM9200: | ||
120 | at91_soc_initdata.type = AT91_SOC_RM9200; | ||
121 | at91_boot_soc = at91rm9200_soc; | ||
122 | break; | ||
123 | |||
124 | case ARCH_ID_AT91SAM9260: | ||
125 | at91_soc_initdata.type = AT91_SOC_SAM9260; | ||
126 | at91_boot_soc = at91sam9260_soc; | ||
127 | break; | ||
128 | |||
129 | case ARCH_ID_AT91SAM9261: | ||
130 | at91_soc_initdata.type = AT91_SOC_SAM9261; | ||
131 | at91_boot_soc = at91sam9261_soc; | ||
132 | break; | ||
133 | |||
134 | case ARCH_ID_AT91SAM9263: | ||
135 | at91_soc_initdata.type = AT91_SOC_SAM9263; | ||
136 | at91_boot_soc = at91sam9263_soc; | ||
137 | break; | ||
138 | |||
139 | case ARCH_ID_AT91SAM9G20: | ||
140 | at91_soc_initdata.type = AT91_SOC_SAM9G20; | ||
141 | at91_boot_soc = at91sam9260_soc; | ||
142 | break; | ||
143 | |||
144 | case ARCH_ID_AT91SAM9G45: | ||
145 | at91_soc_initdata.type = AT91_SOC_SAM9G45; | ||
146 | if (cidr == ARCH_ID_AT91SAM9G45ES) | ||
147 | at91_soc_initdata.subtype = AT91_SOC_SAM9G45ES; | ||
148 | at91_boot_soc = at91sam9g45_soc; | ||
149 | break; | ||
150 | |||
151 | case ARCH_ID_AT91SAM9RL64: | ||
152 | at91_soc_initdata.type = AT91_SOC_SAM9RL; | ||
153 | at91_boot_soc = at91sam9rl_soc; | ||
154 | break; | ||
155 | |||
156 | case ARCH_ID_AT91SAM9X5: | ||
157 | at91_soc_initdata.type = AT91_SOC_SAM9X5; | ||
158 | at91_boot_soc = at91sam9x5_soc; | ||
159 | break; | ||
160 | } | ||
161 | |||
162 | /* at91sam9g10 */ | ||
163 | if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { | ||
164 | at91_soc_initdata.type = AT91_SOC_SAM9G10; | ||
165 | at91_boot_soc = at91sam9261_soc; | ||
166 | } | ||
167 | /* at91sam9xe */ | ||
168 | else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) { | ||
169 | at91_soc_initdata.type = AT91_SOC_SAM9260; | ||
170 | at91_soc_initdata.subtype = AT91_SOC_SAM9XE; | ||
171 | at91_boot_soc = at91sam9260_soc; | ||
172 | } | ||
173 | |||
174 | if (!at91_soc_is_detected()) | ||
175 | return; | ||
176 | |||
177 | at91_soc_initdata.cidr = cidr; | ||
178 | |||
179 | /* sub version of soc */ | ||
180 | at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID); | ||
181 | |||
182 | if (at91_soc_initdata.type == AT91_SOC_SAM9G45) { | ||
183 | switch (at91_soc_initdata.exid) { | ||
184 | case ARCH_EXID_AT91SAM9M10: | ||
185 | at91_soc_initdata.subtype = AT91_SOC_SAM9M10; | ||
186 | break; | ||
187 | case ARCH_EXID_AT91SAM9G46: | ||
188 | at91_soc_initdata.subtype = AT91_SOC_SAM9G46; | ||
189 | break; | ||
190 | case ARCH_EXID_AT91SAM9M11: | ||
191 | at91_soc_initdata.subtype = AT91_SOC_SAM9M11; | ||
192 | break; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | if (at91_soc_initdata.type == AT91_SOC_SAM9X5) { | ||
197 | switch (at91_soc_initdata.exid) { | ||
198 | case ARCH_EXID_AT91SAM9G15: | ||
199 | at91_soc_initdata.subtype = AT91_SOC_SAM9G15; | ||
200 | break; | ||
201 | case ARCH_EXID_AT91SAM9G35: | ||
202 | at91_soc_initdata.subtype = AT91_SOC_SAM9G35; | ||
203 | break; | ||
204 | case ARCH_EXID_AT91SAM9X35: | ||
205 | at91_soc_initdata.subtype = AT91_SOC_SAM9X35; | ||
206 | break; | ||
207 | case ARCH_EXID_AT91SAM9G25: | ||
208 | at91_soc_initdata.subtype = AT91_SOC_SAM9G25; | ||
209 | break; | ||
210 | case ARCH_EXID_AT91SAM9X25: | ||
211 | at91_soc_initdata.subtype = AT91_SOC_SAM9X25; | ||
212 | break; | ||
213 | } | ||
214 | } | ||
215 | } | ||
216 | |||
217 | static const char *soc_name[] = { | ||
218 | [AT91_SOC_RM9200] = "at91rm9200", | ||
219 | [AT91_SOC_CAP9] = "at91cap9", | ||
220 | [AT91_SOC_SAM9260] = "at91sam9260", | ||
221 | [AT91_SOC_SAM9261] = "at91sam9261", | ||
222 | [AT91_SOC_SAM9263] = "at91sam9263", | ||
223 | [AT91_SOC_SAM9G10] = "at91sam9g10", | ||
224 | [AT91_SOC_SAM9G20] = "at91sam9g20", | ||
225 | [AT91_SOC_SAM9G45] = "at91sam9g45", | ||
226 | [AT91_SOC_SAM9RL] = "at91sam9rl", | ||
227 | [AT91_SOC_SAM9X5] = "at91sam9x5", | ||
228 | [AT91_SOC_NONE] = "Unknown" | ||
229 | }; | ||
230 | |||
231 | const char *at91_get_soc_type(struct at91_socinfo *c) | ||
232 | { | ||
233 | return soc_name[c->type]; | ||
234 | } | ||
235 | EXPORT_SYMBOL(at91_get_soc_type); | ||
236 | |||
237 | static const char *soc_subtype_name[] = { | ||
238 | [AT91_SOC_RM9200_BGA] = "at91rm9200 BGA", | ||
239 | [AT91_SOC_RM9200_PQFP] = "at91rm9200 PQFP", | ||
240 | [AT91_SOC_CAP9_REV_B] = "at91cap9 revB", | ||
241 | [AT91_SOC_CAP9_REV_C] = "at91cap9 revC", | ||
242 | [AT91_SOC_SAM9XE] = "at91sam9xe", | ||
243 | [AT91_SOC_SAM9G45ES] = "at91sam9g45es", | ||
244 | [AT91_SOC_SAM9M10] = "at91sam9m10", | ||
245 | [AT91_SOC_SAM9G46] = "at91sam9g46", | ||
246 | [AT91_SOC_SAM9M11] = "at91sam9m11", | ||
247 | [AT91_SOC_SAM9G15] = "at91sam9g15", | ||
248 | [AT91_SOC_SAM9G35] = "at91sam9g35", | ||
249 | [AT91_SOC_SAM9X35] = "at91sam9x35", | ||
250 | [AT91_SOC_SAM9G25] = "at91sam9g25", | ||
251 | [AT91_SOC_SAM9X25] = "at91sam9x25", | ||
252 | [AT91_SOC_SUBTYPE_NONE] = "Unknown" | ||
253 | }; | ||
254 | |||
255 | const char *at91_get_soc_subtype(struct at91_socinfo *c) | ||
256 | { | ||
257 | return soc_subtype_name[c->subtype]; | ||
258 | } | ||
259 | EXPORT_SYMBOL(at91_get_soc_subtype); | ||
260 | |||
261 | void __init at91_map_io(void) | ||
262 | { | ||
263 | /* Map peripherals */ | ||
264 | iotable_init(&at91_io_desc, 1); | ||
265 | |||
266 | at91_soc_initdata.type = AT91_SOC_NONE; | ||
267 | at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; | ||
268 | |||
269 | soc_detect(AT91_DBGU0); | ||
270 | if (!at91_soc_is_detected()) | ||
271 | soc_detect(AT91_DBGU1); | ||
272 | |||
273 | if (!at91_soc_is_detected()) | ||
274 | panic("AT91: Impossible to detect the SOC type"); | ||
275 | |||
276 | pr_info("AT91: Detected soc type: %s\n", | ||
277 | at91_get_soc_type(&at91_soc_initdata)); | ||
278 | pr_info("AT91: Detected soc subtype: %s\n", | ||
279 | at91_get_soc_subtype(&at91_soc_initdata)); | ||
280 | |||
281 | if (!at91_soc_is_enabled()) | ||
282 | panic("AT91: Soc not enabled"); | ||
283 | |||
284 | if (at91_boot_soc.map_io) | ||
285 | at91_boot_soc.map_io(); | ||
286 | } | ||
287 | |||
288 | void __init at91_initialize(unsigned long main_clock) | ||
289 | { | ||
290 | /* Init clock subsystem */ | ||
291 | at91_clock_init(main_clock); | ||
292 | |||
293 | /* Register the processor-specific clocks */ | ||
294 | at91_boot_soc.register_clocks(); | ||
295 | |||
296 | at91_boot_soc.init(); | ||
297 | } | ||