]>
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> | |
7d30e8b3 | 23 | #include <plat/exynos4.h> |
1036c3ab | 24 | #include <plat/sdhci.h> |
604eefeb SN |
25 | #include <plat/devs.h> |
26 | #include <plat/fimc-core.h> | |
5f27275e | 27 | #include <plat/iic-core.h> |
2b12b5c4 CY |
28 | |
29 | #include <mach/regs-irq.h> | |
30 | ||
2b12b5c4 CY |
31 | extern int combiner_init(unsigned int combiner_nr, void __iomem *base, |
32 | unsigned int irq_start); | |
33 | extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); | |
34 | ||
35 | /* Initial IO mappings */ | |
7d30e8b3 | 36 | static struct map_desc exynos4_iodesc[] __initdata = { |
2b12b5c4 | 37 | { |
2b740159 CY |
38 | .virtual = (unsigned long)S5P_VA_SYSTIMER, |
39 | .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER), | |
40 | .length = SZ_4K, | |
41 | .type = MT_DEVICE, | |
42 | }, { | |
19a2c065 | 43 | .virtual = (unsigned long)S5P_VA_SYSRAM, |
7d30e8b3 | 44 | .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM), |
19a2c065 KK |
45 | .length = SZ_4K, |
46 | .type = MT_DEVICE, | |
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 | ||
7d30e8b3 | 120 | static void exynos4_idle(void) |
2b12b5c4 CY |
121 | { |
122 | if (!need_resched()) | |
123 | cpu_do_idle(); | |
124 | ||
125 | local_irq_enable(); | |
126 | } | |
127 | ||
7d30e8b3 KK |
128 | /* |
129 | * exynos4_map_io | |
2b12b5c4 CY |
130 | * |
131 | * register the standard cpu IO areas | |
7d30e8b3 KK |
132 | */ |
133 | void __init exynos4_map_io(void) | |
2b12b5c4 | 134 | { |
7d30e8b3 | 135 | iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc)); |
1036c3ab HL |
136 | |
137 | /* initialize device information early */ | |
7d30e8b3 KK |
138 | exynos4_default_sdhci0(); |
139 | exynos4_default_sdhci1(); | |
140 | exynos4_default_sdhci2(); | |
141 | exynos4_default_sdhci3(); | |
604eefeb SN |
142 | |
143 | s3c_fimc_setname(0, "exynos4-fimc"); | |
144 | s3c_fimc_setname(1, "exynos4-fimc"); | |
145 | s3c_fimc_setname(2, "exynos4-fimc"); | |
146 | s3c_fimc_setname(3, "exynos4-fimc"); | |
5f27275e SN |
147 | |
148 | /* The I2C bus controllers are directly compatible with s3c2440 */ | |
149 | s3c_i2c0_setname("s3c2440-i2c"); | |
150 | s3c_i2c1_setname("s3c2440-i2c"); | |
151 | s3c_i2c2_setname("s3c2440-i2c"); | |
2b12b5c4 CY |
152 | } |
153 | ||
7d30e8b3 | 154 | void __init exynos4_init_clocks(int xtal) |
2b12b5c4 CY |
155 | { |
156 | printk(KERN_DEBUG "%s: initializing clocks\n", __func__); | |
157 | ||
158 | s3c24xx_register_baseclocks(xtal); | |
159 | s5p_register_clocks(xtal); | |
7d30e8b3 KK |
160 | exynos4_register_clocks(); |
161 | exynos4_setup_clocks(); | |
2b12b5c4 CY |
162 | } |
163 | ||
aab74d3e CY |
164 | static void exynos4_gic_irq_eoi(struct irq_data *d) |
165 | { | |
166 | struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); | |
167 | ||
168 | gic_data->cpu_base = S5P_VA_GIC_CPU + | |
169 | (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); | |
170 | } | |
171 | ||
7d30e8b3 | 172 | void __init exynos4_init_irq(void) |
2b12b5c4 CY |
173 | { |
174 | int irq; | |
175 | ||
b580b899 | 176 | gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); |
aab74d3e | 177 | gic_arch_extn.irq_eoi = exynos4_gic_irq_eoi; |
2b12b5c4 CY |
178 | |
179 | for (irq = 0; irq < MAX_COMBINER_NR; irq++) { | |
1f2d6c49 | 180 | |
2b12b5c4 CY |
181 | combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), |
182 | COMBINER_IRQ(irq, 0)); | |
183 | combiner_cascade_irq(irq, IRQ_SPI(irq)); | |
184 | } | |
185 | ||
186 | /* The parameters of s5p_init_irq() are for VIC init. | |
7d30e8b3 | 187 | * Theses parameters should be NULL and 0 because EXYNOS4 |
2b12b5c4 CY |
188 | * uses GIC instead of VIC. |
189 | */ | |
190 | s5p_init_irq(NULL, 0); | |
191 | } | |
192 | ||
7d30e8b3 KK |
193 | struct sysdev_class exynos4_sysclass = { |
194 | .name = "exynos4-core", | |
2b12b5c4 CY |
195 | }; |
196 | ||
7d30e8b3 KK |
197 | static struct sys_device exynos4_sysdev = { |
198 | .cls = &exynos4_sysclass, | |
2b12b5c4 CY |
199 | }; |
200 | ||
7d30e8b3 | 201 | static int __init exynos4_core_init(void) |
2b12b5c4 | 202 | { |
7d30e8b3 | 203 | return sysdev_class_register(&exynos4_sysclass); |
2b12b5c4 CY |
204 | } |
205 | ||
7d30e8b3 | 206 | core_initcall(exynos4_core_init); |
2b12b5c4 | 207 | |
1cf0eb79 | 208 | #ifdef CONFIG_CACHE_L2X0 |
7d30e8b3 | 209 | static int __init exynos4_l2x0_cache_init(void) |
1cf0eb79 KP |
210 | { |
211 | /* TAG, Data Latency Control: 2cycle */ | |
212 | __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); | |
213 | __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); | |
214 | ||
215 | /* L2X0 Prefetch Control */ | |
216 | __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); | |
217 | ||
218 | /* L2X0 Power Control */ | |
219 | __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, | |
220 | S5P_VA_L2CC + L2X0_POWER_CTRL); | |
221 | ||
a50eb1c7 | 222 | l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); |
1cf0eb79 KP |
223 | |
224 | return 0; | |
225 | } | |
226 | ||
7d30e8b3 | 227 | early_initcall(exynos4_l2x0_cache_init); |
1cf0eb79 KP |
228 | #endif |
229 | ||
7d30e8b3 | 230 | int __init exynos4_init(void) |
2b12b5c4 | 231 | { |
7d30e8b3 | 232 | printk(KERN_INFO "EXYNOS4: Initializing architecture\n"); |
2b12b5c4 CY |
233 | |
234 | /* set idle function */ | |
7d30e8b3 | 235 | pm_idle = exynos4_idle; |
2b12b5c4 | 236 | |
7d30e8b3 | 237 | return sysdev_register(&exynos4_sysdev); |
2b12b5c4 | 238 | } |