Thu Jan 3 14:44:21 2019 UTC ()
Add Allwinner A80 SMP support.


(jmcneill)
diff -r1.58 -r1.59 src/sys/arch/arm/sunxi/files.sunxi
diff -r1.2 -r1.3 src/sys/arch/arm/sunxi/sunxi_mc_smp.c
diff -r1.1 -r1.2 src/sys/arch/arm/sunxi/sunxi_mc_smp.h
diff -r1.33 -r1.34 src/sys/arch/arm/sunxi/sunxi_platform.c

cvs diff -r1.58 -r1.59 src/sys/arch/arm/sunxi/files.sunxi (expand / switch to unified diff)

--- src/sys/arch/arm/sunxi/files.sunxi 2019/01/03 11:01:59 1.58
+++ src/sys/arch/arm/sunxi/files.sunxi 2019/01/03 14:44:21 1.59
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: files.sunxi,v 1.58 2019/01/03 11:01:59 jmcneill Exp $ 1# $NetBSD: files.sunxi,v 1.59 2019/01/03 14:44:21 jmcneill Exp $
2# 2#
3# Configuration info for Allwinner sunxi family SoCs 3# Configuration info for Allwinner sunxi family SoCs
4# 4#
5# 5#
6 6
7file arch/arm/sunxi/sunxi_platform.c soc_sunxi 7file arch/arm/sunxi/sunxi_platform.c soc_sunxi
8 8
9file arch/arm/sunxi/sunxi_mc_smp.c soc_sunxi_mc 9file arch/arm/sunxi/sunxi_mc_smp.c soc_sunxi_mc
10file arch/arm/sunxi/sunxi_mc_mpstart.S soc_sunxi_mc 10file arch/arm/sunxi/sunxi_mc_mpstart.S soc_sunxi_mc
11 11
12# CCU 12# CCU
13define sunxi_ccu 13define sunxi_ccu
14file arch/arm/sunxi/sunxi_ccu.c sunxi_ccu 14file arch/arm/sunxi/sunxi_ccu.c sunxi_ccu
@@ -302,18 +302,18 @@ defflag opt_soc.h SOC_SUNXI @@ -302,18 +302,18 @@ defflag opt_soc.h SOC_SUNXI
302defflag opt_soc.h SOC_SUNXI_MC 302defflag opt_soc.h SOC_SUNXI_MC
303defflag opt_soc.h SOC_SUN4I: SOC_SUNXI 303defflag opt_soc.h SOC_SUN4I: SOC_SUNXI
304defflag opt_soc.h SOC_SUN4I_A10: SOC_SUN4I 304defflag opt_soc.h SOC_SUN4I_A10: SOC_SUN4I
305defflag opt_soc.h SOC_SUN5I: SOC_SUNXI 305defflag opt_soc.h SOC_SUN5I: SOC_SUNXI
306defflag opt_soc.h SOC_SUN5I_A13: SOC_SUN5I 306defflag opt_soc.h SOC_SUN5I_A13: SOC_SUN5I
307defflag opt_soc.h SOC_SUN6I: SOC_SUNXI 307defflag opt_soc.h SOC_SUN6I: SOC_SUNXI
308defflag opt_soc.h SOC_SUN6I_A31: SOC_SUN6I 308defflag opt_soc.h SOC_SUN6I_A31: SOC_SUN6I
309defflag opt_soc.h SOC_SUN7I: SOC_SUNXI 309defflag opt_soc.h SOC_SUN7I: SOC_SUNXI
310defflag opt_soc.h SOC_SUN7I_A20: SOC_SUN7I 310defflag opt_soc.h SOC_SUN7I_A20: SOC_SUN7I
311defflag opt_soc.h SOC_SUN8I: SOC_SUNXI 311defflag opt_soc.h SOC_SUN8I: SOC_SUNXI
312defflag opt_soc.h SOC_SUN8I_A83T: SOC_SUN8I, SOC_SUNXI_MC 312defflag opt_soc.h SOC_SUN8I_A83T: SOC_SUN8I, SOC_SUNXI_MC
313defflag opt_soc.h SOC_SUN8I_H3: SOC_SUN8I 313defflag opt_soc.h SOC_SUN8I_H3: SOC_SUN8I
314defflag opt_soc.h SOC_SUN9I: SOC_SUNXI 314defflag opt_soc.h SOC_SUN9I: SOC_SUNXI
315defflag opt_soc.h SOC_SUN9I_A80: SOC_SUN9I 315defflag opt_soc.h SOC_SUN9I_A80: SOC_SUN9I, SOC_SUNXI_MC
316defflag opt_soc.h SOC_SUN50I: SOC_SUNXI 316defflag opt_soc.h SOC_SUN50I: SOC_SUNXI
317defflag opt_soc.h SOC_SUN50I_A64: SOC_SUN50I 317defflag opt_soc.h SOC_SUN50I_A64: SOC_SUN50I
318defflag opt_soc.h SOC_SUN50I_H5: SOC_SUN50I, SOC_SUN8I_H3 318defflag opt_soc.h SOC_SUN50I_H5: SOC_SUN50I, SOC_SUN8I_H3
319defflag opt_soc.h SOC_SUN50I_H6: SOC_SUN50I 319defflag opt_soc.h SOC_SUN50I_H6: SOC_SUN50I

