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