Blame view

arch/arm/mach-at91/setup.c 7.13 KB
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
1
2
3
4
5
6
7
8
9
  /*
   * Copyright (C) 2007 Atmel Corporation.
   * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
   *
   * Under GPLv2
   */
  
  #include <linux/module.h>
  #include <linux/io.h>
fb149f9e2   Jean-Christophe PLAGNIOL-VILLARD   at91: add arch sp...
10
  #include <linux/mm.h>
f22deee52   Jean-Christophe PLAGNIOL-VILLARD   ARM: at91: make s...
11
  #include <linux/pm.h>
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
12
13
14
15
16
  
  #include <asm/mach/map.h>
  
  #include <mach/hardware.h>
  #include <mach/cpu.h>
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
17
18
  #include <mach/at91_dbgu.h>
  #include <mach/at91_pmc.h>
f22deee52   Jean-Christophe PLAGNIOL-VILLARD   ARM: at91: make s...
19
  #include <mach/at91_shdwc.h>
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
20
21
22
  
  #include "soc.h"
  #include "generic.h"
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
23
24
25
26
27
28
29
30
31
32
33
34
  struct at91_init_soc __initdata at91_boot_soc;
  
  struct at91_socinfo at91_soc_initdata;
  EXPORT_SYMBOL(at91_soc_initdata);
  
  void __init at91rm9200_set_type(int type)
  {
  	if (type == ARCH_REVISON_9200_PQFP)
  		at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
  	else
  		at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP;
  }
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
35

92100c12c   Jean-Christophe PLAGNIOL-VILLARD   at91: factorize a...
36
37
38
39
40
41
42
43
44
45
46
47
48
  void __init at91_init_irq_default(void)
  {
  	at91_init_interrupts(at91_boot_soc.default_irq_priority);
  }
  
  void __init at91_init_interrupts(unsigned int *priority)
  {
  	/* Initialize the AIC interrupt controller */
  	at91_aic_init(priority);
  
  	/* Enable GPIO interrupts */
  	at91_gpio_irq_setup();
  }
f0051d82a   Jean-Christophe PLAGNIOL-VILLARD   at91: factorize s...
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  static struct map_desc sram_desc[2] __initdata;
  
  void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
  {
  	struct map_desc *desc = &sram_desc[bank];
  
  	desc->virtual = AT91_IO_VIRT_BASE - length;
  	if (bank > 0)
  		desc->virtual -= sram_desc[bank - 1].length;
  
  	desc->pfn = __phys_to_pfn(base);
  	desc->length = length;
  	desc->type = MT_DEVICE;
  
  	pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx
  ",
  		base, length, desc->virtual);
  
  	iotable_init(desc, 1);
  }
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
69
70
71
72
73
74
  static struct map_desc at91_io_desc __initdata = {
  	.virtual	= AT91_VA_BASE_SYS,
  	.pfn		= __phys_to_pfn(AT91_BASE_SYS),
  	.length		= SZ_16K,
  	.type		= MT_DEVICE,
  };
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
75
  static void __init soc_detect(u32 dbgu_base)
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
76
  {
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
77
78
79
80
  	u32 cidr, socid;
  
  	cidr = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_CIDR);
  	socid = cidr & ~AT91_CIDR_VERSION;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
81

