Index: sys/arm/allwinner/a20/a20_mp.c =================================================================== --- sys/arm/allwinner/a20/a20_mp.c +++ /dev/null @@ -1,162 +0,0 @@ -/*- - * Copyright (c) 2014 Ganbold Tsagaankhuu - * 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. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#define CPUCFG_BASE 0x01c25c00 -#define CPUCFG_SIZE 0x400 - -#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 CPUCFG_DBGCTL0 0x1e0 -#define CPUCFG_DBGCTL1 0x1e4 - -void -platform_mp_init_secondary(void) -{ - - intr_pic_init_secondary(); -} - -void -platform_mp_setmaxid(void) -{ - int ncpu; - - 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; - - mp_ncpus = ncpu; - mp_maxid = ncpu - 1; -} - -int -platform_mp_probe(void) -{ - - if (mp_ncpus == 0) - platform_mp_setmaxid(); - - return (mp_ncpus > 1); -} - -void -platform_mp_start_ap(void) -{ - bus_space_handle_t cpucfg; - - 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, - pmap_kextract((vm_offset_t)mpentry)); - - /* - * Assert nCOREPORESET low and set L1RSTDISABLE low. - * 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); - - /* Set L1RSTDISABLE low */ - val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL); - val &= ~(1 << 1); - 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); - 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); - 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); - DELAY(1000); - - /* De-assert cpu core reset */ - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 3); - - /* Assert DBGPWRDUP signal */ - val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); - val |= (1 << 1); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); - - armv7_sev(); - bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE); -} - -void -platform_ipi_send(cpuset_t cpus, u_int ipi) -{ - - pic_ipi_send(cpus, ipi); -} Index: sys/arm/allwinner/a20/files.a20 =================================================================== --- sys/arm/allwinner/a20/files.a20 +++ sys/arm/allwinner/a20/files.a20 @@ -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 Index: sys/arm/allwinner/aw_mp.c =================================================================== --- /dev/null +++ sys/arm/allwinner/aw_mp.c @@ -0,0 +1,259 @@ +/*- + * Copyright (c) 2014 Ganbold Tsagaankhuu + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +/* Register for all dual-core SoC */ +#define A20_CPUCFG_BASE 0x01c25c00 +/* Register for all quad-core SoC */ +#define A31_CPUCFG_BASE 0x01f01c00 +#define CPUCFG_SIZE 0x400 +#define A31_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 CPUCFG_GENCTL 0x184 +#define CPUCFG_P_REG0 0x1a4 + +#define A20_CPU1_PWR_CLAMP 0x1b0 +#define A31_CPU_PWR_CLAMP_REG 0x140 +#define A31_CPU_PWR_CLAMP(cpu) ((cpu * 4) + A31_CPU_PWR_CLAMP_REG) + +#define A20_CPU1_PWROFF_REG 0x1b4 +#define A31_CPU_PWROFF 0x100 + +#define CPUCFG_DBGCTL0 0x1e0 +#define CPUCFG_DBGCTL1 0x1e4 + +void +platform_mp_init_secondary(void) +{ + + intr_pic_init_secondary(); +} + +void +platform_mp_setmaxid(void) +{ + int ncpu; + + 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; + + mp_ncpus = ncpu; + mp_maxid = ncpu - 1; +} + +int +platform_mp_probe(void) +{ + + if (mp_ncpus == 0) + platform_mp_setmaxid(); + + return (mp_ncpus > 1); +} + +static void +platform_mp_a20_start_ap(void) +{ + bus_space_handle_t cpucfg; + int i, j; + uint32_t val; + + if (bus_space_map(fdtbus_bs_tag, A20_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, + pmap_kextract((vm_offset_t)mpentry)); + + /* + * Assert nCOREPORESET low and set L1RSTDISABLE low. + * Ensure DBGPWRDUP is set to LOW to prevent any external + * debug access to the processor. + */ + 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); + 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); + for (i = 1; i < mp_ncpus; i++) + val &= ~(1 << i); + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); + + /* Release power clamp */ + for (j = 0; j <= 8; j++) + 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, 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 */ + for (i = 1; i < mp_ncpus; i++) + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU_RST_CTL(i), 3); + + /* Assert DBGPWRDUP signal */ + val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); + 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); +} + +static void +platform_mp_a31_start_ap(void) +{ + bus_space_handle_t cpucfg; + bus_space_handle_t prcm; + int i, j; + uint32_t val; + + if (bus_space_map(fdtbus_bs_tag, A31_CPUCFG_BASE, CPUCFG_SIZE, 0, + &cpucfg) != 0) + panic("Couldn't map the CPUCFG\n"); + if (bus_space_map(fdtbus_bs_tag, A31_PRCM_BASE, PRCM_SIZE, 0, + &prcm) != 0) + panic("Couldn't map the PRCM\n"); + + dcache_wbinv_poc_all(); + + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_P_REG0, + pmap_kextract((vm_offset_t)mpentry)); + + /* + * Assert nCOREPORESET low and set L1RSTDISABLE low. + * Ensure DBGPWRDUP is set to LOW to prevent any external + * debug access to the processor. + */ + 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); + 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); + for (i = 1; i < mp_ncpus; i++) + val &= ~(1 << i); + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); + + /* Release power clamp */ + for (i = 1; i < mp_ncpus; i++) + for (j = 0; j <= 8; j++) + bus_space_write_4(fdtbus_bs_tag, + prcm, + A31_CPU_PWR_CLAMP(i), + 0xff >> j); + DELAY(10000); + /* Clear power-off gating */ + val = bus_space_read_4(fdtbus_bs_tag, prcm, A31_CPU_PWROFF); + for (i = 0; i < mp_ncpus; i++) + val &= ~(1 << i); + bus_space_write_4(fdtbus_bs_tag, prcm, A31_CPU_PWROFF, val); + DELAY(1000); + + /* De-assert cpu core reset */ + for (i = 1; i < mp_ncpus; i++) + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU_RST_CTL(i), 3); + + /* Assert DBGPWRDUP signal */ + val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); + 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 +platform_mp_start_ap(void) +{ + switch (allwinner_soc_type()) { + case ALLWINNERSOC_A20: + platform_mp_a20_start_ap(); + break; + case ALLWINNERSOC_A31: + case ALLWINNERSOC_A31S: + platform_mp_a31_start_ap(); + break; + } +} + +void +platform_ipi_send(cpuset_t cpus, u_int ipi) +{ + + pic_ipi_send(cpus, ipi); +}