2 * Copyright (C) 2007 Atmel Corporation.
3 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
8 #define pr_fmt(fmt) "AT91: " fmt
10 #include <linux/module.h>
14 #include <linux/of_address.h>
15 #include <linux/pinctrl/machine.h>
16 #include <linux/clk/at91_pmc.h>
18 #include <asm/system_misc.h>
19 #include <asm/mach/map.h>
21 #include <mach/hardware.h>
23 #include <mach/at91_dbgu.h>
28 struct at91_socinfo at91_soc_initdata
;
29 EXPORT_SYMBOL(at91_soc_initdata
);
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
),
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
),
45 static void __init
soc_detect(u32 dbgu_base
)
49 cidr
= __raw_readl(AT91_IO_P2V(dbgu_base
) + AT91_DBGU_CIDR
);
50 socid
= cidr
& ~AT91_CIDR_VERSION
;
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
;
59 case ARCH_ID_AT91SAM9260
:
60 at91_soc_initdata
.type
= AT91_SOC_SAM9260
;
61 at91_soc_initdata
.subtype
= AT91_SOC_SUBTYPE_NONE
;
64 case ARCH_ID_AT91SAM9261
:
65 at91_soc_initdata
.type
= AT91_SOC_SAM9261
;
66 at91_soc_initdata
.subtype
= AT91_SOC_SUBTYPE_NONE
;
69 case ARCH_ID_AT91SAM9263
:
70 at91_soc_initdata
.type
= AT91_SOC_SAM9263
;
71 at91_soc_initdata
.subtype
= AT91_SOC_SUBTYPE_NONE
;
74 case ARCH_ID_AT91SAM9G20
:
75 at91_soc_initdata
.type
= AT91_SOC_SAM9G20
;
76 at91_soc_initdata
.subtype
= AT91_SOC_SUBTYPE_NONE
;
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
;
85 case ARCH_ID_AT91SAM9RL64
:
86 at91_soc_initdata
.type
= AT91_SOC_SAM9RL
;
87 at91_soc_initdata
.subtype
= AT91_SOC_SUBTYPE_NONE
;
90 case ARCH_ID_AT91SAM9X5
:
91 at91_soc_initdata
.type
= AT91_SOC_SAM9X5
;
94 case ARCH_ID_AT91SAM9N12
:
95 at91_soc_initdata
.type
= AT91_SOC_SAM9N12
;
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
;
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
;
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
;
117 if (!at91_soc_is_detected())
120 at91_soc_initdata
.cidr
= cidr
;
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
);
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
;
131 case ARCH_EXID_AT91SAM9G46
:
132 at91_soc_initdata
.subtype
= AT91_SOC_SAM9G46
;
134 case ARCH_EXID_AT91SAM9M11
:
135 at91_soc_initdata
.subtype
= AT91_SOC_SAM9M11
;
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
;
145 case ARCH_EXID_AT91SAM9G35
:
146 at91_soc_initdata
.subtype
= AT91_SOC_SAM9G35
;
148 case ARCH_EXID_AT91SAM9X35
:
149 at91_soc_initdata
.subtype
= AT91_SOC_SAM9X35
;
151 case ARCH_EXID_AT91SAM9G25
:
152 at91_soc_initdata
.subtype
= AT91_SOC_SAM9G25
;
154 case ARCH_EXID_AT91SAM9X25
:
155 at91_soc_initdata
.subtype
= AT91_SOC_SAM9X25
;
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
;
165 case ARCH_EXID_SAMA5D33
:
166 at91_soc_initdata
.subtype
= AT91_SOC_SAMA5D33
;
168 case ARCH_EXID_SAMA5D34
:
169 at91_soc_initdata
.subtype
= AT91_SOC_SAMA5D34
;
171 case ARCH_EXID_SAMA5D35
:
172 at91_soc_initdata
.subtype
= AT91_SOC_SAMA5D35
;
174 case ARCH_EXID_SAMA5D36
:
175 at91_soc_initdata
.subtype
= AT91_SOC_SAMA5D36
;
181 static void __init
alt_soc_detect(u32 dbgu_base
)
186 cidr
= __raw_readl(AT91_ALT_IO_P2V(dbgu_base
) + AT91_DBGU_CIDR
);
187 socid
= cidr
& ~AT91_CIDR_VERSION
;
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
;
200 if (!at91_soc_is_detected())
203 at91_soc_initdata
.cidr
= cidr
;
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
);
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
;
214 case ARCH_EXID_SAMA5D42
:
215 at91_soc_initdata
.subtype
= AT91_SOC_SAMA5D42
;
217 case ARCH_EXID_SAMA5D43
:
218 at91_soc_initdata
.subtype
= AT91_SOC_SAMA5D43
;
220 case ARCH_EXID_SAMA5D44
:
221 at91_soc_initdata
.subtype
= AT91_SOC_SAMA5D44
;
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",
243 const char *at91_get_soc_type(struct at91_socinfo
*c
)
245 return soc_name
[c
->type
];
247 EXPORT_SYMBOL(at91_get_soc_type
);
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",
275 const char *at91_get_soc_subtype(struct at91_socinfo
*c
)
277 return soc_subtype_name
[c
->subtype
];
279 EXPORT_SYMBOL(at91_get_soc_subtype
);
281 void __init
at91_map_io(void)
283 /* Map peripherals */
284 iotable_init(&at91_io_desc
, 1);
286 at91_soc_initdata
.type
= AT91_SOC_UNKNOWN
;
287 at91_soc_initdata
.subtype
= AT91_SOC_SUBTYPE_UNKNOWN
;
289 soc_detect(AT91_BASE_DBGU0
);
290 if (!at91_soc_is_detected())
291 soc_detect(AT91_BASE_DBGU1
);
293 if (!at91_soc_is_detected())
294 panic(pr_fmt("Impossible to detect the SOC type"));
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
));
303 void __init
at91_alt_map_io(void)
305 /* Map peripherals */
306 iotable_init(&at91_alt_io_desc
, 1);
308 at91_soc_initdata
.type
= AT91_SOC_UNKNOWN
;
309 at91_soc_initdata
.subtype
= AT91_SOC_SUBTYPE_UNKNOWN
;
311 alt_soc_detect(AT91_BASE_DBGU2
);
312 if (!at91_soc_is_detected())
313 panic("AT91: Impossible to detect the SOC type");
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
));
322 void __iomem
*at91_matrix_base
;
323 EXPORT_SYMBOL_GPL(at91_matrix_base
);
325 void __init
at91_ioremap_matrix(u32 base_addr
)
327 at91_matrix_base
= ioremap(base_addr
, 512);
328 if (!at91_matrix_base
)
329 panic(pr_fmt("Impossible to ioremap at91_matrix_base\n"));