xref: /openbsd-src/sys/arch/octeon/include/octeonvar.h (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1 /*	$OpenBSD: octeonvar.h,v 1.49 2020/09/04 15:18:05 visa Exp $	*/
2 /*	$NetBSD: maltavar.h,v 1.3 2002/03/18 10:10:16 simonb Exp $	*/
3 
4 /*-
5  * Copyright (c) 2001 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Jason R. Thorpe.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef _MIPS_OCTEON_OCTEONVAR_H_
34 #define _MIPS_OCTEON_OCTEONVAR_H_
35 
36 #include <machine/bus.h>
37 
38 /* XXX elsewhere */
39 #define	_ASM_PROLOGUE \
40 		"	.set push			\n" \
41 		"	.set noreorder			\n"
42 #define	_ASM_PROLOGUE_MIPS64 \
43 		_ASM_PROLOGUE				\
44 		"	.set mips64			\n"
45 #define	_ASM_PROLOGUE_OCTEON \
46 		_ASM_PROLOGUE				\
47 		"	.set arch=octeon		\n"
48 #define	_ASM_EPILOGUE \
49 		"	.set pop			\n"
50 /*
51  * subbits = __BITS64_GET(XXX, bits);
52  * bits = __BITS64_SET(XXX, subbits);
53  */
54 #ifndef	__BITS64_GET
55 #define	__BITS64_GET(name, bits)	\
56 	    (((uint64_t)(bits) & name) >> name##_SHIFT)
57 #endif
58 #ifndef	__BITS64_SET
59 #define	__BITS64_SET(name, subbits)	\
60 	    (((uint64_t)(subbits) << name##_SHIFT) & name)
61 #endif
62 
63 struct octeon_config {
64 	bus_space_tag_t mc_iobus_bust;
65 	bus_space_tag_t mc_bootbus_bust;
66 
67 	bus_dma_tag_t mc_iobus_dmat;
68 	bus_dma_tag_t mc_bootbus_dmat;
69 };
70 
71 #define	GPIO_CONFIG_MD_OUTPUT_SEL_MASK	(GPIO_CONFIG_MD0 | GPIO_CONFIG_MD1)
72 #define	GPIO_CONFIG_MD_USB0_VBUS_CTRL	GPIO_CONFIG_MD0
73 #define	GPIO_CONFIG_MD_USB1_VBUS_CTRL	GPIO_CONFIG_MD1
74 
75 /*
76  * FPA map
77  */
78 
79 #define	OCTEON_POOL_NO_PKT	0
80 #define	OCTEON_POOL_NO_WQE	1
81 #define	OCTEON_POOL_NO_CMD	2
82 #define	OCTEON_POOL_NO_SG	3
83 #define	OCTEON_POOL_NO_XXX_4	4
84 #define	OCTEON_POOL_NO_XXX_5	5
85 #define	OCTEON_POOL_NO_XXX_6	6
86 #define	OCTEON_POOL_NO_DUMP	7	/* FPA debug dump */
87 
88 #define	OCTEON_POOL_SIZE_PKT	1920	/* 128 x 15 */
89 #define	OCTEON_POOL_SIZE_WQE	128	/* 128 x 1 */
90 #define	OCTEON_POOL_SIZE_CMD	1024	/* 128 x 8 */
91 #define	OCTEON_POOL_SIZE_SG	128	/* 128 x 1 */
92 #define	OCTEON_POOL_SIZE_XXX_4	0
93 #define	OCTEON_POOL_SIZE_XXX_5	0
94 #define	OCTEON_POOL_SIZE_XXX_6	0
95 #define	OCTEON_POOL_SIZE_XXX_7	0
96 
97 #define	OCTEON_POOL_NELEMS_PKT		4096
98 #define	OCTEON_POOL_NELEMS_WQE		4096
99 #define	OCTEON_POOL_NELEMS_CMD		32
100 #define	OCTEON_POOL_NELEMS_SG		4096
101 #define	OCTEON_POOL_NELEMS_XXX_4	0
102 #define	OCTEON_POOL_NELEMS_XXX_5	0
103 #define	OCTEON_POOL_NELEMS_XXX_6	0
104 #define	OCTEON_POOL_NELEMS_XXX_7	0
105 
106 /*
107  * CVMSEG (``scratch'') memory map
108  */
109 struct octeon_cvmseg_map {
110 	uint64_t		csm_pow_intr;
111 
112 	struct octeon_cvmseg_ether_map {
113 		uint64_t	csm_ether_fau_done;
114 	} csm_ether[12/* XXX */];
115 } __packed;
116 #define	OCTEON_CVMSEG_OFFSET(entry) \
117 	offsetof(struct octeon_cvmseg_map, entry)
118 #define	OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
119 	(offsetof(struct octeon_cvmseg_map, csm_ether) + \
120 	 sizeof(struct octeon_cvmseg_ether_map) * (n) + \
121 	 offsetof(struct octeon_cvmseg_ether_map, entry))
122 
123 /*
124  * FAU register map
125  *
126  * => FAU registers exist in FAU unit
127  * => devices (PKO) can access these registers
128  * => CPU can read those values after loading them into CVMSEG
129  */
130 struct octeon_fau_map {
131 	struct {
132 		/* PKO command index */
133 		uint64_t	_fau_map_port_pkocmdidx;
134 		/* send requested */
135 		uint64_t	_fau_map_port_txreq;
136 		/* send completed */
137 		uint64_t	_fau_map_port_txdone;
138 		/* XXX */
139 		uint64_t	_fau_map_port_pad;
140 	} __packed _fau_map_port[3];
141 };
142 
143 /*
144  * POW qos/group map
145  */
146 
147 #define	OCTEON_POW_QOS_PIP		0
148 #define	OCTEON_POW_QOS_CORE1		1
149 #define	OCTEON_POW_QOS_XXX_2		2
150 #define	OCTEON_POW_QOS_XXX_3		3
151 #define	OCTEON_POW_QOS_XXX_4		4
152 #define	OCTEON_POW_QOS_XXX_5		5
153 #define	OCTEON_POW_QOS_XXX_6		6
154 #define	OCTEON_POW_QOS_XXX_7		7
155 
156 #define	OCTEON_POW_GROUP_MAX		16
157 
158 enum cnmac_stat {
159 	cnmac_stat_rx_toto_gmx,
160 	cnmac_stat_rx_totp_gmx,
161 	cnmac_stat_rx_toto_pip,
162 	cnmac_stat_rx_totp_pip,
163 	cnmac_stat_rx_h64,
164 	cnmac_stat_rx_h127,
165 	cnmac_stat_rx_h255,
166 	cnmac_stat_rx_h511,
167 	cnmac_stat_rx_h1023,
168 	cnmac_stat_rx_h1518,
169 	cnmac_stat_rx_hmax,
170 	cnmac_stat_rx_bcast,
171 	cnmac_stat_rx_mcast,
172 	cnmac_stat_rx_qdpo,
173 	cnmac_stat_rx_qdpp,
174 	cnmac_stat_rx_fcs,
175 	cnmac_stat_rx_frag,
176 	cnmac_stat_rx_undersz,
177 	cnmac_stat_rx_jabber,
178 	cnmac_stat_rx_oversz,
179 	cnmac_stat_rx_raw,
180 	cnmac_stat_rx_bad,
181 	cnmac_stat_rx_drop,
182 	cnmac_stat_rx_ctl,
183 	cnmac_stat_rx_dmac,
184 	cnmac_stat_tx_toto,
185 	cnmac_stat_tx_totp,
186 	cnmac_stat_tx_hmin,
187 	cnmac_stat_tx_h64,
188 	cnmac_stat_tx_h127,
189 	cnmac_stat_tx_h255,
190 	cnmac_stat_tx_h511,
191 	cnmac_stat_tx_h1023,
192 	cnmac_stat_tx_h1518,
193 	cnmac_stat_tx_hmax,
194 	cnmac_stat_tx_bcast,
195 	cnmac_stat_tx_mcast,
196 	cnmac_stat_tx_coll,
197 	cnmac_stat_tx_defer,
198 	cnmac_stat_tx_scol,
199 	cnmac_stat_tx_mcol,
200 	cnmac_stat_tx_ctl,
201 	cnmac_stat_tx_uflow,
202 	cnmac_stat_count
203 };
204 
205 /*
206  * Octeon board types known to work with OpenBSD/octeon.
207  * NB: BOARD_TYPE_UBIQUITI_E100 is also used by other vendors, but we don't run
208  * on those boards yet.
209  */
210 #define	BOARD_TYPE_CN3010_EVB_HS5	11
211 #define	BOARD_TYPE_UBIQUITI_E100	20002
212 #define	BOARD_TYPE_UBIQUITI_E200	20003
213 #define	BOARD_TYPE_UBIQUITI_E120	20004
214 #define	BOARD_TYPE_UBIQUITI_E220	20005
215 #define	BOARD_TYPE_UBIQUITI_E1000	20010
216 #define	BOARD_TYPE_RHINOLABS_SHASTA	20012
217 #define	BOARD_TYPE_DSR_500		20015
218 #define	BOARD_TYPE_UBIQUITI_E300	20300
219 
220 #if defined(_KERNEL) || defined(_STANDALONE)
221 #define OCTEON_ARGV_MAX 64
222 
223 struct boot_desc {
224 	uint32_t	desc_ver;
225 	uint32_t	desc_size;
226 	uint64_t	stack_top;
227 	uint64_t 	heap_start;
228 	uint64_t	heap_end;
229 	uint64_t      	__unused17;
230 	uint64_t     	__unused16;
231 	uint32_t      	__unused18;
232 	uint32_t      	__unused15;
233 	uint32_t      	__unused14;
234 	uint32_t	argc;
235 	uint32_t	argv[OCTEON_ARGV_MAX];
236 	uint32_t	flags;
237 	uint32_t	core_mask;
238 	uint32_t	dram_size;
239 	uint32_t	phy_mem_desc_addr;
240 	uint32_t	debugger_flag_addr;
241 	uint32_t	eclock;
242 	uint32_t      	__unused10;
243 	uint32_t      	__unused9;
244 	uint16_t      	__unused8;
245 	uint8_t 	__unused7;
246 	uint8_t 	__unused6;
247 	uint16_t 	__unused5;
248 	uint8_t 	__unused4;
249 	uint8_t 	__unused3;
250 	uint8_t 	__unused2[20];
251 	uint8_t 	__unused1[6];
252 	uint8_t 	__unused0;
253 	uint64_t 	boot_info_addr;
254 };
255 
256 struct boot_info {
257 	uint32_t ver_major;
258 	uint32_t ver_minor;
259 	uint64_t stack_top;
260 	uint64_t heap_start;
261 	uint64_t heap_end;
262 	uint64_t boot_desc_addr;
263 	uint32_t exception_base_addr;
264 	uint32_t stack_size;
265 	uint32_t flags;
266 	uint32_t core_mask;
267 	uint32_t dram_size;
268 	uint32_t phys_mem_desc_addr;
269 	uint32_t debugger_flags_addr;
270 	uint32_t eclock;
271 	uint32_t dclock;
272 	uint32_t __unused0;
273 	uint16_t board_type;
274 	uint8_t board_rev_major;
275 	uint8_t board_rev_minor;
276 	uint16_t __unused1;
277 	uint8_t __unused2;
278 	uint8_t __unused3;
279 	char board_serial[20];
280 	uint8_t mac_addr_base[6];
281 	uint8_t mac_addr_count;
282 	uint64_t cf_common_addr;
283 	uint64_t cf_attr_addr;
284 	uint64_t led_display_addr;
285 	uint32_t dfaclock;
286 	uint32_t config_flags;
287 	/* The fields below are available when ver_minor >= 3. */
288 	uint64_t fdt_addr;
289 };
290 
291 struct octeon_bootmem_desc {
292 	uint32_t	lock;
293 	uint32_t	flags;
294 	uint64_t	head_addr;
295 	uint32_t	major_version;
296 	uint32_t	minor_version;
297 	uint64_t	app_data_addr;
298 	uint64_t	app_data_size;
299 	uint32_t	named_block_num_blocks;
300 	uint32_t	named_block_name_len;
301 	uint64_t	named_block_array_addr;
302 };
303 
304 struct octeon_bootmem_block {
305 	uint64_t	next;
306 	uint64_t	size;
307 };
308 
309 extern struct boot_desc *octeon_boot_desc;
310 extern struct boot_info *octeon_boot_info;
311 
312 #ifdef _KERNEL
313 /* Device capabilities advertised in boot_info->config_flags */
314 #define BOOTINFO_CFG_FLAG_PCI_HOST	(1ull << 0)
315 #define BOOTINFO_CFG_FLAG_PCI_TARGET	(1ull << 1)
316 #define BOOTINFO_CFG_FLAG_DEBUG		(1ull << 2)
317 #define BOOTINFO_CFG_FLAG_NO_MAGIC	(1ull << 3)
318 
319 #define BOOTMEM_BLOCK_ALIGN		16
320 #define BOOTMEM_BLOCK_MASK		(BOOTMEM_BLOCK_ALIGN - 1)
321 #define BOOTMEM_BLOCK_MIN_SIZE		16
322 
323 int	bootmem_alloc_region(paddr_t, size_t);
324 void	bootmem_free(paddr_t, size_t);
325 
326 int	octeon_ioclock_speed(void);
327 
328 #endif /* _KERNEL */
329 #endif /* _KERNEL || _STANDALONE */
330 
331 static inline int
332 ffs64(uint64_t val)
333 {
334 	int ret;
335 
336 	__asm volatile ( \
337 		_ASM_PROLOGUE_MIPS64
338 		"	dclz	%0, %1			\n"
339 		_ASM_EPILOGUE
340 		: "=r"(ret) : "r"(val));
341 	return 64 - ret;
342 }
343 
344 static inline int
345 ffs32(uint32_t val)
346 {
347 	int ret;
348 
349 	__asm __volatile ( \
350 		_ASM_PROLOGUE_MIPS64
351 		"	clz	%0, %1			\n"
352 		_ASM_EPILOGUE
353 		: "=r"(ret) : "r"(val));
354 	return 32 - ret;
355 }
356 
357 static inline uint64_t
358 octeon_xkphys_read_8(paddr_t address)
359 {
360 	volatile uint64_t *p =
361 	    (volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC));
362 	return (*p);
363 }
364 
365 #define	MIO_BOOT_BIST_STAT			0x00011800000000f8ULL
366 static inline void
367 octeon_xkphys_write_8(paddr_t address, uint64_t value)
368 {
369 	*(volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)) = value;
370 
371 	/*
372 	 * It seems an immediate read is necessary when doing a write to an RSL
373 	 * register in order to complete the write.
374 	 * We use MIO_BOOT_BIST_STAT because it's apparently the fastest
375 	 * write.
376 	 */
377 
378 	/*
379 	 * XXX
380 	 * This if would be better writen as:
381 	 * if ((address & 0xffffff0000000000ULL) == OCTEON_MIO_BOOT_BASE) {
382 	 * but octeonreg.h can't be included here and we want this inlined
383 	 *
384 	 * Note that the SDK masks with 0x7ffff but that doesn't make sense.
385 	 * This is a physical address.
386 	 */
387 	if (((address >> 40) & 0xfffff) == (0x118)) {
388 		value = *(volatile uint64_t *)
389 		    (PHYS_TO_XKPHYS(MIO_BOOT_BIST_STAT, CCA_NC));
390 	}
391 }
392 
393 static inline void
394 octeon_iobdma_write_8(uint64_t value)
395 {
396 	uint64_t addr = 0xffffffffffffa200ULL;
397 
398 	*(volatile uint64_t *)addr = value;
399 }
400 
401 static inline void
402 octeon_lmtdma_write_8(off_t offset, uint64_t value)
403 {
404 	*(volatile uint64_t *)(0xffffffffffffa400ULL + offset) = value;
405 }
406 
407 static inline uint64_t
408 octeon_cvmseg_read_8(size_t offset)
409 {
410 	return *(volatile uint64_t *)(0xffffffffffff8000ULL + offset);
411 }
412 
413 static inline void
414 octeon_cvmseg_write_8(size_t offset, uint64_t value)
415 {
416 	*(volatile uint64_t *)(0xffffffffffff8000ULL + offset) = value;
417 }
418 
419 static inline uint32_t
420 octeon_get_coreid(void)
421 {
422 	uint32_t coreid;
423 
424 	__asm volatile (
425 		_ASM_PROLOGUE_OCTEON
426 		"	rdhwr	%0, $0\n"
427 		_ASM_EPILOGUE
428 		: "=r" (coreid));
429 	return coreid;
430 }
431 
432 static inline uint64_t
433 octeon_get_cycles(void)
434 {
435 	uint64_t tmp;
436 
437 	__asm volatile (
438 		_ASM_PROLOGUE_MIPS64
439 		"	dmfc0	%[tmp], $9, 6		\n"
440 		_ASM_EPILOGUE
441 		: [tmp]"=&r"(tmp));
442 	return tmp;
443 }
444 
445 static inline uint64_t
446 octeon_get_cvmctl(void)
447 {
448 	uint64_t tmp;
449 
450 	__asm volatile (
451 		_ASM_PROLOGUE_OCTEON
452 		"	dmfc0	%[tmp], $9, 7		\n"
453 		_ASM_EPILOGUE
454 		: [tmp]"=r"(tmp));
455 	return tmp;
456 }
457 
458 static inline uint64_t
459 octeon_get_cvmmemctl(void)
460 {
461 	uint64_t tmp;
462 
463 	__asm volatile (
464 		_ASM_PROLOGUE_OCTEON
465 		"	dmfc0	%[tmp], $11, 7		\n"
466 		_ASM_EPILOGUE
467 		: [tmp]"=r"(tmp));
468 	return tmp;
469 }
470 
471 static inline void
472 octeon_set_cvmmemctl(uint64_t val)
473 {
474 	__asm volatile (
475 		_ASM_PROLOGUE_OCTEON
476 		"	dmtc0	%[tmp], $11, 7		\n"
477 		_ASM_EPILOGUE
478 		: : [tmp]"r"(val) : "memory");
479 }
480 
481 static inline void
482 octeon_synciobdma(void)
483 {
484 	__asm volatile (
485 		_ASM_PROLOGUE_OCTEON
486 		"	synciobdma\n"
487 		_ASM_EPILOGUE
488 		: : : "memory");
489 }
490 
491 #endif	/* _MIPS_OCTEON_OCTEONVAR_H_ */
492