svn commit: r296426 - in head/sys/arm: allwinner allwinner/a20 conf

Andrew Turner andrew at FreeBSD.org
Sun Mar 6 11:41:10 UTC 2016


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 <manu at 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 <ganbold at freebsd.org>
+ * Copyright (c) 2016 Emmanuel Vadot <manu at 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 <manu at 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


More information about the svn-src-all mailing list