diff options
author | Olof Johansson <olof@lixom.net> | 2018-05-25 16:59:28 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2018-05-25 16:59:28 -0400 |
commit | 977d29f89c743c187b8c2cba58f60e798a3e2164 (patch) | |
tree | c9d435eef4b0a1dcd45b789a944d819b29dff96a | |
parent | 68fc6c839af7da9009bf3fa9da4468c67f3ee5de (diff) | |
parent | 6961275e72a8c15cc4ebf108a81eee758480a6a2 (diff) |
Merge tag 'sunxi-core-for-4.18' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into next/soc
Allwinner core changes for 4.18
The A83t, unlike the other Allwinner SoCs, cannot use PSCI because of a
silicon bug. As such, we needed to have some smp_ops in order to bringup
the various cores (and clusters) found on this SoC.
* tag 'sunxi-core-for-4.18' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux:
ARM: sun8i: smp: Add support for A83T
ARM: sun9i: smp: Add is_a83t field
ARM: sun9i: smp: Rename clusters's power-off
ARM: shmobile: Convert file to use cntvoff
ARM: sunxi: Add initialization of CNTVOFF
ARM: smp: Add initialization of CNTVOFF
ARM: sunxi: smp: Move assembly code into a file
ARM: Allow this header to be included by assembly files
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | arch/arm/common/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/common/secure_cntvoff.S | 32 | ||||
-rw-r--r-- | arch/arm/include/asm/secure_cntvoff.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/common.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/headsmp-apmu.S | 22 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-rcar-gen2.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-sunxi/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-sunxi/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-sunxi/headsmp.S | 81 | ||||
-rw-r--r-- | arch/arm/mach-sunxi/mc_smp.c | 239 | ||||
-rw-r--r-- | arch/arm/mach-sunxi/sunxi.c | 20 |
11 files changed, 291 insertions, 120 deletions
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 70b4a14ed993..1e9f7af8f70f 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_DMABOUNCE) += dmabounce.o | |||
10 | obj-$(CONFIG_SHARP_LOCOMO) += locomo.o | 10 | obj-$(CONFIG_SHARP_LOCOMO) += locomo.o |
11 | obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o | 11 | obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o |
12 | obj-$(CONFIG_SHARP_SCOOP) += scoop.o | 12 | obj-$(CONFIG_SHARP_SCOOP) += scoop.o |
13 | obj-$(CONFIG_SMP) += secure_cntvoff.o | ||
13 | obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o | 14 | obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o |
14 | obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o | 15 | obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o |
15 | CFLAGS_REMOVE_mcpm_entry.o = -pg | 16 | CFLAGS_REMOVE_mcpm_entry.o = -pg |
diff --git a/arch/arm/common/secure_cntvoff.S b/arch/arm/common/secure_cntvoff.S new file mode 100644 index 000000000000..53fc7bdb6c2e --- /dev/null +++ b/arch/arm/common/secure_cntvoff.S | |||
@@ -0,0 +1,32 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (C) 2014 Renesas Electronics Corporation | ||
4 | * | ||
5 | * Initialization of CNTVOFF register from secure mode | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #include <linux/linkage.h> | ||
10 | #include <asm/assembler.h> | ||
11 | |||
12 | ENTRY(secure_cntvoff_init) | ||
13 | .arch armv7-a | ||
14 | /* | ||
15 | * CNTVOFF has to be initialized either from non-secure Hypervisor | ||
16 | * mode or secure Monitor mode with SCR.NS==1. If TrustZone is enabled | ||
17 | * then it should be handled by the secure code. The CPU must implement | ||
18 | * the virtualization extensions. | ||
19 | */ | ||
20 | cps #MON_MODE | ||
21 | mrc p15, 0, r1, c1, c1, 0 /* Get Secure Config */ | ||
22 | orr r0, r1, #1 | ||
23 | mcr p15, 0, r0, c1, c1, 0 /* Set Non Secure bit */ | ||
24 | isb | ||
25 | mov r0, #0 | ||
26 | mcrr p15, 4, r0, r0, c14 /* CNTVOFF = 0 */ | ||
27 | isb | ||
28 | mcr p15, 0, r1, c1, c1, 0 /* Set Secure bit */ | ||
29 | isb | ||
30 | cps #SVC_MODE | ||
31 | ret lr | ||
32 | ENDPROC(secure_cntvoff_init) | ||
diff --git a/arch/arm/include/asm/secure_cntvoff.h b/arch/arm/include/asm/secure_cntvoff.h new file mode 100644 index 000000000000..1f93aee1f630 --- /dev/null +++ b/arch/arm/include/asm/secure_cntvoff.h | |||
@@ -0,0 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | |||
3 | #ifndef __ASMARM_ARCH_CNTVOFF_H | ||
4 | #define __ASMARM_ARCH_CNTVOFF_H | ||
5 | |||
6 | extern void secure_cntvoff_init(void); | ||
7 | |||
8 | #endif | ||
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index 43c1ac696274..2109f123bdfb 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h | |||
@@ -2,7 +2,6 @@ | |||
2 | #ifndef __ARCH_MACH_COMMON_H | 2 | #ifndef __ARCH_MACH_COMMON_H |
3 | #define __ARCH_MACH_COMMON_H | 3 | #define __ARCH_MACH_COMMON_H |
4 | 4 | ||
5 | extern void shmobile_init_cntvoff(void); | ||
6 | extern void shmobile_init_delay(void); | 5 | extern void shmobile_init_delay(void); |
7 | extern void shmobile_boot_vector(void); | 6 | extern void shmobile_boot_vector(void); |
8 | extern unsigned long shmobile_boot_fn; | 7 | extern unsigned long shmobile_boot_fn; |
diff --git a/arch/arm/mach-shmobile/headsmp-apmu.S b/arch/arm/mach-shmobile/headsmp-apmu.S index 5672b5849401..d49ab194766a 100644 --- a/arch/arm/mach-shmobile/headsmp-apmu.S +++ b/arch/arm/mach-shmobile/headsmp-apmu.S | |||
@@ -11,29 +11,9 @@ | |||
11 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
12 | #include <asm/assembler.h> | 12 | #include <asm/assembler.h> |
13 | 13 | ||
14 | ENTRY(shmobile_init_cntvoff) | ||
15 | /* | ||
16 | * CNTVOFF has to be initialized either from non-secure Hypervisor | ||
17 | * mode or secure Monitor mode with SCR.NS==1. If TrustZone is enabled | ||
18 | * then it should be handled by the secure code | ||
19 | */ | ||
20 | cps #MON_MODE | ||
21 | mrc p15, 0, r1, c1, c1, 0 /* Get Secure Config */ | ||
22 | orr r0, r1, #1 | ||
23 | mcr p15, 0, r0, c1, c1, 0 /* Set Non Secure bit */ | ||
24 | instr_sync | ||
25 | mov r0, #0 | ||
26 | mcrr p15, 4, r0, r0, c14 /* CNTVOFF = 0 */ | ||
27 | instr_sync | ||
28 | mcr p15, 0, r1, c1, c1, 0 /* Set Secure bit */ | ||
29 | instr_sync | ||
30 | cps #SVC_MODE | ||
31 | ret lr | ||
32 | ENDPROC(shmobile_init_cntvoff) | ||
33 | |||
34 | #ifdef CONFIG_SMP | 14 | #ifdef CONFIG_SMP |
35 | ENTRY(shmobile_boot_apmu) | 15 | ENTRY(shmobile_boot_apmu) |
36 | bl shmobile_init_cntvoff | 16 | bl secure_cntvoff_init |
37 | b secondary_startup | 17 | b secondary_startup |
38 | ENDPROC(shmobile_boot_apmu) | 18 | ENDPROC(shmobile_boot_apmu) |
39 | #endif | 19 | #endif |
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index 5561dbed7a33..4a881026d740 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/of_fdt.h> | 26 | #include <linux/of_fdt.h> |
27 | #include <linux/of_platform.h> | 27 | #include <linux/of_platform.h> |
28 | #include <asm/mach/arch.h> | 28 | #include <asm/mach/arch.h> |
29 | #include <asm/secure_cntvoff.h> | ||
29 | #include "common.h" | 30 | #include "common.h" |
30 | #include "rcar-gen2.h" | 31 | #include "rcar-gen2.h" |
31 | 32 | ||
@@ -70,7 +71,7 @@ void __init rcar_gen2_timer_init(void) | |||
70 | void __iomem *base; | 71 | void __iomem *base; |
71 | u32 freq; | 72 | u32 freq; |
72 | 73 | ||
73 | shmobile_init_cntvoff(); | 74 | secure_cntvoff_init(); |
74 | 75 | ||
75 | if (of_machine_is_compatible("renesas,r8a7745") || | 76 | if (of_machine_is_compatible("renesas,r8a7745") || |
76 | of_machine_is_compatible("renesas,r8a7792") || | 77 | of_machine_is_compatible("renesas,r8a7792") || |
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index ce53ceaf4cc5..d9c8ecf88ec6 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig | |||
@@ -51,7 +51,7 @@ config MACH_SUN9I | |||
51 | config ARCH_SUNXI_MC_SMP | 51 | config ARCH_SUNXI_MC_SMP |
52 | bool | 52 | bool |
53 | depends on SMP | 53 | depends on SMP |
54 | default MACH_SUN9I | 54 | default MACH_SUN9I || MACH_SUN8I |
55 | select ARM_CCI400_PORT_CTRL | 55 | select ARM_CCI400_PORT_CTRL |
56 | select ARM_CPU_SUSPEND | 56 | select ARM_CPU_SUSPEND |
57 | 57 | ||
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index 7de9cc286d53..71429aa85143 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | CFLAGS_mc_smp.o += -march=armv7-a | 1 | CFLAGS_mc_smp.o += -march=armv7-a |
2 | 2 | ||
3 | obj-$(CONFIG_ARCH_SUNXI) += sunxi.o | 3 | obj-$(CONFIG_ARCH_SUNXI) += sunxi.o |
4 | obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o | 4 | obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o headsmp.o |
5 | obj-$(CONFIG_SMP) += platsmp.o | 5 | obj-$(CONFIG_SMP) += platsmp.o |
diff --git a/arch/arm/mach-sunxi/headsmp.S b/arch/arm/mach-sunxi/headsmp.S new file mode 100644 index 000000000000..32d76be98541 --- /dev/null +++ b/arch/arm/mach-sunxi/headsmp.S | |||
@@ -0,0 +1,81 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 | ||
2 | * | ||
3 | * Copyright (c) 2018 Chen-Yu Tsai | ||
4 | * Copyright (c) 2018 Bootlin | ||
5 | * | ||
6 | * Chen-Yu Tsai <wens@csie.org> | ||
7 | * Mylène Josserand <mylene.josserand@bootlin.com> | ||
8 | * | ||
9 | * SMP support for sunxi based systems with Cortex A7/A15 | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/linkage.h> | ||
14 | #include <asm/assembler.h> | ||
15 | #include <asm/cputype.h> | ||
16 | |||
17 | ENTRY(sunxi_mc_smp_cluster_cache_enable) | ||
18 | .arch armv7-a | ||
19 | /* | ||
20 | * Enable cluster-level coherency, in preparation for turning on the MMU. | ||
21 | * | ||
22 | * Also enable regional clock gating and L2 data latency settings for | ||
23 | * Cortex-A15. These settings are from the vendor kernel. | ||
24 | */ | ||
25 | mrc p15, 0, r1, c0, c0, 0 | ||
26 | movw r2, #(ARM_CPU_PART_MASK & 0xffff) | ||
27 | movt r2, #(ARM_CPU_PART_MASK >> 16) | ||
28 | and r1, r1, r2 | ||
29 | movw r2, #(ARM_CPU_PART_CORTEX_A15 & 0xffff) | ||
30 | movt r2, #(ARM_CPU_PART_CORTEX_A15 >> 16) | ||
31 | cmp r1, r2 | ||
32 | bne not_a15 | ||
33 | |||
34 | /* The following is Cortex-A15 specific */ | ||
35 | |||
36 | /* ACTLR2: Enable CPU regional clock gates */ | ||
37 | mrc p15, 1, r1, c15, c0, 4 | ||
38 | orr r1, r1, #(0x1 << 31) | ||
39 | mcr p15, 1, r1, c15, c0, 4 | ||
40 | |||
41 | /* L2ACTLR */ | ||
42 | mrc p15, 1, r1, c15, c0, 0 | ||
43 | /* Enable L2, GIC, and Timer regional clock gates */ | ||
44 | orr r1, r1, #(0x1 << 26) | ||
45 | /* Disable clean/evict from being pushed to external */ | ||
46 | orr r1, r1, #(0x1<<3) | ||
47 | mcr p15, 1, r1, c15, c0, 0 | ||
48 | |||
49 | /* L2CTRL: L2 data RAM latency */ | ||
50 | mrc p15, 1, r1, c9, c0, 2 | ||
51 | bic r1, r1, #(0x7 << 0) | ||
52 | orr r1, r1, #(0x3 << 0) | ||
53 | mcr p15, 1, r1, c9, c0, 2 | ||
54 | |||
55 | /* End of Cortex-A15 specific setup */ | ||
56 | not_a15: | ||
57 | |||
58 | /* Get value of sunxi_mc_smp_first_comer */ | ||
59 | adr r1, first | ||
60 | ldr r0, [r1] | ||
61 | ldr r0, [r1, r0] | ||
62 | |||
63 | /* Skip cci_enable_port_for_self if not first comer */ | ||
64 | cmp r0, #0 | ||
65 | bxeq lr | ||
66 | b cci_enable_port_for_self | ||
67 | |||
68 | .align 2 | ||
69 | first: .word sunxi_mc_smp_first_comer - . | ||
70 | ENDPROC(sunxi_mc_smp_cluster_cache_enable) | ||
71 | |||
72 | ENTRY(sunxi_mc_smp_secondary_startup) | ||
73 | bl sunxi_mc_smp_cluster_cache_enable | ||
74 | bl secure_cntvoff_init | ||
75 | b secondary_startup | ||
76 | ENDPROC(sunxi_mc_smp_secondary_startup) | ||
77 | |||
78 | ENTRY(sunxi_mc_smp_resume) | ||
79 | bl sunxi_mc_smp_cluster_cache_enable | ||
80 | b cpu_resume | ||
81 | ENDPROC(sunxi_mc_smp_resume) | ||
diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c index c0246ec54a0a..b4037b603897 100644 --- a/arch/arm/mach-sunxi/mc_smp.c +++ b/arch/arm/mach-sunxi/mc_smp.c | |||
@@ -55,22 +55,35 @@ | |||
55 | #define CPUCFG_CX_RST_CTRL_L2_RST BIT(8) | 55 | #define CPUCFG_CX_RST_CTRL_L2_RST BIT(8) |
56 | #define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n)) | 56 | #define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n)) |
57 | #define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n) | 57 | #define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n) |
58 | #define CPUCFG_CX_RST_CTRL_CORE_RST_ALL (0xf << 0) | ||
58 | 59 | ||
59 | #define PRCM_CPU_PO_RST_CTRL(c) (0x4 + 0x4 * (c)) | 60 | #define PRCM_CPU_PO_RST_CTRL(c) (0x4 + 0x4 * (c)) |
60 | #define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n) | 61 | #define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n) |
61 | #define PRCM_CPU_PO_RST_CTRL_CORE_ALL 0xf | 62 | #define PRCM_CPU_PO_RST_CTRL_CORE_ALL 0xf |
62 | #define PRCM_PWROFF_GATING_REG(c) (0x100 + 0x4 * (c)) | 63 | #define PRCM_PWROFF_GATING_REG(c) (0x100 + 0x4 * (c)) |
63 | #define PRCM_PWROFF_GATING_REG_CLUSTER BIT(4) | 64 | /* The power off register for clusters are different from a80 and a83t */ |
65 | #define PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I BIT(0) | ||
66 | #define PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I BIT(4) | ||
64 | #define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n) | 67 | #define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n) |
65 | #define PRCM_PWR_SWITCH_REG(c, cpu) (0x140 + 0x10 * (c) + 0x4 * (cpu)) | 68 | #define PRCM_PWR_SWITCH_REG(c, cpu) (0x140 + 0x10 * (c) + 0x4 * (cpu)) |
66 | #define PRCM_CPU_SOFT_ENTRY_REG 0x164 | 69 | #define PRCM_CPU_SOFT_ENTRY_REG 0x164 |
67 | 70 | ||
71 | /* R_CPUCFG registers, specific to sun8i-a83t */ | ||
72 | #define R_CPUCFG_CLUSTER_PO_RST_CTRL(c) (0x30 + (c) * 0x4) | ||
73 | #define R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(n) BIT(n) | ||
74 | #define R_CPUCFG_CPU_SOFT_ENTRY_REG 0x01a4 | ||
75 | |||
68 | #define CPU0_SUPPORT_HOTPLUG_MAGIC0 0xFA50392F | 76 | #define CPU0_SUPPORT_HOTPLUG_MAGIC0 0xFA50392F |
69 | #define CPU0_SUPPORT_HOTPLUG_MAGIC1 0x790DCA3A | 77 | #define CPU0_SUPPORT_HOTPLUG_MAGIC1 0x790DCA3A |
70 | 78 | ||
71 | static void __iomem *cpucfg_base; | 79 | static void __iomem *cpucfg_base; |
72 | static void __iomem *prcm_base; | 80 | static void __iomem *prcm_base; |
73 | static void __iomem *sram_b_smp_base; | 81 | static void __iomem *sram_b_smp_base; |
82 | static void __iomem *r_cpucfg_base; | ||
83 | |||
84 | extern void sunxi_mc_smp_secondary_startup(void); | ||
85 | extern void sunxi_mc_smp_resume(void); | ||
86 | static bool is_a83t; | ||
74 | 87 | ||
75 | static bool sunxi_core_is_cortex_a15(unsigned int core, unsigned int cluster) | 88 | static bool sunxi_core_is_cortex_a15(unsigned int core, unsigned int cluster) |
76 | { | 89 | { |
@@ -157,6 +170,16 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster) | |||
157 | reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu); | 170 | reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu); |
158 | writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); | 171 | writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); |
159 | 172 | ||
173 | if (is_a83t) { | ||
174 | /* assert cpu power-on reset */ | ||
175 | reg = readl(r_cpucfg_base + | ||
176 | R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); | ||
177 | reg &= ~(R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu)); | ||
178 | writel(reg, r_cpucfg_base + | ||
179 | R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); | ||
180 | udelay(10); | ||
181 | } | ||
182 | |||
160 | /* Cortex-A7: hold L1 reset disable signal low */ | 183 | /* Cortex-A7: hold L1 reset disable signal low */ |
161 | if (!sunxi_core_is_cortex_a15(cpu, cluster)) { | 184 | if (!sunxi_core_is_cortex_a15(cpu, cluster)) { |
162 | reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster)); | 185 | reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster)); |
@@ -180,17 +203,38 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster) | |||
180 | /* open power switch */ | 203 | /* open power switch */ |
181 | sunxi_cpu_power_switch_set(cpu, cluster, true); | 204 | sunxi_cpu_power_switch_set(cpu, cluster, true); |
182 | 205 | ||
206 | /* Handle A83T bit swap */ | ||
207 | if (is_a83t) { | ||
208 | if (cpu == 0) | ||
209 | cpu = 4; | ||
210 | } | ||
211 | |||
183 | /* clear processor power gate */ | 212 | /* clear processor power gate */ |
184 | reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); | 213 | reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); |
185 | reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu); | 214 | reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu); |
186 | writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); | 215 | writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); |
187 | udelay(20); | 216 | udelay(20); |
188 | 217 | ||
218 | /* Handle A83T bit swap */ | ||
219 | if (is_a83t) { | ||
220 | if (cpu == 4) | ||
221 | cpu = 0; | ||
222 | } | ||
223 | |||
189 | /* de-assert processor power-on reset */ | 224 | /* de-assert processor power-on reset */ |
190 | reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); | 225 | reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); |
191 | reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu); | 226 | reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu); |
192 | writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); | 227 | writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); |
193 | 228 | ||
229 | if (is_a83t) { | ||
230 | reg = readl(r_cpucfg_base + | ||
231 | R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); | ||
232 | reg |= R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu); | ||
233 | writel(reg, r_cpucfg_base + | ||
234 | R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); | ||
235 | udelay(10); | ||
236 | } | ||
237 | |||
194 | /* de-assert all processor resets */ | 238 | /* de-assert all processor resets */ |
195 | reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); | 239 | reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); |
196 | reg |= CPUCFG_CX_RST_CTRL_DBG_RST(cpu); | 240 | reg |= CPUCFG_CX_RST_CTRL_DBG_RST(cpu); |
@@ -212,6 +256,14 @@ static int sunxi_cluster_powerup(unsigned int cluster) | |||
212 | if (cluster >= SUNXI_NR_CLUSTERS) | 256 | if (cluster >= SUNXI_NR_CLUSTERS) |
213 | return -EINVAL; | 257 | return -EINVAL; |
214 | 258 | ||
259 | /* For A83T, assert cluster cores resets */ | ||
260 | if (is_a83t) { | ||
261 | reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); | ||
262 | reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL; /* Core Reset */ | ||
263 | writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); | ||
264 | udelay(10); | ||
265 | } | ||
266 | |||
215 | /* assert ACINACTM */ | 267 | /* assert ACINACTM */ |
216 | reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); | 268 | reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); |
217 | reg |= CPUCFG_CX_CTRL_REG1_ACINACTM; | 269 | reg |= CPUCFG_CX_CTRL_REG1_ACINACTM; |
@@ -222,6 +274,16 @@ static int sunxi_cluster_powerup(unsigned int cluster) | |||
222 | reg &= ~PRCM_CPU_PO_RST_CTRL_CORE_ALL; | 274 | reg &= ~PRCM_CPU_PO_RST_CTRL_CORE_ALL; |
223 | writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); | 275 | writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); |
224 | 276 | ||
277 | /* assert cluster cores resets */ | ||
278 | if (is_a83t) { | ||
279 | reg = readl(r_cpucfg_base + | ||
280 | R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); | ||
281 | reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL; | ||
282 | writel(reg, r_cpucfg_base + | ||
283 | R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); | ||
284 | udelay(10); | ||
285 | } | ||
286 | |||
225 | /* assert cluster resets */ | 287 | /* assert cluster resets */ |
226 | reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); | 288 | reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); |
227 | reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST; | 289 | reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST; |
@@ -252,7 +314,10 @@ static int sunxi_cluster_powerup(unsigned int cluster) | |||
252 | 314 | ||
253 | /* clear cluster power gate */ | 315 | /* clear cluster power gate */ |
254 | reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); | 316 | reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); |
255 | reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER; | 317 | if (is_a83t) |
318 | reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I; | ||
319 | else | ||
320 | reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; | ||
256 | writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); | 321 | writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); |
257 | udelay(20); | 322 | udelay(20); |
258 | 323 | ||
@@ -300,74 +365,7 @@ static void sunxi_cluster_cache_disable_without_axi(void) | |||
300 | } | 365 | } |
301 | 366 | ||
302 | static int sunxi_mc_smp_cpu_table[SUNXI_NR_CLUSTERS][SUNXI_CPUS_PER_CLUSTER]; | 367 | static int sunxi_mc_smp_cpu_table[SUNXI_NR_CLUSTERS][SUNXI_CPUS_PER_CLUSTER]; |
303 | static int sunxi_mc_smp_first_comer; | 368 | int sunxi_mc_smp_first_comer; |
304 | |||
305 | /* | ||
306 | * Enable cluster-level coherency, in preparation for turning on the MMU. | ||
307 | * | ||
308 | * Also enable regional clock gating and L2 data latency settings for | ||
309 | * Cortex-A15. These settings are from the vendor kernel. | ||
310 | */ | ||
311 | static void __naked sunxi_mc_smp_cluster_cache_enable(void) | ||
312 | { | ||
313 | asm volatile ( | ||
314 | "mrc p15, 0, r1, c0, c0, 0\n" | ||
315 | "movw r2, #" __stringify(ARM_CPU_PART_MASK & 0xffff) "\n" | ||
316 | "movt r2, #" __stringify(ARM_CPU_PART_MASK >> 16) "\n" | ||
317 | "and r1, r1, r2\n" | ||
318 | "movw r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 & 0xffff) "\n" | ||
319 | "movt r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 >> 16) "\n" | ||
320 | "cmp r1, r2\n" | ||
321 | "bne not_a15\n" | ||
322 | |||
323 | /* The following is Cortex-A15 specific */ | ||
324 | |||
325 | /* ACTLR2: Enable CPU regional clock gates */ | ||
326 | "mrc p15, 1, r1, c15, c0, 4\n" | ||
327 | "orr r1, r1, #(0x1<<31)\n" | ||
328 | "mcr p15, 1, r1, c15, c0, 4\n" | ||
329 | |||
330 | /* L2ACTLR */ | ||
331 | "mrc p15, 1, r1, c15, c0, 0\n" | ||
332 | /* Enable L2, GIC, and Timer regional clock gates */ | ||
333 | "orr r1, r1, #(0x1<<26)\n" | ||
334 | /* Disable clean/evict from being pushed to external */ | ||
335 | "orr r1, r1, #(0x1<<3)\n" | ||
336 | "mcr p15, 1, r1, c15, c0, 0\n" | ||
337 | |||
338 | /* L2CTRL: L2 data RAM latency */ | ||
339 | "mrc p15, 1, r1, c9, c0, 2\n" | ||
340 | "bic r1, r1, #(0x7<<0)\n" | ||
341 | "orr r1, r1, #(0x3<<0)\n" | ||
342 | "mcr p15, 1, r1, c9, c0, 2\n" | ||
343 | |||
344 | /* End of Cortex-A15 specific setup */ | ||
345 | "not_a15:\n" | ||
346 | |||
347 | /* Get value of sunxi_mc_smp_first_comer */ | ||
348 | "adr r1, first\n" | ||
349 | "ldr r0, [r1]\n" | ||
350 | "ldr r0, [r1, r0]\n" | ||
351 | |||
352 | /* Skip cci_enable_port_for_self if not first comer */ | ||
353 | "cmp r0, #0\n" | ||
354 | "bxeq lr\n" | ||
355 | "b cci_enable_port_for_self\n" | ||
356 | |||
357 | ".align 2\n" | ||
358 | "first: .word sunxi_mc_smp_first_comer - .\n" | ||
359 | ); | ||
360 | } | ||
361 | |||
362 | static void __naked sunxi_mc_smp_secondary_startup(void) | ||
363 | { | ||
364 | asm volatile( | ||
365 | "bl sunxi_mc_smp_cluster_cache_enable\n" | ||
366 | "b secondary_startup" | ||
367 | /* Let compiler know about sunxi_mc_smp_cluster_cache_enable */ | ||
368 | :: "i" (sunxi_mc_smp_cluster_cache_enable) | ||
369 | ); | ||
370 | } | ||
371 | 369 | ||
372 | static DEFINE_SPINLOCK(boot_lock); | 370 | static DEFINE_SPINLOCK(boot_lock); |
373 | 371 | ||
@@ -516,7 +514,10 @@ static int sunxi_cluster_powerdown(unsigned int cluster) | |||
516 | /* gate cluster power */ | 514 | /* gate cluster power */ |
517 | pr_debug("%s: gate cluster power\n", __func__); | 515 | pr_debug("%s: gate cluster power\n", __func__); |
518 | reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); | 516 | reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); |
519 | reg |= PRCM_PWROFF_GATING_REG_CLUSTER; | 517 | if (is_a83t) |
518 | reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I; | ||
519 | else | ||
520 | reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; | ||
520 | writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); | 521 | writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); |
521 | udelay(20); | 522 | udelay(20); |
522 | 523 | ||
@@ -598,8 +599,12 @@ out: | |||
598 | return !ret; | 599 | return !ret; |
599 | } | 600 | } |
600 | 601 | ||
601 | static bool sunxi_mc_smp_cpu_can_disable(unsigned int __unused) | 602 | static bool sunxi_mc_smp_cpu_can_disable(unsigned int cpu) |
602 | { | 603 | { |
604 | /* CPU0 hotplug not handled for sun8i-a83t */ | ||
605 | if (is_a83t) | ||
606 | if (cpu == 0) | ||
607 | return false; | ||
603 | return true; | 608 | return true; |
604 | } | 609 | } |
605 | #endif | 610 | #endif |
@@ -637,16 +642,6 @@ static bool __init sunxi_mc_smp_cpu_table_init(void) | |||
637 | */ | 642 | */ |
638 | typedef typeof(cpu_reset) phys_reset_t; | 643 | typedef typeof(cpu_reset) phys_reset_t; |
639 | 644 | ||
640 | static void __init __naked sunxi_mc_smp_resume(void) | ||
641 | { | ||
642 | asm volatile( | ||
643 | "bl sunxi_mc_smp_cluster_cache_enable\n" | ||
644 | "b cpu_resume" | ||
645 | /* Let compiler know about sunxi_mc_smp_cluster_cache_enable */ | ||
646 | :: "i" (sunxi_mc_smp_cluster_cache_enable) | ||
647 | ); | ||
648 | } | ||
649 | |||
650 | static int __init nocache_trampoline(unsigned long __unused) | 645 | static int __init nocache_trampoline(unsigned long __unused) |
651 | { | 646 | { |
652 | phys_reset_t phys_reset; | 647 | phys_reset_t phys_reset; |
@@ -692,12 +687,14 @@ struct sunxi_mc_smp_nodes { | |||
692 | struct device_node *prcm_node; | 687 | struct device_node *prcm_node; |
693 | struct device_node *cpucfg_node; | 688 | struct device_node *cpucfg_node; |
694 | struct device_node *sram_node; | 689 | struct device_node *sram_node; |
690 | struct device_node *r_cpucfg_node; | ||
695 | }; | 691 | }; |
696 | 692 | ||
697 | /* This structure holds SoC-specific bits tied to an enable-method string. */ | 693 | /* This structure holds SoC-specific bits tied to an enable-method string. */ |
698 | struct sunxi_mc_smp_data { | 694 | struct sunxi_mc_smp_data { |
699 | const char *enable_method; | 695 | const char *enable_method; |
700 | int (*get_smp_nodes)(struct sunxi_mc_smp_nodes *nodes); | 696 | int (*get_smp_nodes)(struct sunxi_mc_smp_nodes *nodes); |
697 | bool is_a83t; | ||
701 | }; | 698 | }; |
702 | 699 | ||
703 | static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes) | 700 | static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes) |
@@ -705,6 +702,7 @@ static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes) | |||
705 | of_node_put(nodes->prcm_node); | 702 | of_node_put(nodes->prcm_node); |
706 | of_node_put(nodes->cpucfg_node); | 703 | of_node_put(nodes->cpucfg_node); |
707 | of_node_put(nodes->sram_node); | 704 | of_node_put(nodes->sram_node); |
705 | of_node_put(nodes->r_cpucfg_node); | ||
708 | memset(nodes, 0, sizeof(*nodes)); | 706 | memset(nodes, 0, sizeof(*nodes)); |
709 | } | 707 | } |
710 | 708 | ||
@@ -734,11 +732,42 @@ static int __init sun9i_a80_get_smp_nodes(struct sunxi_mc_smp_nodes *nodes) | |||
734 | return 0; | 732 | return 0; |
735 | } | 733 | } |
736 | 734 | ||
735 | static int __init sun8i_a83t_get_smp_nodes(struct sunxi_mc_smp_nodes *nodes) | ||
736 | { | ||
737 | nodes->prcm_node = of_find_compatible_node(NULL, NULL, | ||
738 | "allwinner,sun8i-a83t-r-ccu"); | ||
739 | if (!nodes->prcm_node) { | ||
740 | pr_err("%s: PRCM not available\n", __func__); | ||
741 | return -ENODEV; | ||
742 | } | ||
743 | |||
744 | nodes->cpucfg_node = of_find_compatible_node(NULL, NULL, | ||
745 | "allwinner,sun8i-a83t-cpucfg"); | ||
746 | if (!nodes->cpucfg_node) { | ||
747 | pr_err("%s: CPUCFG not available\n", __func__); | ||
748 | return -ENODEV; | ||
749 | } | ||
750 | |||
751 | nodes->r_cpucfg_node = of_find_compatible_node(NULL, NULL, | ||
752 | "allwinner,sun8i-a83t-r-cpucfg"); | ||
753 | if (!nodes->r_cpucfg_node) { | ||
754 | pr_err("%s: RCPUCFG not available\n", __func__); | ||
755 | return -ENODEV; | ||
756 | } | ||
757 | |||
758 | return 0; | ||
759 | } | ||
760 | |||
737 | static const struct sunxi_mc_smp_data sunxi_mc_smp_data[] __initconst = { | 761 | static const struct sunxi_mc_smp_data sunxi_mc_smp_data[] __initconst = { |
738 | { | 762 | { |
739 | .enable_method = "allwinner,sun9i-a80-smp", | 763 | .enable_method = "allwinner,sun9i-a80-smp", |
740 | .get_smp_nodes = sun9i_a80_get_smp_nodes, | 764 | .get_smp_nodes = sun9i_a80_get_smp_nodes, |
741 | }, | 765 | }, |
766 | { | ||
767 | .enable_method = "allwinner,sun8i-a83t-smp", | ||
768 | .get_smp_nodes = sun8i_a83t_get_smp_nodes, | ||
769 | .is_a83t = true, | ||
770 | }, | ||
742 | }; | 771 | }; |
743 | 772 | ||
744 | static int __init sunxi_mc_smp_init(void) | 773 | static int __init sunxi_mc_smp_init(void) |
@@ -746,6 +775,7 @@ static int __init sunxi_mc_smp_init(void) | |||
746 | struct sunxi_mc_smp_nodes nodes = { 0 }; | 775 | struct sunxi_mc_smp_nodes nodes = { 0 }; |
747 | struct device_node *node; | 776 | struct device_node *node; |
748 | struct resource res; | 777 | struct resource res; |
778 | void __iomem *addr; | ||
749 | int i, ret; | 779 | int i, ret; |
750 | 780 | ||
751 | /* | 781 | /* |
@@ -771,6 +801,8 @@ static int __init sunxi_mc_smp_init(void) | |||
771 | break; | 801 | break; |
772 | } | 802 | } |
773 | 803 | ||
804 | is_a83t = sunxi_mc_smp_data[i].is_a83t; | ||
805 | |||
774 | of_node_put(node); | 806 | of_node_put(node); |
775 | if (ret) | 807 | if (ret) |
776 | return -ENODEV; | 808 | return -ENODEV; |
@@ -808,12 +840,23 @@ static int __init sunxi_mc_smp_init(void) | |||
808 | goto err_unmap_prcm; | 840 | goto err_unmap_prcm; |
809 | } | 841 | } |
810 | 842 | ||
811 | sram_b_smp_base = of_io_request_and_map(nodes.sram_node, 0, | 843 | if (is_a83t) { |
812 | "sunxi-mc-smp"); | 844 | r_cpucfg_base = of_io_request_and_map(nodes.r_cpucfg_node, |
813 | if (IS_ERR(sram_b_smp_base)) { | 845 | 0, "sunxi-mc-smp"); |
814 | ret = PTR_ERR(sram_b_smp_base); | 846 | if (IS_ERR(r_cpucfg_base)) { |
815 | pr_err("%s: failed to map secure SRAM\n", __func__); | 847 | ret = PTR_ERR(r_cpucfg_base); |
816 | goto err_unmap_release_cpucfg; | 848 | pr_err("%s: failed to map R-CPUCFG registers\n", |
849 | __func__); | ||
850 | goto err_unmap_release_cpucfg; | ||
851 | } | ||
852 | } else { | ||
853 | sram_b_smp_base = of_io_request_and_map(nodes.sram_node, 0, | ||
854 | "sunxi-mc-smp"); | ||
855 | if (IS_ERR(sram_b_smp_base)) { | ||
856 | ret = PTR_ERR(sram_b_smp_base); | ||
857 | pr_err("%s: failed to map secure SRAM\n", __func__); | ||
858 | goto err_unmap_release_cpucfg; | ||
859 | } | ||
817 | } | 860 | } |
818 | 861 | ||
819 | /* Configure CCI-400 for boot cluster */ | 862 | /* Configure CCI-400 for boot cluster */ |
@@ -821,15 +864,18 @@ static int __init sunxi_mc_smp_init(void) | |||
821 | if (ret) { | 864 | if (ret) { |
822 | pr_err("%s: failed to configure boot cluster: %d\n", | 865 | pr_err("%s: failed to configure boot cluster: %d\n", |
823 | __func__, ret); | 866 | __func__, ret); |
824 | goto err_unmap_release_secure_sram; | 867 | goto err_unmap_release_sram_rcpucfg; |
825 | } | 868 | } |
826 | 869 | ||
827 | /* We don't need the device nodes anymore */ | 870 | /* We don't need the device nodes anymore */ |
828 | sunxi_mc_smp_put_nodes(&nodes); | 871 | sunxi_mc_smp_put_nodes(&nodes); |
829 | 872 | ||
830 | /* Set the hardware entry point address */ | 873 | /* Set the hardware entry point address */ |
831 | writel(__pa_symbol(sunxi_mc_smp_secondary_startup), | 874 | if (is_a83t) |
832 | prcm_base + PRCM_CPU_SOFT_ENTRY_REG); | 875 | addr = r_cpucfg_base + R_CPUCFG_CPU_SOFT_ENTRY_REG; |
876 | else | ||
877 | addr = prcm_base + PRCM_CPU_SOFT_ENTRY_REG; | ||
878 | writel(__pa_symbol(sunxi_mc_smp_secondary_startup), addr); | ||
833 | 879 | ||
834 | /* Actually enable multi cluster SMP */ | 880 | /* Actually enable multi cluster SMP */ |
835 | smp_set_ops(&sunxi_mc_smp_smp_ops); | 881 | smp_set_ops(&sunxi_mc_smp_smp_ops); |
@@ -838,9 +884,14 @@ static int __init sunxi_mc_smp_init(void) | |||
838 | 884 | ||
839 | return 0; | 885 | return 0; |
840 | 886 | ||
841 | err_unmap_release_secure_sram: | 887 | err_unmap_release_sram_rcpucfg: |
842 | iounmap(sram_b_smp_base); | 888 | if (is_a83t) { |
843 | of_address_to_resource(nodes.sram_node, 0, &res); | 889 | iounmap(r_cpucfg_base); |
890 | of_address_to_resource(nodes.r_cpucfg_node, 0, &res); | ||
891 | } else { | ||
892 | iounmap(sram_b_smp_base); | ||
893 | of_address_to_resource(nodes.sram_node, 0, &res); | ||
894 | } | ||
844 | release_mem_region(res.start, resource_size(&res)); | 895 | release_mem_region(res.start, resource_size(&res)); |
845 | err_unmap_release_cpucfg: | 896 | err_unmap_release_cpucfg: |
846 | iounmap(cpucfg_base); | 897 | iounmap(cpucfg_base); |
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index 5e9602ce1573..de4b0e932f22 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | 17 | ||
18 | #include <asm/mach/arch.h> | 18 | #include <asm/mach/arch.h> |
19 | #include <asm/secure_cntvoff.h> | ||
19 | 20 | ||
20 | static const char * const sunxi_board_dt_compat[] = { | 21 | static const char * const sunxi_board_dt_compat[] = { |
21 | "allwinner,sun4i-a10", | 22 | "allwinner,sun4i-a10", |
@@ -62,7 +63,6 @@ MACHINE_END | |||
62 | static const char * const sun8i_board_dt_compat[] = { | 63 | static const char * const sun8i_board_dt_compat[] = { |
63 | "allwinner,sun8i-a23", | 64 | "allwinner,sun8i-a23", |
64 | "allwinner,sun8i-a33", | 65 | "allwinner,sun8i-a33", |
65 | "allwinner,sun8i-a83t", | ||
66 | "allwinner,sun8i-h2-plus", | 66 | "allwinner,sun8i-h2-plus", |
67 | "allwinner,sun8i-h3", | 67 | "allwinner,sun8i-h3", |
68 | "allwinner,sun8i-r40", | 68 | "allwinner,sun8i-r40", |
@@ -75,6 +75,24 @@ DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i Family") | |||
75 | .dt_compat = sun8i_board_dt_compat, | 75 | .dt_compat = sun8i_board_dt_compat, |
76 | MACHINE_END | 76 | MACHINE_END |
77 | 77 | ||
78 | static void __init sun8i_a83t_cntvoff_init(void) | ||
79 | { | ||
80 | #ifdef CONFIG_SMP | ||
81 | secure_cntvoff_init(); | ||
82 | #endif | ||
83 | } | ||
84 | |||
85 | static const char * const sun8i_a83t_cntvoff_board_dt_compat[] = { | ||
86 | "allwinner,sun8i-a83t", | ||
87 | NULL, | ||
88 | }; | ||
89 | |||
90 | DT_MACHINE_START(SUN8I_A83T_CNTVOFF_DT, "Allwinner A83t board") | ||
91 | .init_early = sun8i_a83t_cntvoff_init, | ||
92 | .init_time = sun6i_timer_init, | ||
93 | .dt_compat = sun8i_a83t_cntvoff_board_dt_compat, | ||
94 | MACHINE_END | ||
95 | |||
78 | static const char * const sun9i_board_dt_compat[] = { | 96 | static const char * const sun9i_board_dt_compat[] = { |
79 | "allwinner,sun9i-a80", | 97 | "allwinner,sun9i-a80", |
80 | NULL, | 98 | NULL, |