]>
Commit | Line | Data |
---|---|---|
7d30e8b3 | 1 | /* linux/arch/arm/mach-exynos4/cpu.c |
2b12b5c4 | 2 | * |
7d30e8b3 KK |
3 | * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. |
4 | * http://www.samsung.com | |
2b12b5c4 CY |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | */ | |
10 | ||
11 | #include <linux/sched.h> | |
12 | #include <linux/sysdev.h> | |
13 | ||
14 | #include <asm/mach/map.h> | |
15 | #include <asm/mach/irq.h> | |
16 | ||
17 | #include <asm/proc-fns.h> | |
1cf0eb79 | 18 | #include <asm/hardware/cache-l2x0.h> |
2b12b5c4 CY |
19 | |
20 | #include <plat/cpu.h> | |
21 | #include <plat/clock.h> | |
7d30e8b3 | 22 | #include <plat/exynos4.h> |
1036c3ab | 23 | #include <plat/sdhci.h> |
604eefeb SN |
24 | #include <plat/devs.h> |
25 | #include <plat/fimc-core.h> | |
2b12b5c4 CY |
26 | |
27 | #include <mach/regs-irq.h> | |
28 | ||
2b12b5c4 CY |
29 | extern int combiner_init(unsigned int combiner_nr, void __iomem *base, |
30 | unsigned int irq_start); | |
31 | extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); | |
32 | ||
33 | /* Initial IO mappings */ | |
7d30e8b3 | 34 | static struct map_desc exynos4_iodesc[] __initdata = { |
2b12b5c4 | 35 | { |
2b740159 CY |
36 | .virtual = (unsigned long)S5P_VA_SYSTIMER, |
37 | .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER), | |
38 | .length = SZ_4K, | |
39 | .type = MT_DEVICE, | |
40 | }, { | |
19a2c065 | 41 | .virtual = (unsigned long)S5P_VA_SYSRAM, |
7d30e8b3 | 42 | .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM), |
19a2c065 KK |
43 | .length = SZ_4K, |
44 | .type = MT_DEVICE, | |
45 | }, { | |
46 | .virtual = (unsigned long)S5P_VA_CMU, | |
7d30e8b3 | 47 | .pfn = __phys_to_pfn(EXYNOS4_PA_CMU), |
19a2c065 | 48 | .length = SZ_128K, |
2b12b5c4 | 49 | .type = MT_DEVICE, |
d6d8b481 CY |
50 | }, { |
51 | .virtual = (unsigned long)S5P_VA_PMU, | |
7d30e8b3 | 52 | .pfn = __phys_to_pfn(EXYNOS4_PA_PMU), |
d6d8b481 CY |
53 | .length = SZ_64K, |
54 | .type = MT_DEVICE, | |
2b12b5c4 CY |
55 | }, { |
56 | .virtual = (unsigned long)S5P_VA_COMBINER_BASE, | |
7d30e8b3 | 57 | .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER), |
2b12b5c4 CY |
58 | .length = SZ_4K, |
59 | .type = MT_DEVICE, | |
19a2c065 KK |
60 | }, { |
61 | .virtual = (unsigned long)S5P_VA_COREPERI_BASE, | |
7d30e8b3 | 62 | .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI), |
19a2c065 KK |
63 | .length = SZ_8K, |
64 | .type = MT_DEVICE, | |
2b12b5c4 CY |
65 | }, { |
66 | .virtual = (unsigned long)S5P_VA_L2CC, | |
7d30e8b3 | 67 | .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC), |
2b12b5c4 CY |
68 | .length = SZ_4K, |
69 | .type = MT_DEVICE, | |
766211e7 | 70 | }, { |
37ea63b1 | 71 | .virtual = (unsigned long)S5P_VA_GPIO1, |
7d30e8b3 | 72 | .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1), |
766211e7 CY |
73 | .length = SZ_4K, |
74 | .type = MT_DEVICE, | |
37ea63b1 JL |
75 | }, { |
76 | .virtual = (unsigned long)S5P_VA_GPIO2, | |
7d30e8b3 | 77 | .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2), |
37ea63b1 JL |
78 | .length = SZ_4K, |
79 | .type = MT_DEVICE, | |
80 | }, { | |
81 | .virtual = (unsigned long)S5P_VA_GPIO3, | |
7d30e8b3 | 82 | .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3), |
37ea63b1 JL |
83 | .length = SZ_256, |
84 | .type = MT_DEVICE, | |
dd0b7e20 SK |
85 | }, { |
86 | .virtual = (unsigned long)S5P_VA_DMC0, | |
7d30e8b3 | 87 | .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), |
dd0b7e20 SK |
88 | .length = SZ_4K, |
89 | .type = MT_DEVICE, | |
c598c47d | 90 | }, { |
19a2c065 KK |
91 | .virtual = (unsigned long)S3C_VA_UART, |
92 | .pfn = __phys_to_pfn(S3C_PA_UART), | |
93 | .length = SZ_512K, | |
c598c47d | 94 | .type = MT_DEVICE, |
09596ba0 DM |
95 | }, { |
96 | .virtual = (unsigned long)S5P_VA_SROMC, | |
7d30e8b3 | 97 | .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC), |
09596ba0 DM |
98 | .length = SZ_4K, |
99 | .type = MT_DEVICE, | |
766211e7 | 100 | }, |
2b12b5c4 CY |
101 | }; |
102 | ||
7d30e8b3 | 103 | static void exynos4_idle(void) |
2b12b5c4 CY |
104 | { |
105 | if (!need_resched()) | |
106 | cpu_do_idle(); | |
107 | ||
108 | local_irq_enable(); | |
109 | } | |
110 | ||
7d30e8b3 KK |
111 | /* |
112 | * exynos4_map_io | |
2b12b5c4 CY |
113 | * |
114 | * register the standard cpu IO areas | |
7d30e8b3 KK |
115 | */ |
116 | void __init exynos4_map_io(void) | |
2b12b5c4 | 117 | { |
7d30e8b3 | 118 | iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc)); |
1036c3ab HL |
119 | |
120 | /* initialize device information early */ | |
7d30e8b3 KK |
121 | exynos4_default_sdhci0(); |
122 | exynos4_default_sdhci1(); | |
123 | exynos4_default_sdhci2(); | |
124 | exynos4_default_sdhci3(); | |
604eefeb SN |
125 | |
126 | s3c_fimc_setname(0, "exynos4-fimc"); | |
127 | s3c_fimc_setname(1, "exynos4-fimc"); | |
128 | s3c_fimc_setname(2, "exynos4-fimc"); | |
129 | s3c_fimc_setname(3, "exynos4-fimc"); | |
2b12b5c4 CY |
130 | } |
131 | ||
7d30e8b3 | 132 | void __init exynos4_init_clocks(int xtal) |
2b12b5c4 CY |
133 | { |
134 | printk(KERN_DEBUG "%s: initializing clocks\n", __func__); | |
135 | ||
136 | s3c24xx_register_baseclocks(xtal); | |
137 | s5p_register_clocks(xtal); | |
7d30e8b3 KK |
138 | exynos4_register_clocks(); |
139 | exynos4_setup_clocks(); | |
2b12b5c4 CY |
140 | } |
141 | ||
7d30e8b3 | 142 | void __init exynos4_init_irq(void) |
2b12b5c4 CY |
143 | { |
144 | int irq; | |
145 | ||
b580b899 | 146 | gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); |
2b12b5c4 CY |
147 | |
148 | for (irq = 0; irq < MAX_COMBINER_NR; irq++) { | |
1f2d6c49 CY |
149 | |
150 | /* | |
151 | * From SPI(0) to SPI(39) and SPI(51), SPI(53) are | |
152 | * connected to the interrupt combiner. These irqs | |
153 | * should be initialized to support cascade interrupt. | |
154 | */ | |
155 | if ((irq >= 40) && !(irq == 51) && !(irq == 53)) | |
156 | continue; | |
157 | ||
2b12b5c4 CY |
158 | combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), |
159 | COMBINER_IRQ(irq, 0)); | |
160 | combiner_cascade_irq(irq, IRQ_SPI(irq)); | |
161 | } | |
162 | ||
163 | /* The parameters of s5p_init_irq() are for VIC init. | |
7d30e8b3 | 164 | * Theses parameters should be NULL and 0 because EXYNOS4 |
2b12b5c4 CY |
165 | * uses GIC instead of VIC. |
166 | */ | |
167 | s5p_init_irq(NULL, 0); | |
168 | } | |
169 | ||
7d30e8b3 KK |
170 | struct sysdev_class exynos4_sysclass = { |
171 | .name = "exynos4-core", | |
2b12b5c4 CY |
172 | }; |
173 | ||
7d30e8b3 KK |
174 | static struct sys_device exynos4_sysdev = { |
175 | .cls = &exynos4_sysclass, | |
2b12b5c4 CY |
176 | }; |
177 | ||
7d30e8b3 | 178 | static int __init exynos4_core_init(void) |
2b12b5c4 | 179 | { |
7d30e8b3 | 180 | return sysdev_class_register(&exynos4_sysclass); |
2b12b5c4 CY |
181 | } |
182 | ||
7d30e8b3 | 183 | core_initcall(exynos4_core_init); |
2b12b5c4 | 184 | |
1cf0eb79 | 185 | #ifdef CONFIG_CACHE_L2X0 |
7d30e8b3 | 186 | static int __init exynos4_l2x0_cache_init(void) |
1cf0eb79 KP |
187 | { |
188 | /* TAG, Data Latency Control: 2cycle */ | |
189 | __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); | |
190 | __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); | |
191 | ||
192 | /* L2X0 Prefetch Control */ | |
193 | __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); | |
194 | ||
195 | /* L2X0 Power Control */ | |
196 | __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, | |
197 | S5P_VA_L2CC + L2X0_POWER_CTRL); | |
198 | ||
a50eb1c7 | 199 | l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); |
1cf0eb79 KP |
200 | |
201 | return 0; | |
202 | } | |
203 | ||
7d30e8b3 | 204 | early_initcall(exynos4_l2x0_cache_init); |
1cf0eb79 KP |
205 | #endif |
206 | ||
7d30e8b3 | 207 | int __init exynos4_init(void) |
2b12b5c4 | 208 | { |
7d30e8b3 | 209 | printk(KERN_INFO "EXYNOS4: Initializing architecture\n"); |
2b12b5c4 CY |
210 | |
211 | /* set idle function */ | |
7d30e8b3 | 212 | pm_idle = exynos4_idle; |
2b12b5c4 | 213 | |
7d30e8b3 | 214 | return sysdev_register(&exynos4_sysdev); |
2b12b5c4 | 215 | } |