xref: /dpdk/drivers/net/octeontx/base/octeontx_io.h (revision eb6d5a0af9a05bf940ba19ec1ddbe575b5e7540b)
1 /*
2  *   BSD LICENSE
3  *
4  *   Copyright (C) Cavium Inc. 2017. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Cavium networks nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef __OCTEONTX_IO_H__
34 #define __OCTEONTX_IO_H__
35 
36 #include <stddef.h>
37 #include <stdint.h>
38 
39 #include <rte_io.h>
40 
41 /* In Cavium OcteonTX SoC, all accesses to the device registers are
42  * implicitly strongly ordered. So, The relaxed version of IO operation is
43  * safe to use with out any IO memory barriers.
44  */
45 #define octeontx_read64 rte_read64_relaxed
46 #define octeontx_write64 rte_write64_relaxed
47 
48 /* ARM64 specific functions */
49 #if defined(RTE_ARCH_ARM64)
50 #define octeontx_prefetch_store_keep(_ptr) ({\
51 	asm volatile("prfm pstl1keep, %a0\n" : : "p" (_ptr)); })
52 
53 #define octeontx_load_pair(val0, val1, addr) ({		\
54 			asm volatile(			\
55 			"ldp %x[x0], %x[x1], [%x[p1]]"	\
56 			:[x0]"=r"(val0), [x1]"=r"(val1) \
57 			:[p1]"r"(addr)			\
58 			); })
59 
60 #define octeontx_store_pair(val0, val1, addr) ({		\
61 			asm volatile(			\
62 			"stp %x[x0], %x[x1], [%x[p1]]"	\
63 			::[x0]"r"(val0), [x1]"r"(val1), [p1]"r"(addr) \
64 			); })
65 #else /* Un optimized functions for building on non arm64 arch */
66 
67 #define octeontx_prefetch_store_keep(_ptr) do {} while (0)
68 
69 #define octeontx_load_pair(val0, val1, addr)		\
70 do {							\
71 	val0 = rte_read64(addr);			\
72 	val1 = rte_read64(((uint8_t *)addr) + 8);	\
73 } while (0)
74 
75 #define octeontx_store_pair(val0, val1, addr)		\
76 do {							\
77 	rte_write64(val0, addr);			\
78 	rte_write64(val1, (((uint8_t *)addr) + 8));	\
79 } while (0)
80 #endif
81 
82 #if defined(RTE_ARCH_ARM64)
83 /**
84  * Perform an atomic fetch-and-add operation.
85  */
86 static inline uint64_t
87 octeontx_reg_ldadd_u64(void *addr, int64_t off)
88 {
89 	uint64_t old_val;
90 
91 	__asm__ volatile(
92 		" .cpu		generic+lse\n"
93 		" ldadd	%1, %0, [%2]\n"
94 		: "=r" (old_val) : "r" (off), "r" (addr) : "memory");
95 
96 	return old_val;
97 }
98 
99 /**
100  * Perform a LMTST operation - an atomic write of up to 128 byte to
101  * an I/O block that supports this operation type.
102  *
103  * @param lmtline_va is the address where LMTLINE is mapped
104  * @param ioreg_va is the virtual address of the device register
105  * @param cmdbuf is the array of peripheral commands to execute
106  * @param cmdsize is the number of 64-bit words in 'cmdbuf'
107  *
108  * @return N/A
109  */
110 static inline void
111 octeontx_reg_lmtst(void *lmtline_va, void *ioreg_va, const uint64_t cmdbuf[],
112 		   uint64_t cmdsize)
113 {
114 	uint64_t result;
115 	uint64_t word_count;
116 	uint64_t *lmtline = lmtline_va;
117 
118 	word_count = cmdsize;
119 
120 	do {
121 		/* Copy commands to LMTLINE */
122 		for (result = 0; result < word_count; result += 2) {
123 			lmtline[result + 0] = cmdbuf[result + 0];
124 			lmtline[result + 1] = cmdbuf[result + 1];
125 		}
126 
127 		/* LDEOR initiates atomic transfer to I/O device */
128 		__asm__ volatile(
129 			" .cpu		generic+lse\n"
130 			" ldeor	xzr, %0, [%1]\n"
131 			: "=r" (result) : "r" (ioreg_va) : "memory");
132 	} while (!result);
133 }
134 
135 #else
136 
137 static inline uint64_t
138 octeontx_reg_ldadd_u64(void *addr, int64_t off)
139 {
140 	RTE_SET_USED(addr);
141 	RTE_SET_USED(off);
142 	return 0;
143 }
144 
145 static inline void
146 octeontx_reg_lmtst(void *lmtline_va, void *ioreg_va, const uint64_t cmdbuf[],
147 		   uint64_t cmdsize)
148 {
149 	RTE_SET_USED(lmtline_va);
150 	RTE_SET_USED(ioreg_va);
151 	RTE_SET_USED(cmdbuf);
152 	RTE_SET_USED(cmdsize);
153 }
154 
155 #endif
156 #endif /* __OCTEONTX_IO_H__ */
157