8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
82
83
84
85
86
87
88
89
90
91
92
  	switch (socid) {
  	case ARCH_ID_AT91CAP9: {
  #ifdef CONFIG_AT91_PMC_UNIT
  		u32 pmc_ver = at91_sys_read(AT91_PMC_VER);
  
  		if (pmc_ver == ARCH_REVISION_CAP9_B)
  			at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_B;
  		else if (pmc_ver == ARCH_REVISION_CAP9_C)
  			at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_C;
  #endif
  		at91_soc_initdata.type = AT91_SOC_CAP9;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
93
  		at91_boot_soc = at91cap9_soc;
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
94
95
96
97
98
  		break;
  	}
  
  	case ARCH_ID_AT91RM9200:
  		at91_soc_initdata.type = AT91_SOC_RM9200;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
99
  		at91_boot_soc = at91rm9200_soc;
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
100
101
102
103
  		break;
  
  	case ARCH_ID_AT91SAM9260:
  		at91_soc_initdata.type = AT91_SOC_SAM9260;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
104
  		at91_boot_soc = at91sam9260_soc;
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
105
106
107
108
  		break;
  
  	case ARCH_ID_AT91SAM9261:
  		at91_soc_initdata.type = AT91_SOC_SAM9261;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
109
  		at91_boot_soc = at91sam9261_soc;
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
110
111
112
113
  		break;
  
  	case ARCH_ID_AT91SAM9263:
  		at91_soc_initdata.type = AT91_SOC_SAM9263;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
114
  		at91_boot_soc = at91sam9263_soc;
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
115
116
117
118
  		break;
  
  	case ARCH_ID_AT91SAM9G20:
  		at91_soc_initdata.type = AT91_SOC_SAM9G20;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
119
  		at91_boot_soc = at91sam9260_soc;
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
120
121
122
123
124
125
  		break;
  
  	case ARCH_ID_AT91SAM9G45:
  		at91_soc_initdata.type = AT91_SOC_SAM9G45;
  		if (cidr == ARCH_ID_AT91SAM9G45ES)
  			at91_soc_initdata.subtype = AT91_SOC_SAM9G45ES;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
126
  		at91_boot_soc = at91sam9g45_soc;
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
127
128
129
130
  		break;
  
  	case ARCH_ID_AT91SAM9RL64:
  		at91_soc_initdata.type = AT91_SOC_SAM9RL;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
131
  		at91_boot_soc = at91sam9rl_soc;
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
132
133
134
135
  		break;
  
  	case ARCH_ID_AT91SAM9X5:
  		at91_soc_initdata.type = AT91_SOC_SAM9X5;
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
136
  		at91_boot_soc = at91sam9x5_soc;
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  		break;
  	}
  
  	/* at91sam9g10 */
  	if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
  		at91_soc_initdata.type = AT91_SOC_SAM9G10;
  		at91_boot_soc = at91sam9261_soc;
  	}
  	/* at91sam9xe */
  	else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) {
  		at91_soc_initdata.type = AT91_SOC_SAM9260;
  		at91_soc_initdata.subtype = AT91_SOC_SAM9XE;
  		at91_boot_soc = at91sam9260_soc;
  	}
  
  	if (!at91_soc_is_detected())
  		return;
  
  	at91_soc_initdata.cidr = cidr;
  
  	/* sub version of soc */
  	at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
  
  	if (at91_soc_initdata.type == AT91_SOC_SAM9G45) {
  		switch (at91_soc_initdata.exid) {
  		case ARCH_EXID_AT91SAM9M10:
  			at91_soc_initdata.subtype = AT91_SOC_SAM9M10;
  			break;
  		case ARCH_EXID_AT91SAM9G46:
  			at91_soc_initdata.subtype = AT91_SOC_SAM9G46;
  			break;
  		case ARCH_EXID_AT91SAM9M11:
  			at91_soc_initdata.subtype = AT91_SOC_SAM9M11;
  			break;
  		}
  	}
  
  	if (at91_soc_initdata.type == AT91_SOC_SAM9X5) {
  		switch (at91_soc_initdata.exid) {
  		case ARCH_EXID_AT91SAM9G15:
  			at91_soc_initdata.subtype = AT91_SOC_SAM9G15;
  			break;
  		case ARCH_EXID_AT91SAM9G35:
  			at91_soc_initdata.subtype = AT91_SOC_SAM9G35;
  			break;
  		case ARCH_EXID_AT91SAM9X35:
  			at91_soc_initdata.subtype = AT91_SOC_SAM9X35;
  			break;
  		case ARCH_EXID_AT91SAM9G25:
  			at91_soc_initdata.subtype = AT91_SOC_SAM9G25;
  			break;
  		case ARCH_EXID_AT91SAM9X25:
  			at91_soc_initdata.subtype = AT91_SOC_SAM9X25;
  			break;
  		}
  	}
  }
  
  static const char *soc_name[] = {
  	[AT91_SOC_RM9200]	= "at91rm9200",
  	[AT91_SOC_CAP9]		= "at91cap9",
  	[AT91_SOC_SAM9260]	= "at91sam9260",
  	[AT91_SOC_SAM9261]	= "at91sam9261",
  	[AT91_SOC_SAM9263]	= "at91sam9263",
  	[AT91_SOC_SAM9G10]	= "at91sam9g10",
  	[AT91_SOC_SAM9G20]	= "at91sam9g20",
  	[AT91_SOC_SAM9G45]	= "at91sam9g45",
  	[AT91_SOC_SAM9RL]	= "at91sam9rl",
  	[AT91_SOC_SAM9X5]	= "at91sam9x5",
  	[AT91_SOC_NONE]		= "Unknown"
  };
  
  const char *at91_get_soc_type(struct at91_socinfo *c)
  {
  	return soc_name[c->type];
  }
  EXPORT_SYMBOL(at91_get_soc_type);
  
  static const char *soc_subtype_name[] = {
  	[AT91_SOC_RM9200_BGA]	= "at91rm9200 BGA",
  	[AT91_SOC_RM9200_PQFP]	= "at91rm9200 PQFP",
  	[AT91_SOC_CAP9_REV_B]	= "at91cap9 revB",
  	[AT91_SOC_CAP9_REV_C]	= "at91cap9 revC",
  	[AT91_SOC_SAM9XE]	= "at91sam9xe",
  	[AT91_SOC_SAM9G45ES]	= "at91sam9g45es",
  	[AT91_SOC_SAM9M10]	= "at91sam9m10",
  	[AT91_SOC_SAM9G46]	= "at91sam9g46",
  	[AT91_SOC_SAM9M11]	= "at91sam9m11",
  	[AT91_SOC_SAM9G15]	= "at91sam9g15",
  	[AT91_SOC_SAM9G35]	= "at91sam9g35",
  	[AT91_SOC_SAM9X35]	= "at91sam9x35",
  	[AT91_SOC_SAM9G25]	= "at91sam9g25",
  	[AT91_SOC_SAM9X25]	= "at91sam9x25",
  	[AT91_SOC_SUBTYPE_NONE]	= "Unknown"
  };
  
  const char *at91_get_soc_subtype(struct at91_socinfo *c)
  {
  	return soc_subtype_name[c->subtype];
  }
  EXPORT_SYMBOL(at91_get_soc_subtype);
  
  void __init at91_map_io(void)
  {
  	/* Map peripherals */
  	iotable_init(&at91_io_desc, 1);
  
  	at91_soc_initdata.type = AT91_SOC_NONE;
  	at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
13079a733   Jean-Christophe PLAGNIOL-VILLARD   ARM: at91: make D...
246
  	soc_detect(AT91_BASE_DBGU0);
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
247
  	if (!at91_soc_is_detected())
13079a733   Jean-Christophe PLAGNIOL-VILLARD   ARM: at91: make D...
248
  		soc_detect(AT91_BASE_DBGU1);
8c3583b63   Jean-Christophe PLAGNIOL-VILLARD   at91: use structu...
249
250
251
252
253
254
255
256
257
258
259
260
261
  
  	if (!at91_soc_is_detected())
  		panic("AT91: Impossible to detect the SOC type");
  
  	pr_info("AT91: Detected soc type: %s
  ",
  		at91_get_soc_type(&at91_soc_initdata));
  	pr_info("AT91: Detected soc subtype: %s
  ",
  		at91_get_soc_subtype(&at91_soc_initdata));
  
  	if (!at91_soc_is_enabled())
  		panic("AT91: Soc not enabled");
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
262
263
264
265
  
  	if (at91_boot_soc.map_io)
  		at91_boot_soc.map_io();
  }
