Commit | Line | Data |
---|---|---|
c942fddf | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
e9e06f28 TZ |
2 | /* |
3 | * Low-level power-management support for Alpine platform. | |
4 | * | |
5 | * Copyright (C) 2015 Annapurna Labs Ltd. | |
e9e06f28 TZ |
6 | */ |
7 | ||
8 | #include <linux/io.h> | |
9 | #include <linux/of.h> | |
10 | #include <linux/of_address.h> | |
11 | #include <linux/regmap.h> | |
12 | #include <linux/mfd/syscon.h> | |
13 | ||
14 | #include "alpine_cpu_pm.h" | |
15 | #include "alpine_cpu_resume.h" | |
16 | ||
17 | /* NB registers */ | |
18 | #define AL_SYSFAB_POWER_CONTROL(cpu) (0x2000 + (cpu)*0x100 + 0x20) | |
19 | ||
20 | static struct regmap *al_sysfabric; | |
21 | static struct al_cpu_resume_regs __iomem *al_cpu_resume_regs; | |
22 | static int wakeup_supported; | |
23 | ||
24 | int alpine_cpu_wakeup(unsigned int phys_cpu, uint32_t phys_resume_addr) | |
25 | { | |
26 | if (!wakeup_supported) | |
27 | return -ENOSYS; | |
28 | ||
29 | /* | |
30 | * Set CPU resume address - | |
31 | * secure firmware running on boot will jump to this address | |
32 | * after setting proper CPU mode, and initialiing e.g. secure | |
33 | * regs (the same mode all CPUs are booted to - usually HYP) | |
34 | */ | |
35 | writel(phys_resume_addr, | |
36 | &al_cpu_resume_regs->per_cpu[phys_cpu].resume_addr); | |
37 | ||
38 | /* Power-up the CPU */ | |
39 | regmap_write(al_sysfabric, AL_SYSFAB_POWER_CONTROL(phys_cpu), 0); | |
40 | ||
41 | return 0; | |
42 | } | |
43 | ||
44 | void __init alpine_cpu_pm_init(void) | |
45 | { | |
46 | struct device_node *np; | |
47 | uint32_t watermark; | |
48 | ||
49 | al_sysfabric = syscon_regmap_lookup_by_compatible("al,alpine-sysfabric-service"); | |
50 | ||
51 | np = of_find_compatible_node(NULL, NULL, "al,alpine-cpu-resume"); | |
52 | al_cpu_resume_regs = of_iomap(np, 0); | |
53 | ||
54 | wakeup_supported = !IS_ERR(al_sysfabric) && al_cpu_resume_regs; | |
55 | ||
56 | if (wakeup_supported) { | |
57 | watermark = readl(&al_cpu_resume_regs->watermark); | |
58 | wakeup_supported = (watermark & AL_CPU_RESUME_MAGIC_NUM_MASK) | |
59 | == AL_CPU_RESUME_MAGIC_NUM; | |
60 | } | |
61 | } |