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 =================================================================== --- sys/arm/allwinner/aw_mp.c +++ sys/arm/allwinner/aw_mp.c @@ -42,19 +42,31 @@ #include #include -#define CPUCFG_BASE 0x01c25c00 +/* 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 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 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 @@ -95,12 +107,23 @@ 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"); + bus_space_handle_t prcm; + int i, j; + uint32_t val; + + if (mp_ncpus == 2) { + if (bus_space_map(fdtbus_bs_tag, A20_CPUCFG_BASE, CPUCFG_SIZE, 0, + &cpucfg) != 0) + panic("Couldn't map the CPUCFG\n"); + } else if (mp_ncpus == 4) { + 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"); + } else + panic("Couldn't find the right number of CPUs\n"); dcache_wbinv_poc_all(); @@ -112,42 +135,59 @@ * 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); - 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); + if (mp_ncpus == 2) { + /* 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); + } else if (mp_ncpus == 4) { + /* 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 */ - 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), 3); /* 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();