diff options
author | Nicolas Ferre <nicolas.ferre@atmel.com> | 2014-09-15 12:15:55 -0400 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2014-09-22 05:39:06 -0400 |
commit | 726d32bf79ef4042004535c9af9c8ea543abe46f (patch) | |
tree | ca28c5477eb81a6b595f5574c7789c7fddee9cce /arch/arm/mach-at91/setup.c | |
parent | 2dc850b62e5b727a5413b60197cdddf92ab4f1a2 (diff) |
ARM: at91: SAMA5D4 SoC detection code and low level routines
SoC identification code, kernel uncompress and low level
debugging routines update.
On SAMA5D4, DBGU is at another address AT91_BASE_DBGU2 so another
round of detection is needed. We also had to differentiate with
SAMA5D3 SoC family and rename some variables.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'arch/arm/mach-at91/setup.c')
-rw-r--r-- | arch/arm/mach-at91/setup.c | 97 |
1 files changed, 93 insertions, 4 deletions
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index f7a07a58ebb6..535a6e70f4ef 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c | |||
@@ -96,6 +96,13 @@ static struct map_desc at91_io_desc __initdata __maybe_unused = { | |||
96 | .type = MT_DEVICE, | 96 | .type = MT_DEVICE, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static struct map_desc at91_alt_io_desc __initdata __maybe_unused = { | ||
100 | .virtual = (unsigned long)AT91_ALT_VA_BASE_SYS, | ||
101 | .pfn = __phys_to_pfn(AT91_ALT_BASE_SYS), | ||
102 | .length = 24 * SZ_1K, | ||
103 | .type = MT_DEVICE, | ||
104 | }; | ||
105 | |||
99 | static void __init soc_detect(u32 dbgu_base) | 106 | static void __init soc_detect(u32 dbgu_base) |
100 | { | 107 | { |
101 | u32 cidr, socid; | 108 | u32 cidr, socid; |
@@ -158,9 +165,12 @@ static void __init soc_detect(u32 dbgu_base) | |||
158 | at91_boot_soc = at91sam9n12_soc; | 165 | at91_boot_soc = at91sam9n12_soc; |
159 | break; | 166 | break; |
160 | 167 | ||
161 | case ARCH_ID_SAMA5D3: | 168 | case ARCH_ID_SAMA5: |
162 | at91_soc_initdata.type = AT91_SOC_SAMA5D3; | 169 | at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID); |
163 | at91_boot_soc = sama5d3_soc; | 170 | if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) { |
171 | at91_soc_initdata.type = AT91_SOC_SAMA5D3; | ||
172 | at91_boot_soc = sama5d3_soc; | ||
173 | } | ||
164 | break; | 174 | break; |
165 | } | 175 | } |
166 | 176 | ||
@@ -183,7 +193,8 @@ static void __init soc_detect(u32 dbgu_base) | |||
183 | at91_soc_initdata.cidr = cidr; | 193 | at91_soc_initdata.cidr = cidr; |
184 | 194 | ||
185 | /* sub version of soc */ | 195 | /* sub version of soc */ |
186 | at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID); | 196 | if (!at91_soc_initdata.exid) |
197 | at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID); | ||
187 | 198 | ||
188 | if (at91_soc_initdata.type == AT91_SOC_SAM9G45) { | 199 | if (at91_soc_initdata.type == AT91_SOC_SAM9G45) { |
189 | switch (at91_soc_initdata.exid) { | 200 | switch (at91_soc_initdata.exid) { |
@@ -240,6 +251,54 @@ static void __init soc_detect(u32 dbgu_base) | |||
240 | } | 251 | } |
241 | } | 252 | } |
242 | 253 | ||
254 | static void __init alt_soc_detect(u32 dbgu_base) | ||
255 | { | ||
256 | u32 cidr, socid; | ||
257 | |||
258 | /* SoC ID */ | ||
259 | cidr = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_CIDR); | ||
260 | socid = cidr & ~AT91_CIDR_VERSION; | ||
261 | |||
262 | switch (socid) { | ||
263 | case ARCH_ID_SAMA5: | ||
264 | at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID); | ||
265 | if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) { | ||
266 | at91_soc_initdata.type = AT91_SOC_SAMA5D3; | ||
267 | at91_boot_soc = sama5d3_soc; | ||
268 | } else if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D4) { | ||
269 | at91_soc_initdata.type = AT91_SOC_SAMA5D4; | ||
270 | at91_boot_soc = sama5d4_soc; | ||
271 | } | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | if (!at91_soc_is_detected()) | ||
276 | return; | ||
277 | |||
278 | at91_soc_initdata.cidr = cidr; | ||
279 | |||
280 | /* sub version of soc */ | ||
281 | if (!at91_soc_initdata.exid) | ||
282 | at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID); | ||
283 | |||
284 | if (at91_soc_initdata.type == AT91_SOC_SAMA5D4) { | ||
285 | switch (at91_soc_initdata.exid) { | ||
286 | case ARCH_EXID_SAMA5D41: | ||
287 | at91_soc_initdata.subtype = AT91_SOC_SAMA5D41; | ||
288 | break; | ||
289 | case ARCH_EXID_SAMA5D42: | ||
290 | at91_soc_initdata.subtype = AT91_SOC_SAMA5D42; | ||
291 | break; | ||
292 | case ARCH_EXID_SAMA5D43: | ||
293 | at91_soc_initdata.subtype = AT91_SOC_SAMA5D43; | ||
294 | break; | ||
295 | case ARCH_EXID_SAMA5D44: | ||
296 | at91_soc_initdata.subtype = AT91_SOC_SAMA5D44; | ||
297 | break; | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | |||
243 | static const char *soc_name[] = { | 302 | static const char *soc_name[] = { |
244 | [AT91_SOC_RM9200] = "at91rm9200", | 303 | [AT91_SOC_RM9200] = "at91rm9200", |
245 | [AT91_SOC_SAM9260] = "at91sam9260", | 304 | [AT91_SOC_SAM9260] = "at91sam9260", |
@@ -252,6 +311,7 @@ static const char *soc_name[] = { | |||
252 | [AT91_SOC_SAM9X5] = "at91sam9x5", | 311 | [AT91_SOC_SAM9X5] = "at91sam9x5", |
253 | [AT91_SOC_SAM9N12] = "at91sam9n12", | 312 | [AT91_SOC_SAM9N12] = "at91sam9n12", |
254 | [AT91_SOC_SAMA5D3] = "sama5d3", | 313 | [AT91_SOC_SAMA5D3] = "sama5d3", |
314 | [AT91_SOC_SAMA5D4] = "sama5d4", | ||
255 | [AT91_SOC_UNKNOWN] = "Unknown", | 315 | [AT91_SOC_UNKNOWN] = "Unknown", |
256 | }; | 316 | }; |
257 | 317 | ||
@@ -279,6 +339,10 @@ static const char *soc_subtype_name[] = { | |||
279 | [AT91_SOC_SAMA5D34] = "sama5d34", | 339 | [AT91_SOC_SAMA5D34] = "sama5d34", |
280 | [AT91_SOC_SAMA5D35] = "sama5d35", | 340 | [AT91_SOC_SAMA5D35] = "sama5d35", |
281 | [AT91_SOC_SAMA5D36] = "sama5d36", | 341 | [AT91_SOC_SAMA5D36] = "sama5d36", |
342 | [AT91_SOC_SAMA5D41] = "sama5d41", | ||
343 | [AT91_SOC_SAMA5D42] = "sama5d42", | ||
344 | [AT91_SOC_SAMA5D43] = "sama5d43", | ||
345 | [AT91_SOC_SAMA5D44] = "sama5d44", | ||
282 | [AT91_SOC_SUBTYPE_NONE] = "None", | 346 | [AT91_SOC_SUBTYPE_NONE] = "None", |
283 | [AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown", | 347 | [AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown", |
284 | }; | 348 | }; |
@@ -341,6 +405,31 @@ void __init at91_ioremap_rstc(u32 base_addr) | |||
341 | panic("Impossible to ioremap at91_rstc_base\n"); | 405 | panic("Impossible to ioremap at91_rstc_base\n"); |
342 | } | 406 | } |
343 | 407 | ||
408 | void __init at91_alt_map_io(void) | ||
409 | { | ||
410 | /* Map peripherals */ | ||
411 | iotable_init(&at91_alt_io_desc, 1); | ||
412 | |||
413 | at91_soc_initdata.type = AT91_SOC_UNKNOWN; | ||
414 | at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_UNKNOWN; | ||
415 | |||
416 | alt_soc_detect(AT91_BASE_DBGU2); | ||
417 | if (!at91_soc_is_detected()) | ||
418 | panic("AT91: Impossible to detect the SOC type"); | ||
419 | |||
420 | pr_info("AT91: Detected soc type: %s\n", | ||
421 | at91_get_soc_type(&at91_soc_initdata)); | ||
422 | if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE) | ||
423 | pr_info("AT91: Detected soc subtype: %s\n", | ||
424 | at91_get_soc_subtype(&at91_soc_initdata)); | ||
425 | |||
426 | if (!at91_soc_is_enabled()) | ||
427 | panic("AT91: Soc not enabled"); | ||
428 | |||
429 | if (at91_boot_soc.map_io) | ||
430 | at91_boot_soc.map_io(); | ||
431 | } | ||
432 | |||
344 | void __iomem *at91_matrix_base; | 433 | void __iomem *at91_matrix_base; |
345 | EXPORT_SYMBOL_GPL(at91_matrix_base); | 434 | EXPORT_SYMBOL_GPL(at91_matrix_base); |
346 | 435 | ||