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