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 <jmcne...@invisible.ca>
@@ -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 <jmcne...@invisible.ca>
@@ -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 <jmcne...@invisible.ca>
@@ -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,

Reply via email to