cvs diff -r1.2 -r1.3 src/sys/arch/arm/sunxi/sunxi_mc_smp.c (expand / switch to unified diff)

--- src/sys/arch/arm/sunxi/sunxi_mc_smp.c 2019/01/03 12:52:40 1.2
+++ src/sys/arch/arm/sunxi/sunxi_mc_smp.c 2019/01/03 14:44:21 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sunxi_mc_smp.c,v 1.2 2019/01/03 12:52:40 jmcneill Exp $ */ 1/* $NetBSD: sunxi_mc_smp.c,v 1.3 2019/01/03 14:44:21 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -18,186 +18,246 @@ @@ -18,186 +18,246 @@
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30 30
31__KERNEL_RCSID(0, "$NetBSD: sunxi_mc_smp.c,v 1.2 2019/01/03 12:52:40 jmcneill Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: sunxi_mc_smp.c,v 1.3 2019/01/03 14:44:21 jmcneill Exp $");
32 32
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/bus.h> 34#include <sys/bus.h>
35#include <sys/device.h> 35#include <sys/device.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37 37
38#include <uvm/uvm_extern.h> 38#include <uvm/uvm_extern.h>
39 39
40#include <dev/fdt/fdtvar.h> 40#include <dev/fdt/fdtvar.h>
41 41
42#include <arm/armreg.h> 42#include <arm/armreg.h>
43#include <arm/cpu.h> 43#include <arm/cpu.h>
44#include <arm/cpufunc.h> 44#include <arm/cpufunc.h>
45#include <arm/locore.h> 45#include <arm/locore.h>
46 46
47#include <arm/sunxi/sunxi_mc_smp.h> 47#include <arm/sunxi/sunxi_mc_smp.h>
48 48
49#define A83T_SMP_ENABLE_METHOD "allwinner,sun8i-a83t-smp" 49#define A80_PRCM_BASE 0x08001400
 50#define A80_PRCM_SIZE 0x200
50 51
51#define PRCM_BASE 0x01f01400 52#define A83T_PRCM_BASE 0x01f01400
52#define PRCM_SIZE 0x800 53#define A83T_PRCM_SIZE 0x800
53 54
54#define PRCM_CL_RST_CTRL(cluster) (0x4 + (cluster) * 0x4) 55#define PRCM_CL_RST_CTRL(cluster) (0x4 + (cluster) * 0x4)
55#define PRCM_CL_PWROFF(cluster) (0x100 + (cluster) * 0x4) 56#define PRCM_CL_PWROFF(cluster) (0x100 + (cluster) * 0x4)
56#define PRCM_CL_PWR_CLAMP(cluster, cpu) (0x140 + (cluster) * 0x10 + (cpu) * 0x4) 57#define PRCM_CL_PWR_CLAMP(cluster, cpu) (0x140 + (cluster) * 0x10 + (cpu) * 0x4)
 58#define PRCM_CPU_SOFT_ENTRY 0x164
57 59
58#define CPUCFG_BASE 0x01f01c00 60#define CPUCFG_BASE 0x01f01c00
59#define CPUCFG_SIZE 0x400 61#define CPUCFG_SIZE 0x400
60 62
61#define CPUCFG_CL_RST(cluster) (0x30 + (cluster) * 0x4) 63#define CPUCFG_CL_RST(cluster) (0x30 + (cluster) * 0x4)
62#define CPUCFG_P_REG0 0x1a4 64#define CPUCFG_P_REG0 0x1a4
63 65
64#define CPUXCFG_BASE 0x01700000 66#define CPUXCFG_BASE 0x01700000
65#define CPUXCFG_SIZE 0x400 67#define CPUXCFG_SIZE 0x400
66 68
67#define CPUXCFG_CL_RST(cluster) (0x80 + (cluster) * 0x4) 69#define CPUXCFG_CL_RST(cluster) (0x80 + (cluster) * 0x4)
68#define CPUXCFG_CL_RST_SOC_DBG_RST __BIT(24) 70#define CPUXCFG_CL_RST_SOC_DBG_RST __BIT(24)
69#define CPUXCFG_CL_RST_ETM_RST(cpu) __BIT(20 + (cpu)) 71#define CPUXCFG_CL_RST_ETM_RST(cpu) __BIT(20 + (cpu))
70#define CPUXCFG_CL_RST_DBG_RST(cpu) __BIT(16 + (cpu)) 72#define CPUXCFG_CL_RST_DBG_RST(cpu) __BIT(16 + (cpu))
71#define CPUXCFG_CL_RST_H_RST __BIT(12) 73#define CPUXCFG_CL_RST_H_RST __BIT(12)
72#define CPUXCFG_CL_RST_L2_RST __BIT(8) 74#define CPUXCFG_CL_RST_L2_RST __BIT(8)
 75#define CPUXCFG_CL_RST_CX_RST(cpu) __BIT(4 + (cpu))
73#define CPUXCFG_CL_CTRL0(cluster) (0x0 + (cluster) * 0x10) 76#define CPUXCFG_CL_CTRL0(cluster) (0x0 + (cluster) * 0x10)
74#define CPUXCFG_CL_CTRL1(cluster) (0x4 + (cluster) * 0x10) 77#define CPUXCFG_CL_CTRL1(cluster) (0x4 + (cluster) * 0x10)
75#define CPUXCFG_CL_CTRL1_ACINACTM __BIT(0) 78#define CPUXCFG_CL_CTRL1_ACINACTM __BIT(0)
76 79
77#define CCI_BASE 0x01790000 80#define A80_CCI_BASE 0x01c90000
78#define CCI_SLAVEIF3_BASE (CCI_BASE + 0x4000) 81#define A83T_CCI_BASE 0x01790000
79#define CCI_SLAVEIF4_BASE (CCI_BASE + 0x5000) 82
 83#define CCI_SLAVEIF3_OFFSET 0x4000
 84#define CCI_SLAVEIF4_OFFSET 0x5000
80 85
81extern struct bus_space arm_generic_bs_tag; 86extern struct bus_space arm_generic_bs_tag;
82 87
83uint32_t sunxi_mc_cci_port[MAXCPUS] = { 88enum sunxi_mc_soc {
84 CCI_SLAVEIF3_BASE, 89 MC_SOC_A80,
85 CCI_SLAVEIF3_BASE, 90 MC_SOC_A83T
86 CCI_SLAVEIF3_BASE, 91};
87 CCI_SLAVEIF3_BASE, 92
88 CCI_SLAVEIF4_BASE, 93enum sunxi_mc_cpu {
89 CCI_SLAVEIF4_BASE, 94 MC_CORE_CA7,
90 CCI_SLAVEIF4_BASE, 95 MC_CORE_CA15
91 CCI_SLAVEIF4_BASE, 
92}; 96};
93 97
 98uint32_t sunxi_mc_cci_port[MAXCPUS];
 99
94static uint32_t 100static uint32_t
95sunxi_mc_smp_pa(void) 101sunxi_mc_smp_pa(void)
96{ 102{
97 extern void sunxi_mc_mpstart(void); 103 extern void sunxi_mc_mpstart(void);
98 bool ok __diagused; 104 bool ok __diagused;
99 paddr_t pa; 105 paddr_t pa;
100 106
101 ok = pmap_extract(pmap_kernel(), (vaddr_t)sunxi_mc_mpstart, &pa); 107 ok = pmap_extract(pmap_kernel(), (vaddr_t)sunxi_mc_mpstart, &pa);
102 KASSERT(ok); 108 KASSERT(ok);
103 109
104 return pa; 110 return pa;
105} 111}
106 112
107static int 113static int
108sunxi_mc_smp_start(bus_space_tag_t bst, bus_space_handle_t prcm, bus_space_handle_t cpucfg, 114sunxi_mc_smp_start(bus_space_tag_t bst, bus_space_handle_t prcm, bus_space_handle_t cpucfg,
109 bus_space_handle_t cpuxcfg, u_int cluster, u_int cpu) 115 bus_space_handle_t cpuxcfg, u_int cluster, u_int cpu, enum sunxi_mc_soc soc,
 116 enum sunxi_mc_cpu core)
110{ 117{
111 uint32_t val; 118 uint32_t val;
112 int i; 119 int i;
113 120
114 /* Set start vector */ 
115 bus_space_write_4(bst, cpucfg, CPUCFG_P_REG0, sunxi_mc_smp_pa()); 
116 
117 /* Assert core reset */ 121 /* Assert core reset */
118 val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster)); 122 val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster));
119 val &= ~__BIT(cpu); 123 val &= ~__BIT(cpu);
120 bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster), val); 124 bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster), val);
121 125
122 /* Assert power-on reset */ 126 if (soc == MC_SOC_A83T) {
123 val = bus_space_read_4(bst, cpucfg, CPUCFG_CL_RST(cluster)); 127 /* Assert power-on reset */
124 val &= ~__BIT(cpu); 128 val = bus_space_read_4(bst, cpucfg, CPUCFG_CL_RST(cluster));
125 bus_space_write_4(bst, cpucfg, CPUCFG_CL_RST(cluster), val); 129 val &= ~__BIT(cpu);
 130 bus_space_write_4(bst, cpucfg, CPUCFG_CL_RST(cluster), val);
 131 }
