From owner-svn-src-head@freebsd.org Sun Mar 6 11:41:10 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1142DA95F7E; Sun, 6 Mar 2016 11:41:10 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E0F1BF9; Sun, 6 Mar 2016 11:41:09 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u26Bf8P3055835; Sun, 6 Mar 2016 11:41:08 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u26Bf8EW055830; Sun, 6 Mar 2016 11:41:08 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <201603061141.u26Bf8EW055830@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Sun, 6 Mar 2016 11:41:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r296426 - in head/sys/arm: allwinner allwinner/a20 conf X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 06 Mar 2016 11:41:10 -0000 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 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 +#include #include #include @@ -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 + * Copyright (c) 2016 Emmanuel Vadot * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,53 +39,69 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include +#include -#define CPUCFG_BASE 0x01c25c00 +#include +#include + +/* 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 + * 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