ARM: EXYNOS: Make exynos machine_ops as static
[deliverable/linux.git] / arch / arm / mach-exynos / exynos.c
CommitLineData
cc511b8d 1/*
cbf08b9e 2 * SAMSUNG EXYNOS Flattened Device Tree enabled machine
cc511b8d 3 *
cbf08b9e
SK
4 * Copyright (c) 2010-2014 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
cc511b8d
KK
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
cbf08b9e 12#include <linux/init.h>
cc511b8d 13#include <linux/io.h>
cbf08b9e 14#include <linux/kernel.h>
334a1c70 15#include <linux/serial_s3c.h>
237c78be 16#include <linux/of.h>
e873a47c 17#include <linux/of_address.h>
cbf08b9e
SK
18#include <linux/of_fdt.h>
19#include <linux/of_platform.h>
35baa336 20#include <linux/platform_device.h>
cbf08b9e 21#include <linux/pm_domain.h>
cc511b8d 22
cbf08b9e 23#include <asm/cacheflush.h>
cc511b8d 24#include <asm/hardware/cache-l2x0.h>
cbf08b9e 25#include <asm/mach/arch.h>
cc511b8d 26#include <asm/mach/map.h>
cbf08b9e 27#include <asm/memory.h>
cc511b8d 28
cc511b8d 29#include "common.h"
cbf08b9e 30#include "mfc.h"
65c9a853
KK
31#include "regs-pmu.h"
32
94c7ca71
KK
33static struct map_desc exynos4_iodesc[] __initdata = {
34 {
cc511b8d
KK
35 .virtual = (unsigned long)S3C_VA_SYS,
36 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSCON),
37 .length = SZ_64K,
38 .type = MT_DEVICE,
39 }, {
40 .virtual = (unsigned long)S3C_VA_TIMER,
41 .pfn = __phys_to_pfn(EXYNOS4_PA_TIMER),
42 .length = SZ_16K,
43 .type = MT_DEVICE,
44 }, {
45 .virtual = (unsigned long)S3C_VA_WATCHDOG,
46 .pfn = __phys_to_pfn(EXYNOS4_PA_WATCHDOG),
47 .length = SZ_4K,
48 .type = MT_DEVICE,
49 }, {
50 .virtual = (unsigned long)S5P_VA_SROMC,
51 .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
52 .length = SZ_4K,
53 .type = MT_DEVICE,
54 }, {
55 .virtual = (unsigned long)S5P_VA_SYSTIMER,
56 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
57 .length = SZ_4K,
58 .type = MT_DEVICE,
59 }, {
60 .virtual = (unsigned long)S5P_VA_PMU,
61 .pfn = __phys_to_pfn(EXYNOS4_PA_PMU),
62 .length = SZ_64K,
63 .type = MT_DEVICE,
64 }, {
65 .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
66 .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER),
67 .length = SZ_4K,
68 .type = MT_DEVICE,
69 }, {
70 .virtual = (unsigned long)S5P_VA_GIC_CPU,
71 .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_CPU),
72 .length = SZ_64K,
73 .type = MT_DEVICE,
74 }, {
75 .virtual = (unsigned long)S5P_VA_GIC_DIST,
76 .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_DIST),
77 .length = SZ_64K,
78 .type = MT_DEVICE,
94c7ca71 79 }, {
cc511b8d
KK
80 .virtual = (unsigned long)S5P_VA_CMU,
81 .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
82 .length = SZ_128K,
83 .type = MT_DEVICE,
84 }, {
85 .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
86 .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
87 .length = SZ_8K,
88 .type = MT_DEVICE,
89 }, {
90 .virtual = (unsigned long)S5P_VA_L2CC,
91 .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC),
92 .length = SZ_4K,
93 .type = MT_DEVICE,
cc511b8d
KK
94 }, {
95 .virtual = (unsigned long)S5P_VA_DMC0,
96 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
2bde0b08
MH
97 .length = SZ_64K,
98 .type = MT_DEVICE,
99 }, {
100 .virtual = (unsigned long)S5P_VA_DMC1,
101 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
102 .length = SZ_64K,
cc511b8d 103 .type = MT_DEVICE,
cc511b8d
KK
104 }, {
105 .virtual = (unsigned long)S3C_VA_USB_HSPHY,
106 .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY),
107 .length = SZ_4K,
108 .type = MT_DEVICE,
109 },
110};
111
94c7ca71
KK
112static struct map_desc exynos5_iodesc[] __initdata = {
113 {
114 .virtual = (unsigned long)S3C_VA_SYS,
115 .pfn = __phys_to_pfn(EXYNOS5_PA_SYSCON),
116 .length = SZ_64K,
117 .type = MT_DEVICE,
118 }, {
119 .virtual = (unsigned long)S3C_VA_TIMER,
120 .pfn = __phys_to_pfn(EXYNOS5_PA_TIMER),
121 .length = SZ_16K,
122 .type = MT_DEVICE,
123 }, {
124 .virtual = (unsigned long)S3C_VA_WATCHDOG,
125 .pfn = __phys_to_pfn(EXYNOS5_PA_WATCHDOG),
126 .length = SZ_4K,
127 .type = MT_DEVICE,
128 }, {
129 .virtual = (unsigned long)S5P_VA_SROMC,
130 .pfn = __phys_to_pfn(EXYNOS5_PA_SROMC),
131 .length = SZ_4K,
132 .type = MT_DEVICE,
94c7ca71
KK
133 }, {
134 .virtual = (unsigned long)S5P_VA_CMU,
135 .pfn = __phys_to_pfn(EXYNOS5_PA_CMU),
136 .length = 144 * SZ_1K,
137 .type = MT_DEVICE,
138 }, {
139 .virtual = (unsigned long)S5P_VA_PMU,
140 .pfn = __phys_to_pfn(EXYNOS5_PA_PMU),
141 .length = SZ_64K,
142 .type = MT_DEVICE,
2edb36c4
KK
143 },
144};
145
5e299f65 146static void exynos_restart(enum reboot_mode mode, const char *cmd)
94c7ca71 147{
60db7e5f 148 struct device_node *np;
cbf08b9e
SK
149 u32 val = 0x1;
150 void __iomem *addr = EXYNOS_SWRESET;
eff4e7c7
CK
151
152 if (of_machine_is_compatible("samsung,exynos5440")) {
1ba830c9 153 u32 status;
60db7e5f 154 np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
1ba830c9
JL
155
156 addr = of_iomap(np, 0) + 0xbc;
157 status = __raw_readl(addr);
158
60db7e5f 159 addr = of_iomap(np, 0) + 0xcc;
1ba830c9
JL
160 val = __raw_readl(addr);
161
162 val = (val & 0xffff0000) | (status & 0xffff);
2edb36c4
KK
163 }
164
165 __raw_writel(val, addr);
94c7ca71
KK
166}
167
35baa336 168static struct platform_device exynos_cpuidle = {
277f5046
DL
169 .name = "exynos_cpuidle",
170 .dev.platform_data = exynos_enter_aftr,
171 .id = -1,
35baa336
BZ
172};
173
174void __init exynos_cpuidle_init(void)
175{
bed71189
TF
176 if (soc_is_exynos4210() || soc_is_exynos5250())
177 platform_device_register(&exynos_cpuidle);
35baa336
BZ
178}
179
d568b6f7
LM
180void __init exynos_cpufreq_init(void)
181{
182 platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
183}
184
1754c42e
OJ
185void __iomem *sysram_base_addr;
186void __iomem *sysram_ns_base_addr;
187
188void __init exynos_sysram_init(void)
189{
190 struct device_node *node;
191
192 for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram") {
193 if (!of_device_is_available(node))
194 continue;
195 sysram_base_addr = of_iomap(node, 0);
196 break;
197 }
198
199 for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram-ns") {
200 if (!of_device_is_available(node))
201 continue;
202 sysram_ns_base_addr = of_iomap(node, 0);
203 break;
204 }
205}
206
5e299f65 207static void __init exynos_init_late(void)
bb13fabc 208{
2edb36c4
KK
209 if (of_machine_is_compatible("samsung,exynos5440"))
210 /* to be supported later */
211 return;
212
1fd3cbcc 213 pm_genpd_poweroff_unused();
559ba237 214 exynos_pm_init();
bb13fabc
SG
215}
216
564d06b1 217static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
f5f83c71
TA
218 int depth, void *data)
219{
220 struct map_desc iodesc;
3eb93646 221 const __be32 *reg;
9d0c4dfe 222 int len;
f5f83c71
TA
223
224 if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
225 !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
226 return 0;
227
228 reg = of_get_flat_dt_prop(node, "reg", &len);
229 if (reg == NULL || len != (sizeof(unsigned long) * 2))
230 return 0;
231
232 iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
233 iodesc.length = be32_to_cpu(reg[1]) - 1;
234 iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
235 iodesc.type = MT_DEVICE;
236 iotable_init(&iodesc, 1);
237 return 1;
238}
f5f83c71 239
cc511b8d
KK
240/*
241 * exynos_map_io
242 *
243 * register the standard cpu IO areas
244 */
6eb84669
SK
245static void __init exynos_map_io(void)
246{
cbf08b9e 247 if (soc_is_exynos4())
6eb84669
SK
248 iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
249
cbf08b9e 250 if (soc_is_exynos5())
6eb84669 251 iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
6eb84669 252}
cc511b8d 253
5e299f65 254static void __init exynos_init_io(void)
cc511b8d 255{
9c1fcdcc
DA
256 debug_ll_io_init();
257
04fae596 258 of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
2edb36c4 259
cc511b8d
KK
260 /* detect cpu id and rev. */
261 s5p_init_cpu(S5P_VA_CHIPID);
262
6eb84669 263 exynos_map_io();
94c7ca71
KK
264}
265
cbf08b9e 266static void __init exynos_dt_machine_init(void)
cc511b8d 267{
cbf08b9e
SK
268 struct device_node *i2c_np;
269 const char *i2c_compat = "samsung,s3c2440-i2c";
270 unsigned int tmp;
271 int id;
272
273 /*
274 * Exynos5's legacy i2c controller and new high speed i2c
275 * controller have muxed interrupt sources. By default the
276 * interrupts for 4-channel HS-I2C controller are enabled.
277 * If node for first four channels of legacy i2c controller
278 * are available then re-configure the interrupts via the
279 * system register.
280 */
281 if (soc_is_exynos5()) {
282 for_each_compatible_node(i2c_np, NULL, i2c_compat) {
283 if (of_device_is_available(i2c_np)) {
284 id = of_alias_get_id(i2c_np, "i2c");
285 if (id < 4) {
286 tmp = readl(EXYNOS5_SYS_I2C_CFG);
287 writel(tmp & ~(0x1 << id),
288 EXYNOS5_SYS_I2C_CFG);
289 }
290 }
291 }
292 }
94c7ca71 293
1754c42e
OJ
294 /*
295 * This is called from smp_prepare_cpus if we've built for SMP, but
296 * we still need to set it up for PM and firmware ops if not.
297 */
73ea6ec6 298 if (!IS_ENABLED(CONFIG_SMP))
1754c42e
OJ
299 exynos_sysram_init();
300
cbf08b9e
SK
301 exynos_cpuidle_init();
302 exynos_cpufreq_init();
303
304 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
cc511b8d 305}
cbf08b9e
SK
306
307static char const *exynos_dt_compat[] __initconst = {
940bc58d
CC
308 "samsung,exynos3",
309 "samsung,exynos3250",
4868123c 310 "samsung,exynos4",
cbf08b9e
SK
311 "samsung,exynos4210",
312 "samsung,exynos4212",
313 "samsung,exynos4412",
4868123c 314 "samsung,exynos5",
cbf08b9e 315 "samsung,exynos5250",
ed08f103 316 "samsung,exynos5260",
cbf08b9e
SK
317 "samsung,exynos5420",
318 "samsung,exynos5440",
319 NULL
320};
321
322static void __init exynos_reserve(void)
323{
324#ifdef CONFIG_S5P_DEV_MFC
325 int i;
326 char *mfc_mem[] = {
327 "samsung,mfc-v5",
328 "samsung,mfc-v6",
329 "samsung,mfc-v7",
330 };
331
332 for (i = 0; i < ARRAY_SIZE(mfc_mem); i++)
333 if (of_scan_flat_dt(s5p_fdt_alloc_mfc_mem, mfc_mem[i]))
334 break;
335#endif
336}
337
338DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
339 /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
340 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
15b0bc40
RK
341 .l2c_aux_val = 0x3c400001,
342 .l2c_aux_mask = 0xc20fffff,
cbf08b9e
SK
343 .smp = smp_ops(exynos_smp_ops),
344 .map_io = exynos_init_io,
345 .init_early = exynos_firmware_init,
346 .init_machine = exynos_dt_machine_init,
347 .init_late = exynos_init_late,
348 .dt_compat = exynos_dt_compat,
349 .restart = exynos_restart,
350 .reserve = exynos_reserve,
351MACHINE_END
This page took 0.171672 seconds and 5 git commands to generate.