126 132
127 /* Disable automatic L1 cache invalidate at reset */ 133 if (core == MC_CORE_CA7) {
128 val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_CTRL0(cluster)); 134 /* Disable automatic L1 cache invalidate at reset */
129 val &= ~__BIT(cpu); 135 val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_CTRL0(cluster));
130 bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_CTRL0(cluster), val); 136 val &= ~__BIT(cpu);
 137 bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_CTRL0(cluster), val);
 138 }
131 139
132 /* Release power clamp */ 140 /* Release power clamp */
133 for (i = 0; i <= 8; i++) { 141 for (i = 0; i <= 8; i++) {
134 bus_space_write_4(bst, prcm, PRCM_CL_PWR_CLAMP(cluster, cpu), 0xff >> i); 142 bus_space_write_4(bst, prcm, PRCM_CL_PWR_CLAMP(cluster, cpu), 0xff >> i);
135 delay(10); 143 delay(10);
136 } 144 }
137 for (i = 100000; i > 0; i--) { 145 for (i = 100000; i > 0; i--) {
138 if (bus_space_read_4(bst, prcm, PRCM_CL_PWR_CLAMP(cluster, cpu)) == 0) 146 if (bus_space_read_4(bst, prcm, PRCM_CL_PWR_CLAMP(cluster, cpu)) == 0)
139 break; 147 break;
140 } 148 }
141 if (i == 0) { 149 if (i == 0) {
142 printf("CPU %#llx failed to start\n", __SHIFTIN(cluster, MPIDR_AFF1) | __SHIFTIN(cpu, MPIDR_AFF0)); 150 printf("CPU %#llx failed to start\n", __SHIFTIN(cluster, MPIDR_AFF1) | __SHIFTIN(cpu, MPIDR_AFF0));
143 return ETIMEDOUT; 151 return ETIMEDOUT;
144 } 152 }
145 153
146 /* Clear power-off gating */ 154 /* Clear power-off gating */
147 val = bus_space_read_4(bst, prcm, PRCM_CL_PWROFF(cluster)); 155 val = bus_space_read_4(bst, prcm, PRCM_CL_PWROFF(cluster));
148 if (cpu == 0) 156 if (soc == MC_SOC_A83T) {
149 val &= ~__BIT(4); 157 if (cpu == 0)
150 val &= ~__BIT(cpu); 158 val &= ~__BIT(4);
 159 val &= ~__BIT(0); /* cluster power gate */
 160 } else {
 161 val &= ~__BIT(cpu);
 162 val &= ~__BIT(4); /* cluster power gate */
 163 }
