1252391Sray/*- 2267388Sbr * Copyright (c) 2013-2014 Ruslan Bukin <br@bsdpad.com> 3252391Sray * All rights reserved. 4252391Sray * 5252391Sray * Redistribution and use in source and binary forms, with or without 6252391Sray * modification, are permitted provided that the following conditions 7252391Sray * are met: 8252391Sray * 1. Redistributions of source code must retain the above copyright 9252391Sray * notice, this list of conditions and the following disclaimer. 10252391Sray * 2. Redistributions in binary form must reproduce the above copyright 11252391Sray * notice, this list of conditions and the following disclaimer in the 12252391Sray * documentation and/or other materials provided with the distribution. 13252391Sray * 14252391Sray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15252391Sray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16252391Sray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17252391Sray * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18252391Sray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19252391Sray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20252391Sray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21252391Sray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22252391Sray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23252391Sray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24252391Sray * SUCH DAMAGE. 25252391Sray */ 26252391Sray 27252391Sray#include <sys/cdefs.h> 28252391Sray__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_mp.c 307344 2016-10-15 08:27:54Z mmel $"); 29252391Sray#include <sys/param.h> 30252391Sray#include <sys/systm.h> 31252391Sray#include <sys/bus.h> 32252391Sray#include <sys/lock.h> 33252391Sray#include <sys/mutex.h> 34252391Sray#include <sys/smp.h> 35252391Sray 36281092Sandrew#include <vm/vm.h> 37281092Sandrew#include <vm/pmap.h> 38281092Sandrew 39295319Smmel#include <machine/cpu.h> 40252391Sray#include <machine/smp.h> 41252391Sray#include <machine/fdt.h> 42252391Sray#include <machine/intr.h> 43252391Sray 44267388Sbr#define EXYNOS_CHIPID 0x10000000 45252391Sray 46267388Sbr#define EXYNOS5250_SOC_ID 0x43520000 47267388Sbr#define EXYNOS5420_SOC_ID 0xE5420000 48267388Sbr#define EXYNOS5_SOC_ID_MASK 0xFFFFF000 49267388Sbr 50267388Sbr#define EXYNOS_SYSRAM 0x02020000 51267388Sbr#define EXYNOS5420_SYSRAM_NS (EXYNOS_SYSRAM + 0x53000 + 0x1c) 52267388Sbr 53267388Sbr#define EXYNOS_PMU_BASE 0x10040000 54267388Sbr#define CORE_CONFIG(n) (0x2000 + (0x80 * (n))) 55267388Sbr#define CORE_STATUS(n) (CORE_CONFIG(n) + 0x4) 56267388Sbr#define CORE_PWR_EN 0x3 57267388Sbr 58267388Sbrstatic int 59267388Sbrexynos_get_soc_id(void) 60267388Sbr{ 61267388Sbr bus_addr_t chipid; 62267388Sbr int reg; 63267388Sbr 64267388Sbr if (bus_space_map(fdtbus_bs_tag, EXYNOS_CHIPID, 65267388Sbr 0x1000, 0, &chipid) != 0) 66267388Sbr panic("Couldn't map chipid\n"); 67267388Sbr reg = bus_space_read_4(fdtbus_bs_tag, chipid, 0x0); 68267388Sbr bus_space_unmap(fdtbus_bs_tag, chipid, 0x1000); 69267388Sbr 70267388Sbr return (reg & EXYNOS5_SOC_ID_MASK); 71267388Sbr} 72267388Sbr 73252391Srayvoid 74252391Srayplatform_mp_setmaxid(void) 75252391Sray{ 76252391Sray 77267388Sbr if (exynos_get_soc_id() == EXYNOS5420_SOC_ID) 78267388Sbr mp_ncpus = 4; 79267388Sbr else 80267388Sbr mp_ncpus = 2; 81267388Sbr 82267388Sbr mp_maxid = mp_ncpus - 1; 83252391Sray} 84252391Sray 85252391Srayvoid 86252391Srayplatform_mp_start_ap(void) 87252391Sray{ 88267388Sbr bus_addr_t sysram, pmu; 89267388Sbr int err, i, j; 90267388Sbr int status; 91267388Sbr int reg; 92252391Sray 93267388Sbr err = bus_space_map(fdtbus_bs_tag, EXYNOS_PMU_BASE, 0x20000, 0, &pmu); 94252391Sray if (err != 0) 95267388Sbr panic("Couldn't map pmu\n"); 96267388Sbr 97267388Sbr if (exynos_get_soc_id() == EXYNOS5420_SOC_ID) 98267388Sbr reg = EXYNOS5420_SYSRAM_NS; 99267388Sbr else 100267388Sbr reg = EXYNOS_SYSRAM; 101267388Sbr 102267388Sbr err = bus_space_map(fdtbus_bs_tag, reg, 0x100, 0, &sysram); 103267388Sbr if (err != 0) 104252391Sray panic("Couldn't map sysram\n"); 105252391Sray 106267388Sbr /* Give power to CPUs */ 107267388Sbr for (i = 1; i < mp_ncpus; i++) { 108267388Sbr bus_space_write_4(fdtbus_bs_tag, pmu, CORE_CONFIG(i), 109267388Sbr CORE_PWR_EN); 110267388Sbr 111267388Sbr for (j = 10; j >= 0; j--) { 112267388Sbr status = bus_space_read_4(fdtbus_bs_tag, pmu, 113267388Sbr CORE_STATUS(i)); 114267388Sbr if ((status & CORE_PWR_EN) == CORE_PWR_EN) 115267388Sbr break; 116267388Sbr DELAY(10); 117267388Sbr if (j == 0) 118267388Sbr printf("Can't power on CPU%d\n", i); 119267388Sbr } 120267388Sbr } 121267388Sbr 122252391Sray bus_space_write_4(fdtbus_bs_tag, sysram, 0x0, 123252391Sray pmap_kextract((vm_offset_t)mpentry)); 124252391Sray 125295319Smmel dcache_wbinv_poc_all(); 126252391Sray 127307344Smmel dsb(); 128307344Smmel sev(); 129252391Sray bus_space_unmap(fdtbus_bs_tag, sysram, 0x100); 130267388Sbr bus_space_unmap(fdtbus_bs_tag, pmu, 0x20000); 131252391Sray} 132