ARM: dts: Specify the NAND ECC scheme explicitly on Armada 385 DB board
[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
cbf08b9e 146void 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{
70ecb842
DL
176 if (soc_is_exynos5440())
177 return;
178
35baa336
BZ
179 platform_device_register(&exynos_cpuidle);
180}
181
d568b6f7
LM
182void __init exynos_cpufreq_init(void)
183{
184 platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
185}
186
bb13fabc
SG
187void __init exynos_init_late(void)
188{
2edb36c4
KK
189 if (of_machine_is_compatible("samsung,exynos5440"))
190 /* to be supported later */
191 return;
192
1fd3cbcc 193 pm_genpd_poweroff_unused();
559ba237 194 exynos_pm_init();
bb13fabc
SG
195}
196
564d06b1 197static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
f5f83c71
TA
198 int depth, void *data)
199{
200 struct map_desc iodesc;
201 __be32 *reg;
9d0c4dfe 202 int len;
f5f83c71
TA
203
204 if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
205 !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
206 return 0;
207
208 reg = of_get_flat_dt_prop(node, "reg", &len);
209 if (reg == NULL || len != (sizeof(unsigned long) * 2))
210 return 0;
211
212 iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
213 iodesc.length = be32_to_cpu(reg[1]) - 1;
214 iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
215 iodesc.type = MT_DEVICE;
216 iotable_init(&iodesc, 1);
217 return 1;
218}
f5f83c71 219
cc511b8d
KK
220/*
221 * exynos_map_io
222 *
223 * register the standard cpu IO areas
224 */
6eb84669
SK
225static void __init exynos_map_io(void)
226{
cbf08b9e 227 if (soc_is_exynos4())
6eb84669
SK
228 iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
229
cbf08b9e 230 if (soc_is_exynos5())
6eb84669 231 iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
6eb84669 232}
cc511b8d 233
0e2238ec 234void __init exynos_init_io(void)
cc511b8d 235{
9c1fcdcc
DA
236 debug_ll_io_init();
237
04fae596 238 of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
2edb36c4 239
cc511b8d
KK
240 /* detect cpu id and rev. */
241 s5p_init_cpu(S5P_VA_CHIPID);
242
6eb84669 243 exynos_map_io();
94c7ca71
KK
244}
245
cbf08b9e 246static void __init exynos_dt_machine_init(void)
cc511b8d 247{
cbf08b9e
SK
248 struct device_node *i2c_np;
249 const char *i2c_compat = "samsung,s3c2440-i2c";
250 unsigned int tmp;
251 int id;
252
253 /*
254 * Exynos5's legacy i2c controller and new high speed i2c
255 * controller have muxed interrupt sources. By default the
256 * interrupts for 4-channel HS-I2C controller are enabled.
257 * If node for first four channels of legacy i2c controller
258 * are available then re-configure the interrupts via the
259 * system register.
260 */
261 if (soc_is_exynos5()) {
262 for_each_compatible_node(i2c_np, NULL, i2c_compat) {
263 if (of_device_is_available(i2c_np)) {
264 id = of_alias_get_id(i2c_np, "i2c");
265 if (id < 4) {
266 tmp = readl(EXYNOS5_SYS_I2C_CFG);
267 writel(tmp & ~(0x1 << id),
268 EXYNOS5_SYS_I2C_CFG);
269 }
270 }
271 }
272 }
94c7ca71 273
cbf08b9e
SK
274 exynos_cpuidle_init();
275 exynos_cpufreq_init();
276
277 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
cc511b8d 278}
cbf08b9e
SK
279
280static char const *exynos_dt_compat[] __initconst = {
940bc58d
CC
281 "samsung,exynos3",
282 "samsung,exynos3250",
4868123c 283 "samsung,exynos4",
cbf08b9e
SK
284 "samsung,exynos4210",
285 "samsung,exynos4212",
286 "samsung,exynos4412",
4868123c 287 "samsung,exynos5",
cbf08b9e 288 "samsung,exynos5250",
ed08f103 289 "samsung,exynos5260",
cbf08b9e
SK
290 "samsung,exynos5420",
291 "samsung,exynos5440",
292 NULL
293};
294
295static void __init exynos_reserve(void)
296{
297#ifdef CONFIG_S5P_DEV_MFC
298 int i;
299 char *mfc_mem[] = {
300 "samsung,mfc-v5",
301 "samsung,mfc-v6",
302 "samsung,mfc-v7",
303 };
304
305 for (i = 0; i < ARRAY_SIZE(mfc_mem); i++)
306 if (of_scan_flat_dt(s5p_fdt_alloc_mfc_mem, mfc_mem[i]))
307 break;
308#endif
309}
310
311DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
312 /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
313 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
15b0bc40
RK
314 .l2c_aux_val = 0x3c400001,
315 .l2c_aux_mask = 0xc20fffff,
cbf08b9e
SK
316 .smp = smp_ops(exynos_smp_ops),
317 .map_io = exynos_init_io,
318 .init_early = exynos_firmware_init,
319 .init_machine = exynos_dt_machine_init,
320 .init_late = exynos_init_late,
321 .dt_compat = exynos_dt_compat,
322 .restart = exynos_restart,
323 .reserve = exynos_reserve,
324MACHINE_END
This page took 0.170882 seconds and 5 git commands to generate.