151 bus_space_write_4(bst, prcm, PRCM_CL_PWROFF(cluster), val); 164 bus_space_write_4(bst, prcm, PRCM_CL_PWROFF(cluster), val);
152 165
153 /* De-assert power-on reset */ 166 /* De-assert power-on reset */
154 val = bus_space_read_4(bst, prcm, PRCM_CL_RST_CTRL(cluster)); 167 val = bus_space_read_4(bst, prcm, PRCM_CL_RST_CTRL(cluster));
155 val |= __BIT(cpu); 168 val |= __BIT(cpu);
156 bus_space_write_4(bst, prcm, PRCM_CL_RST_CTRL(cluster), val); 169 bus_space_write_4(bst, prcm, PRCM_CL_RST_CTRL(cluster), val);
157 170
158 val = bus_space_read_4(bst, cpucfg, CPUCFG_CL_RST(cluster)); 171 if (soc == MC_SOC_A83T) {
159 val |= __BIT(cpu); 172 val = bus_space_read_4(bst, cpucfg, CPUCFG_CL_RST(cluster));
160 bus_space_write_4(bst, cpucfg, CPUCFG_CL_RST(cluster), val); 173 val |= __BIT(cpu);
161 delay(10); 174 bus_space_write_4(bst, cpucfg, CPUCFG_CL_RST(cluster), val);
 175 delay(10);
 176 }
162 177
163 /* De-assert core reset */ 178 /* De-assert core reset */
164 val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster)); 179 val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster));
165 val |= __BIT(cpu); 180 val |= __BIT(cpu);
166 val |= CPUXCFG_CL_RST_SOC_DBG_RST; 181 val |= CPUXCFG_CL_RST_SOC_DBG_RST;
167 val |= CPUXCFG_CL_RST_ETM_RST(cpu); 182 if (core == MC_CORE_CA7)
 183 val |= CPUXCFG_CL_RST_ETM_RST(cpu);
 184 else
 185 val |= CPUXCFG_CL_RST_CX_RST(cpu);
