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