1/*- 2 * Copyright (c) 2013-2014 Ruslan Bukin <br@bsdpad.com> 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 AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_mp.c 307344 2016-10-15 08:27:54Z mmel $"); 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/bus.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/cpu.h> 40#include <machine/smp.h> 41#include <machine/fdt.h> 42#include <machine/intr.h> 43 44#define EXYNOS_CHIPID 0x10000000 45 46#define EXYNOS5250_SOC_ID 0x43520000 47#define EXYNOS5420_SOC_ID 0xE5420000 48#define EXYNOS5_SOC_ID_MASK 0xFFFFF000 49 50#define EXYNOS_SYSRAM 0x02020000 51#define EXYNOS5420_SYSRAM_NS (EXYNOS_SYSRAM + 0x53000 + 0x1c) 52 53#define EXYNOS_PMU_BASE 0x10040000 54#define CORE_CONFIG(n) (0x2000 + (0x80 * (n))) 55#define CORE_STATUS(n) (CORE_CONFIG(n) + 0x4) 56#define CORE_PWR_EN 0x3 57 58static int 59exynos_get_soc_id(void) 60{ 61 bus_addr_t chipid; 62 int reg; 63 64 if (bus_space_map(fdtbus_bs_tag, EXYNOS_CHIPID, 65 0x1000, 0, &chipid) != 0) 66 panic("Couldn't map chipid\n"); 67 reg = bus_space_read_4(fdtbus_bs_tag, chipid, 0x0); 68 bus_space_unmap(fdtbus_bs_tag, chipid, 0x1000); 69 70 return (reg & EXYNOS5_SOC_ID_MASK); 71} 72 73void 74platform_mp_setmaxid(void) 75{ 76 77 if (exynos_get_soc_id() == EXYNOS5420_SOC_ID) 78 mp_ncpus = 4; 79 else 80 mp_ncpus = 2; 81 82 mp_maxid = mp_ncpus - 1; 83} 84 85void 86platform_mp_start_ap(void) 87{ 88 bus_addr_t sysram, pmu; 89 int err, i, j; 90 int status; 91 int reg; 92 93 err = bus_space_map(fdtbus_bs_tag, EXYNOS_PMU_BASE, 0x20000, 0, &pmu); 94 if (err != 0) 95 panic("Couldn't map pmu\n"); 96 97 if (exynos_get_soc_id() == EXYNOS5420_SOC_ID) 98 reg = EXYNOS5420_SYSRAM_NS; 99 else 100 reg = EXYNOS_SYSRAM; 101 102 err = bus_space_map(fdtbus_bs_tag, reg, 0x100, 0, &sysram); 103 if (err != 0) 104 panic("Couldn't map sysram\n"); 105 106 /* Give power to CPUs */ 107 for (i = 1; i < mp_ncpus; i++) { 108 bus_space_write_4(fdtbus_bs_tag, pmu, CORE_CONFIG(i), 109 CORE_PWR_EN); 110 111 for (j = 10; j >= 0; j--) { 112 status = bus_space_read_4(fdtbus_bs_tag, pmu, 113 CORE_STATUS(i)); 114 if ((status & CORE_PWR_EN) == CORE_PWR_EN) 115 break; 116 DELAY(10); 117 if (j == 0) 118 printf("Can't power on CPU%d\n", i); 119 } 120 } 121 122 bus_space_write_4(fdtbus_bs_tag, sysram, 0x0, 123 pmap_kextract((vm_offset_t)mpentry)); 124 125 dcache_wbinv_poc_all(); 126 127 dsb(); 128 sev(); 129 bus_space_unmap(fdtbus_bs_tag, sysram, 0x100); 130 bus_space_unmap(fdtbus_bs_tag, pmu, 0x20000); 131} 132