Merge remote-tracking branch 'asoc/fix/fsl-ssi' into asoc-linus
[deliverable/linux.git] / arch / arm / mach-at91 / setup.c
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 #define pr_fmt(fmt) "AT91: " fmt
9
10 #include <linux/module.h>
11 #include <linux/io.h>
12 #include <linux/mm.h>
13 #include <linux/pm.h>
14 #include <linux/of_address.h>
15 #include <linux/pinctrl/machine.h>
16 #include <linux/clk/at91_pmc.h>
17
18 #include <asm/system_misc.h>
19 #include <asm/mach/map.h>
20
21 #include <mach/hardware.h>
22 #include <mach/cpu.h>
23 #include <mach/at91_dbgu.h>
24
25 #include "generic.h"
26 #include "pm.h"
27
28 struct at91_socinfo at91_soc_initdata;
29 EXPORT_SYMBOL(at91_soc_initdata);
30
31 static struct map_desc at91_io_desc __initdata __maybe_unused = {
32 .virtual = (unsigned long)AT91_VA_BASE_SYS,
33 .pfn = __phys_to_pfn(AT91_BASE_SYS),
34 .length = SZ_16K,
35 .type = MT_DEVICE,
36 };
37
38 static struct map_desc at91_alt_io_desc __initdata __maybe_unused = {
39 .virtual = (unsigned long)AT91_ALT_VA_BASE_SYS,
40 .pfn = __phys_to_pfn(AT91_ALT_BASE_SYS),
41 .length = 24 * SZ_1K,
42 .type = MT_DEVICE,
43 };
44
45 static void __init soc_detect(u32 dbgu_base)
46 {
47 u32 cidr, socid;
48
49 cidr = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_CIDR);
50 socid = cidr & ~AT91_CIDR_VERSION;
51
52 switch (socid) {
53 case ARCH_ID_AT91RM9200:
54 at91_soc_initdata.type = AT91_SOC_RM9200;
55 if (at91_soc_initdata.subtype == AT91_SOC_SUBTYPE_UNKNOWN)
56 at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
57 break;
58
59 case ARCH_ID_AT91SAM9260:
60 at91_soc_initdata.type = AT91_SOC_SAM9260;
61 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
62 break;
63
64 case ARCH_ID_AT91SAM9261:
65 at91_soc_initdata.type = AT91_SOC_SAM9261;
66 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
67 break;
68
69 case ARCH_ID_AT91SAM9263:
70 at91_soc_initdata.type = AT91_SOC_SAM9263;
71 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
72 break;
73
74 case ARCH_ID_AT91SAM9G20:
75 at91_soc_initdata.type = AT91_SOC_SAM9G20;
76 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
77 break;
78
79 case ARCH_ID_AT91SAM9G45:
80 at91_soc_initdata.type = AT91_SOC_SAM9G45;
81 if (cidr == ARCH_ID_AT91SAM9G45ES)
82 at91_soc_initdata.subtype = AT91_SOC_SAM9G45ES;
83 break;
84
85 case ARCH_ID_AT91SAM9RL64:
86 at91_soc_initdata.type = AT91_SOC_SAM9RL;
87 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
88 break;
89
90 case ARCH_ID_AT91SAM9X5:
91 at91_soc_initdata.type = AT91_SOC_SAM9X5;
92 break;
93
94 case ARCH_ID_AT91SAM9N12:
95 at91_soc_initdata.type = AT91_SOC_SAM9N12;
96 break;
97
98 case ARCH_ID_SAMA5:
99 at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
100 if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
101 at91_soc_initdata.type = AT91_SOC_SAMA5D3;
102 }
103 break;
104 }
105
106 /* at91sam9g10 */
107 if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
108 at91_soc_initdata.type = AT91_SOC_SAM9G10;
109 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
110 }
111 /* at91sam9xe */
112 else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) {
113 at91_soc_initdata.type = AT91_SOC_SAM9260;
114 at91_soc_initdata.subtype = AT91_SOC_SAM9XE;
115 }
116
117 if (!at91_soc_is_detected())
118 return;
119
120 at91_soc_initdata.cidr = cidr;
121
122 /* sub version of soc */
123 if (!at91_soc_initdata.exid)
124 at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
125
126 if (at91_soc_initdata.type == AT91_SOC_SAM9G45) {
127 switch (at91_soc_initdata.exid) {
128 case ARCH_EXID_AT91SAM9M10:
129 at91_soc_initdata.subtype = AT91_SOC_SAM9M10;
130 break;
131 case ARCH_EXID_AT91SAM9G46:
132 at91_soc_initdata.subtype = AT91_SOC_SAM9G46;
133 break;
134 case ARCH_EXID_AT91SAM9M11:
135 at91_soc_initdata.subtype = AT91_SOC_SAM9M11;
136 break;
137 }
138 }
139
140 if (at91_soc_initdata.type == AT91_SOC_SAM9X5) {
141 switch (at91_soc_initdata.exid) {
142 case ARCH_EXID_AT91SAM9G15:
143 at91_soc_initdata.subtype = AT91_SOC_SAM9G15;
144 break;
145 case ARCH_EXID_AT91SAM9G35:
146 at91_soc_initdata.subtype = AT91_SOC_SAM9G35;
147 break;
148 case ARCH_EXID_AT91SAM9X35:
149 at91_soc_initdata.subtype = AT91_SOC_SAM9X35;
150 break;
151 case ARCH_EXID_AT91SAM9G25:
152 at91_soc_initdata.subtype = AT91_SOC_SAM9G25;
153 break;
154 case ARCH_EXID_AT91SAM9X25:
155 at91_soc_initdata.subtype = AT91_SOC_SAM9X25;
156 break;
157 }
158 }
159
160 if (at91_soc_initdata.type == AT91_SOC_SAMA5D3) {
161 switch (at91_soc_initdata.exid) {
162 case ARCH_EXID_SAMA5D31:
163 at91_soc_initdata.subtype = AT91_SOC_SAMA5D31;
164 break;
165 case ARCH_EXID_SAMA5D33:
166 at91_soc_initdata.subtype = AT91_SOC_SAMA5D33;
167 break;
168 case ARCH_EXID_SAMA5D34:
169 at91_soc_initdata.subtype = AT91_SOC_SAMA5D34;
170 break;
171 case ARCH_EXID_SAMA5D35:
172 at91_soc_initdata.subtype = AT91_SOC_SAMA5D35;
173 break;
174 case ARCH_EXID_SAMA5D36:
175 at91_soc_initdata.subtype = AT91_SOC_SAMA5D36;
176 break;
177 }
178 }
179 }
180
181 static void __init alt_soc_detect(u32 dbgu_base)
182 {
183 u32 cidr, socid;
184
185 /* SoC ID */
186 cidr = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_CIDR);
187 socid = cidr & ~AT91_CIDR_VERSION;
188
189 switch (socid) {
190 case ARCH_ID_SAMA5:
191 at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
192 if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
193 at91_soc_initdata.type = AT91_SOC_SAMA5D3;
194 } else if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D4) {
195 at91_soc_initdata.type = AT91_SOC_SAMA5D4;
196 }
197 break;
198 }
199
200 if (!at91_soc_is_detected())
201 return;
202
203 at91_soc_initdata.cidr = cidr;
204
205 /* sub version of soc */
206 if (!at91_soc_initdata.exid)
207 at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
208
209 if (at91_soc_initdata.type == AT91_SOC_SAMA5D4) {
210 switch (at91_soc_initdata.exid) {
211 case ARCH_EXID_SAMA5D41:
212 at91_soc_initdata.subtype = AT91_SOC_SAMA5D41;
213 break;
214 case ARCH_EXID_SAMA5D42:
215 at91_soc_initdata.subtype = AT91_SOC_SAMA5D42;
216 break;
217 case ARCH_EXID_SAMA5D43:
218 at91_soc_initdata.subtype = AT91_SOC_SAMA5D43;
219 break;
220 case ARCH_EXID_SAMA5D44:
221 at91_soc_initdata.subtype = AT91_SOC_SAMA5D44;
222 break;
223 }
224 }
225 }
226
227 static const char *soc_name[] = {
228 [AT91_SOC_RM9200] = "at91rm9200",
229 [AT91_SOC_SAM9260] = "at91sam9260",
230 [AT91_SOC_SAM9261] = "at91sam9261",
231 [AT91_SOC_SAM9263] = "at91sam9263",
232 [AT91_SOC_SAM9G10] = "at91sam9g10",
233 [AT91_SOC_SAM9G20] = "at91sam9g20",
234 [AT91_SOC_SAM9G45] = "at91sam9g45",
235 [AT91_SOC_SAM9RL] = "at91sam9rl",
236 [AT91_SOC_SAM9X5] = "at91sam9x5",
237 [AT91_SOC_SAM9N12] = "at91sam9n12",
238 [AT91_SOC_SAMA5D3] = "sama5d3",
239 [AT91_SOC_SAMA5D4] = "sama5d4",
240 [AT91_SOC_UNKNOWN] = "Unknown",
241 };
242
243 const char *at91_get_soc_type(struct at91_socinfo *c)
244 {
245 return soc_name[c->type];
246 }
247 EXPORT_SYMBOL(at91_get_soc_type);
248
249 static const char *soc_subtype_name[] = {
250 [AT91_SOC_RM9200_BGA] = "at91rm9200 BGA",
251 [AT91_SOC_RM9200_PQFP] = "at91rm9200 PQFP",
252 [AT91_SOC_SAM9XE] = "at91sam9xe",
253 [AT91_SOC_SAM9G45ES] = "at91sam9g45es",
254 [AT91_SOC_SAM9M10] = "at91sam9m10",
255 [AT91_SOC_SAM9G46] = "at91sam9g46",
256 [AT91_SOC_SAM9M11] = "at91sam9m11",
257 [AT91_SOC_SAM9G15] = "at91sam9g15",
258 [AT91_SOC_SAM9G35] = "at91sam9g35",
259 [AT91_SOC_SAM9X35] = "at91sam9x35",
260 [AT91_SOC_SAM9G25] = "at91sam9g25",
261 [AT91_SOC_SAM9X25] = "at91sam9x25",
262 [AT91_SOC_SAMA5D31] = "sama5d31",
263 [AT91_SOC_SAMA5D33] = "sama5d33",
264 [AT91_SOC_SAMA5D34] = "sama5d34",
265 [AT91_SOC_SAMA5D35] = "sama5d35",
266 [AT91_SOC_SAMA5D36] = "sama5d36",
267 [AT91_SOC_SAMA5D41] = "sama5d41",
268 [AT91_SOC_SAMA5D42] = "sama5d42",
269 [AT91_SOC_SAMA5D43] = "sama5d43",
270 [AT91_SOC_SAMA5D44] = "sama5d44",
271 [AT91_SOC_SUBTYPE_NONE] = "None",
272 [AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown",
273 };
274
275 const char *at91_get_soc_subtype(struct at91_socinfo *c)
276 {
277 return soc_subtype_name[c->subtype];
278 }
279 EXPORT_SYMBOL(at91_get_soc_subtype);
280
281 void __init at91_map_io(void)
282 {
283 /* Map peripherals */
284 iotable_init(&at91_io_desc, 1);
285
286 at91_soc_initdata.type = AT91_SOC_UNKNOWN;
287 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_UNKNOWN;
288
289 soc_detect(AT91_BASE_DBGU0);
290 if (!at91_soc_is_detected())
291 soc_detect(AT91_BASE_DBGU1);
292
293 if (!at91_soc_is_detected())
294 panic(pr_fmt("Impossible to detect the SOC type"));
295
296 pr_info("Detected soc type: %s\n",
297 at91_get_soc_type(&at91_soc_initdata));
298 if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
299 pr_info("Detected soc subtype: %s\n",
300 at91_get_soc_subtype(&at91_soc_initdata));
301 }
302
303 void __init at91_alt_map_io(void)
304 {
305 /* Map peripherals */
306 iotable_init(&at91_alt_io_desc, 1);
307
308 at91_soc_initdata.type = AT91_SOC_UNKNOWN;
309 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_UNKNOWN;
310
311 alt_soc_detect(AT91_BASE_DBGU2);
312 if (!at91_soc_is_detected())
313 panic("AT91: Impossible to detect the SOC type");
314
315 pr_info("AT91: Detected soc type: %s\n",
316 at91_get_soc_type(&at91_soc_initdata));
317 if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
318 pr_info("AT91: Detected soc subtype: %s\n",
319 at91_get_soc_subtype(&at91_soc_initdata));
320 }
321
322 void __iomem *at91_matrix_base;
323 EXPORT_SYMBOL_GPL(at91_matrix_base);
324
325 void __init at91_ioremap_matrix(u32 base_addr)
326 {
327 at91_matrix_base = ioremap(base_addr, 512);
328 if (!at91_matrix_base)
329 panic(pr_fmt("Impossible to ioremap at91_matrix_base\n"));
330 }
This page took 0.036185 seconds and 5 git commands to generate.