1 /* $NetBSD: octeonvar.h,v 1.18 2022/01/26 11:48:54 andvar Exp $ */
2
3 /*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef _MIPS_OCTEON_OCTEONVAR_H_
33 #define _MIPS_OCTEON_OCTEONVAR_H_
34
35 #include <sys/bus.h>
36 #include <sys/evcnt.h>
37 #include <sys/kcpuset.h>
38 #include <mips/locore.h>
39 #include <dev/pci/pcivar.h>
40
41 #include <mips/cavium/octeonreg.h>
42 #include <mips/cache_octeon.h>
43
44 /* XXX elsewhere */
45 #define _ASM_PROLOGUE \
46 " .set push \n" \
47 " .set noreorder \n"
48 #define _ASM_PROLOGUE_MIPS64 \
49 _ASM_PROLOGUE \
50 " .set mips64 \n"
51 #define _ASM_PROLOGUE_OCTEON \
52 _ASM_PROLOGUE \
53 " .set arch=octeon \n"
54 #define _ASM_EPILOGUE \
55 " .set pop \n"
56
57 #ifdef _KERNEL
58 extern int octeon_core_ver;
59 #endif /* _KERNEL */
60 #define OCTEON_1 1
61 #define OCTEON_PLUS 10 /* arbitrary, keep sequence for others */
62 #define OCTEON_2 2
63 #define OCTEON_3 3
64
65 struct octeon_config {
66 struct mips_bus_space mc_iobus_bust;
67 struct mips_bus_space mc_bootbus_bust;
68 struct mips_pci_chipset mc_pc;
69
70 struct mips_bus_dma_tag mc_iobus_dmat;
71 struct mips_bus_dma_tag mc_bootbus_dmat;
72 struct mips_bus_dma_tag mc_core1_dmat;
73 struct mips_bus_dma_tag mc_fpa_dmat;
74
75 struct extent *mc_io_ex;
76 struct extent *mc_mem_ex;
77
78 int mc_mallocsafe;
79 };
80
81 #define NIRQS 128
82 #define NBANKS 2
83
84 struct cpu_softc {
85 struct cpu_info *cpu_ci;
86
87 uint64_t cpu_ip2_sum0;
88 uint64_t cpu_ip3_sum0;
89 uint64_t cpu_ip4_sum0;
90
91 uint64_t cpu_int_sum1;
92
93 uint64_t cpu_ip2_en[NBANKS];
94 uint64_t cpu_ip3_en[NBANKS];
95 uint64_t cpu_ip4_en[NBANKS];
96
97 uint64_t cpu_ip2_enable[NBANKS];
98 uint64_t cpu_ip3_enable[NBANKS];
99 uint64_t cpu_ip4_enable[NBANKS];
100
101 struct evcnt cpu_intr_evs[NIRQS];
102
103 void *cpu_wdog_sih; // wdog softint handler
104 uint64_t cpu_wdog;
105 uint64_t cpu_pp_poke;
106
107 #ifdef MULTIPROCESSOR
108 uint64_t cpu_mbox_set;
109 uint64_t cpu_mbox_clr;
110 #endif
111 } __aligned(OCTEON_CACHELINE_SIZE);
112
113 /*
114 * FPA map
115 */
116
117 #define OCTEON_POOL_NO_PKT 0
118 #define OCTEON_POOL_NO_WQE 1
119 #define OCTEON_POOL_NO_CMD 2
120 #define OCTEON_POOL_NO_SG 3
121 #define OCTEON_POOL_NO_XXX_4 4
122 #define OCTEON_POOL_NO_XXX_5 5
123 #define OCTEON_POOL_NO_XXX_6 6
124 #define OCTEON_POOL_NO_DUMP 7 /* FPA debug dump */
125
126 #define OCTEON_POOL_SIZE_PKT 2048 /* 128 x 16 */
127 #define OCTEON_POOL_SIZE_WQE 128 /* 128 x 1 */
128 #define OCTEON_POOL_SIZE_CMD 1024 /* 128 x 8 */
129 #define OCTEON_POOL_SIZE_SG 512 /* 128 x 4 */
130 #define OCTEON_POOL_SIZE_XXX_4 0
131 #define OCTEON_POOL_SIZE_XXX_5 0
132 #define OCTEON_POOL_SIZE_XXX_6 0
133 #define OCTEON_POOL_SIZE_XXX_7 0
134
135 #define OCTEON_POOL_NELEMS_PKT 4096
136 #define OCTEON_POOL_NELEMS_WQE 4096
137 #define OCTEON_POOL_NELEMS_CMD 32
138 #define OCTEON_POOL_NELEMS_SG 1024
139 #define OCTEON_POOL_NELEMS_XXX_4 0
140 #define OCTEON_POOL_NELEMS_XXX_5 0
141 #define OCTEON_POOL_NELEMS_XXX_6 0
142 #define OCTEON_POOL_NELEMS_XXX_7 0
143
144 /*
145 * CVMSEG (``scratch'') memory map
146 */
147
148 #define CVMSEG_LM_RNM_SIZE 16 /* limited by CN70XX hardware (why?) */
149 #define CVMSEG_LM_ETHER_COUNT 4 /* limits number of cnmac devices */
150
151 struct octeon_cvmseg_map {
152 uint64_t csm_pow_intr;
153
154 struct octeon_cvmseg_ether_map {
155 uint64_t csm_ether_fau_done;
156 } csm_ether[CVMSEG_LM_ETHER_COUNT];
157
158 uint64_t csm_rnm[CVMSEG_LM_RNM_SIZE];
159 } __packed;
160 #define OCTEON_CVMSEG_OFFSET(entry) \
161 offsetof(struct octeon_cvmseg_map, entry)
162 #define OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
163 (offsetof(struct octeon_cvmseg_map, csm_ether) + \
164 sizeof(struct octeon_cvmseg_ether_map) * (n) + \
165 offsetof(struct octeon_cvmseg_ether_map, entry))
166
167 /*
168 * FAU register map
169 *
170 * => FAU registers exist in FAU unit
171 * => devices (PKO) can access these registers
172 * => CPU can read those values after loading them into CVMSEG
173 */
174 struct octfau_map {
175 struct {
176 /* PKO command index */
177 uint64_t _fau_map_port_pkocmdidx;
178 /* send requested */
179 uint64_t _fau_map_port_txreq;
180 /* send completed */
181 uint64_t _fau_map_port_txdone;
182 /* XXX */
183 uint64_t _fau_map_port_pad;
184 } __packed _fau_map_port[3];
185 };
186
187 /*
188 * POW qos/group map
189 */
190
191 #define OCTEON_POW_QOS_PIP 0
192 #define OCTEON_POW_QOS_CORE1 1
193 #define OCTEON_POW_QOS_XXX_2 2
194 #define OCTEON_POW_QOS_XXX_3 3
195 #define OCTEON_POW_QOS_XXX_4 4
196 #define OCTEON_POW_QOS_XXX_5 5
197 #define OCTEON_POW_QOS_XXX_6 6
198 #define OCTEON_POW_QOS_XXX_7 7
199
200 #define OCTEON_POW_GROUP_MAX 16
201
202 #ifdef _KERNEL
203 extern struct octeon_config octeon_configuration;
204
205 const char *octeon_cpu_model(mips_prid_t);
206
207 void octeon_bus_io_init(bus_space_tag_t, void *);
208 void octeon_bus_mem_init(bus_space_tag_t, void *);
209 void octeon_cal_timer(int);
210 void octeon_dma_init(struct octeon_config *);
211 void octeon_intr_init(struct cpu_info *);
212 void octeon_iointr(int, vaddr_t, uint32_t);
213 void octpci_init(pci_chipset_tag_t, struct octeon_config *);
214 void *octeon_intr_establish(int, int, int (*)(void *), void *);
215 void octeon_intr_disestablish(void *cookie);
216
217 int octeon_ioclock_speed(void);
218 void octeon_soft_reset(void);
219
220 void octeon_reset_vector(void);
221 uint64_t mips_cp0_cvmctl_read(void);
222 void mips_cp0_cvmctl_write(uint64_t);
223 #endif /* _KERNEL */
224
225 #if defined(__mips_n32)
226 #define ffs64 __builtin_ffsll
227 #elif defined(_LP64)
228 #define ffs64 __builtin_ffsl
229 #else
230 #error unknown ABI
231 #endif
232
233 /*
234 * Prefetch
235 *
236 * OCTEON_PREF normal (L1 and L2)
237 * OCTEON_PREF_L1 L1 only
238 * OCTEON_PREF_L2 L2 only
239 * OCTEON_PREF_DWB don't write back
240 * OCTEON_PREF_PFS prepare for store
241 */
242 #define __OCTEON_PREF_N(n, base, offset) \
243 __asm __volatile ( \
244 " .set push \
245 " .set arch=octeon \n" \
246 " pref "#n", "#offset"(%[base]) \n" \
247 " .set pop \
248 : : [base] "d" (base) \
249 )
250 #define __OCTEON_PREF_0(base, offset) __OCTEON_PREF_N(0, base, offset)
251 #define __OCTEON_PREF_4(base, offset) __OCTEON_PREF_N(4, base, offset)
252 #define __OCTEON_PREF_28(base, offset) __OCTEON_PREF_N(28, base, offset)
253 #define __OCTEON_PREF_29(base, offset) __OCTEON_PREF_N(29, base, offset)
254 #define __OCTEON_PREF_30(base, offset) __OCTEON_PREF_N(30, base, offset)
255 #define OCTEON_PREF(base, offset) __OCTEON_PREF_0(base, offset)
256 #define OCTEON_PREF_L1(base, offset) __OCTEON_PREF_4(base, offset)
257 #define OCTEON_PREF_L2(base, offset) __OCTEON_PREF_28(base, offset)
258 #define OCTEON_PREF_DWB(base, offset) __OCTEON_PREF_29(base, offset)
259 #define OCTEON_PREF_PFS(base, offset) __OCTEON_PREF_30(base, offset)
260
261 /*
262 * Sync
263 */
264 #define OCTEON_SYNCCOMMON(name) \
265 __asm __volatile ( \
266 _ASM_PROLOGUE_OCTEON \
267 " "#name" \n" \
268 _ASM_EPILOGUE \
269 ::: "memory")
270 #define OCTEON_SYNCIOBDMA OCTEON_SYNCCOMMON(synciobdma)
271 #define OCTEON_SYNCW OCTEON_SYNCCOMMON(syncw)
272 #define OCTEON_SYNC OCTEON_SYNCCOMMON(sync)
273 #define OCTEON_SYNCWS OCTEON_SYNCCOMMON(syncws)
274 #define OCTEON_SYNCS OCTEON_SYNCCOMMON(syncs)
275
276 /* octeon core does not use cca to determine cacheability */
277 #define OCTEON_CCA_NONE UINT64_C(0)
278
279 static __inline uint64_t
octeon_xkphys_read_8(paddr_t address)280 octeon_xkphys_read_8(paddr_t address)
281 {
282 return mips3_ld(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address));
283 }
284
285 static __inline void
octeon_xkphys_write_8(paddr_t address,uint64_t value)286 octeon_xkphys_write_8(paddr_t address, uint64_t value)
287 {
288 mips3_sd(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address), value);
289 }
290
291 static __inline void
octeon_iobdma_write_8(uint64_t value)292 octeon_iobdma_write_8(uint64_t value)
293 {
294
295 octeon_xkphys_write_8(OCTEON_IOBDMA_ADDR, value);
296 }
297
298 static __inline uint64_t
octeon_cvmseg_read_8(size_t offset)299 octeon_cvmseg_read_8(size_t offset)
300 {
301
302 return octeon_xkphys_read_8(OCTEON_CVMSEG_LM + offset);
303 }
304
305 static __inline void
octeon_cvmseg_write_8(size_t offset,uint64_t value)306 octeon_cvmseg_write_8(size_t offset, uint64_t value)
307 {
308
309 octeon_xkphys_write_8(OCTEON_CVMSEG_LM + offset, value);
310 }
311
312 #endif /* _MIPS_OCTEON_OCTEONVAR_H_ */
313