168 val |= CPUXCFG_CL_RST_DBG_RST(cpu); 186 val |= CPUXCFG_CL_RST_DBG_RST(cpu);
169 val |= CPUXCFG_CL_RST_L2_RST; 187 val |= CPUXCFG_CL_RST_L2_RST;
170 val |= CPUXCFG_CL_RST_H_RST; 188 val |= CPUXCFG_CL_RST_H_RST;
171 bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster), val); 189 bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_RST(cluster), val);
172 190
173 /* De-assert ACINACTM */ 191 /* De-assert ACINACTM */
174 val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_CTRL1(cluster)); 192 val = bus_space_read_4(bst, cpuxcfg, CPUXCFG_CL_CTRL1(cluster));
175 val &= ~CPUXCFG_CL_CTRL1_ACINACTM; 193 val &= ~CPUXCFG_CL_CTRL1_ACINACTM;
176 bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_CTRL1(cluster), val); 194 bus_space_write_4(bst, cpuxcfg, CPUXCFG_CL_CTRL1(cluster), val);
177 195
178 return 0; 196 return 0;
179} 197}
180 198
181int 199int
182sunxi_mc_smp_enable(u_int mpidr) 200sun8i_a83t_smp_enable(u_int mpidr)
183{ 201{
184 bus_space_tag_t bst = &arm_generic_bs_tag; 202 bus_space_tag_t bst = &arm_generic_bs_tag;
185 bus_space_handle_t prcm, cpucfg, cpuxcfg; 203 bus_space_handle_t prcm, cpucfg, cpuxcfg;
186 int error; 204 int error;
187 205
188 const u_int cluster = __SHIFTOUT(mpidr, MPIDR_AFF1); 206 const u_int cluster = __SHIFTOUT(mpidr, MPIDR_AFF1);
189 const u_int cpu = __SHIFTOUT(mpidr, MPIDR_AFF0); 207 const u_int cpu = __SHIFTOUT(mpidr, MPIDR_AFF0);
190 208
191 if (bus_space_map(bst, PRCM_BASE, PRCM_SIZE, 0, &prcm) != 0 || 209 if (bus_space_map(bst, A83T_PRCM_BASE, A83T_PRCM_SIZE, 0, &prcm) != 0 ||
192 bus_space_map(bst, CPUCFG_BASE, CPUCFG_SIZE, 0, &cpucfg) != 0 || 210 bus_space_map(bst, CPUCFG_BASE, CPUCFG_SIZE, 0, &cpucfg) != 0 ||
193 bus_space_map(bst, CPUXCFG_BASE, CPUXCFG_SIZE, 0, &cpuxcfg) != 0) 211 bus_space_map(bst, CPUXCFG_BASE, CPUXCFG_SIZE, 0, &cpuxcfg) != 0)
194 return ENOMEM; 212 return ENOMEM;
195 213
196 error = sunxi_mc_smp_start(bst, prcm, cpucfg, cpuxcfg, cluster, cpu); 214 for (int i = 0; i < 4; i++)
 215 sunxi_mc_cci_port[i] = A83T_CCI_BASE + CCI_SLAVEIF3_OFFSET;
 216 for (int i = 4; i < 8; i++)
 217 sunxi_mc_cci_port[i] = A83T_CCI_BASE + CCI_SLAVEIF4_OFFSET;
 218
 219 /* Set start vector */
 220 bus_space_write_4(bst, cpucfg, CPUCFG_P_REG0, sunxi_mc_smp_pa());
 221 cpu_idcache_wbinv_all();
 222
 223 error = sunxi_mc_smp_start(bst, prcm, cpucfg, cpuxcfg, cluster, cpu,
 224 MC_SOC_A83T, MC_CORE_CA7);
197 225
198 bus_space_unmap(bst, cpuxcfg, CPUXCFG_SIZE); 226 bus_space_unmap(bst, cpuxcfg, CPUXCFG_SIZE);
199 bus_space_unmap(bst, cpucfg, CPUCFG_SIZE); 227 bus_space_unmap(bst, cpucfg, CPUCFG_SIZE);
200 bus_space_unmap(bst, prcm, PRCM_SIZE); 228 bus_space_unmap(bst, prcm, A83T_PRCM_SIZE);
 229
 230 return error;
 231}
 232
 233int
 234sun9i_a80_smp_enable(u_int mpidr)
 235{
 236 bus_space_tag_t bst = &arm_generic_bs_tag;
 237 bus_space_handle_t prcm, cpuxcfg;
 238 int error;
 239
 240 const u_int cluster = __SHIFTOUT(mpidr, MPIDR_AFF1);
 241 const u_int cpu = __SHIFTOUT(mpidr, MPIDR_AFF0);
 242
 243 if (bus_space_map(bst, A80_PRCM_BASE, A80_PRCM_SIZE, 0, &prcm) != 0 ||
 244 bus_space_map(bst, CPUXCFG_BASE, CPUXCFG_SIZE, 0, &cpuxcfg) != 0)
 245 return ENOMEM;
 246
 247 for (int i = 0; i < 4; i++)
 248 sunxi_mc_cci_port[i] = A80_CCI_BASE + CCI_SLAVEIF3_OFFSET;
 249 for (int i = 4; i < 8; i++)
 250 sunxi_mc_cci_port[i] = A80_CCI_BASE + CCI_SLAVEIF4_OFFSET;
 251
 252 /* Set start vector */
 253 bus_space_write_4(bst, prcm, PRCM_CPU_SOFT_ENTRY, sunxi_mc_smp_pa());
 254 cpu_idcache_wbinv_all();
 255
 256 error = sunxi_mc_smp_start(bst, prcm, 0, cpuxcfg, cluster, cpu,
 257 MC_SOC_A80, cluster == 0 ? MC_CORE_CA7 : MC_CORE_CA15);
 258
 259 bus_space_unmap(bst, cpuxcfg, CPUXCFG_SIZE);
 260 bus_space_unmap(bst, prcm, A80_PRCM_SIZE);
201 261
202 return error; 262 return error;
203} 263}

