Author: andrew
Date: Sun Mar  6 11:41:08 2016
New Revision: 296426
URL: https://svnweb.freebsd.org/changeset/base/296426

Log:
  Add SMP support for the Allwinner A31 and A31s. This updated the existing
  code for the A20 to use the new PLATFORM_SMP interface, and extends it to
  add support for the new SoCs allowing for both to coexist within the same
  kernel.
  
  Submitted by: Emmanuel Vadot <m...@bidouilliste.com>
  Reviewed by:  jmcneill
  Differential Revision:        https://reviews.freebsd.org/D5342

Added:
  head/sys/arm/allwinner/aw_mp.c
     - copied, changed from r296425, head/sys/arm/allwinner/a20/a20_mp.c
  head/sys/arm/allwinner/aw_mp.h   (contents, props changed)
Deleted:
  head/sys/arm/allwinner/a20/a20_mp.c
Modified:
  head/sys/arm/allwinner/a20/files.a20
  head/sys/arm/allwinner/allwinner_machdep.c
  head/sys/arm/conf/A20

Modified: head/sys/arm/allwinner/a20/files.a20
==============================================================================
--- head/sys/arm/allwinner/a20/files.a20        Sun Mar  6 08:52:03 2016        
(r296425)
+++ head/sys/arm/allwinner/a20/files.a20        Sun Mar  6 11:41:08 2016        
(r296426)
@@ -1,5 +1,5 @@
 # $FreeBSD$
 
 arm/allwinner/a20/a20_padconf.c                standard
-arm/allwinner/a20/a20_mp.c             optional        smp
+arm/allwinner/aw_mp.c                  optional        smp
 arm/allwinner/a20/a20_if_dwc.c         optional        dwc

Modified: head/sys/arm/allwinner/allwinner_machdep.c
==============================================================================
--- head/sys/arm/allwinner/allwinner_machdep.c  Sun Mar  6 08:52:03 2016        
(r296425)
+++ head/sys/arm/allwinner/allwinner_machdep.c  Sun Mar  6 11:41:08 2016        
(r296426)
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/fdt/fdt_common.h>
 
+#include <arm/allwinner/aw_mp.h>
 #include <arm/allwinner/aw_wdog.h>
 #include <arm/allwinner/allwinner_machdep.h>
 
@@ -152,6 +153,10 @@ static platform_method_t a20_methods[] =
        PLATFORMMETHOD(platform_lastaddr,       allwinner_lastaddr),
        PLATFORMMETHOD(platform_devmap_init,    allwinner_devmap_init),
 
+#ifdef SMP
+       PLATFORMMETHOD(platform_mp_start_ap,    a20_mp_start_ap),
+       PLATFORMMETHOD(platform_mp_setmaxid,    aw_mp_setmaxid),
+#endif
        PLATFORMMETHOD_END,
 };
 
@@ -160,6 +165,10 @@ static platform_method_t a31_methods[] =
        PLATFORMMETHOD(platform_lastaddr,       allwinner_lastaddr),
        PLATFORMMETHOD(platform_devmap_init,    allwinner_devmap_init),
 
+#ifdef SMP
+       PLATFORMMETHOD(platform_mp_start_ap,    a31_mp_start_ap),
+       PLATFORMMETHOD(platform_mp_setmaxid,    aw_mp_setmaxid),
+#endif
        PLATFORMMETHOD_END,
 };
 
@@ -168,6 +177,10 @@ static platform_method_t a31s_methods[] 
        PLATFORMMETHOD(platform_lastaddr,       allwinner_lastaddr),
        PLATFORMMETHOD(platform_devmap_init,    allwinner_devmap_init),
 
+#ifdef SMP
+       PLATFORMMETHOD(platform_mp_start_ap,    a31_mp_start_ap),
+       PLATFORMMETHOD(platform_mp_setmaxid,    aw_mp_setmaxid),
+#endif
        PLATFORMMETHOD_END,
 };
 

Copied and modified: head/sys/arm/allwinner/aw_mp.c (from r296425, 
head/sys/arm/allwinner/a20/a20_mp.c)
==============================================================================
--- head/sys/arm/allwinner/a20/a20_mp.c Sun Mar  6 08:52:03 2016        
(r296425, copy source)
+++ head/sys/arm/allwinner/aw_mp.c      Sun Mar  6 11:41:08 2016        
(r296426)
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2014 Ganbold Tsagaankhuu <ganb...@freebsd.org>
+ * Copyright (c) 2016 Emmanuel Vadot <m...@bidouilliste.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,53 +39,69 @@ __FBSDID("$FreeBSD$");
 #include <vm/pmap.h>
 
 #include <machine/cpu.h>
