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