f22deee52   Jean-Christophe PLAGNIOL-VILLARD   ARM: at91: make s...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  void __iomem *at91_shdwc_base = NULL;
  
  static void at91sam9_poweroff(void)
  {
  	at91_shdwc_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
  }
  
  void __init at91_ioremap_shdwc(u32 base_addr)
  {
  	at91_shdwc_base = ioremap(base_addr, 16);
  	if (!at91_shdwc_base)
  		panic("Impossible to ioremap at91_shdwc_base
  ");
  	pm_power_off = at91sam9_poweroff;
  }
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
281
282
  void __init at91_initialize(unsigned long main_clock)
  {
cfa5a1fe7   Jean-Christophe PLAGNIOL-VILLARD   ARM: at91: add io...
283
  	at91_boot_soc.ioremap_registers();
465393749   Jean-Christophe PLAGNIOL-VILLARD   at91: move clock ...
284
285
  	/* Init clock subsystem */
  	at91_clock_init(main_clock);
51ddec761   Jean-Christophe PLAGNIOL-VILLARD   at91: move regist...
286
287
  	/* Register the processor-specific clocks */
  	at91_boot_soc.register_clocks();
465393749   Jean-Christophe PLAGNIOL-VILLARD   at91: move clock ...
288
  	at91_boot_soc.init();
21d08b9d5   Jean-Christophe PLAGNIOL-VILLARD   at91: introduce c...
289
  }