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