aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2011-04-23 10:12:57 -0400
committerArnd Bergmann <arnd@arndb.de>2011-07-28 11:07:28 -0400
commit8c3583b634d5705d8f604c0d9392bc273d19c256 (patch)
treefa2c010c4dbea580526cb91a25ae0e57abc0f099 /arch/arm/mach-at91
parent1ff5b1b411bf8a8157ae949a1b3ed8666d96c1db (diff)
at91: use structure to store the current soc
instead of reading the registers everytime the current implementation respect the following constrain: - allow 1 to n soc to be enabled - allow to have a virtual cpu type and subtype - always detect the cpu type and subtype and report it - detect if the soc support is enabled - prepare for sysfs export support - drop soc specific code via compiler when the soc not enabled (via cpu_is_xxx) Today if we read the exid we will have the same value for 9g35 and 9m11 and we will need to check the cidr too with the new implementation we just need to check the soc subtype this will also allow to have specific virtual subtype for rm9200 which the board will have to specify via at91rm9200_set_type(int) as we have no way to detect it. this implementation is inspired by the SH cpu detection support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Cc: Nicolas Ferre <nicolas.ferre@atmel.com> Cc: Patrice Vilchez <patrice.vilchez@atmel.com>
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r--arch/arm/mach-at91/at91cap9.c2
-rw-r--r--arch/arm/mach-at91/at91rm9200.c10
-rw-r--r--arch/arm/mach-at91/at91sam9260.c9
-rw-r--r--arch/arm/mach-at91/at91sam9261.c2
-rw-r--r--arch/arm/mach-at91/at91sam9263.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c2
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c9
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h159
-rw-r--r--arch/arm/mach-at91/setup.c209
-rw-r--r--arch/arm/mach-at91/soc.h57
10 files changed, 341 insertions, 120 deletions
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
index 9a0137043780..6287c0dea47a 100644
--- a/arch/arm/mach-at91/at91cap9.c
+++ b/arch/arm/mach-at91/at91cap9.c
@@ -403,7 +403,7 @@ static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = {
403 0, /* Advanced Interrupt Controller (IRQ1) */ 403 0, /* Advanced Interrupt Controller (IRQ1) */
404}; 404};
405 405
406struct at91_soc __initdata at91cap9_soc = { 406struct at91_init_soc __initdata at91cap9_soc = {
407 .map_io = at91cap9_map_io, 407 .map_io = at91cap9_map_io,
408 .default_irq_priority = at91cap9_default_irq_priority, 408 .default_irq_priority = at91cap9_default_irq_priority,
409 .init = at91cap9_initialize, 409 .init = at91cap9_initialize,
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index d7801bed9afe..36d37bd49cbf 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -300,14 +300,6 @@ static void at91rm9200_reset(void)
300 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); 300 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
301} 301}
302 302
303int rm9200_type;
304EXPORT_SYMBOL(rm9200_type);
305
306void __init at91rm9200_set_type(int type)
307{
308 rm9200_type = type;
309}
310
311/* -------------------------------------------------------------------- 303/* --------------------------------------------------------------------
312 * AT91RM9200 processor initialization 304 * AT91RM9200 processor initialization
313 * -------------------------------------------------------------------- */ 305 * -------------------------------------------------------------------- */
@@ -379,7 +371,7 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
379 0 /* Advanced Interrupt Controller (IRQ6) */ 371 0 /* Advanced Interrupt Controller (IRQ6) */
380}; 372};
381 373
382struct at91_soc __initdata at91rm9200_soc = { 374struct at91_init_soc __initdata at91rm9200_soc = {
383 .map_io = at91rm9200_map_io, 375 .map_io = at91rm9200_map_io,
384 .default_irq_priority = at91rm9200_default_irq_priority, 376 .default_irq_priority = at91rm9200_default_irq_priority,
385 .init = at91rm9200_initialize, 377 .init = at91rm9200_initialize,
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 57974b19d7a7..8a6b9aa1dd9c 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -17,6 +17,7 @@
17#include <asm/mach/arch.h> 17#include <asm/mach/arch.h>
18#include <asm/mach/map.h> 18#include <asm/mach/map.h>
19#include <mach/cpu.h> 19#include <mach/cpu.h>
20#include <mach/at91_dbgu.h>
20#include <mach/at91sam9260.h> 21#include <mach/at91sam9260.h>
21#include <mach/at91_pmc.h> 22#include <mach/at91_pmc.h>
22#include <mach/at91_rstc.h> 23#include <mach/at91_rstc.h>
@@ -322,11 +323,9 @@ static void at91sam9260_poweroff(void)
322 323
323static void __init at91sam9xe_map_io(void) 324static void __init at91sam9xe_map_io(void)
324{ 325{
325 unsigned long cidr, sram_size; 326 unsigned long sram_size;
326 327
327 cidr = dbgu_readl(AT91_DBGU, CIDR); 328 switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) {
328
329 switch (cidr & AT91_CIDR_SRAMSIZ) {
330 case AT91_CIDR_SRAMSIZ_32K: 329 case AT91_CIDR_SRAMSIZ_32K:
331 sram_size = 2 * SZ_16K; 330 sram_size = 2 * SZ_16K;
332 break; 331 break;
@@ -410,7 +409,7 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
410 0, /* Advanced Interrupt Controller */ 409 0, /* Advanced Interrupt Controller */
411}; 410};
412 411
413struct at91_soc __initdata at91sam9260_soc = { 412struct at91_init_soc __initdata at91sam9260_soc = {
414 .map_io = at91sam9260_map_io, 413 .map_io = at91sam9260_map_io,
415 .default_irq_priority = at91sam9260_default_irq_priority, 414 .default_irq_priority = at91sam9260_default_irq_priority,
416 .init = at91sam9260_initialize, 415 .init = at91sam9260_initialize,
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 7a4a673eedeb..f6a2b30884e9 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -361,7 +361,7 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
361 0, /* Advanced Interrupt Controller */ 361 0, /* Advanced Interrupt Controller */
362}; 362};
363 363
364struct at91_soc __initdata at91sam9261_soc = { 364struct at91_init_soc __initdata at91sam9261_soc = {
365 .map_io = at91sam9261_map_io, 365 .map_io = at91sam9261_map_io,
366 .default_irq_priority = at91sam9261_default_irq_priority, 366 .default_irq_priority = at91sam9261_default_irq_priority,
367 .init = at91sam9261_initialize, 367 .init = at91sam9261_initialize,
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 3140a13abc4a..7245a8e112e5 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -372,7 +372,7 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
372 0, /* Advanced Interrupt Controller (IRQ1) */ 372 0, /* Advanced Interrupt Controller (IRQ1) */
373}; 373};
374 374
375struct at91_soc __initdata at91sam9263_soc = { 375struct at91_init_soc __initdata at91sam9263_soc = {
376 .map_io = at91sam9263_map_io, 376 .map_io = at91sam9263_map_io,
377 .default_irq_priority = at91sam9263_default_irq_priority, 377 .default_irq_priority = at91sam9263_default_irq_priority,
378 .init = at91sam9263_initialize, 378 .init = at91sam9263_initialize,
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index f5e72da65ce7..57a472633cda 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -388,7 +388,7 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
388 0, /* Advanced Interrupt Controller (IRQ0) */ 388 0, /* Advanced Interrupt Controller (IRQ0) */
389}; 389};
390 390
391struct at91_soc __initdata at91sam9g45_soc = { 391struct at91_init_soc __initdata at91sam9g45_soc = {
392 .map_io = at91sam9g45_map_io, 392 .map_io = at91sam9g45_map_io,
393 .default_irq_priority = at91sam9g45_default_irq_priority, 393 .default_irq_priority = at91sam9g45_default_irq_priority,
394 .init = at91sam9g45_initialize, 394 .init = at91sam9g45_initialize,
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 0788adb1b53c..b83098c1db12 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -16,6 +16,7 @@
16#include <asm/mach/arch.h> 16#include <asm/mach/arch.h>
17#include <asm/mach/map.h> 17#include <asm/mach/map.h>
18#include <mach/cpu.h> 18#include <mach/cpu.h>
19#include <mach/at91_dbgu.h>
19#include <mach/at91sam9rl.h> 20#include <mach/at91sam9rl.h>
20#include <mach/at91_pmc.h> 21#include <mach/at91_pmc.h>
21#include <mach/at91_rstc.h> 22#include <mach/at91_rstc.h>
@@ -281,11 +282,9 @@ static void at91sam9rl_poweroff(void)
281 282
282static void __init at91sam9rl_map_io(void) 283static void __init at91sam9rl_map_io(void)
283{ 284{
284 unsigned long cidr, sram_size; 285 unsigned long sram_size;
285 286
286 cidr = dbgu_readl(AT91_DBGU, CIDR); 287 switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) {
287
288 switch (cidr & AT91_CIDR_SRAMSIZ) {
289 case AT91_CIDR_SRAMSIZ_32K: 288 case AT91_CIDR_SRAMSIZ_32K:
290 sram_size = 2 * SZ_16K; 289 sram_size = 2 * SZ_16K;
291 break; 290 break;
@@ -359,7 +358,7 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = {
359 0, /* Advanced Interrupt Controller */ 358 0, /* Advanced Interrupt Controller */
360}; 359};
361 360
362struct at91_soc __initdata at91sam9rl_soc = { 361struct at91_init_soc __initdata at91sam9rl_soc = {
363 .map_io = at91sam9rl_map_io, 362 .map_io = at91sam9rl_map_io,
364 .default_irq_priority = at91sam9rl_default_irq_priority, 363 .default_irq_priority = at91sam9rl_default_irq_priority,
365 .init = at91sam9rl_initialize, 364 .init = at91sam9rl_initialize,
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 3cf69198f8a4..f6ce936dba2b 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -1,7 +1,8 @@
1/* 1/*
2 * arch/arm/mach-at91/include/mach/cpu.h 2 * arch/arm/mach-at91/include/mach/cpu.h
3 * 3 *
4 * Copyright (C) 2006 SAN People 4 * Copyright (C) 2006 SAN People
5 * Copyright (C) 2011 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
@@ -10,12 +11,8 @@
10 * 11 *
11 */ 12 */
12 13
13#ifndef __ASM_ARCH_CPU_H 14#ifndef __MACH_CPU_H__
14#define __ASM_ARCH_CPU_H 15#define __MACH_CPU_H__
15
16#include <mach/hardware.h>
17#include <mach/at91_dbgu.h>
18
19 16
20#define ARCH_ID_AT91RM9200 0x09290780 17#define ARCH_ID_AT91RM9200 0x09290780
21#define ARCH_ID_AT91SAM9260 0x019803a0 18#define ARCH_ID_AT91SAM9260 0x019803a0
@@ -39,16 +36,6 @@
39#define ARCH_ID_AT91M40807 0x14080745 36#define ARCH_ID_AT91M40807 0x14080745
40#define ARCH_ID_AT91R40008 0x44000840 37#define ARCH_ID_AT91R40008 0x44000840
41 38
42static inline unsigned long at91_cpu_identify(void)
43{
44 return (dbgu_readl(AT91_DBGU, CIDR) & ~AT91_CIDR_VERSION);
45}
46
47static inline unsigned long at91_cpu_fully_identify(void)
48{
49 return dbgu_readl(AT91_DBGU, CIDR);
50}
51
52#define ARCH_EXID_AT91SAM9M11 0x00000001 39#define ARCH_EXID_AT91SAM9M11 0x00000001
53#define ARCH_EXID_AT91SAM9M10 0x00000002 40#define ARCH_EXID_AT91SAM9M10 0x00000002
54#define ARCH_EXID_AT91SAM9G46 0x00000003 41#define ARCH_EXID_AT91SAM9G46 0x00000003
@@ -60,40 +47,80 @@ static inline unsigned long at91_cpu_fully_identify(void)
60#define ARCH_EXID_AT91SAM9G25 0x00000003 47#define ARCH_EXID_AT91SAM9G25 0x00000003
61#define ARCH_EXID_AT91SAM9X25 0x00000004 48#define ARCH_EXID_AT91SAM9X25 0x00000004
62 49
63static inline unsigned long at91_exid_identify(void)
64{
65 return dbgu_readl(AT91_DBGU, EXID);
66}
67
68
69#define ARCH_FAMILY_AT91X92 0x09200000 50#define ARCH_FAMILY_AT91X92 0x09200000
70#define ARCH_FAMILY_AT91SAM9 0x01900000 51#define ARCH_FAMILY_AT91SAM9 0x01900000
71#define ARCH_FAMILY_AT91SAM9XE 0x02900000 52#define ARCH_FAMILY_AT91SAM9XE 0x02900000
72 53
73static inline unsigned long at91_arch_identify(void) 54/* PMC revision */
74{
75 return (dbgu_readl(AT91_DBGU, CIDR) & AT91_CIDR_ARCH);
76}
77
78#ifdef CONFIG_ARCH_AT91CAP9
79#include <mach/at91_pmc.h>
80
81#define ARCH_REVISION_CAP9_B 0x399 55#define ARCH_REVISION_CAP9_B 0x399
82#define ARCH_REVISION_CAP9_C 0x601 56#define ARCH_REVISION_CAP9_C 0x601
83 57
84static inline unsigned long at91cap9_rev_identify(void) 58/* RM9200 type */
59#define ARCH_REVISON_9200_BGA (0 << 0)
60#define ARCH_REVISON_9200_PQFP (1 << 0)
61
62enum at91_soc_type {
63 /* 920T */
64 AT91_SOC_RM9200,
65
66 /* CAP */
67 AT91_SOC_CAP9,
68
69 /* SAM92xx */
70 AT91_SOC_SAM9260, AT91_SOC_SAM9261, AT91_SOC_SAM9263,
71
72 /* SAM9Gxx */
73 AT91_SOC_SAM9G10, AT91_SOC_SAM9G20, AT91_SOC_SAM9G45,
74
75 /* SAM9RL */
76 AT91_SOC_SAM9RL,
77
78 /* SAM9X5 */
79 AT91_SOC_SAM9X5,
80
81 /* Unknown type */
82 AT91_SOC_NONE
83};
84
85enum at91_soc_subtype {
86 /* RM9200 */
87 AT91_SOC_RM9200_BGA, AT91_SOC_RM9200_PQFP,
88
89 /* CAP9 */
90 AT91_SOC_CAP9_REV_B, AT91_SOC_CAP9_REV_C,
91
92 /* SAM9260 */
93 AT91_SOC_SAM9XE,
94
95 /* SAM9G45 */
96 AT91_SOC_SAM9G45ES, AT91_SOC_SAM9M10, AT91_SOC_SAM9G46, AT91_SOC_SAM9M11,
97
98 /* SAM9X5 */
99 AT91_SOC_SAM9G15, AT91_SOC_SAM9G35, AT91_SOC_SAM9X35,
100 AT91_SOC_SAM9G25, AT91_SOC_SAM9X25,
101
102 /* Unknown subtype */
103 AT91_SOC_SUBTYPE_NONE
104};
105
106struct at91_socinfo {
107 unsigned int type, subtype;
108 unsigned int cidr, exid;
109};
110
111extern struct at91_socinfo at91_soc_initdata;
112const char *at91_get_soc_type(struct at91_socinfo *c);
113const char *at91_get_soc_subtype(struct at91_socinfo *c);
114
115static inline int at91_soc_is_detected(void)
85{ 116{
86 return (at91_sys_read(AT91_PMC_VER)); 117 return at91_soc_initdata.type != AT91_SOC_NONE;
87} 118}
88#endif
89 119
90#ifdef CONFIG_ARCH_AT91RM9200 120#ifdef CONFIG_ARCH_AT91RM9200
91extern int rm9200_type; 121#define cpu_is_at91rm9200() (at91_soc_initdata.type == AT91_SOC_RM9200)
92#define ARCH_REVISON_9200_BGA (0 << 0) 122#define cpu_is_at91rm9200_bga() (at91_soc_initdata.subtype == AT91_SOC_RM9200_BGA)
93#define ARCH_REVISON_9200_PQFP (1 << 0) 123#define cpu_is_at91rm9200_pqfp() (at91_soc_initdata.subtype == AT91_SOC_RM9200_PQFP)
94#define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200)
95#define cpu_is_at91rm9200_bga() (!cpu_is_at91rm9200_pqfp())
96#define cpu_is_at91rm9200_pqfp() (cpu_is_at91rm9200() && rm9200_type & ARCH_REVISON_9200_PQFP)
97#else 124#else
98#define cpu_is_at91rm9200() (0) 125#define cpu_is_at91rm9200() (0)
99#define cpu_is_at91rm9200_bga() (0) 126#define cpu_is_at91rm9200_bga() (0)
@@ -101,52 +128,49 @@ extern int rm9200_type;
101#endif 128#endif
102 129
103#ifdef CONFIG_ARCH_AT91SAM9260 130#ifdef CONFIG_ARCH_AT91SAM9260
104#define cpu_is_at91sam9xe() (at91_arch_identify() == ARCH_FAMILY_AT91SAM9XE) 131#define cpu_is_at91sam9xe() (at91_soc_initdata.subtype == AT91_SOC_SAM9XE)
105#define cpu_is_at91sam9260() ((at91_cpu_identify() == ARCH_ID_AT91SAM9260) || cpu_is_at91sam9xe()) 132#define cpu_is_at91sam9260() (at91_soc_initdata.type == AT91_SOC_SAM9260)
106#else 133#else
107#define cpu_is_at91sam9xe() (0) 134#define cpu_is_at91sam9xe() (0)
108#define cpu_is_at91sam9260() (0) 135#define cpu_is_at91sam9260() (0)
109#endif 136#endif
110 137
111#ifdef CONFIG_ARCH_AT91SAM9G20 138#ifdef CONFIG_ARCH_AT91SAM9G20
112#define cpu_is_at91sam9g20() (at91_cpu_identify() == ARCH_ID_AT91SAM9G20) 139#define cpu_is_at91sam9g20() (at91_soc_initdata.type == AT91_SOC_SAM9G20)
113#else 140#else
114#define cpu_is_at91sam9g20() (0) 141#define cpu_is_at91sam9g20() (0)
115#endif 142#endif
116 143
117#ifdef CONFIG_ARCH_AT91SAM9261 144#ifdef CONFIG_ARCH_AT91SAM9261
118#define cpu_is_at91sam9261() (at91_cpu_identify() == ARCH_ID_AT91SAM9261) 145#define cpu_is_at91sam9261() (at91_soc_initdata.type == AT91_SOC_SAM9261)
119#else 146#else
120#define cpu_is_at91sam9261() (0) 147#define cpu_is_at91sam9261() (0)
121#endif 148#endif
122 149
123#ifdef CONFIG_ARCH_AT91SAM9G10 150#ifdef CONFIG_ARCH_AT91SAM9G10
124#define cpu_is_at91sam9g10() ((at91_cpu_identify() & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) 151#define cpu_is_at91sam9g10() (at91_soc_initdata.type == AT91_SOC_SAM9G10)
125#else 152#else
126#define cpu_is_at91sam9g10() (0) 153#define cpu_is_at91sam9g10() (0)
127#endif 154#endif
128 155
129#ifdef CONFIG_ARCH_AT91SAM9263 156#ifdef CONFIG_ARCH_AT91SAM9263
130#define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263) 157#define cpu_is_at91sam9263() (at91_soc_initdata.type == AT91_SOC_SAM9263)
131#else 158#else
132#define cpu_is_at91sam9263() (0) 159#define cpu_is_at91sam9263() (0)
133#endif 160#endif
134 161
135#ifdef CONFIG_ARCH_AT91SAM9RL 162#ifdef CONFIG_ARCH_AT91SAM9RL
136#define cpu_is_at91sam9rl() (at91_cpu_identify() == ARCH_ID_AT91SAM9RL64) 163#define cpu_is_at91sam9rl() (at91_soc_initdata.type == AT91_SOC_SAM9RL)
137#else 164#else
138#define cpu_is_at91sam9rl() (0) 165#define cpu_is_at91sam9rl() (0)
139#endif 166#endif
140 167
141#ifdef CONFIG_ARCH_AT91SAM9G45 168#ifdef CONFIG_ARCH_AT91SAM9G45
142#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45) 169#define cpu_is_at91sam9g45() (at91_soc_initdata.type == AT91_SOC_SAM9G45)
143#define cpu_is_at91sam9g45es() (at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES) 170#define cpu_is_at91sam9g45es() (at91_soc_initdata.subtype == AT91_SOC_SAM9G45ES)
144#define cpu_is_at91sam9m10() (cpu_is_at91sam9g45() && \ 171#define cpu_is_at91sam9m10() (at91_soc_initdata.subtype == AT91_SOC_SAM9M10)
145 (at91_exid_identify() == ARCH_EXID_AT91SAM9M10)) 172#define cpu_is_at91sam9g46() (at91_soc_initdata.subtype == AT91_SOC_SAM9G46)
146#define cpu_is_at91sam9m46() (cpu_is_at91sam9g45() && \ 173#define cpu_is_at91sam9m11() (at91_soc_initdata.subtype == AT91_SOC_SAM9M11)
147 (at91_exid_identify() == ARCH_EXID_AT91SAM9G46))
148#define cpu_is_at91sam9m11() (cpu_is_at91sam9g45() && \
149 (at91_exid_identify() == ARCH_EXID_AT91SAM9M11))
150#else 174#else
151#define cpu_is_at91sam9g45() (0) 175#define cpu_is_at91sam9g45() (0)
152#define cpu_is_at91sam9g45es() (0) 176#define cpu_is_at91sam9g45es() (0)
@@ -156,17 +180,12 @@ extern int rm9200_type;
156#endif 180#endif
157 181
158#ifdef CONFIG_ARCH_AT91SAM9X5 182#ifdef CONFIG_ARCH_AT91SAM9X5
159#define cpu_is_at91sam9x5() (at91_cpu_identify() == ARCH_ID_AT91SAM9X5) 183#define cpu_is_at91sam9x5() (at91_soc_initdata.type == AT91_SOC_SAM9X5)
160#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \ 184#define cpu_is_at91sam9g15() (at91_soc_initdata.subtype == AT91_SOC_SAM9G15)
161 (at91_exid_identify() == ARCH_EXID_AT91SAM9G15)) 185#define cpu_is_at91sam9g35() (at91_soc_initdata.subtype == AT91_SOC_SAM9G35)
162#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \ 186#define cpu_is_at91sam9x35() (at91_soc_initdata.subtype == AT91_SOC_SAM9X35)
163 (at91_exid_identify() == ARCH_EXID_AT91SAM9G35)) 187#define cpu_is_at91sam9g25() (at91_soc_initdata.subtype == AT91_SOC_SAM9G25)
164#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \ 188#define cpu_is_at91sam9x25() (at91_soc_initdata.subtype == AT91_SOC_SAM9X25)
165 (at91_exid_identify() == ARCH_EXID_AT91SAM9X35))
166#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \
167 (at91_exid_identify() == ARCH_EXID_AT91SAM9G25))
168#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \
169 (at91_exid_identify() == ARCH_EXID_AT91SAM9X25))
170#else 189#else
171#define cpu_is_at91sam9x5() (0) 190#define cpu_is_at91sam9x5() (0)
172#define cpu_is_at91sam9g15() (0) 191#define cpu_is_at91sam9g15() (0)
@@ -177,9 +196,9 @@ extern int rm9200_type;
177#endif 196#endif
178 197
179#ifdef CONFIG_ARCH_AT91CAP9 198#ifdef CONFIG_ARCH_AT91CAP9
180#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) 199#define cpu_is_at91cap9() (at91_soc_initdata.type == AT91_SOC_CAP9)
181#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) 200#define cpu_is_at91cap9_revB() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_B)
182#define cpu_is_at91cap9_revC() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_C) 201#define cpu_is_at91cap9_revC() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_C)
183#else 202#else
184#define cpu_is_at91cap9() (0) 203#define cpu_is_at91cap9() (0)
185#define cpu_is_at91cap9_revB() (0) 204#define cpu_is_at91cap9_revB() (0)
@@ -192,4 +211,4 @@ extern int rm9200_type;
192 */ 211 */
193#define cpu_is_at32ap7000() (0) 212#define cpu_is_at32ap7000() (0)
194 213
195#endif 214#endif /* __MACH_CPU_H__ */
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 8962d9a1a8f6..9ea41838f5db 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -12,11 +12,24 @@
12 12
13#include <mach/hardware.h> 13#include <mach/hardware.h>
14#include <mach/cpu.h> 14#include <mach/cpu.h>
15#include <mach/at91_dbgu.h>
16#include <mach/at91_pmc.h>
15 17
16#include "soc.h" 18#include "soc.h"
17#include "generic.h" 19#include "generic.h"
18 20
19struct at91_soc __initdata at91_boot_soc; 21struct at91_init_soc __initdata at91_boot_soc;
22
23struct at91_socinfo at91_soc_initdata;
24EXPORT_SYMBOL(at91_soc_initdata);
25
26void __init at91rm9200_set_type(int type)
27{
28 if (type == ARCH_REVISON_9200_PQFP)
29 at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
30 else
31 at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP;
32}
20 33
21void __init at91_init_irq_default(void) 34void __init at91_init_irq_default(void)
22{ 35{
@@ -39,33 +52,195 @@ static struct map_desc at91_io_desc __initdata = {
39 .type = MT_DEVICE, 52 .type = MT_DEVICE,
40}; 53};
41 54
42void __init at91_map_io(void) 55#define AT91_DBGU0 0xfffff200
56#define AT91_DBGU1 0xffffee00
57
58static void __init soc_detect(u32 dbgu_base)
43{ 59{
44 /* Map peripherals */ 60 u32 cidr, socid;
45 iotable_init(&at91_io_desc, 1); 61
62 cidr = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_CIDR);
63 socid = cidr & ~AT91_CIDR_VERSION;
46 64
47 if (cpu_is_at91cap9()) 65 switch (socid) {
66 case ARCH_ID_AT91CAP9: {
67#ifdef CONFIG_AT91_PMC_UNIT
68 u32 pmc_ver = at91_sys_read(AT91_PMC_VER);
69
70 if (pmc_ver == ARCH_REVISION_CAP9_B)
71 at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_B;
72 else if (pmc_ver == ARCH_REVISION_CAP9_C)
73 at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_C;
74#endif
75 at91_soc_initdata.type = AT91_SOC_CAP9;
48 at91_boot_soc = at91cap9_soc; 76 at91_boot_soc = at91cap9_soc;
49 else if (cpu_is_at91rm9200()) 77 break;
78 }
79
80 case ARCH_ID_AT91RM9200:
81 at91_soc_initdata.type = AT91_SOC_RM9200;
50 at91_boot_soc = at91rm9200_soc; 82 at91_boot_soc = at91rm9200_soc;
51 else if (cpu_is_at91sam9260()) 83 break;
84
85 case ARCH_ID_AT91SAM9260:
86 at91_soc_initdata.type = AT91_SOC_SAM9260;
52 at91_boot_soc = at91sam9260_soc; 87 at91_boot_soc = at91sam9260_soc;
53 else if (cpu_is_at91sam9261()) 88 break;
89
90 case ARCH_ID_AT91SAM9261:
91 at91_soc_initdata.type = AT91_SOC_SAM9261;
54 at91_boot_soc = at91sam9261_soc; 92 at91_boot_soc = at91sam9261_soc;
55 else if (cpu_is_at91sam9263()) 93 break;
94
95 case ARCH_ID_AT91SAM9263:
96 at91_soc_initdata.type = AT91_SOC_SAM9263;
56 at91_boot_soc = at91sam9263_soc; 97 at91_boot_soc = at91sam9263_soc;
57 else if (cpu_is_at91sam9g10()) 98 break;
58 at91_boot_soc = at91sam9261_soc; 99
59 else if (cpu_is_at91sam9g20()) 100 case ARCH_ID_AT91SAM9G20:
101 at91_soc_initdata.type = AT91_SOC_SAM9G20;
60 at91_boot_soc = at91sam9260_soc; 102 at91_boot_soc = at91sam9260_soc;
61 else if (cpu_is_at91sam9g45()) 103 break;
104
105 case ARCH_ID_AT91SAM9G45:
106 at91_soc_initdata.type = AT91_SOC_SAM9G45;
107 if (cidr == ARCH_ID_AT91SAM9G45ES)
108 at91_soc_initdata.subtype = AT91_SOC_SAM9G45ES;
62 at91_boot_soc = at91sam9g45_soc; 109 at91_boot_soc = at91sam9g45_soc;
63 else if (cpu_is_at91sam9rl()) 110 break;
111
112 case ARCH_ID_AT91SAM9RL64:
113 at91_soc_initdata.type = AT91_SOC_SAM9RL;
64 at91_boot_soc = at91sam9rl_soc; 114 at91_boot_soc = at91sam9rl_soc;
65 else if (cpu_is_at91sam9x5()) 115 break;
116
117 case ARCH_ID_AT91SAM9X5:
118 at91_soc_initdata.type = AT91_SOC_SAM9X5;
66 at91_boot_soc = at91sam9x5_soc; 119 at91_boot_soc = at91sam9x5_soc;
67 else 120 break;
68 panic("Impossible to detect the SOC type"); 121 }
122
123 /* at91sam9g10 */
124 if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
125 at91_soc_initdata.type = AT91_SOC_SAM9G10;
126 at91_boot_soc = at91sam9261_soc;
127 }
128 /* at91sam9xe */
129 else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) {
130 at91_soc_initdata.type = AT91_SOC_SAM9260;
131 at91_soc_initdata.subtype = AT91_SOC_SAM9XE;
132 at91_boot_soc = at91sam9260_soc;
133 }
134
135 if (!at91_soc_is_detected())
136 return;
137
138 at91_soc_initdata.cidr = cidr;
139
140 /* sub version of soc */
141 at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
142
143 if (at91_soc_initdata.type == AT91_SOC_SAM9G45) {
144 switch (at91_soc_initdata.exid) {
145 case ARCH_EXID_AT91SAM9M10:
146 at91_soc_initdata.subtype = AT91_SOC_SAM9M10;
147 break;
148 case ARCH_EXID_AT91SAM9G46:
149 at91_soc_initdata.subtype = AT91_SOC_SAM9G46;
150 break;
151 case ARCH_EXID_AT91SAM9M11:
152 at91_soc_initdata.subtype = AT91_SOC_SAM9M11;
153 break;
154 }
155 }
156
157 if (at91_soc_initdata.type == AT91_SOC_SAM9X5) {
158 switch (at91_soc_initdata.exid) {
159 case ARCH_EXID_AT91SAM9G15:
160 at91_soc_initdata.subtype = AT91_SOC_SAM9G15;
161 break;
162 case ARCH_EXID_AT91SAM9G35:
163 at91_soc_initdata.subtype = AT91_SOC_SAM9G35;
164 break;
165 case ARCH_EXID_AT91SAM9X35:
166 at91_soc_initdata.subtype = AT91_SOC_SAM9X35;
167 break;
168 case ARCH_EXID_AT91SAM9G25:
169 at91_soc_initdata.subtype = AT91_SOC_SAM9G25;
170 break;
171 case ARCH_EXID_AT91SAM9X25:
172 at91_soc_initdata.subtype = AT91_SOC_SAM9X25;
173 break;
174 }
175 }
176}
177
178static const char *soc_name[] = {
179 [AT91_SOC_RM9200] = "at91rm9200",
180 [AT91_SOC_CAP9] = "at91cap9",
181 [AT91_SOC_SAM9260] = "at91sam9260",
182 [AT91_SOC_SAM9261] = "at91sam9261",
183 [AT91_SOC_SAM9263] = "at91sam9263",
184 [AT91_SOC_SAM9G10] = "at91sam9g10",
185 [AT91_SOC_SAM9G20] = "at91sam9g20",
186 [AT91_SOC_SAM9G45] = "at91sam9g45",
187 [AT91_SOC_SAM9RL] = "at91sam9rl",
188 [AT91_SOC_SAM9X5] = "at91sam9x5",
189 [AT91_SOC_NONE] = "Unknown"
190};
191
192const char *at91_get_soc_type(struct at91_socinfo *c)
193{
194 return soc_name[c->type];
195}
196EXPORT_SYMBOL(at91_get_soc_type);
197
198static const char *soc_subtype_name[] = {
199 [AT91_SOC_RM9200_BGA] = "at91rm9200 BGA",
200 [AT91_SOC_RM9200_PQFP] = "at91rm9200 PQFP",
201 [AT91_SOC_CAP9_REV_B] = "at91cap9 revB",
202 [AT91_SOC_CAP9_REV_C] = "at91cap9 revC",
203 [AT91_SOC_SAM9XE] = "at91sam9xe",
204 [AT91_SOC_SAM9G45ES] = "at91sam9g45es",
205 [AT91_SOC_SAM9M10] = "at91sam9m10",
206 [AT91_SOC_SAM9G46] = "at91sam9g46",
207 [AT91_SOC_SAM9M11] = "at91sam9m11",
208 [AT91_SOC_SAM9G15] = "at91sam9g15",
209 [AT91_SOC_SAM9G35] = "at91sam9g35",
210 [AT91_SOC_SAM9X35] = "at91sam9x35",
211 [AT91_SOC_SAM9G25] = "at91sam9g25",
212 [AT91_SOC_SAM9X25] = "at91sam9x25",
213 [AT91_SOC_SUBTYPE_NONE] = "Unknown"
214};
215
216const char *at91_get_soc_subtype(struct at91_socinfo *c)
217{
218 return soc_subtype_name[c->subtype];
219}
220EXPORT_SYMBOL(at91_get_soc_subtype);
221
222void __init at91_map_io(void)
223{
224 /* Map peripherals */
225 iotable_init(&at91_io_desc, 1);
226
227 at91_soc_initdata.type = AT91_SOC_NONE;
228 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
229
230 soc_detect(AT91_DBGU0);
231 if (!at91_soc_is_detected())
232 soc_detect(AT91_DBGU1);
233
234 if (!at91_soc_is_detected())
235 panic("AT91: Impossible to detect the SOC type");
236
237 pr_info("AT91: Detected soc type: %s\n",
238 at91_get_soc_type(&at91_soc_initdata));
239 pr_info("AT91: Detected soc subtype: %s\n",
240 at91_get_soc_subtype(&at91_soc_initdata));
241
242 if (!at91_soc_is_enabled())
243 panic("AT91: Soc not enabled");
69 244
70 if (at91_boot_soc.map_io) 245 if (at91_boot_soc.map_io)
71 at91_boot_soc.map_io(); 246 at91_boot_soc.map_io();
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index 99afa7c90d65..9de7be4037c4 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -4,18 +4,55 @@
4 * Under GPLv2 4 * Under GPLv2
5 */ 5 */
6 6
7struct at91_soc { 7struct at91_init_soc {
8 unsigned int *default_irq_priority; 8 unsigned int *default_irq_priority;
9 void (*map_io)(void); 9 void (*map_io)(void);
10 void (*init)(unsigned long main_clock); 10 void (*init)(unsigned long main_clock);
11}; 11};
12 12
13extern struct at91_soc at91_boot_soc; 13extern struct at91_init_soc at91_boot_soc;
14extern struct at91_soc at91cap9_soc; 14extern struct at91_init_soc at91cap9_soc;
15extern struct at91_soc at91rm9200_soc; 15extern struct at91_init_soc at91rm9200_soc;
16extern struct at91_soc at91sam9260_soc; 16extern struct at91_init_soc at91sam9260_soc;
17extern struct at91_soc at91sam9261_soc; 17extern struct at91_init_soc at91sam9261_soc;
18extern struct at91_soc at91sam9263_soc; 18extern struct at91_init_soc at91sam9263_soc;
19extern struct at91_soc at91sam9g45_soc; 19extern struct at91_init_soc at91sam9g45_soc;
20extern struct at91_soc at91sam9rl_soc; 20extern struct at91_init_soc at91sam9rl_soc;
21extern struct at91_soc at91sam9x5_soc; 21extern struct at91_init_soc at91sam9x5_soc;
22
23static inline int at91_soc_is_enabled(void)
24{
25 return at91_boot_soc.init != NULL;
26}
27
28#if !defined(CONFIG_ARCH_AT91CAP9)
29#define at91cap9_soc at91_boot_soc
30#endif
31
32#if !defined(CONFIG_ARCH_AT91RM9200)
33#define at91rm9200_soc at91_boot_soc
34#endif
35
36#if !(defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20))
37#define at91sam9260_soc at91_boot_soc
38#endif
39
40#if !(defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10))
41#define at91sam9261_soc at91_boot_soc
42#endif
43
44#if !defined(CONFIG_ARCH_AT91SAM9263)
45#define at91sam9263_soc at91_boot_soc
46#endif
47
48#if !defined(CONFIG_ARCH_AT91SAM9G45)
49#define at91sam9g45_soc at91_boot_soc
50#endif
51
52#if !defined(CONFIG_ARCH_AT91SAM9RL)
53#define at91sam9rl_soc at91_boot_soc
54#endif
55
56#if !defined(CONFIG_ARCH_AT91SAM9X5)
57#define at91sam9x5_soc at91_boot_soc
58#endif