a20_mp.c revision 266337
1/*- 2 * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> 27__FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a20/a20_mp.c 266337 2014-05-17 18:53:36Z ian $"); 28#include <sys/param.h> 29#include <sys/systm.h> 30#include <sys/bus.h> 31#include <sys/kernel.h> 32#include <sys/lock.h> 33#include <sys/mutex.h> 34#include <sys/smp.h> 35 36#include <machine/smp.h> 37#include <machine/fdt.h> 38#include <machine/intr.h> 39 40#define CPUCFG_BASE 0x01c25c00 41#define CPUCFG_SIZE 0x400 42 43#define CPU0_RST_CTL 0x40 44#define CPU0_CTL 0x44 45#define CPU0_STATUS 0x48 46#define CPU1_RST_CTL 0x80 47#define CPU1_CTL 0x84 48#define CPU1_STATUS 0x88 49#define CPUCFG_GENCTL 0x184 50#define CPUCFG_P_REG0 0x1a4 51#define CPU1_PWR_CLAMP 0x1b0 52#define CPU1_PWROFF_REG 0x1b4 53#define CPUCFG_DBGCTL0 0x1e0 54#define CPUCFG_DBGCTL1 0x1e4 55 56void 57platform_mp_init_secondary(void) 58{ 59 60 gic_init_secondary(); 61} 62 63void 64platform_mp_setmaxid(void) 65{ 66 int ncpu; 67 68 if (mp_ncpus != 0) 69 return; 70 71 /* Read current CP15 Cache Size ID Register */ 72 __asm __volatile("mrc p15, 1, %0, c9, c0, 2" : "=r" (ncpu)); 73 ncpu = ((ncpu >> 24) & 0x3) + 1; 74 75 mp_ncpus = ncpu; 76 mp_maxid = ncpu - 1; 77} 78 79int 80platform_mp_probe(void) 81{ 82 83 if (mp_ncpus == 0) 84 platform_mp_setmaxid(); 85 86 return (mp_ncpus > 1); 87} 88 89void 90platform_mp_start_ap(void) 91{ 92 bus_space_handle_t cpucfg; 93 94 uint32_t val; 95 96 if (bus_space_map(fdtbus_bs_tag, CPUCFG_BASE, CPUCFG_SIZE, 0, 97 &cpucfg) != 0) 98 panic("Couldn't map the CPUCFG\n"); 99 100 cpu_idcache_wbinv_all(); 101 cpu_l2cache_wbinv_all(); 102 103 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_P_REG0, 104 pmap_kextract((vm_offset_t)mpentry)); 105 106 /* 107 * Assert nCOREPORESET low and set L1RSTDISABLE low. 108 * Ensure DBGPWRDUP is set to LOW to prevent any external 109 * debug access to the processor. 110 */ 111 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 0); 112 113 /* Set L1RSTDISABLE low */ 114 val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL); 115 val &= ~(1 << 1); 116 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL, val); 117 118 /* Set DBGPWRDUP low */ 119 val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); 120 val &= ~(1 << 1); 121 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); 122 123 /* Release power clamp */ 124 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0xff); 125 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x7f); 126 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x3f); 127 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x1f); 128 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x0f); 129 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x07); 130 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x03); 131 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x01); 132 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x00); 133 DELAY(10000); 134 135 /* Clear power-off gating */ 136 val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG); 137 val &= ~(1 << 0); 138 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG, val); 139 DELAY(1000); 140 141 /* De-assert cpu core reset */ 142 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 3); 143 144 /* Assert DBGPWRDUP signal */ 145 val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); 146 val |= (1 << 1); 147 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); 148 149 armv7_sev(); 150 bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE); 151} 152 153void 154platform_ipi_send(cpuset_t cpus, u_int ipi) 155{ 156 157 pic_ipi_send(cpus, ipi); 158} 159