cvs diff -r1.1 -r1.2 src/sys/arch/arm/sunxi/sunxi_mc_smp.h (expand / switch to unified diff)

--- src/sys/arch/arm/sunxi/sunxi_mc_smp.h 2019/01/03 11:01:59 1.1
+++ src/sys/arch/arm/sunxi/sunxi_mc_smp.h 2019/01/03 14:44:21 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sunxi_mc_smp.h,v 1.1 2019/01/03 11:01:59 jmcneill Exp $ */ 1/* $NetBSD: sunxi_mc_smp.h,v 1.2 2019/01/03 14:44:21 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -20,16 +20,17 @@ @@ -20,16 +20,17 @@
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#ifndef _SUNXI_MC_SMP_H 29#ifndef _SUNXI_MC_SMP_H
30#define _SUNXI_MC_SMP_H 30#define _SUNXI_MC_SMP_H
31 31
32int sunxi_mc_smp_match(const char *); 32int sunxi_mc_smp_match(const char *);
33int sunxi_mc_smp_enable(u_int); 33int sun8i_a83t_smp_enable(u_int);
 34int sun9i_a80_smp_enable(u_int);
34 35
35#endif /* !_SUNXI_MC_SMP_H */ 36#endif /* !_SUNXI_MC_SMP_H */

cvs diff -r1.33 -r1.34 src/sys/arch/arm/sunxi/sunxi_platform.c (expand / switch to unified diff)

