Module Name: src
Committed By: jmcneill
Date: Thu Jan 3 14:44:21 UTC 2019
Modified Files:
src/sys/arch/arm/sunxi: files.sunxi sunxi_mc_smp.c sunxi_mc_smp.h
sunxi_platform.c
Log Message:
Add Allwinner A80 SMP support.
To generate a diff of this commit:
cvs rdiff -u -r1.58 -r1.59 src/sys/arch/arm/sunxi/files.sunxi
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/sunxi/sunxi_mc_smp.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/sunxi/sunxi_mc_smp.h
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/arm/sunxi/sunxi_platform.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/sunxi/files.sunxi
diff -u src/sys/arch/arm/sunxi/files.sunxi:1.58 src/sys/arch/arm/sunxi/files.sunxi:1.59
--- src/sys/arch/arm/sunxi/files.sunxi:1.58 Thu Jan 3 11:01:59 2019
+++ src/sys/arch/arm/sunxi/files.sunxi Thu Jan 3 14:44:21 2019
@@ -1,4 +1,4 @@
-# $NetBSD: files.sunxi,v 1.58 2019/01/03 11:01:59 jmcneill Exp $
+# $NetBSD: files.sunxi,v 1.59 2019/01/03 14:44:21 jmcneill Exp $
#
# Configuration info for Allwinner sunxi family SoCs
#
@@ -312,7 +312,7 @@ defflag opt_soc.h SOC_SUN8I: SOC_SUNXI
defflag opt_soc.h SOC_SUN8I_A83T: SOC_SUN8I, SOC_SUNXI_MC
defflag opt_soc.h SOC_SUN8I_H3: SOC_SUN8I
defflag opt_soc.h SOC_SUN9I: SOC_SUNXI
-defflag opt_soc.h SOC_SUN9I_A80: SOC_SUN9I
+defflag opt_soc.h SOC_SUN9I_A80: SOC_SUN9I, SOC_SUNXI_MC
defflag opt_soc.h SOC_SUN50I: SOC_SUNXI
defflag opt_soc.h SOC_SUN50I_A64: SOC_SUN50I
defflag opt_soc.h SOC_SUN50I_H5: SOC_SUN50I, SOC_SUN8I_H3
Index: src/sys/arch/arm/sunxi/sunxi_mc_smp.c
diff -u src/sys/arch/arm/sunxi/sunxi_mc_smp.c:1.2 src/sys/arch/arm/sunxi/sunxi_mc_smp.c:1.3
--- src/sys/arch/arm/sunxi/sunxi_mc_smp.c:1.2 Thu Jan 3 12:52:40 2019
+++ src/sys/arch/arm/sunxi/sunxi_mc_smp.c Thu Jan 3 14:44:21 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_mc_smp.c,v 1.2 2019/01/03 12:52:40 jmcneill Exp $ */
+/* $NetBSD: sunxi_mc_smp.c,v 1.3 2019/01/03 14:44:21 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_mc_smp.c,v 1.2 2019/01/03 12:52:40 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_mc_smp.c,v 1.3 2019/01/03 14:44:21 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -46,14 +46,16 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_mc_smp
#include <arm/sunxi/sunxi_mc_smp.h>
-#define A83T_SMP_ENABLE_METHOD "allwinner,sun8i-a83t-smp"
+#define A80_PRCM_BASE 0x08001400
+#define A80_PRCM_SIZE 0x200
-#define PRCM_BASE 0x01f01400
-#define PRCM_SIZE 0x800
+#define A83T_PRCM_BASE 0x01f01400
+#define A83T_PRCM_SIZE 0x800
#define PRCM_CL_RST_CTRL(cluster) (0x4 + (cluster) * 0x4)
#define PRCM_CL_PWROFF(cluster) (0x100 + (cluster) * 0x4)
#define PRCM_CL_PWR_CLAMP(cluster, cpu) (0x140 + (cluster) * 0x10 + (cpu) * 0x4)
+#define PRCM_CPU_SOFT_ENTRY 0x164
#define CPUCFG_BASE 0x01f01c00
#define CPUCFG_SIZE 0x400
@@ -70,27 +72,31 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_mc_smp
#define CPUXCFG_CL_RST_DBG_RST(cpu) __BIT(16 + (cpu))
#define CPUXCFG_CL_RST_H_RST __BIT(12)
#define CPUXCFG_CL_RST_L2_RST __BIT(8)
+#define CPUXCFG_CL_RST_CX_RST(cpu) __BIT(4 + (cpu))
#define CPUXCFG_CL_CTRL0(cluster) (0x0 + (cluster) * 0x10)
#define CPUXCFG_CL_CTRL1(cluster) (0x4 + (cluster) * 0x10)
#define CPUXCFG_CL_CTRL1_ACINACTM __BIT(0)
-#define CCI_BASE 0x01790000
-#define CCI_SLAVEIF3_BASE (CCI_BASE + 0x4000)
-#define CCI_SLAVEIF4_BASE (CCI_BASE + 0x5000)
+#define A80_CCI_BASE 0x01c90000
+#define A83T_CCI_BASE 0x01790000
+
+#define CCI_SLAVEIF3_OFFSET 0x4000
+#define CCI_SLAVEIF4_OFFSET 0x5000
extern struct bus_space arm_generic_bs_tag;
-uint32_t sunxi_mc_cci_port[MAXCPUS] = {
- CCI_SLAVEIF3_BASE,
- CCI_SLAVEIF3_BASE,
- CCI_SLAVEIF3_BASE,
- CCI_SLAVEIF3_BASE,
- CCI_SLAVEIF4_BASE,
- CCI_SLAVEIF4_BASE,
- CCI_SLAVEIF4_BASE,
- CCI_SLAVEIF4_BASE,
+enum sunxi_mc_soc {
+ MC_SOC_A80,
+ MC_SOC_A83T
+};
+
+enum sunxi_mc_cpu {
+ MC_CORE_CA7,
+ MC_CORE_CA15
};
+uint32_t sunxi_mc_cci_port[MAXCPUS];
+
static uint32_t
sunxi_mc_smp_pa(void)
{
@@ -106,28 +112,30 @@ sunxi_mc_smp_pa(void)
static int
sunxi_mc_smp_start(bus_space_tag_t bst, bus_space_handle_t prcm, bus_space_handle_t cpucfg,
- bus_space_handle_t cpuxcfg, u_int cluster, u_int cpu)
+ bus_space_handle_t cpuxcfg, u_int cluster, u_int cpu, enum sunxi_mc_soc soc,
+ enum sunxi_mc_cpu core)
{
uint32_t val;
int i;
- /* Set start vector */
- bus_space_write_4(bst, cpucfg, CPUCFG_P_REG0, sunxi_mc_smp_pa());
-
/* Assert core reset */
val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster));
val &= ~__BIT(cpu);
bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster), val);
- /* Assert power-on reset */
- val = bus_space_read_4(bst, cpucfg, CPUCFG_CL_RST(cluster));
- val &= ~__BIT(cpu);
- bus_space_write_4(bst, cpucfg, CPUCFG_CL_RST(cluster), val);
+ if (soc == MC_SOC_A83T) {
+ /* Assert power-on reset */
+ val = bus_space_read_4(bst, cpucfg, CPUCFG_CL_RST(cluster));
+ val &= ~__BIT(cpu);
+ bus_space_write_4(bst, cpucfg, CPUCFG_CL_RST(cluster), val);
+ }
- /* Disable automatic L1 cache invalidate at reset */
- val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_CTRL0(cluster));
- val &= ~__BIT(cpu);
- bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_CTRL0(cluster), val);
+ if (core == MC_CORE_CA7) {
+ /* Disable automatic L1 cache invalidate at reset */
+ val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_CTRL0(cluster));
+ val &= ~__BIT(cpu);
+ bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_CTRL0(cluster), val);
+ }
/* Release power clamp */
for (i = 0; i <= 8; i++) {
@@ -145,9 +153,14 @@ sunxi_mc_smp_start(bus_space_tag_t bst,
/* Clear power-off gating */
val = bus_space_read_4(bst, prcm, PRCM_CL_PWROFF(cluster));
- if (cpu == 0)
- val &= ~__BIT(4);
- val &= ~__BIT(cpu);
+ if (soc == MC_SOC_A83T) {
+ if (cpu == 0)
+ val &= ~__BIT(4);
+ val &= ~__BIT(0); /* cluster power gate */
+ } else {
+ val &= ~__BIT(cpu);
+ val &= ~__BIT(4); /* cluster power gate */
+ }
bus_space_write_4(bst, prcm, PRCM_CL_PWROFF(cluster), val);
/* De-assert power-on reset */
@@ -155,16 +168,21 @@ sunxi_mc_smp_start(bus_space_tag_t bst,
val |= __BIT(cpu);
bus_space_write_4(bst, prcm, PRCM_CL_RST_CTRL(cluster), val);
- val = bus_space_read_4(bst, cpucfg, CPUCFG_CL_RST(cluster));
- val |= __BIT(cpu);
- bus_space_write_4(bst, cpucfg, CPUCFG_CL_RST(cluster), val);
- delay(10);
+ if (soc == MC_SOC_A83T) {
+ val = bus_space_read_4(bst, cpucfg, CPUCFG_CL_RST(cluster));
+ val |= __BIT(cpu);
+ bus_space_write_4(bst, cpucfg, CPUCFG_CL_RST(cluster), val);
+ delay(10);
+ }
/* De-assert core reset */
val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster));
val |= __BIT(cpu);
val |= CPUXCFG_CL_RST_SOC_DBG_RST;
- val |= CPUXCFG_CL_RST_ETM_RST(cpu);
+ if (core == MC_CORE_CA7)
+ val |= CPUXCFG_CL_RST_ETM_RST(cpu);
+ else
+ val |= CPUXCFG_CL_RST_CX_RST(cpu);
val |= CPUXCFG_CL_RST_DBG_RST(cpu);
val |= CPUXCFG_CL_RST_L2_RST;
val |= CPUXCFG_CL_RST_H_RST;
@@ -179,7 +197,7 @@ sunxi_mc_smp_start(bus_space_tag_t bst,
}
int
-sunxi_mc_smp_enable(u_int mpidr)
+sun8i_a83t_smp_enable(u_int mpidr)
{
bus_space_tag_t bst = &arm_generic_bs_tag;
bus_space_handle_t prcm, cpucfg, cpuxcfg;
@@ -188,16 +206,58 @@ sunxi_mc_smp_enable(u_int mpidr)
const u_int cluster = __SHIFTOUT(mpidr, MPIDR_AFF1);
const u_int cpu = __SHIFTOUT(mpidr, MPIDR_AFF0);
- if (bus_space_map(bst, PRCM_BASE, PRCM_SIZE, 0, &prcm) != 0 ||
+ if (bus_space_map(bst, A83T_PRCM_BASE, A83T_PRCM_SIZE, 0, &prcm) != 0 ||
bus_space_map(bst, CPUCFG_BASE, CPUCFG_SIZE, 0, &cpucfg) != 0 ||
bus_space_map(bst, CPUXCFG_BASE, CPUXCFG_SIZE, 0, &cpuxcfg) != 0)
return ENOMEM;
- error = sunxi_mc_smp_start(bst, prcm, cpucfg, cpuxcfg, cluster, cpu);
+ for (int i = 0; i < 4; i++)
+ sunxi_mc_cci_port[i] = A83T_CCI_BASE + CCI_SLAVEIF3_OFFSET;
+ for (int i = 4; i < 8; i++)
+ sunxi_mc_cci_port[i] = A83T_CCI_BASE + CCI_SLAVEIF4_OFFSET;
+
+ /* Set start vector */
+ bus_space_write_4(bst, cpucfg, CPUCFG_P_REG0, sunxi_mc_smp_pa());
+ cpu_idcache_wbinv_all();
+
+ error = sunxi_mc_smp_start(bst, prcm, cpucfg, cpuxcfg, cluster, cpu,
+ MC_SOC_A83T, MC_CORE_CA7);
bus_space_unmap(bst, cpuxcfg, CPUXCFG_SIZE);
bus_space_unmap(bst, cpucfg, CPUCFG_SIZE);
- bus_space_unmap(bst, prcm, PRCM_SIZE);
+ bus_space_unmap(bst, prcm, A83T_PRCM_SIZE);
+
+ return error;
+}
+
+int
+sun9i_a80_smp_enable(u_int mpidr)
+{
+ bus_space_tag_t bst = &arm_generic_bs_tag;
+ bus_space_handle_t prcm, cpuxcfg;
+ int error;
+
+ const u_int cluster = __SHIFTOUT(mpidr, MPIDR_AFF1);
+ const u_int cpu = __SHIFTOUT(mpidr, MPIDR_AFF0);
+
+ if (bus_space_map(bst, A80_PRCM_BASE, A80_PRCM_SIZE, 0, &prcm) != 0 ||
+ bus_space_map(bst, CPUXCFG_BASE, CPUXCFG_SIZE, 0, &cpuxcfg) != 0)
+ return ENOMEM;
+
+ for (int i = 0; i < 4; i++)
+ sunxi_mc_cci_port[i] = A80_CCI_BASE + CCI_SLAVEIF3_OFFSET;
+ for (int i = 4; i < 8; i++)
+ sunxi_mc_cci_port[i] = A80_CCI_BASE + CCI_SLAVEIF4_OFFSET;
+
+ /* Set start vector */
+ bus_space_write_4(bst, prcm, PRCM_CPU_SOFT_ENTRY, sunxi_mc_smp_pa());
+ cpu_idcache_wbinv_all();
+
+ error = sunxi_mc_smp_start(bst, prcm, 0, cpuxcfg, cluster, cpu,
+ MC_SOC_A80, cluster == 0 ? MC_CORE_CA7 : MC_CORE_CA15);
+
+ bus_space_unmap(bst, cpuxcfg, CPUXCFG_SIZE);
+ bus_space_unmap(bst, prcm, A80_PRCM_SIZE);
return error;
}
Index: src/sys/arch/arm/sunxi/sunxi_mc_smp.h
diff -u src/sys/arch/arm/sunxi/sunxi_mc_smp.h:1.1 src/sys/arch/arm/sunxi/sunxi_mc_smp.h:1.2
--- src/sys/arch/arm/sunxi/sunxi_mc_smp.h:1.1 Thu Jan 3 11:01:59 2019
+++ src/sys/arch/arm/sunxi/sunxi_mc_smp.h Thu Jan 3 14:44:21 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_mc_smp.h,v 1.1 2019/01/03 11:01:59 jmcneill Exp $ */
+/* $NetBSD: sunxi_mc_smp.h,v 1.2 2019/01/03 14:44:21 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -30,6 +30,7 @@
#define _SUNXI_MC_SMP_H
int sunxi_mc_smp_match(const char *);
-int sunxi_mc_smp_enable(u_int);
+int sun8i_a83t_smp_enable(u_int);
+int sun9i_a80_smp_enable(u_int);
#endif /* !_SUNXI_MC_SMP_H */
Index: src/sys/arch/arm/sunxi/sunxi_platform.c
diff -u src/sys/arch/arm/sunxi/sunxi_platform.c:1.33 src/sys/arch/arm/sunxi/sunxi_platform.c:1.34
--- src/sys/arch/arm/sunxi/sunxi_platform.c:1.33 Thu Jan 3 12:52:40 2019
+++ src/sys/arch/arm/sunxi/sunxi_platform.c Thu Jan 3 14:44:21 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_platform.c,v 1.33 2019/01/03 12:52:40 jmcneill Exp $ */
+/* $NetBSD: sunxi_platform.c,v 1.34 2019/01/03 14:44:21 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -31,7 +31,7 @@
#include "opt_console.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.33 2019/01/03 12:52:40 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.34 2019/01/03 14:44:21 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -127,9 +127,9 @@ sunxi_platform_devmap(void)
return devmap;
}
-#define SUN8I_A83T_CPU_VBASE (SUNXI_CORE_VBASE + SUNXI_CORE_SIZE)
-#define SUN8I_A83T_CPU_PBASE 0x01700000
-#define SUN8I_A83T_CPU_SIZE 0x00100000
+#define SUNXI_MC_CPU_VBASE (SUNXI_CORE_VBASE + SUNXI_CORE_SIZE)
+#define SUNXI_MC_CPU_PBASE 0x01700000
+#define SUNXI_MC_CPU_SIZE 0x00100000
static const struct pmap_devmap *
sun8i_a83t_platform_devmap(void)
@@ -138,15 +138,39 @@ sun8i_a83t_platform_devmap(void)
DEVMAP_ENTRY(SUNXI_CORE_VBASE,
SUNXI_CORE_PBASE,
SUNXI_CORE_SIZE),
- DEVMAP_ENTRY(SUN8I_A83T_CPU_VBASE,
- SUN8I_A83T_CPU_PBASE,
- SUN8I_A83T_CPU_SIZE),
+ DEVMAP_ENTRY(SUNXI_MC_CPU_VBASE,
+ SUNXI_MC_CPU_PBASE,
+ SUNXI_MC_CPU_SIZE),
DEVMAP_ENTRY_END
};
return devmap;
}
+#define SUN9I_A80_PRCM_VBASE (SUNXI_MC_CPU_VBASE + SUNXI_MC_CPU_PBASE)
+#define SUN9I_A80_PRCM_PBASE 0x08000000
+#define SUN9I_A80_PRCM_SIZE 0x00100000
+
+static const struct pmap_devmap *
+sun9i_a80_platform_devmap(void)
+{
+ static const struct pmap_devmap devmap[] = {
+ DEVMAP_ENTRY(SUNXI_CORE_VBASE,
+ SUNXI_CORE_PBASE,
+ SUNXI_CORE_SIZE),
+ DEVMAP_ENTRY(SUNXI_MC_CPU_VBASE,
+ SUNXI_MC_CPU_PBASE,
+ SUNXI_MC_CPU_SIZE),
+ DEVMAP_ENTRY(SUN9I_A80_PRCM_VBASE,
+ SUN9I_A80_PRCM_PBASE,
+ SUN9I_A80_PRCM_SIZE),
+ DEVMAP_ENTRY_END
+ };
+
+ return devmap;
+}
+
+
static void
sunxi_platform_init_attach_args(struct fdt_attach_args *faa)
{
@@ -237,15 +261,26 @@ sunxi_platform_bootstrap(void)
#if defined(SOC_SUNXI_MC)
static int
-cpu_enable_sunxi_mc(int phandle)
+cpu_enable_sun8i_a83t(int phandle)
{
uint64_t mpidr;
fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
- return sunxi_mc_smp_enable(mpidr);
+ return sun8i_a83t_smp_enable(mpidr);
}
-ARM_CPU_METHOD(sun8i_a83t, "allwinner,sun8i-a83t-smp", cpu_enable_sunxi_mc);
+ARM_CPU_METHOD(sun8i_a83t, "allwinner,sun8i-a83t-smp", cpu_enable_sun8i_a83t);
+
+static int
+cpu_enable_sun9i_a80(int phandle)
+{
+ uint64_t mpidr;
+
+ fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
+
+ return sun9i_a80_smp_enable(mpidr);
+}
+ARM_CPU_METHOD(sun9i_a80, "allwinner,sun9i-a80-smp", cpu_enable_sun9i_a80);
#endif
static void
@@ -411,7 +446,7 @@ static const struct arm_platform sun8i_a
ARM_PLATFORM(sun8i_a83t, "allwinner,sun8i-a83t", &sun8i_a83t_platform);
static const struct arm_platform sun9i_platform = {
- .ap_devmap = sunxi_platform_devmap,
+ .ap_devmap = sun9i_a80_platform_devmap,
.ap_bootstrap = sunxi_platform_bootstrap,
.ap_init_attach_args = sunxi_platform_init_attach_args,
.ap_device_register = sunxi_platform_device_register,