Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[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>
237c78be 14#include <linux/of.h>
e873a47c 15#include <linux/of_address.h>
cbf08b9e
SK
16#include <linux/of_fdt.h>
17#include <linux/of_platform.h>
35baa336 18#include <linux/platform_device.h>
fce9e5bb 19#include <linux/irqchip.h>
2262d6ef 20#include <linux/soc/samsung/exynos-regs-pmu.h>
cc511b8d 21
cbf08b9e 22#include <asm/cacheflush.h>
cc511b8d 23#include <asm/hardware/cache-l2x0.h>
cbf08b9e 24#include <asm/mach/arch.h>
cc511b8d 25#include <asm/mach/map.h>
cc511b8d 26
32b0aa9a
PD
27#include <mach/map.h>
28
cc511b8d 29#include "common.h"
cbf08b9e 30#include "mfc.h"
65c9a853 31
94c7ca71
KK
32static struct map_desc exynos4_iodesc[] __initdata = {
33 {
cc511b8d
KK
34 .virtual = (unsigned long)S5P_VA_CMU,
35 .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
36 .length = SZ_128K,
37 .type = MT_DEVICE,
38 }, {
39 .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
40 .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
41 .length = SZ_8K,
42 .type = MT_DEVICE,
cc511b8d
KK
43 }, {
44 .virtual = (unsigned long)S5P_VA_DMC0,
45 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
2bde0b08
MH
46 .length = SZ_64K,
47 .type = MT_DEVICE,
48 }, {
49 .virtual = (unsigned long)S5P_VA_DMC1,
50 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
51 .length = SZ_64K,
cc511b8d 52 .type = MT_DEVICE,
cc511b8d
KK
53 },
54};
55
35baa336 56static struct platform_device exynos_cpuidle = {
277f5046 57 .name = "exynos_cpuidle",
658cff0d 58#ifdef CONFIG_ARM_EXYNOS_CPUIDLE
277f5046 59 .dev.platform_data = exynos_enter_aftr,
658cff0d 60#endif
277f5046 61 .id = -1,
35baa336
BZ
62};
63
1754c42e
OJ
64void __iomem *sysram_base_addr;
65void __iomem *sysram_ns_base_addr;
66
67void __init exynos_sysram_init(void)
68{
69 struct device_node *node;
70
71 for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram") {
72 if (!of_device_is_available(node))
73 continue;
74 sysram_base_addr = of_iomap(node, 0);
75 break;
76 }
77
78 for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram-ns") {
79 if (!of_device_is_available(node))
80 continue;
81 sysram_ns_base_addr = of_iomap(node, 0);
82 break;
83 }
84}
85
5e299f65 86static void __init exynos_init_late(void)
bb13fabc 87{
2edb36c4
KK
88 if (of_machine_is_compatible("samsung,exynos5440"))
89 /* to be supported later */
90 return;
91
559ba237 92 exynos_pm_init();
bb13fabc
SG
93}
94
564d06b1 95static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
f5f83c71
TA
96 int depth, void *data)
97{
98 struct map_desc iodesc;
3eb93646 99 const __be32 *reg;
9d0c4dfe 100 int len;
f5f83c71
TA
101
102 if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
103 !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
104 return 0;
105
106 reg = of_get_flat_dt_prop(node, "reg", &len);
107 if (reg == NULL || len != (sizeof(unsigned long) * 2))
108 return 0;
109
110 iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
111 iodesc.length = be32_to_cpu(reg[1]) - 1;
112 iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
113 iodesc.type = MT_DEVICE;
114 iotable_init(&iodesc, 1);
115 return 1;
116}
f5f83c71 117
cc511b8d
KK
118/*
119 * exynos_map_io
120 *
121 * register the standard cpu IO areas
122 */
6eb84669
SK
123static void __init exynos_map_io(void)
124{
cbf08b9e 125 if (soc_is_exynos4())
6eb84669 126 iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
6eb84669 127}
cc511b8d 128
5e299f65 129static void __init exynos_init_io(void)
cc511b8d 130{
9c1fcdcc
DA
131 debug_ll_io_init();
132
04fae596 133 of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
2edb36c4 134
cc511b8d
KK
135 /* detect cpu id and rev. */
136 s5p_init_cpu(S5P_VA_CHIPID);
137
6eb84669 138 exynos_map_io();
94c7ca71
KK
139}
140
6f024978
KK
141/*
142 * Set or clear the USE_DELAYED_RESET_ASSERTION option. Used by smp code
143 * and suspend.
144 *
145 * This is necessary only on Exynos4 SoCs. When system is running
146 * USE_DELAYED_RESET_ASSERTION should be set so the ARM CLK clock down
147 * feature could properly detect global idle state when secondary CPU is
148 * powered down.
149 *
150 * However this should not be set when such system is going into suspend.
151 */
152void exynos_set_delayed_reset_assertion(bool enable)
153{
c1f0ecff 154 if (of_machine_is_compatible("samsung,exynos4")) {
6f024978
KK
155 unsigned int tmp, core_id;
156
157 for (core_id = 0; core_id < num_possible_cpus(); core_id++) {
158 tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id));
159 if (enable)
160 tmp |= S5P_USE_DELAYED_RESET_ASSERTION;
161 else
162 tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION);
163 pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id));
164 }
165 }
166}
167
8b283c02
MZ
168/*
169 * Apparently, these SoCs are not able to wake-up from suspend using
170 * the PMU. Too bad. Should they suddenly become capable of such a
171 * feat, the matches below should be moved to suspend.c.
172 */
fce9e5bb 173static const struct of_device_id exynos_dt_pmu_match[] = {
22ead0d7 174 { .compatible = "samsung,exynos5260-pmu" },
98504def 175 { .compatible = "samsung,exynos5410-pmu" },
fce9e5bb
PD
176 { /*sentinel*/ },
177};
178
179static void exynos_map_pmu(void)
180{
181 struct device_node *np;
182
183 np = of_find_matching_node(NULL, exynos_dt_pmu_match);
184 if (np)
185 pmu_base_addr = of_iomap(np, 0);
fce9e5bb
PD
186}
187
188static void __init exynos_init_irq(void)
189{
190 irqchip_init();
191 /*
192 * Since platsmp.c needs pmu base address by the time
193 * DT is not unflatten so we can't use DT APIs before
194 * init_irq
195 */
196 exynos_map_pmu();
197}
198
cbf08b9e 199static void __init exynos_dt_machine_init(void)
cc511b8d 200{
1754c42e
OJ
201 /*
202 * This is called from smp_prepare_cpus if we've built for SMP, but
203 * we still need to set it up for PM and firmware ops if not.
204 */
73ea6ec6 205 if (!IS_ENABLED(CONFIG_SMP))
1754c42e
OJ
206 exynos_sysram_init();
207
cfdda353 208#if defined(CONFIG_SMP) && defined(CONFIG_ARM_EXYNOS_CPUIDLE)
af997114
BZ
209 if (of_machine_is_compatible("samsung,exynos4210") ||
210 of_machine_is_compatible("samsung,exynos3250"))
712eddf7
BZ
211 exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data;
212#endif
6887d9e5 213 if (of_machine_is_compatible("samsung,exynos4210") ||
42d5dc37
BZ
214 of_machine_is_compatible("samsung,exynos4212") ||
215 (of_machine_is_compatible("samsung,exynos4412") &&
216 of_machine_is_compatible("samsung,trats2")) ||
bd0d888c 217 of_machine_is_compatible("samsung,exynos3250") ||
42d5dc37 218 of_machine_is_compatible("samsung,exynos5250"))
6887d9e5 219 platform_device_register(&exynos_cpuidle);
b5a296cd 220
cbf08b9e 221 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
cc511b8d 222}
cbf08b9e 223
543c5040 224static char const *const exynos_dt_compat[] __initconst = {
940bc58d
CC
225 "samsung,exynos3",
226 "samsung,exynos3250",
4868123c 227 "samsung,exynos4",
cbf08b9e
SK
228 "samsung,exynos4210",
229 "samsung,exynos4212",
230 "samsung,exynos4412",
c0adae9e 231 "samsung,exynos4415",
4868123c 232 "samsung,exynos5",
cbf08b9e 233 "samsung,exynos5250",
ed08f103 234 "samsung,exynos5260",
cbf08b9e
SK
235 "samsung,exynos5420",
236 "samsung,exynos5440",
237 NULL
238};
239
240static void __init exynos_reserve(void)
241{
242#ifdef CONFIG_S5P_DEV_MFC
243 int i;
244 char *mfc_mem[] = {
245 "samsung,mfc-v5",
246 "samsung,mfc-v6",
247 "samsung,mfc-v7",
adacba58 248 "samsung,mfc-v8",
cbf08b9e
SK
249 };
250
251 for (i = 0; i < ARRAY_SIZE(mfc_mem); i++)
252 if (of_scan_flat_dt(s5p_fdt_alloc_mfc_mem, mfc_mem[i]))
253 break;
254#endif
255}
256
5a12a597
LA
257static void __init exynos_dt_fixup(void)
258{
259 /*
260 * Some versions of uboot pass garbage entries in the memory node,
261 * use the old CONFIG_ARM_NR_BANKS
262 */
263 of_fdt_limit_memory(8);
264}
265
cbf08b9e
SK
266DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
267 /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
268 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
15b0bc40
RK
269 .l2c_aux_val = 0x3c400001,
270 .l2c_aux_mask = 0xc20fffff,
cbf08b9e
SK
271 .smp = smp_ops(exynos_smp_ops),
272 .map_io = exynos_init_io,
273 .init_early = exynos_firmware_init,
fce9e5bb 274 .init_irq = exynos_init_irq,
cbf08b9e
SK
275 .init_machine = exynos_dt_machine_init,
276 .init_late = exynos_init_late,
277 .dt_compat = exynos_dt_compat,
cbf08b9e 278 .reserve = exynos_reserve,
5a12a597 279 .dt_fixup = exynos_dt_fixup,
cbf08b9e 280MACHINE_END
This page took 0.375583 seconds and 5 git commands to generate.