--- src/sys/arch/arm/sunxi/sunxi_platform.c 2019/01/03 12:52:40 1.33
+++ src/sys/arch/arm/sunxi/sunxi_platform.c 2019/01/03 14:44:21 1.34
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sunxi_platform.c,v 1.33 2019/01/03 12:52:40 jmcneill Exp $ */ 1/* $NetBSD: sunxi_platform.c,v 1.34 2019/01/03 14:44:21 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include "opt_soc.h" 29#include "opt_soc.h"
30#include "opt_multiprocessor.h" 30#include "opt_multiprocessor.h"
31#include "opt_console.h" 31#include "opt_console.h"
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.33 2019/01/03 12:52:40 jmcneill Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.34 2019/01/03 14:44:21 jmcneill Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/bus.h> 37#include <sys/bus.h>
38#include <sys/cpu.h> 38#include <sys/cpu.h>
39#include <sys/device.h> 39#include <sys/device.h>
40#include <sys/termios.h> 40#include <sys/termios.h>
41 41
42#include <dev/fdt/fdtvar.h> 42#include <dev/fdt/fdtvar.h>
43#include <arm/fdt/arm_fdtvar.h> 43#include <arm/fdt/arm_fdtvar.h>
44 44
45#include <uvm/uvm_extern.h> 45#include <uvm/uvm_extern.h>
46 46
47#include <machine/bootconfig.h> 47#include <machine/bootconfig.h>
@@ -117,46 +117,70 @@ extern struct bus_space arm_generic_a4x_ @@ -117,46 +117,70 @@ extern struct bus_space arm_generic_a4x_
117static const struct pmap_devmap * 117static const struct pmap_devmap *
118sunxi_platform_devmap(void) 118sunxi_platform_devmap(void)
119{ 119{
120 static const struct pmap_devmap devmap[] = { 120 static const struct pmap_devmap devmap[] = {
121 DEVMAP_ENTRY(SUNXI_CORE_VBASE, 121 DEVMAP_ENTRY(SUNXI_CORE_VBASE,
122 SUNXI_CORE_PBASE, 122 SUNXI_CORE_PBASE,
123 SUNXI_CORE_SIZE), 123 SUNXI_CORE_SIZE),
124 DEVMAP_ENTRY_END 124 DEVMAP_ENTRY_END
125 }; 125 };
126 126
127 return devmap; 127 return devmap;
128} 128}
129 129
130#define SUN8I_A83T_CPU_VBASE (SUNXI_CORE_VBASE + SUNXI_CORE_SIZE) 130#define SUNXI_MC_CPU_VBASE (SUNXI_CORE_VBASE + SUNXI_CORE_SIZE)
131#define SUN8I_A83T_CPU_PBASE 0x01700000 131#define SUNXI_MC_CPU_PBASE 0x01700000
132#define SUN8I_A83T_CPU_SIZE 0x00100000 132#define SUNXI_MC_CPU_SIZE 0x00100000
133 133
134static const struct pmap_devmap * 134static const struct pmap_devmap *
135sun8i_a83t_platform_devmap(void) 135sun8i_a83t_platform_devmap(void)
136{ 136{
137 static const struct pmap_devmap devmap[] = { 137 static const struct pmap_devmap devmap[] = {
138 DEVMAP_ENTRY(SUNXI_CORE_VBASE, 138 DEVMAP_ENTRY(SUNXI_CORE_VBASE,
139 SUNXI_CORE_PBASE, 139 SUNXI_CORE_PBASE,
140 SUNXI_CORE_SIZE), 140 SUNXI_CORE_SIZE),
141 DEVMAP_ENTRY(SUN8I_A83T_CPU_VBASE, 141 DEVMAP_ENTRY(SUNXI_MC_CPU_VBASE,
142 SUN8I_A83T_CPU_PBASE, 142 SUNXI_MC_CPU_PBASE,
143 SUN8I_A83T_CPU_SIZE), 143 SUNXI_MC_CPU_SIZE),
144 DEVMAP_ENTRY_END 144 DEVMAP_ENTRY_END
145 }; 145 };
146 146
147 return devmap; 147 return devmap;
148} 148}
149 149
 150#define SUN9I_A80_PRCM_VBASE (SUNXI_MC_CPU_VBASE + SUNXI_MC_CPU_PBASE)
 151#define SUN9I_A80_PRCM_PBASE 0x08000000
 152#define SUN9I_A80_PRCM_SIZE 0x00100000
 153
 154static const struct pmap_devmap *
 155sun9i_a80_platform_devmap(void)
 156{
 157 static const struct pmap_devmap devmap[] = {
 158 DEVMAP_ENTRY(SUNXI_CORE_VBASE,
 159 SUNXI_CORE_PBASE,
 160 SUNXI_CORE_SIZE),
 161 DEVMAP_ENTRY(SUNXI_MC_CPU_VBASE,
 162 SUNXI_MC_CPU_PBASE,
 163 SUNXI_MC_CPU_SIZE),
 164 DEVMAP_ENTRY(SUN9I_A80_PRCM_VBASE,
 165 SUN9I_A80_PRCM_PBASE,
 166 SUN9I_A80_PRCM_SIZE),
 167 DEVMAP_ENTRY_END
 168 };
 169
 170 return devmap;
 171}
 172
 173
150static void 174static void
151sunxi_platform_init_attach_args(struct fdt_attach_args *faa) 175sunxi_platform_init_attach_args(struct fdt_attach_args *faa)
152{ 176{
153 faa->faa_bst = &sunxi_bs_tag; 177 faa->faa_bst = &sunxi_bs_tag;
154 faa->faa_a4x_bst = &sunxi_a4x_bs_tag; 178 faa->faa_a4x_bst = &sunxi_a4x_bs_tag;
155 faa->faa_dmat = &sunxi_dma_tag; 179 faa->faa_dmat = &sunxi_dma_tag;
156} 180}
157 181
158void sunxi_platform_early_putchar(char); 182void sunxi_platform_early_putchar(char);
159 183
160void 184void
161sunxi_platform_early_putchar(char c) 185sunxi_platform_early_putchar(char c)
162{ 186{
@@ -227,35 +251,46 @@ sunxi_platform_bootstrap(void) @@ -227,35 +251,46 @@ sunxi_platform_bootstrap(void)
227 if (status == NULL || strncmp(status, "ok", 2) == 0) { 251 if (status == NULL || strncmp(status, "ok", 2) == 0) {
228 fdt_setprop_string(fdt_data, chosen_off, 252 fdt_setprop_string(fdt_data, chosen_off,
229 "stdout-path", "/chosen/framebuffer"); 253 "stdout-path", "/chosen/framebuffer");
230 } 254 }
231 } 255 }
232 } else if (match_bootconf_option(boot_args, "console", "serial")) { 256 } else if (match_bootconf_option(boot_args, "console", "serial")) {
233 fdt_setprop_string(fdt_data, chosen_off, 257 fdt_setprop_string(fdt_data, chosen_off,
234 "stdout-path", "serial0:115200n8"); 258 "stdout-path", "serial0:115200n8");
235 } 259 }
236} 260}
237 261
238#if defined(SOC_SUNXI_MC) 262#if defined(SOC_SUNXI_MC)
239static int 263static int
240cpu_enable_sunxi_mc(int phandle) 264cpu_enable_sun8i_a83t(int phandle)
241{ 265{
242 uint64_t mpidr; 266 uint64_t mpidr;
243 267
244 fdtbus_get_reg64(phandle, 0, &mpidr, NULL); 268 fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
245 269
246 return sunxi_mc_smp_enable(mpidr); 270 return sun8i_a83t_smp_enable(mpidr);
247} 271}
248ARM_CPU_METHOD(sun8i_a83t, "allwinner,sun8i-a83t-smp", cpu_enable_sunxi_mc); 272ARM_CPU_METHOD(sun8i_a83t, "allwinner,sun8i-a83t-smp", cpu_enable_sun8i_a83t);
 273
 274static int
 275cpu_enable_sun9i_a80(int phandle)
 276{
 277 uint64_t mpidr;
 278
 279 fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
 280
 281 return sun9i_a80_smp_enable(mpidr);
 282}
 283ARM_CPU_METHOD(sun9i_a80, "allwinner,sun9i-a80-smp", cpu_enable_sun9i_a80);
249#endif 284#endif
250 285
251static void 286static void
252sun4i_platform_reset(void) 287sun4i_platform_reset(void)
253{ 288{
254 bus_space_tag_t bst = &sunxi_bs_tag; 289 bus_space_tag_t bst = &sunxi_bs_tag;
255 bus_space_handle_t bsh; 290 bus_space_handle_t bsh;
256 291
257 bus_space_map(bst, SUN4I_WDT_BASE, SUN4I_WDT_SIZE, 0, &bsh); 292 bus_space_map(bst, SUN4I_WDT_BASE, SUN4I_WDT_SIZE, 0, &bsh);
258 293
259 bus_space_write_4(bst, bsh, SUN4I_WDT_CTRL, 294 bus_space_write_4(bst, bsh, SUN4I_WDT_CTRL,
260 SUN4I_WDT_CTRL_KEY | SUN4I_WDT_CTRL_RESTART); 295 SUN4I_WDT_CTRL_KEY | SUN4I_WDT_CTRL_RESTART);
261 for (;;) { 296 for (;;) {
@@ -401,27 +436,27 @@ static const struct arm_platform sun8i_a @@ -401,27 +436,27 @@ static const struct arm_platform sun8i_a
401 .ap_devmap = sun8i_a83t_platform_devmap, 436 .ap_devmap = sun8i_a83t_platform_devmap,
402 .ap_bootstrap = sunxi_platform_bootstrap, 437 .ap_bootstrap = sunxi_platform_bootstrap,
403 .ap_init_attach_args = sunxi_platform_init_attach_args, 438 .ap_init_attach_args = sunxi_platform_init_attach_args,
404 .ap_device_register = sunxi_platform_device_register, 439 .ap_device_register = sunxi_platform_device_register,
405 .ap_reset = sun6i_platform_reset, 440 .ap_reset = sun6i_platform_reset,
406 .ap_delay = gtmr_delay, 441 .ap_delay = gtmr_delay,
407 .ap_uart_freq = sunxi_platform_uart_freq, 442 .ap_uart_freq = sunxi_platform_uart_freq,
408 .ap_mpstart = arm_fdt_cpu_mpstart, 443 .ap_mpstart = arm_fdt_cpu_mpstart,
409}; 444};
410 445
411ARM_PLATFORM(sun8i_a83t, "allwinner,sun8i-a83t", &sun8i_a83t_platform); 446ARM_PLATFORM(sun8i_a83t, "allwinner,sun8i-a83t", &sun8i_a83t_platform);
412 447
413static const struct arm_platform sun9i_platform = { 448static const struct arm_platform sun9i_platform = {
414 .ap_devmap = sunxi_platform_devmap, 449 .ap_devmap = sun9i_a80_platform_devmap,
415 .ap_bootstrap = sunxi_platform_bootstrap, 450 .ap_bootstrap = sunxi_platform_bootstrap,
416 .ap_init_attach_args = sunxi_platform_init_attach_args, 451 .ap_init_attach_args = sunxi_platform_init_attach_args,
417 .ap_device_register = sunxi_platform_device_register, 452 .ap_device_register = sunxi_platform_device_register,
418 .ap_reset = sun9i_platform_reset, 453 .ap_reset = sun9i_platform_reset,
419 .ap_delay = gtmr_delay, 454 .ap_delay = gtmr_delay,
420 .ap_uart_freq = sunxi_platform_uart_freq, 455 .ap_uart_freq = sunxi_platform_uart_freq,
421 .ap_mpstart = arm_fdt_cpu_mpstart, 456 .ap_mpstart = arm_fdt_cpu_mpstart,
422}; 457};
423 458
424ARM_PLATFORM(sun9i_a80, "allwinner,sun9i-a80", &sun9i_platform); 459ARM_PLATFORM(sun9i_a80, "allwinner,sun9i-a80", &sun9i_platform);
425 460
426static const struct arm_platform sun50i_platform = { 461static const struct arm_platform sun50i_platform = {
427 .ap_devmap = sunxi_platform_devmap, 462 .ap_devmap = sunxi_platform_devmap,