aw_mp.c revision 281092
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: head/sys/arm/allwinner/a20/a20_mp.c 281092 2015-04-04 23:03:11Z andrew $"); 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 <vm/vm.h> 37#include <vm/pmap.h> 38 39#include <machine/smp.h> 40#include <machine/fdt.h> 41#include <machine/intr.h> 42 43#define CPUCFG_BASE 0x01c25c00 44#define CPUCFG_SIZE 0x400 45 46#define CPU0_RST_CTL 0x40 47#define CPU0_CTL 0x44 48#define CPU0_STATUS 0x48 49#define CPU1_RST_CTL 0x80 50#define CPU1_CTL 0x84 51#define CPU1_STATUS 0x88 52#define CPUCFG_GENCTL 0x184 53#define CPUCFG_P_REG0 0x1a4 54#define CPU1_PWR_CLAMP 0x1b0 55#define CPU1_PWROFF_REG 0x1b4 56#define CPUCFG_DBGCTL0 0x1e0 57#define CPUCFG_DBGCTL1 0x1e4 58 59void 60platform_mp_init_secondary(void) 61{ 62 63 arm_init_secondary_ic(); 64} 65 66void 67platform_mp_setmaxid(void) 68{ 69 int ncpu; 70 71 if (mp_ncpus != 0) 72 return; 73 74 /* Read current CP15 Cache Size ID Register */ 75 __asm __volatile("mrc p15, 1, %0, c9, c0, 2" : "=r" (ncpu)); 76 ncpu = ((ncpu >> 24) & 0x3) + 1; 77 78 mp_ncpus = ncpu; 79 mp_maxid = ncpu - 1; 80} 81 82int 83platform_mp_probe(void) 84{ 85 86 if (mp_ncpus == 0) 87 platform_mp_setmaxid(); 88 89 return (mp_ncpus > 1); 90} 91 92void 93platform_mp_start_ap(void) 94{ 95 bus_space_handle_t cpucfg; 96 97 uint32_t val; 98 99 if (bus_space_map(fdtbus_bs_tag, CPUCFG_BASE, CPUCFG_SIZE, 0, 100 &cpucfg) != 0) 101 panic("Couldn't map the CPUCFG\n"); 102 103 cpu_idcache_wbinv_all(); 104 cpu_l2cache_wbinv_all(); 105 106 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_P_REG0, 107 pmap_kextract((vm_offset_t)mpentry)); 108 109 /* 110 * Assert nCOREPORESET low and set L1RSTDISABLE low. 111 * Ensure DBGPWRDUP is set to LOW to prevent any external 112 * debug access to the processor. 113 */ 114 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 0); 115 116 /* Set L1RSTDISABLE low */ 117 val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL); 118 val &= ~(1 << 1); 119 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL, val); 120 121 /* Set DBGPWRDUP low */ 122 val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); 123 val &= ~(1 << 1); 124 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); 125 126 /* Release power clamp */ 127 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0xff); 128 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x7f); 129 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x3f); 130 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x1f); 131 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x0f); 132 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x07); 133 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x03); 134 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x01); 135 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x00); 136 DELAY(10000); 137 138 /* Clear power-off gating */ 139 val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG); 140 val &= ~(1 << 0); 141 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG, val); 142 DELAY(1000); 143 144 /* De-assert cpu core reset */ 145 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 3); 146 147 /* Assert DBGPWRDUP signal */ 148 val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); 149 val |= (1 << 1); 150 bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); 151 152 armv7_sev(); 153 bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE); 154} 155 156void 157platform_ipi_send(cpuset_t cpus, u_int ipi) 158{ 159 160 pic_ipi_send(cpus, ipi); 161} 162