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