+#include <machine/cpu-v6.h>
 #include <machine/smp.h>
 #include <machine/fdt.h>
 #include <machine/intr.h>
+#include <machine/platformvar.h>
 
-#define        CPUCFG_BASE             0x01c25c00
+#include <arm/allwinner/aw_mp.h>
+#include <arm/allwinner/allwinner_machdep.h>
+
+/* Register for all dual-core SoC */
+#define        A20_CPUCFG_BASE         0x01c25c00
+/* Register for all quad-core SoC */
+#define        CPUCFG_BASE             0x01f01c00
 #define        CPUCFG_SIZE             0x400
+#define        PRCM_BASE               0x01f01400
+#define        PRCM_SIZE               0x800
+
+#define        CPU_OFFSET              0x40
+#define        CPU_OFFSET_CTL          0x04
+#define        CPU_OFFSET_STATUS       0x08
+#define        CPU_RST_CTL(cpuid)      ((cpuid + 1) * CPU_OFFSET)
+#define        CPU_CTL(cpuid)          (((cpuid + 1) * CPU_OFFSET) + 
CPU_OFFSET_CTL)
+#define        CPU_STATUS(cpuid)       (((cpuid + 1) * CPU_OFFSET) + 
CPU_OFFSET_STATUS)
+
+#define        CPU_RESET               (1 << 0)
+#define        CPU_CORE_RESET          (1 << 1)
 
-#define        CPU0_RST_CTL            0x40
-#define        CPU0_CTL                0x44
-#define        CPU0_STATUS             0x48
-#define        CPU1_RST_CTL            0x80
-#define        CPU1_CTL                0x84
-#define        CPU1_STATUS             0x88
 #define        CPUCFG_GENCTL           0x184
 #define        CPUCFG_P_REG0           0x1a4
-#define        CPU1_PWR_CLAMP          0x1b0
-#define        CPU1_PWROFF_REG         0x1b4
+
+#define        A20_CPU1_PWR_CLAMP      0x1b0
+#define        CPU_PWR_CLAMP_REG       0x140
+#define        CPU_PWR_CLAMP(cpu)      ((cpu * 4) + CPU_PWR_CLAMP_REG)
+#define        CPU_PWR_CLAMP_STEPS     8
+
+#define        A20_CPU1_PWROFF_REG     0x1b4
+#define        CPU_PWROFF              0x100
+
 #define        CPUCFG_DBGCTL0          0x1e0
 #define        CPUCFG_DBGCTL1          0x1e4
 
 void
-platform_mp_setmaxid(void)
+aw_mp_setmaxid(platform_t plat)
 {
        int ncpu;
+       uint32_t reg;
 
        if (mp_ncpus != 0)
                return;
 
-       /* Read the number of cores from the CP15 L2 Control Register. */
-       __asm __volatile("mrc p15, 1, %0, c9, c0, 2" : "=r" (ncpu));
-       ncpu = ((ncpu >> 24) & 0x3) + 1;
+       reg = cp15_l2ctlr_get();
+       ncpu = CPUV7_L2CTLR_NPROC(reg);
 
        mp_ncpus = ncpu;
        mp_maxid = ncpu - 1;
 }
 
-void
-platform_mp_start_ap(void)
+static void
+aw_common_mp_start_ap(bus_space_handle_t cpucfg, bus_space_handle_t prcm)
 {
-       bus_space_handle_t cpucfg;
-
+       int i, j;
        uint32_t val;
 
-       if (bus_space_map(fdtbus_bs_tag, CPUCFG_BASE, CPUCFG_SIZE, 0,
-           &cpucfg) != 0)
-               panic("Couldn't map the CPUCFG\n");
-
        dcache_wbinv_poc_all();
 
        bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_P_REG0,
@@ -95,44 +112,93 @@ platform_mp_start_ap(void)
         * Ensure DBGPWRDUP is set to LOW to prevent any external
         * debug access to the processor.
         */
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 0);
+       for (i = 1; i < mp_ncpus; i++)
+               bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU_RST_CTL(i), 0);
 
        /* Set L1RSTDISABLE low */
        val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL);
-       val &= ~(1 << 1);
+       for (i = 1; i < mp_ncpus; i++)
+               val &= ~(1 << i);
        bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL, val);
 
        /* Set DBGPWRDUP low */
        val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1);
