ARM: EXYNOS: Remove legacy L2X0 initialization
[deliverable/linux.git] / arch / arm / mach-exynos / common.c
CommitLineData
cc511b8d
KK
1/*
2 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Common Codes for EXYNOS
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
68a433f1 13#include <linux/bitops.h>
cc511b8d
KK
14#include <linux/interrupt.h>
15#include <linux/irq.h>
a900e5d9 16#include <linux/irqchip.h>
cc511b8d 17#include <linux/io.h>
7affca35 18#include <linux/device.h>
cc511b8d 19#include <linux/gpio.h>
68a433f1 20#include <clocksource/samsung_pwm.h>
cc511b8d
KK
21#include <linux/sched.h>
22#include <linux/serial_core.h>
237c78be 23#include <linux/of.h>
5b7897db 24#include <linux/of_fdt.h>
237c78be 25#include <linux/of_irq.h>
1e60bc0b
TA
26#include <linux/export.h>
27#include <linux/irqdomain.h>
e873a47c 28#include <linux/of_address.h>
6923ae4b
TA
29#include <linux/clocksource.h>
30#include <linux/clk-provider.h>
520f7bd7 31#include <linux/irqchip/arm-gic.h>
de88cbb7 32#include <linux/irqchip/chained_irq.h>
cc511b8d
KK
33
34#include <asm/proc-fns.h>
40ba95fd 35#include <asm/exception.h>
cc511b8d 36#include <asm/hardware/cache-l2x0.h>
cc511b8d
KK
37#include <asm/mach/map.h>
38#include <asm/mach/irq.h>
b756a50f 39#include <asm/cacheflush.h>
cc511b8d
KK
40
41#include <mach/regs-irq.h>
42#include <mach/regs-pmu.h>
cc511b8d
KK
43
44#include <plat/cpu.h>
cc511b8d 45#include <plat/pm.h>
cc511b8d
KK
46#include <plat/regs-serial.h>
47
48#include "common.h"
6cdeddcc
ADK
49#define L2_AUX_VAL 0x7C470001
50#define L2_AUX_MASK 0xC200ffff
cc511b8d 51
cc511b8d
KK
52static const char name_exynos4210[] = "EXYNOS4210";
53static const char name_exynos4212[] = "EXYNOS4212";
54static const char name_exynos4412[] = "EXYNOS4412";
94c7ca71 55static const char name_exynos5250[] = "EXYNOS5250";
2edb36c4 56static const char name_exynos5440[] = "EXYNOS5440";
cc511b8d 57
906c789c 58static void exynos4_map_io(void);
94c7ca71 59static void exynos5_map_io(void);
2edb36c4 60static void exynos5440_map_io(void);
906c789c 61static int exynos_init(void);
cc511b8d 62
92744274
TA
63unsigned long xxti_f = 0, xusbxti_f = 0;
64
cc511b8d
KK
65static struct cpu_table cpu_ids[] __initdata = {
66 {
67 .idcode = EXYNOS4210_CPU_ID,
68 .idmask = EXYNOS4_CPU_MASK,
69 .map_io = exynos4_map_io,
cc511b8d
KK
70 .init = exynos_init,
71 .name = name_exynos4210,
72 }, {
73 .idcode = EXYNOS4212_CPU_ID,
74 .idmask = EXYNOS4_CPU_MASK,
75 .map_io = exynos4_map_io,
cc511b8d
KK
76 .init = exynos_init,
77 .name = name_exynos4212,
78 }, {
79 .idcode = EXYNOS4412_CPU_ID,
80 .idmask = EXYNOS4_CPU_MASK,
81 .map_io = exynos4_map_io,
cc511b8d
KK
82 .init = exynos_init,
83 .name = name_exynos4412,
94c7ca71
KK
84 }, {
85 .idcode = EXYNOS5250_SOC_ID,
86 .idmask = EXYNOS5_SOC_MASK,
87 .map_io = exynos5_map_io,
94c7ca71
KK
88 .init = exynos_init,
89 .name = name_exynos5250,
2edb36c4
KK
90 }, {
91 .idcode = EXYNOS5440_SOC_ID,
92 .idmask = EXYNOS5_SOC_MASK,
93 .map_io = exynos5440_map_io,
94 .init = exynos_init,
95 .name = name_exynos5440,
cc511b8d
KK
96 },
97};
98
99/* Initial IO mappings */
100
94c7ca71
KK
101static struct map_desc exynos4_iodesc[] __initdata = {
102 {
cc511b8d
KK
103 .virtual = (unsigned long)S3C_VA_SYS,
104 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSCON),
105 .length = SZ_64K,
106 .type = MT_DEVICE,
107 }, {
108 .virtual = (unsigned long)S3C_VA_TIMER,
109 .pfn = __phys_to_pfn(EXYNOS4_PA_TIMER),
110 .length = SZ_16K,
111 .type = MT_DEVICE,
112 }, {
113 .virtual = (unsigned long)S3C_VA_WATCHDOG,
114 .pfn = __phys_to_pfn(EXYNOS4_PA_WATCHDOG),
115 .length = SZ_4K,
116 .type = MT_DEVICE,
117 }, {
118 .virtual = (unsigned long)S5P_VA_SROMC,
119 .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
120 .length = SZ_4K,
121 .type = MT_DEVICE,
122 }, {
123 .virtual = (unsigned long)S5P_VA_SYSTIMER,
124 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
125 .length = SZ_4K,
126 .type = MT_DEVICE,
127 }, {
128 .virtual = (unsigned long)S5P_VA_PMU,
129 .pfn = __phys_to_pfn(EXYNOS4_PA_PMU),
130 .length = SZ_64K,
131 .type = MT_DEVICE,
132 }, {
133 .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
134 .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER),
135 .length = SZ_4K,
136 .type = MT_DEVICE,
137 }, {
138 .virtual = (unsigned long)S5P_VA_GIC_CPU,
139 .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_CPU),
140 .length = SZ_64K,
141 .type = MT_DEVICE,
142 }, {
143 .virtual = (unsigned long)S5P_VA_GIC_DIST,
144 .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_DIST),
145 .length = SZ_64K,
146 .type = MT_DEVICE,
147 }, {
148 .virtual = (unsigned long)S3C_VA_UART,
149 .pfn = __phys_to_pfn(EXYNOS4_PA_UART),
150 .length = SZ_512K,
151 .type = MT_DEVICE,
94c7ca71 152 }, {
cc511b8d
KK
153 .virtual = (unsigned long)S5P_VA_CMU,
154 .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
155 .length = SZ_128K,
156 .type = MT_DEVICE,
157 }, {
158 .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
159 .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
160 .length = SZ_8K,
161 .type = MT_DEVICE,
162 }, {
163 .virtual = (unsigned long)S5P_VA_L2CC,
164 .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC),
165 .length = SZ_4K,
166 .type = MT_DEVICE,
cc511b8d
KK
167 }, {
168 .virtual = (unsigned long)S5P_VA_DMC0,
169 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
2bde0b08
MH
170 .length = SZ_64K,
171 .type = MT_DEVICE,
172 }, {
173 .virtual = (unsigned long)S5P_VA_DMC1,
174 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
175 .length = SZ_64K,
cc511b8d 176 .type = MT_DEVICE,
cc511b8d
KK
177 }, {
178 .virtual = (unsigned long)S3C_VA_USB_HSPHY,
179 .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY),
180 .length = SZ_4K,
181 .type = MT_DEVICE,
182 },
183};
184
185static struct map_desc exynos4_iodesc0[] __initdata = {
186 {
187 .virtual = (unsigned long)S5P_VA_SYSRAM,
188 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM0),
189 .length = SZ_4K,
190 .type = MT_DEVICE,
191 },
192};
193
194static struct map_desc exynos4_iodesc1[] __initdata = {
195 {
196 .virtual = (unsigned long)S5P_VA_SYSRAM,
197 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
198 .length = SZ_4K,
199 .type = MT_DEVICE,
200 },
201};
202
41de8986
TF
203static struct map_desc exynos4210_iodesc[] __initdata = {
204 {
205 .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
206 .pfn = __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS),
207 .length = SZ_4K,
208 .type = MT_DEVICE,
209 },
210};
211
212static struct map_desc exynos4x12_iodesc[] __initdata = {
213 {
214 .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
215 .pfn = __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS),
216 .length = SZ_4K,
217 .type = MT_DEVICE,
218 },
219};
220
221static struct map_desc exynos5250_iodesc[] __initdata = {
222 {
223 .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
224 .pfn = __phys_to_pfn(EXYNOS5250_PA_SYSRAM_NS),
225 .length = SZ_4K,
226 .type = MT_DEVICE,
227 },
228};
229
94c7ca71
KK
230static struct map_desc exynos5_iodesc[] __initdata = {
231 {
232 .virtual = (unsigned long)S3C_VA_SYS,
233 .pfn = __phys_to_pfn(EXYNOS5_PA_SYSCON),
234 .length = SZ_64K,
235 .type = MT_DEVICE,
236 }, {
237 .virtual = (unsigned long)S3C_VA_TIMER,
238 .pfn = __phys_to_pfn(EXYNOS5_PA_TIMER),
239 .length = SZ_16K,
240 .type = MT_DEVICE,
241 }, {
242 .virtual = (unsigned long)S3C_VA_WATCHDOG,
243 .pfn = __phys_to_pfn(EXYNOS5_PA_WATCHDOG),
244 .length = SZ_4K,
245 .type = MT_DEVICE,
246 }, {
247 .virtual = (unsigned long)S5P_VA_SROMC,
248 .pfn = __phys_to_pfn(EXYNOS5_PA_SROMC),
249 .length = SZ_4K,
250 .type = MT_DEVICE,
94c7ca71
KK
251 }, {
252 .virtual = (unsigned long)S5P_VA_SYSRAM,
253 .pfn = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
254 .length = SZ_4K,
255 .type = MT_DEVICE,
256 }, {
257 .virtual = (unsigned long)S5P_VA_CMU,
258 .pfn = __phys_to_pfn(EXYNOS5_PA_CMU),
259 .length = 144 * SZ_1K,
260 .type = MT_DEVICE,
261 }, {
262 .virtual = (unsigned long)S5P_VA_PMU,
263 .pfn = __phys_to_pfn(EXYNOS5_PA_PMU),
264 .length = SZ_64K,
265 .type = MT_DEVICE,
94c7ca71
KK
266 }, {
267 .virtual = (unsigned long)S3C_VA_UART,
268 .pfn = __phys_to_pfn(EXYNOS5_PA_UART),
269 .length = SZ_512K,
270 .type = MT_DEVICE,
94c7ca71
KK
271 },
272};
273
2edb36c4
KK
274static struct map_desc exynos5440_iodesc0[] __initdata = {
275 {
276 .virtual = (unsigned long)S3C_VA_UART,
277 .pfn = __phys_to_pfn(EXYNOS5440_PA_UART0),
278 .length = SZ_512K,
279 .type = MT_DEVICE,
280 },
281};
282
9eb48595 283void exynos4_restart(char mode, const char *cmd)
cc511b8d
KK
284{
285 __raw_writel(0x1, S5P_SWRESET);
286}
287
94c7ca71
KK
288void exynos5_restart(char mode, const char *cmd)
289{
60db7e5f 290 struct device_node *np;
2edb36c4
KK
291 u32 val;
292 void __iomem *addr;
293
294 if (of_machine_is_compatible("samsung,exynos5250")) {
295 val = 0x1;
296 addr = EXYNOS_SWRESET;
297 } else if (of_machine_is_compatible("samsung,exynos5440")) {
1ba830c9 298 u32 status;
60db7e5f 299 np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
1ba830c9
JL
300
301 addr = of_iomap(np, 0) + 0xbc;
302 status = __raw_readl(addr);
303
60db7e5f 304 addr = of_iomap(np, 0) + 0xcc;
1ba830c9
JL
305 val = __raw_readl(addr);
306
307 val = (val & 0xffff0000) | (status & 0xffff);
2edb36c4
KK
308 } else {
309 pr_err("%s: cannot support non-DT\n", __func__);
310 return;
311 }
312
313 __raw_writel(val, addr);
94c7ca71
KK
314}
315
bb13fabc
SG
316void __init exynos_init_late(void)
317{
2edb36c4
KK
318 if (of_machine_is_compatible("samsung,exynos5440"))
319 /* to be supported later */
320 return;
321
bb13fabc
SG
322 exynos_pm_late_initcall();
323}
324
f5f83c71
TA
325int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
326 int depth, void *data)
327{
328 struct map_desc iodesc;
329 __be32 *reg;
330 unsigned long len;
331
332 if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
333 !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
334 return 0;
335
336 reg = of_get_flat_dt_prop(node, "reg", &len);
337 if (reg == NULL || len != (sizeof(unsigned long) * 2))
338 return 0;
339
340 iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
341 iodesc.length = be32_to_cpu(reg[1]) - 1;
342 iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
343 iodesc.type = MT_DEVICE;
344 iotable_init(&iodesc, 1);
345 return 1;
346}
f5f83c71 347
cc511b8d
KK
348/*
349 * exynos_map_io
350 *
351 * register the standard cpu IO areas
352 */
353
0e2238ec 354void __init exynos_init_io(void)
cc511b8d 355{
9c1fcdcc
DA
356 debug_ll_io_init();
357
04fae596 358 of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
2edb36c4 359
cc511b8d
KK
360 /* detect cpu id and rev. */
361 s5p_init_cpu(S5P_VA_CHIPID);
362
363 s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
364}
365
906c789c 366static void __init exynos4_map_io(void)
cc511b8d
KK
367{
368 iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
369
370 if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
371 iotable_init(exynos4_iodesc0, ARRAY_SIZE(exynos4_iodesc0));
372 else
373 iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1));
374
41de8986
TF
375 if (soc_is_exynos4210())
376 iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
377 if (soc_is_exynos4212() || soc_is_exynos4412())
378 iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
cc511b8d
KK
379}
380
94c7ca71
KK
381static void __init exynos5_map_io(void)
382{
383 iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
41de8986
TF
384
385 if (soc_is_exynos5250())
386 iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
94c7ca71
KK
387}
388
2edb36c4
KK
389static void __init exynos5440_map_io(void)
390{
391 iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0));
392}
393
6923ae4b 394void __init exynos_init_time(void)
94c7ca71 395{
3c70348c
TF
396 of_clk_init(NULL);
397 clocksource_of_init();
94c7ca71
KK
398}
399
9ee6af9c
TA
400struct bus_type exynos_subsys = {
401 .name = "exynos-core",
402 .dev_name = "exynos-core",
94c7ca71
KK
403};
404
7affca35 405static struct device exynos4_dev = {
9ee6af9c 406 .bus = &exynos_subsys,
94c7ca71
KK
407};
408
409static int __init exynos_core_init(void)
cc511b8d 410{
9ee6af9c 411 return subsys_system_register(&exynos_subsys, NULL);
cc511b8d 412}
94c7ca71 413core_initcall(exynos_core_init);
cc511b8d 414
cc511b8d
KK
415static int __init exynos4_l2x0_cache_init(void)
416{
e1b1994e
IH
417 int ret;
418
6cdeddcc 419 ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
87107d89
AB
420 if (ret)
421 return ret;
cc511b8d 422
87107d89
AB
423 l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
424 clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
cc511b8d
KK
425 return 0;
426}
cc511b8d 427early_initcall(exynos4_l2x0_cache_init);
cc511b8d 428
906c789c 429static int __init exynos_init(void)
cc511b8d
KK
430{
431 printk(KERN_INFO "EXYNOS: Initializing architecture\n");
94c7ca71 432
9ee6af9c 433 return device_register(&exynos4_dev);
cc511b8d 434}
This page took 0.152445 seconds and 5 git commands to generate.