]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/nlm/hal/cop2.h
dts: Update our copy to Linux 4.17
[FreeBSD/FreeBSD.git] / sys / mips / nlm / hal / cop2.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * NETLOGIC_BSD
31  * $FreeBSD$
32  */
33
34 #ifndef __NLM_HAL_COP2_H__
35 #define __NLM_HAL_COP2_H__
36
37 #define COP2_TX_BUF             0
38 #define COP2_RX_BUF             1
39 #define COP2_TXMSGSTATUS        2
40 #define COP2_RXMSGSTATUS        3
41 #define COP2_MSGSTATUS1         4
42 #define COP2_MSGCONFIG          5
43 #define COP2_MSGERROR           6
44
45 #define CROSSTHR_POPQ_EN        0x01
46 #define VC0_POPQ_EN             0x02
47 #define VC1_POPQ_EN             0x04
48 #define VC2_POPQ_EN             0x08
49 #define VC3_POPQ_EN             0x10
50 #define ALL_VC_POPQ_EN          0x1E
51 #define ALL_VC_CT_POPQ_EN       0x1F
52
53 struct nlm_fmn_msg {
54         uint64_t msg[4];
55 };
56
57 #define NLM_DEFINE_COP2_ACCESSORS32(name, reg, sel)             \
58 static inline uint32_t nlm_read_c2_##name(void)                 \
59 {                                                               \
60         uint32_t __rv;                                          \
61         __asm__ __volatile__ (                                  \
62         ".set   push\n"                                         \
63         ".set   noreorder\n"                                    \
64         ".set   mips64\n"                                       \
65         "mfc2   %0, $%1, %2\n"                                  \
66         ".set   pop\n"                                          \
67         : "=r" (__rv)                                           \
68         : "i" (reg), "i" (sel));                                \
69         return __rv;                                            \
70 }                                                               \
71                                                                 \
72 static inline void nlm_write_c2_##name(uint32_t val)            \
73 {                                                               \
74         __asm__ __volatile__(                                   \
75         ".set   push\n"                                         \
76         ".set   noreorder\n"                                    \
77         ".set   mips64\n"                                       \
78         "mtc2   %0, $%1, %2\n"                                  \
79         ".set   pop\n"                                          \
80         : : "r" (val), "i" (reg), "i" (sel));                   \
81 } struct __hack
82
83 #if (__mips == 64)
84 #define NLM_DEFINE_COP2_ACCESSORS64(name, reg, sel)             \
85 static inline uint64_t nlm_read_c2_##name(void)                 \
86 {                                                               \
87         uint64_t __rv;                                          \
88         __asm__ __volatile__ (                                  \
89         ".set   push\n"                                         \
90         ".set   noreorder\n"                                    \
91         ".set   mips64\n"                                       \
92         "dmfc2  %0, $%1, %2\n"                                  \
93         ".set   pop\n"                                          \
94         : "=r" (__rv)                                           \
95         : "i" (reg), "i" (sel));                                \
96         return __rv;                                            \
97 }                                                               \
98                                                                 \
99 static inline void nlm_write_c2_##name(uint64_t val)            \
100 {                                                               \
101         __asm__ __volatile__ (                                  \
102         ".set   push\n"                                         \
103         ".set   noreorder\n"                                    \
104         ".set   mips64\n"                                       \
105         "dmtc2  %0, $%1, %2\n"                                  \
106         ".set   pop\n"                                          \
107         : : "r" (val), "i" (reg), "i" (sel));                   \
108 } struct __hack
109
110 #else
111
112 #define NLM_DEFINE_COP2_ACCESSORS64(name, reg, sel)             \
113 static inline uint64_t nlm_read_c2_##name(void)                 \
114 {                                                               \
115         uint32_t __high, __low;                                 \
116         __asm__ __volatile__ (                                  \
117         ".set   push\n"                                         \
118         ".set   noreorder\n"                                    \
119         ".set   mips64\n"                                       \
120         "dmfc2  $8, $%2, %3\n"                                  \
121         "dsra32 %0, $8, 0\n"                                    \
122         "sll    %1, $8, 0\n"                                    \
123         ".set   pop\n"                                          \
124         : "=r"(__high), "=r"(__low)                             \
125         : "i"(reg), "i"(sel)                                    \
126         : "$8");                                                \
127                                                                 \
128         return ((uint64_t)__high << 32) | __low;                \
129 }                                                               \
130                                                                 \
131 static inline void nlm_write_c2_##name(uint64_t val)            \
132 {                                                               \
133         uint32_t __high = val >> 32;                            \
134         uint32_t __low = val & 0xffffffff;                      \
135         __asm__ __volatile__ (                                  \
136         ".set   push\n"                                         \
137         ".set   noreorder\n"                                    \
138         ".set   mips64\n"                                       \
139         "dsll32 $8, %1, 0\n"                                    \
140         "dsll32 $9, %0, 0\n"                                    \
141         "dsrl32 $8, $8, 0\n"                                    \
142         "or     $8, $8, $9\n"                                   \
143         "dmtc2  $8, $%2, %3\n"                                  \
144         ".set   pop\n"                                          \
145         : : "r"(__high), "r"(__low),  "i"(reg), "i"(sel)        \
146         : "$8", "$9");                                          \
147 } struct __hack
148
149 #endif
150
151 NLM_DEFINE_COP2_ACCESSORS64(txbuf0, COP2_TX_BUF, 0);
152 NLM_DEFINE_COP2_ACCESSORS64(txbuf1, COP2_TX_BUF, 1);
153 NLM_DEFINE_COP2_ACCESSORS64(txbuf2, COP2_TX_BUF, 2);
154 NLM_DEFINE_COP2_ACCESSORS64(txbuf3, COP2_TX_BUF, 3);
155
156 NLM_DEFINE_COP2_ACCESSORS64(rxbuf0, COP2_RX_BUF, 0);
157 NLM_DEFINE_COP2_ACCESSORS64(rxbuf1, COP2_RX_BUF, 1);
158 NLM_DEFINE_COP2_ACCESSORS64(rxbuf2, COP2_RX_BUF, 2);
159 NLM_DEFINE_COP2_ACCESSORS64(rxbuf3, COP2_RX_BUF, 3);
160
161 NLM_DEFINE_COP2_ACCESSORS32(txmsgstatus, COP2_TXMSGSTATUS, 0);
162 NLM_DEFINE_COP2_ACCESSORS32(rxmsgstatus, COP2_RXMSGSTATUS, 0);
163 NLM_DEFINE_COP2_ACCESSORS32(msgstatus1, COP2_MSGSTATUS1, 0);
164 NLM_DEFINE_COP2_ACCESSORS32(msgconfig, COP2_MSGCONFIG, 0);
165 NLM_DEFINE_COP2_ACCESSORS32(msgerror0, COP2_MSGERROR, 0);
166 NLM_DEFINE_COP2_ACCESSORS32(msgerror1, COP2_MSGERROR, 1);
167 NLM_DEFINE_COP2_ACCESSORS32(msgerror2, COP2_MSGERROR, 2);
168 NLM_DEFINE_COP2_ACCESSORS32(msgerror3, COP2_MSGERROR, 3);
169
170 /* successful completion returns 1, else 0 */
171 static inline int
172 nlm_msgsend(int val)
173 {
174         int result;
175         __asm__ volatile (
176                 ".set push\n"
177                 ".set noreorder\n"
178                 ".set mips64\n"
179                 "move   $8, %1\n"
180                 "sync\n"
181                 "/* msgsnds     $9, $8 */\n"
182                 ".word  0x4a084801\n"
183                 "move   %0, $9\n"
184                 ".set pop\n"
185                 : "=r" (result)
186                 : "r" (val)
187                 : "$8", "$9");
188         return result;
189 }
190
191 static inline int
192 nlm_msgld(int vc)
193 {
194         int val;
195         __asm__ volatile (
196                 ".set push\n"
197                 ".set noreorder\n"
198                 ".set mips64\n"
199                 "move   $8, %1\n"
200                 "/* msgld       $9, $8 */\n"
201                 ".word 0x4a084802\n"
202                 "move   %0, $9\n"
203                 ".set pop\n"
204                 : "=r" (val)
205                 : "r" (vc)
206                 : "$8", "$9");
207         return val;
208 }
209
210 static inline void
211 nlm_msgwait(int vc)
212 {
213         __asm__ volatile (
214                 ".set push\n"
215                 ".set noreorder\n"
216                 ".set mips64\n"
217                 "move   $8, %0\n"
218                 "/* msgwait     $8 */\n"
219                 ".word 0x4a080003\n"
220                 ".set pop\n"
221                 : : "r" (vc)
222                 : "$8");
223 }
224
225 static inline int
226 nlm_fmn_msgsend(int dstid, int size, int swcode, struct nlm_fmn_msg *m)
227 {
228         uint32_t flags, status;
229         int rv;
230
231         size -= 1;
232         flags = nlm_save_flags_cop2();
233         switch (size) {
234         case 3:
235                 nlm_write_c2_txbuf3(m->msg[3]);
236         case 2:
237                 nlm_write_c2_txbuf2(m->msg[2]);
238         case 1:
239                 nlm_write_c2_txbuf1(m->msg[1]);
240         case 0:
241                 nlm_write_c2_txbuf0(m->msg[0]);
242         }
243
244         dstid |= ((swcode << 24) | (size << 16));
245         status = nlm_msgsend(dstid);
246         rv = !status;
247         if (rv != 0)
248                 rv = nlm_read_c2_txmsgstatus();
249         nlm_restore_flags(flags);
250
251         return rv;
252 }
253
254 static inline int
255 nlm_fmn_msgrcv(int vc, int *srcid, int *size, int *code, struct nlm_fmn_msg *m)
256 {
257         uint32_t status;
258         uint32_t msg_status, flags;
259         int tmp_sz, rv;
260
261         flags = nlm_save_flags_cop2();
262         status = nlm_msgld(vc); /* will return 0, if error */
263         rv = !status;
264         if (rv == 0) {
265                 msg_status = nlm_read_c2_rxmsgstatus();
266                 *size = ((msg_status >> 26) & 0x3) + 1;
267                 *code = (msg_status >> 18) & 0xff;
268                 *srcid = (msg_status >> 4) & 0xfff;
269                 tmp_sz = *size - 1;
270                 switch (tmp_sz) {
271                 case 3:
272                         m->msg[3] = nlm_read_c2_rxbuf3();
273                 case 2:
274                         m->msg[2] = nlm_read_c2_rxbuf2();
275                 case 1:
276                         m->msg[1] = nlm_read_c2_rxbuf1();
277                 case 0:
278                         m->msg[0] = nlm_read_c2_rxbuf0();
279                 }
280         }
281         nlm_restore_flags(flags);
282
283         return rv;
284 }
285
286 static inline void
287 nlm_fmn_cpu_init(int int_vec, int ecc_en, int v0pe, int v1pe, int v2pe, int v3pe)
288 {
289         uint32_t val = nlm_read_c2_msgconfig();
290
291         /* Note: in XLP PRM 0.8.1, the int_vec bits are un-documented
292          * in msgconfig register of cop2.
293          * As per chip/cpu RTL, [16:20] bits consist of int_vec.
294          */
295         val |= (((int_vec & 0x1f) << 16) |
296                 ((ecc_en & 0x1) << 8) |
297                 ((v3pe & 0x1) << 4) |
298                 ((v2pe & 0x1) << 3) |
299                 ((v1pe & 0x1) << 2) |
300                 ((v0pe & 0x1) << 1));
301
302         nlm_write_c2_msgconfig(val);
303 }
304 #endif