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 --- 9 unchanged lines hidden (view full) --- 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: head/sys/arm/samsung/exynos/exynos5_mp.c 267388 2014-06-12 11:37:38Z br $"); |
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 <machine/smp.h> 37#include <machine/fdt.h> 38#include <machine/intr.h> 39 |
40#define EXYNOS_CHIPID 0x10000000 |
41 |
42#define EXYNOS5250_SOC_ID 0x43520000 43#define EXYNOS5420_SOC_ID 0xE5420000 44#define EXYNOS5_SOC_ID_MASK 0xFFFFF000 45 46#define EXYNOS_SYSRAM 0x02020000 47#define EXYNOS5420_SYSRAM_NS (EXYNOS_SYSRAM + 0x53000 + 0x1c) 48 49#define EXYNOS_PMU_BASE 0x10040000 50#define CORE_CONFIG(n) (0x2000 + (0x80 * (n))) 51#define CORE_STATUS(n) (CORE_CONFIG(n) + 0x4) 52#define CORE_PWR_EN 0x3 53 54static int 55exynos_get_soc_id(void) 56{ 57 bus_addr_t chipid; 58 int reg; 59 60 if (bus_space_map(fdtbus_bs_tag, EXYNOS_CHIPID, 61 0x1000, 0, &chipid) != 0) 62 panic("Couldn't map chipid\n"); 63 reg = bus_space_read_4(fdtbus_bs_tag, chipid, 0x0); 64 bus_space_unmap(fdtbus_bs_tag, chipid, 0x1000); 65 66 return (reg & EXYNOS5_SOC_ID_MASK); 67} 68 |
69void 70platform_mp_init_secondary(void) 71{ 72 73 gic_init_secondary(); 74} 75 76void 77platform_mp_setmaxid(void) 78{ 79 |
80 if (exynos_get_soc_id() == EXYNOS5420_SOC_ID) 81 mp_ncpus = 4; 82 else 83 mp_ncpus = 2; 84 85 mp_maxid = mp_ncpus - 1; |
86} 87 88int 89platform_mp_probe(void) 90{ 91 |
92 return (mp_ncpus > 1); |
93} 94 95void 96platform_mp_start_ap(void) 97{ |
98 bus_addr_t sysram, pmu; 99 int err, i, j; 100 int status; 101 int reg; |
102 |
103 err = bus_space_map(fdtbus_bs_tag, EXYNOS_PMU_BASE, 0x20000, 0, &pmu); |
104 if (err != 0) |
105 panic("Couldn't map pmu\n"); 106 107 if (exynos_get_soc_id() == EXYNOS5420_SOC_ID) 108 reg = EXYNOS5420_SYSRAM_NS; 109 else 110 reg = EXYNOS_SYSRAM; 111 112 err = bus_space_map(fdtbus_bs_tag, reg, 0x100, 0, &sysram); 113 if (err != 0) |
114 panic("Couldn't map sysram\n"); 115 |
116 /* Give power to CPUs */ 117 for (i = 1; i < mp_ncpus; i++) { 118 bus_space_write_4(fdtbus_bs_tag, pmu, CORE_CONFIG(i), 119 CORE_PWR_EN); 120 121 for (j = 10; j >= 0; j--) { 122 status = bus_space_read_4(fdtbus_bs_tag, pmu, 123 CORE_STATUS(i)); 124 if ((status & CORE_PWR_EN) == CORE_PWR_EN) 125 break; 126 DELAY(10); 127 if (j == 0) 128 printf("Can't power on CPU%d\n", i); 129 } 130 } 131 |
132 bus_space_write_4(fdtbus_bs_tag, sysram, 0x0, 133 pmap_kextract((vm_offset_t)mpentry)); 134 135 cpu_idcache_wbinv_all(); 136 cpu_l2cache_wbinv_all(); 137 138 armv7_sev(); 139 bus_space_unmap(fdtbus_bs_tag, sysram, 0x100); |
140 bus_space_unmap(fdtbus_bs_tag, pmu, 0x20000); |
141} 142 143void 144platform_ipi_send(cpuset_t cpus, u_int ipi) 145{ 146 147 pic_ipi_send(cpus, ipi); 148} |