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> |
aab74d3e | 19 | #include <asm/hardware/gic.h> |
2b12b5c4 CY |
20 | |
21 | #include <plat/cpu.h> | |
22 | #include <plat/clock.h> | |
0e9e5265 | 23 | #include <plat/devs.h> |
7d30e8b3 | 24 | #include <plat/exynos4.h> |
0e9e5265 | 25 | #include <plat/adc-core.h> |
1036c3ab | 26 | #include <plat/sdhci.h> |
e61b1701 | 27 | #include <plat/fb-core.h> |
604eefeb | 28 | #include <plat/fimc-core.h> |
5f27275e | 29 | #include <plat/iic-core.h> |
d2edddf2 | 30 | #include <plat/reset.h> |
fbf05563 | 31 | #include <plat/tv-core.h> |
2b12b5c4 CY |
32 | |
33 | #include <mach/regs-irq.h> | |
d2edddf2 | 34 | #include <mach/regs-pmu.h> |
2b12b5c4 | 35 | |
2b12b5c4 CY |
36 | extern int combiner_init(unsigned int combiner_nr, void __iomem *base, |
37 | unsigned int irq_start); | |
38 | extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); | |
39 | ||
40 | /* Initial IO mappings */ | |
7d30e8b3 | 41 | static struct map_desc exynos4_iodesc[] __initdata = { |
2b12b5c4 | 42 | { |
2b740159 CY |
43 | .virtual = (unsigned long)S5P_VA_SYSTIMER, |
44 | .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER), | |
45 | .length = SZ_4K, | |
46 | .type = MT_DEVICE, | |
19a2c065 KK |
47 | }, { |
48 | .virtual = (unsigned long)S5P_VA_CMU, | |
7d30e8b3 | 49 | .pfn = __phys_to_pfn(EXYNOS4_PA_CMU), |
19a2c065 | 50 | .length = SZ_128K, |
2b12b5c4 | 51 | .type = MT_DEVICE, |
d6d8b481 CY |
52 | }, { |
53 | .virtual = (unsigned long)S5P_VA_PMU, | |
7d30e8b3 | 54 | .pfn = __phys_to_pfn(EXYNOS4_PA_PMU), |
d6d8b481 CY |
55 | .length = SZ_64K, |
56 | .type = MT_DEVICE, | |
2b12b5c4 CY |
57 | }, { |
58 | .virtual = (unsigned long)S5P_VA_COMBINER_BASE, | |
7d30e8b3 | 59 | .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER), |
2b12b5c4 CY |
60 | .length = SZ_4K, |
61 | .type = MT_DEVICE, | |
19a2c065 KK |
62 | }, { |
63 | .virtual = (unsigned long)S5P_VA_COREPERI_BASE, | |
7d30e8b3 | 64 | .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI), |
19a2c065 KK |
65 | .length = SZ_8K, |
66 | .type = MT_DEVICE, | |
2b12b5c4 CY |
67 | }, { |
68 | .virtual = (unsigned long)S5P_VA_L2CC, | |
7d30e8b3 | 69 | .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC), |
2b12b5c4 CY |
70 | .length = SZ_4K, |
71 | .type = MT_DEVICE, | |
766211e7 | 72 | }, { |
37ea63b1 | 73 | .virtual = (unsigned long)S5P_VA_GPIO1, |
7d30e8b3 | 74 | .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1), |
766211e7 CY |
75 | .length = SZ_4K, |
76 | .type = MT_DEVICE, | |
37ea63b1 JL |
77 | }, { |
78 | .virtual = (unsigned long)S5P_VA_GPIO2, | |
7d30e8b3 | 79 | .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2), |
37ea63b1 JL |
80 | .length = SZ_4K, |
81 | .type = MT_DEVICE, | |
82 | }, { | |
83 | .virtual = (unsigned long)S5P_VA_GPIO3, | |
7d30e8b3 | 84 | .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3), |
37ea63b1 JL |
85 | .length = SZ_256, |
86 | .type = MT_DEVICE, | |
dd0b7e20 SK |
87 | }, { |
88 | .virtual = (unsigned long)S5P_VA_DMC0, | |
7d30e8b3 | 89 | .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), |
dd0b7e20 SK |
90 | .length = SZ_4K, |
91 | .type = MT_DEVICE, | |
c598c47d | 92 | }, { |
19a2c065 KK |
93 | .virtual = (unsigned long)S3C_VA_UART, |
94 | .pfn = __phys_to_pfn(S3C_PA_UART), | |
95 | .length = SZ_512K, | |
c598c47d | 96 | .type = MT_DEVICE, |
09596ba0 DM |
97 | }, { |
98 | .virtual = (unsigned long)S5P_VA_SROMC, | |
7d30e8b3 | 99 | .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC), |
09596ba0 DM |
100 | .length = SZ_4K, |
101 | .type = MT_DEVICE, | |
8f1d169f | 102 | }, { |
08115a13 | 103 | .virtual = (unsigned long)S3C_VA_USB_HSPHY, |
8f1d169f JS |
104 | .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY), |
105 | .length = SZ_4K, | |
106 | .type = MT_DEVICE, | |
eb13f2bf CY |
107 | }, { |
108 | .virtual = (unsigned long)S5P_VA_GIC_CPU, | |
109 | .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_CPU), | |
110 | .length = SZ_64K, | |
111 | .type = MT_DEVICE, | |
112 | }, { | |
113 | .virtual = (unsigned long)S5P_VA_GIC_DIST, | |
114 | .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_DIST), | |
115 | .length = SZ_64K, | |
116 | .type = MT_DEVICE, | |
117 | }, | |
2b12b5c4 CY |
118 | }; |
119 | ||
56b20922 KK |
120 | static struct map_desc exynos4_iodesc0[] __initdata = { |
121 | { | |
122 | .virtual = (unsigned long)S5P_VA_SYSRAM, | |
123 | .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM0), | |
124 | .length = SZ_4K, | |
125 | .type = MT_DEVICE, | |
126 | }, | |
127 | }; | |
128 | ||
129 | static struct map_desc exynos4_iodesc1[] __initdata = { | |
130 | { | |
131 | .virtual = (unsigned long)S5P_VA_SYSRAM, | |
132 | .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM1), | |
133 | .length = SZ_4K, | |
134 | .type = MT_DEVICE, | |
135 | }, | |
136 | }; | |
137 | ||
7d30e8b3 | 138 | static void exynos4_idle(void) |
2b12b5c4 CY |
139 | { |
140 | if (!need_resched()) | |
141 | cpu_do_idle(); | |
142 | ||
143 | local_irq_enable(); | |
144 | } | |
145 | ||
d2edddf2 KP |
146 | static void exynos4_sw_reset(void) |
147 | { | |
148 | __raw_writel(0x1, S5P_SWRESET); | |
149 | } | |
150 | ||
7d30e8b3 KK |
151 | /* |
152 | * exynos4_map_io | |
2b12b5c4 CY |
153 | * |
154 | * register the standard cpu IO areas | |
7d30e8b3 KK |
155 | */ |
156 | void __init exynos4_map_io(void) | |
2b12b5c4 | 157 | { |
7d30e8b3 | 158 | iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc)); |
1036c3ab | 159 | |
56b20922 KK |
160 | if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0) |
161 | iotable_init(exynos4_iodesc0, ARRAY_SIZE(exynos4_iodesc0)); | |
162 | else | |
163 | iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1)); | |
164 | ||
1036c3ab | 165 | /* initialize device information early */ |
7d30e8b3 KK |
166 | exynos4_default_sdhci0(); |
167 | exynos4_default_sdhci1(); | |
168 | exynos4_default_sdhci2(); | |
169 | exynos4_default_sdhci3(); | |
604eefeb | 170 | |
0e9e5265 MH |
171 | s3c_adc_setname("samsung-adc-v3"); |
172 | ||
604eefeb SN |
173 | s3c_fimc_setname(0, "exynos4-fimc"); |
174 | s3c_fimc_setname(1, "exynos4-fimc"); | |
175 | s3c_fimc_setname(2, "exynos4-fimc"); | |
176 | s3c_fimc_setname(3, "exynos4-fimc"); | |
5f27275e SN |
177 | |
178 | /* The I2C bus controllers are directly compatible with s3c2440 */ | |
179 | s3c_i2c0_setname("s3c2440-i2c"); | |
180 | s3c_i2c1_setname("s3c2440-i2c"); | |
181 | s3c_i2c2_setname("s3c2440-i2c"); | |
e61b1701 JH |
182 | |
183 | s5p_fb_setname(0, "exynos4-fb"); | |
fbf05563 | 184 | s5p_hdmi_setname("exynos4-hdmi"); |
2b12b5c4 CY |
185 | } |
186 | ||
7d30e8b3 | 187 | void __init exynos4_init_clocks(int xtal) |
2b12b5c4 CY |
188 | { |
189 | printk(KERN_DEBUG "%s: initializing clocks\n", __func__); | |
190 | ||
191 | s3c24xx_register_baseclocks(xtal); | |
192 | s5p_register_clocks(xtal); | |
2bc02c0d KK |
193 | |
194 | if (soc_is_exynos4210()) | |
195 | exynos4210_register_clocks(); | |
196 | else if (soc_is_exynos4212()) | |
197 | exynos4212_register_clocks(); | |
198 | ||
7d30e8b3 KK |
199 | exynos4_register_clocks(); |
200 | exynos4_setup_clocks(); | |
2b12b5c4 CY |
201 | } |
202 | ||
aab74d3e CY |
203 | static void exynos4_gic_irq_eoi(struct irq_data *d) |
204 | { | |
205 | struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); | |
206 | ||
207 | gic_data->cpu_base = S5P_VA_GIC_CPU + | |
208 | (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); | |
209 | } | |
210 | ||
7d30e8b3 | 211 | void __init exynos4_init_irq(void) |
2b12b5c4 CY |
212 | { |
213 | int irq; | |
214 | ||
069d4e74 | 215 | gic_init(0, IRQ_SPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); |
aab74d3e | 216 | gic_arch_extn.irq_eoi = exynos4_gic_irq_eoi; |
2b12b5c4 CY |
217 | |
218 | for (irq = 0; irq < MAX_COMBINER_NR; irq++) { | |
1f2d6c49 | 219 | |
2b12b5c4 CY |
220 | combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), |
221 | COMBINER_IRQ(irq, 0)); | |
222 | combiner_cascade_irq(irq, IRQ_SPI(irq)); | |
223 | } | |
224 | ||
225 | /* The parameters of s5p_init_irq() are for VIC init. | |
7d30e8b3 | 226 | * Theses parameters should be NULL and 0 because EXYNOS4 |
2b12b5c4 CY |
227 | * uses GIC instead of VIC. |
228 | */ | |
229 | s5p_init_irq(NULL, 0); | |
230 | } | |
231 | ||
7d30e8b3 KK |
232 | struct sysdev_class exynos4_sysclass = { |
233 | .name = "exynos4-core", | |
2b12b5c4 CY |
234 | }; |
235 | ||
7d30e8b3 KK |
236 | static struct sys_device exynos4_sysdev = { |
237 | .cls = &exynos4_sysclass, | |
2b12b5c4 CY |
238 | }; |
239 | ||
7d30e8b3 | 240 | static int __init exynos4_core_init(void) |
2b12b5c4 | 241 | { |
7d30e8b3 | 242 | return sysdev_class_register(&exynos4_sysclass); |
2b12b5c4 CY |
243 | } |
244 | ||
7d30e8b3 | 245 | core_initcall(exynos4_core_init); |
2b12b5c4 | 246 | |
1cf0eb79 | 247 | #ifdef CONFIG_CACHE_L2X0 |
7d30e8b3 | 248 | static int __init exynos4_l2x0_cache_init(void) |
1cf0eb79 KP |
249 | { |
250 | /* TAG, Data Latency Control: 2cycle */ | |
251 | __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); | |
68465384 KK |
252 | |
253 | if (soc_is_exynos4210()) | |
254 | __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); | |
255 | else if (soc_is_exynos4212()) | |
256 | __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); | |
1cf0eb79 KP |
257 | |
258 | /* L2X0 Prefetch Control */ | |
259 | __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); | |
260 | ||
261 | /* L2X0 Power Control */ | |
262 | __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, | |
263 | S5P_VA_L2CC + L2X0_POWER_CTRL); | |
264 | ||
a50eb1c7 | 265 | l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); |
1cf0eb79 KP |
266 | |
267 | return 0; | |
268 | } | |
269 | ||
7d30e8b3 | 270 | early_initcall(exynos4_l2x0_cache_init); |
1cf0eb79 KP |
271 | #endif |
272 | ||
7d30e8b3 | 273 | int __init exynos4_init(void) |
2b12b5c4 | 274 | { |
7d30e8b3 | 275 | printk(KERN_INFO "EXYNOS4: Initializing architecture\n"); |
2b12b5c4 CY |
276 | |
277 | /* set idle function */ | |
7d30e8b3 | 278 | pm_idle = exynos4_idle; |
2b12b5c4 | 279 | |
d2edddf2 KP |
280 | /* set sw_reset function */ |
281 | s5p_reset_hook = exynos4_sw_reset; | |
282 | ||
7d30e8b3 | 283 | return sysdev_register(&exynos4_sysdev); |
2b12b5c4 | 284 | } |