xref: /openbsd/sys/arch/octeon/include/octeonvar.h (revision 9b7c3dbb)
1 /*	$OpenBSD: octeonvar.h,v 1.31 2016/07/16 10:19:55 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 /*
79  * FPA map
80  */
81 
82 #define	OCTEON_POOL_NO_PKT	0
83 #define	OCTEON_POOL_NO_WQE	1
84 #define	OCTEON_POOL_NO_CMD	2
85 #define	OCTEON_POOL_NO_SG	3
86 #define	OCTEON_POOL_NO_XXX_4	4
87 #define	OCTEON_POOL_NO_XXX_5	5
88 #define	OCTEON_POOL_NO_XXX_6	6
89 #define	OCTEON_POOL_NO_DUMP	7	/* FPA debug dump */
90 
91 #define	OCTEON_POOL_SIZE_PKT	1920	/* 128 x 15 */
92 #define	OCTEON_POOL_SIZE_WQE	128	/* 128 x 1 */
93 #define	OCTEON_POOL_SIZE_CMD	1024	/* 128 x 8 */
94 #define	OCTEON_POOL_SIZE_SG	128	/* 128 x 1 */
95 #define	OCTEON_POOL_SIZE_XXX_4	0
96 #define	OCTEON_POOL_SIZE_XXX_5	0
97 #define	OCTEON_POOL_SIZE_XXX_6	0
98 #define	OCTEON_POOL_SIZE_XXX_7	0
99 
100 #define	OCTEON_POOL_NELEMS_PKT		4096
101 #define	OCTEON_POOL_NELEMS_WQE		4096
102 #define	OCTEON_POOL_NELEMS_CMD		32
103 #define	OCTEON_POOL_NELEMS_SG		4096
104 #define	OCTEON_POOL_NELEMS_XXX_4	0
105 #define	OCTEON_POOL_NELEMS_XXX_5	0
106 #define	OCTEON_POOL_NELEMS_XXX_6	0
107 #define	OCTEON_POOL_NELEMS_XXX_7	0
108 
109 /*
110  * CVMSEG (``scratch'') memory map
111  */
112 struct octeon_cvmseg_map {
113 	uint64_t		csm_pow_intr;
114 
115 	struct octeon_cvmseg_ether_map {
116 		uint64_t	csm_ether_fau_done;
117 	} csm_ether[12/* XXX */];
118 } __packed;
119 #define	OCTEON_CVMSEG_OFFSET(entry) \
120 	offsetof(struct octeon_cvmseg_map, entry)
121 #define	OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
122 	(offsetof(struct octeon_cvmseg_map, csm_ether) + \
123 	 sizeof(struct octeon_cvmseg_ether_map) * (n) + \
124 	 offsetof(struct octeon_cvmseg_ether_map, entry))
125 
126 /*
127  * FAU register map
128  *
129  * => FAU registers exist in FAU unit
130  * => devices (PKO) can access these registers
131  * => CPU can read those values after loading them into CVMSEG
132  */
133 struct octeon_fau_map {
134 	struct {
135 		/* PKO command index */
136 		uint64_t	_fau_map_port_pkocmdidx;
137 		/* send requested */
138 		uint64_t	_fau_map_port_txreq;
139 		/* send completed */
140 		uint64_t	_fau_map_port_txdone;
141 		/* XXX */
142 		uint64_t	_fau_map_port_pad;
143 	} __packed _fau_map_port[3];
144 };
145 
146 /*
147  * POW qos/group map
148  */
149 
150 #define	OCTEON_POW_QOS_PIP		0
151 #define	OCTEON_POW_QOS_CORE1		1
152 #define	OCTEON_POW_QOS_XXX_2		2
153 #define	OCTEON_POW_QOS_XXX_3		3
154 #define	OCTEON_POW_QOS_XXX_4		4
155 #define	OCTEON_POW_QOS_XXX_5		5
156 #define	OCTEON_POW_QOS_XXX_6		6
157 #define	OCTEON_POW_QOS_XXX_7		7
158 
159 #define	OCTEON_POW_GROUP_PIP		0
160 #define	OCTEON_POW_GROUP_XXX_1		1
161 #define	OCTEON_POW_GROUP_XXX_2		2
162 #define	OCTEON_POW_GROUP_XXX_3		3
163 #define	OCTEON_POW_GROUP_XXX_4		4
164 #define	OCTEON_POW_GROUP_XXX_5		5
165 #define	OCTEON_POW_GROUP_XXX_6		6
166 #define	OCTEON_POW_GROUP_CORE1_SEND	7
167 #define	OCTEON_POW_GROUP_CORE1_TASK_0	8
168 #define	OCTEON_POW_GROUP_CORE1_TASK_1	9
169 #define	OCTEON_POW_GROUP_CORE1_TASK_2	10
170 #define	OCTEON_POW_GROUP_CORE1_TASK_3	11
171 #define	OCTEON_POW_GROUP_CORE1_TASK_4	12
172 #define	OCTEON_POW_GROUP_CORE1_TASK_5	13
173 #define	OCTEON_POW_GROUP_CORE1_TASK_6	14
174 #define	OCTEON_POW_GROUP_CORE1_TASK_7	15
175 
176 /*
177  * Octeon board types known to work with OpenBSD/octeon.
178  * NB: BOARD_TYPE_UBIQUITI_E100 is also used by other vendors, but we don't run
179  * on those boards yet.
180  */
181 #define	BOARD_TYPE_UBIQUITI_E100	20002
182 #define	BOARD_TYPE_UBIQUITI_E200	20003
183 #define	BOARD_TYPE_DSR_500		20015
184 
185 #if defined(_KERNEL) || defined(_STANDALONE)
186 #define OCTEON_ARGV_MAX 64
187 
188 /* Maximum number of cores on <= CN52XX */
189 #define OCTEON_MAXCPUS	4
190 
191 struct boot_desc {
192 	uint32_t	desc_ver;
193 	uint32_t	desc_size;
194 	uint64_t	stack_top;
195 	uint64_t 	heap_start;
196 	uint64_t	heap_end;
197 	uint64_t      	__unused17;
198 	uint64_t     	__unused16;
199 	uint32_t      	__unused18;
200 	uint32_t      	__unused15;
201 	uint32_t      	__unused14;
202 	uint32_t	argc;
203 	uint32_t	argv[OCTEON_ARGV_MAX];
204 	uint32_t	flags;
205 	uint32_t	core_mask;
206 	uint32_t	dram_size;
207 	uint32_t	phy_mem_desc_addr;
208 	uint32_t	debugger_flag_addr;
209 	uint32_t	eclock;
210 	uint32_t      	__unused10;
211 	uint32_t      	__unused9;
212 	uint16_t      	__unused8;
213 	uint8_t 	__unused7;
214 	uint8_t 	__unused6;
215 	uint16_t 	__unused5;
216 	uint8_t 	__unused4;
217 	uint8_t 	__unused3;
218 	uint8_t 	__unused2[20];
219 	uint8_t 	__unused1[6];
220 	uint8_t 	__unused0;
221 	uint64_t 	boot_info_addr;
222 };
223 
224 struct boot_info {
225 	uint32_t ver_major;
226 	uint32_t ver_minor;
227 	uint64_t stack_top;
228 	uint64_t heap_start;
229 	uint64_t heap_end;
230 	uint64_t boot_desc_addr;
231 	uint32_t exception_base_addr;
232 	uint32_t stack_size;
233 	uint32_t flags;
234 	uint32_t core_mask;
235 	uint32_t dram_size;
236 	uint32_t phys_mem_desc_addr;
237 	uint32_t debugger_flags_addr;
238 	uint32_t eclock;
239 	uint32_t dclock;
240 	uint32_t __unused0;
241 	uint16_t board_type;
242 	uint8_t board_rev_major;
243 	uint8_t board_rev_minor;
244 	uint16_t __unused1;
245 	uint8_t __unused2;
246 	uint8_t __unused3;
247 	char board_serial[20];
248 	uint8_t mac_addr_base[6];
249 	uint8_t mac_addr_count;
250 	uint64_t cf_common_addr;
251 	uint64_t cf_attr_addr;
252 	uint64_t led_display_addr;
253 	uint32_t dfaclock;
254 	uint32_t config_flags;
255 	/* The fields below are available when ver_minor >= 3. */
256 	uint64_t fdt_addr;
257 };
258 
259 struct octeon_bootmem_desc {
260 	uint32_t	lock;
261 	uint32_t	flags;
262 	uint64_t	head_addr;
263 	uint32_t	major_version;
264 	uint32_t	minor_version;
265 	uint64_t	app_data_addr;
266 	uint64_t	app_data_size;
267 	uint32_t	named_block_num_blocks;
268 	uint32_t	named_block_name_len;
269 	uint64_t	named_block_array_addr;
270 };
271 
272 struct octeon_bootmem_block {
273 	uint64_t	next;
274 	uint64_t	size;
275 };
276 
277 extern struct boot_desc *octeon_boot_desc;
278 extern struct boot_info *octeon_boot_info;
279 
280 #ifdef _KERNEL
281 /* Device capabilities advertised in boot_info->config_flags */
282 #define BOOTINFO_CFG_FLAG_PCI_HOST	(1ull << 0)
283 #define BOOTINFO_CFG_FLAG_PCI_TARGET	(1ull << 1)
284 #define BOOTINFO_CFG_FLAG_DEBUG		(1ull << 2)
285 #define BOOTINFO_CFG_FLAG_NO_MAGIC	(1ull << 3)
286 
287 int	octeon_ioclock_speed(void);
288 
289 #endif /* _KERNEL */
290 #endif /* _KERNEL || _STANDALONE */
291 
292 static inline int
293 ffs64(uint64_t val)
294 {
295 	int ret;
296 
297 	__asm volatile ( \
298 		_ASM_PROLOGUE_MIPS64
299 		"	dclz	%0, %1			\n"
300 		_ASM_EPILOGUE
301 		: "=r"(ret) : "r"(val));
302 	return 64 - ret;
303 }
304 
305 static inline int
306 ffs32(uint32_t val)
307 {
308 	int ret;
309 
310 	__asm __volatile ( \
311 		_ASM_PROLOGUE_MIPS64
312 		"	clz	%0, %1			\n"
313 		_ASM_EPILOGUE
314 		: "=r"(ret) : "r"(val));
315 	return 32 - ret;
316 }
317 
318 static inline uint64_t
319 octeon_xkphys_read_8(paddr_t address)
320 {
321 	volatile uint64_t *p =
322 	    (volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC));
323 	return (*p);
324 }
325 
326 #define	MIO_BOOT_BIST_STAT			0x00011800000000f8ULL
327 static inline void
328 octeon_xkphys_write_8(paddr_t address, uint64_t value)
329 {
330 	*(volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)) = value;
331 
332 	/*
333 	 * It seems an immediate read is necessary when doing a write to an RSL
334 	 * register in order to complete the write.
335 	 * We use MIO_BOOT_BIST_STAT because it's apparently the fastest
336 	 * write.
337 	 */
338 
339 	/*
340 	 * XXX
341 	 * This if would be better writen as:
342 	 * if ((address & 0xffffff0000000000ULL) == OCTEON_MIO_BOOT_BASE) {
343 	 * but octeonreg.h can't be included here and we want this inlined
344 	 *
345 	 * Note that the SDK masks with 0x7ffff but that doesn't make sense.
346 	 * This is a physical address.
347 	 */
348 	if (((address >> 40) & 0xfffff) == (0x118)) {
349 		value = *(volatile uint64_t *)
350 		    (PHYS_TO_XKPHYS(MIO_BOOT_BIST_STAT, CCA_NC));
351 	}
352 }
353 
354 static inline void
355 octeon_iobdma_write_8(uint64_t value)
356 {
357 	uint64_t addr = 0xffffffffffffa200ULL;
358 
359 	*(volatile uint64_t *)addr = value;
360 }
361 
362 static inline uint64_t
363 octeon_cvmseg_read_8(size_t offset)
364 {
365 	return octeon_xkphys_read_8(0xffffffffffff8000ULL + offset);
366 }
367 
368 static inline void
369 octeon_cvmseg_write_8(size_t offset, uint64_t value)
370 {
371 	octeon_xkphys_write_8(0xffffffffffff8000ULL + offset, value);
372 }
373 
374 static inline uint64_t
375 octeon_get_cycles(void)
376 {
377 	uint64_t tmp;
378 
379 	__asm volatile (
380 		_ASM_PROLOGUE_MIPS64
381 		"	dmfc0	%[tmp], $9, 6		\n"
382 		_ASM_EPILOGUE
383 		: [tmp]"=&r"(tmp));
384 	return tmp;
385 }
386 
387 static inline void
388 octeon_synciobdma(void)
389 {
390 	__asm volatile (
391 		_ASM_PROLOGUE_OCTEON
392 		"	synciobdma\n"
393 		_ASM_EPILOGUE
394 		: : : "memory");
395 }
396 
397 #endif	/* _MIPS_OCTEON_OCTEONVAR_H_ */
398