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