Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/sunxi Add Allwinner A80 SMP support.



details:   https://anonhg.NetBSD.org/src/rev/d6b71c99be8b
branches:  trunk
changeset: 447188:d6b71c99be8b
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Thu Jan 03 14:44:21 2019 +0000

description:
Add Allwinner A80 SMP support.

diffstat:

 sys/arch/arm/sunxi/files.sunxi      |    4 +-
 sys/arch/arm/sunxi/sunxi_mc_smp.c   |  142 +++++++++++++++++++++++++----------
 sys/arch/arm/sunxi/sunxi_mc_smp.h   |    5 +-
 sys/arch/arm/sunxi/sunxi_platform.c |   59 +++++++++++---
 4 files changed, 153 insertions(+), 57 deletions(-)

diffs (truncated from 390 to 300 lines):

diff -r 65dca920e4a7 -r d6b71c99be8b sys/arch/arm/sunxi/files.sunxi
--- a/sys/arch/arm/sunxi/files.sunxi    Thu Jan 03 14:14:08 2019 +0000
+++ b/sys/arch/arm/sunxi/files.sunxi    Thu Jan 03 14:44:21 2019 +0000
@@ -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_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
diff -r 65dca920e4a7 -r d6b71c99be8b sys/arch/arm/sunxi/sunxi_mc_smp.c
--- a/sys/arch/arm/sunxi/sunxi_mc_smp.c Thu Jan 03 14:14:08 2019 +0000
+++ b/sys/arch/arm/sunxi/sunxi_mc_smp.c Thu Jan 03 14:44:21 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
 
 #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 @@
 #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 @@
 
 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 @@
 
        /* 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 @@
        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 @@
 }
 
 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 @@
        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;
+}
diff -r 65dca920e4a7 -r d6b71c99be8b sys/arch/arm/sunxi/sunxi_mc_smp.h
--- a/sys/arch/arm/sunxi/sunxi_mc_smp.h Thu Jan 03 14:14:08 2019 +0000
+++ b/sys/arch/arm/sunxi/sunxi_mc_smp.h Thu Jan 03 14:44:21 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 */
diff -r 65dca920e4a7 -r d6b71c99be8b sys/arch/arm/sunxi/sunxi_platform.c
--- a/sys/arch/arm/sunxi/sunxi_platform.c       Thu Jan 03 14:14:08 2019 +0000
+++ b/sys/arch/arm/sunxi/sunxi_platform.c       Thu Jan 03 14:44:21 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
        return devmap;
 }
 
-#define        SUN8I_A83T_CPU_VBASE    (SUNXI_CORE_VBASE + SUNXI_CORE_SIZE)



Home | Main Index | Thread Index | Old Index