-       val &= ~(1 << 1);
+       for (i = 1; i < mp_ncpus; i++)
+               val &= ~(1 << i);
        bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val);
 
        /* Release power clamp */
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0xff);
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x7f);
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x3f);
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x1f);
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x0f);
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x07);
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x03);
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x01);
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x00);
+       for (i = 1; i < mp_ncpus; i++)
+               for (j = 0; j <= CPU_PWR_CLAMP_STEPS; j++) {
+                       if (prcm) {
+                               bus_space_write_4(fdtbus_bs_tag, prcm,
+                                   CPU_PWR_CLAMP(i), 0xff >> j);
+                       } else {
+                               bus_space_write_4(fdtbus_bs_tag,
+                                   cpucfg, A20_CPU1_PWR_CLAMP, 0xff >> j);
+                       }
+               }
        DELAY(10000);
 
        /* Clear power-off gating */
-       val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG);
-       val &= ~(1 << 0);
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG, val);
+       if (prcm) {
+               val = bus_space_read_4(fdtbus_bs_tag, prcm, CPU_PWROFF);
+               for (i = 0; i < mp_ncpus; i++)
+                       val &= ~(1 << i);
+               bus_space_write_4(fdtbus_bs_tag, prcm, CPU_PWROFF, val);
+       } else {
+               val = bus_space_read_4(fdtbus_bs_tag,
+                   cpucfg, A20_CPU1_PWROFF_REG);
+               val &= ~(1 << 0);
+               bus_space_write_4(fdtbus_bs_tag, cpucfg,
+                   A20_CPU1_PWROFF_REG, val);
+       }
        DELAY(1000);
 
        /* De-assert cpu core reset */
-       bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 3);
+       for (i = 1; i < mp_ncpus; i++)
+               bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU_RST_CTL(i),
+                   CPU_RESET | CPU_CORE_RESET);
 
        /* Assert DBGPWRDUP signal */
        val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1);
-       val |= (1 << 1);
+       for (i = 1; i < mp_ncpus; i++)
+               val |= (1 << i);
        bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val);
 
        armv7_sev();
        bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE);
 }
+
+void
+a20_mp_start_ap(platform_t plat)
+{
+       bus_space_handle_t cpucfg;
+
+       if (bus_space_map(fdtbus_bs_tag, A20_CPUCFG_BASE, CPUCFG_SIZE,
+           0, &cpucfg) != 0)
+               panic("Couldn't map the CPUCFG\n");
+
+       aw_common_mp_start_ap(cpucfg, 0);
+       armv7_sev();
+       bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE);
+}
+
+void
+a31_mp_start_ap(platform_t plat)
+{
+       bus_space_handle_t cpucfg;
+       bus_space_handle_t prcm;
+
+       if (bus_space_map(fdtbus_bs_tag, CPUCFG_BASE, CPUCFG_SIZE,
+           0, &cpucfg) != 0)
+               panic("Couldn't map the CPUCFG\n");
+       if (bus_space_map(fdtbus_bs_tag, PRCM_BASE, PRCM_SIZE, 0,
+           &prcm) != 0)
+               panic("Couldn't map the PRCM\n");
+
+       aw_common_mp_start_ap(cpucfg, prcm);
+       armv7_sev();
+       bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE);
+       bus_space_unmap(fdtbus_bs_tag, prcm, PRCM_SIZE);
+}

Added: head/sys/arm/allwinner/aw_mp.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/allwinner/aw_mp.h      Sun Mar  6 11:41:08 2016        
(r296426)
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2016 Emmanuel Vadot <m...@bidouilliste.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _AW_MP_H_
+#define        _AW_MP_H_
+
+void aw_mp_setmaxid(platform_t plat);
+void a20_mp_start_ap(platform_t plat);
+void a31_mp_start_ap(platform_t plat);
+
+#endif /* _AW_MP_H_ */

Modified: head/sys/arm/conf/A20
==============================================================================
--- head/sys/arm/conf/A20       Sun Mar  6 08:52:03 2016        (r296425)
+++ head/sys/arm/conf/A20       Sun Mar  6 11:41:08 2016        (r296426)
@@ -31,6 +31,7 @@ options       HZ=100
 options        SCHED_ULE               # ULE scheduler
 options        SMP                     # Enable multiple cores
 options        PLATFORM
+options        PLATFORM_SMP
 
 # Debugging for use in -current
 makeoptions    DEBUG=-g                # Build kernel with gdb(1) debug symbols
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to