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