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