octeon_fau.c revision 1.1.2.2 1 /* $NetBSD: octeon_fau.c,v 1.1.2.2 2015/06/06 14:40:01 skrll Exp $ */
2
3 /*
4 * Copyright (c) 2007 Internet Initiative Japan, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: octeon_fau.c,v 1.1.2.2 2015/06/06 14:40:01 skrll Exp $");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <mips/locore.h>
35 #include <mips/cavium/octeonvar.h>
36 #include <mips/cavium/dev/octeon_faureg.h>
37 #include <mips/cavium/dev/octeon_fauvar.h>
38
39 static inline int64_t octeon_fau_op_load(uint64_t);
40 static inline void octeon_fau_op_iobdma(int, uint64_t);
41 static inline void octeon_fau_op_store(uint64_t, int64_t);
42 static inline int64_t octeon_fau_op_load_paddr(int, int, int);
43 static inline void octeon_fau_op_iobdma_store_data(int, int, int, int, int);
44 static inline void octeon_fau_op_store_paddr(int, int, int64_t);
45
46
47 /* ---- utilities */
48
49 static inline int64_t
50 octeon_fau_op_load(uint64_t args)
51 {
52 paddr_t addr;
53
54 addr =
55 ((uint64_t)1 << 48) |
56 ((uint64_t)(CN30XXFAU_MAJORDID & 0x1f) << 43) |
57 ((uint64_t)(CN30XXFAU_SUBDID & 0x7) << 40) |
58 ((uint64_t)(args & 0xfffffffffULL) << 0);
59 return octeon_read_csr(addr);
60 }
61
62 static inline void
63 octeon_fau_op_store(uint64_t args, int64_t value)
64 {
65 paddr_t addr;
66
67 addr =
68 ((uint64_t)1 << 48) |
69 ((uint64_t)(CN30XXFAU_MAJORDID & 0x1f) << 43) |
70 ((uint64_t)(CN30XXFAU_SUBDID & 0x7) << 40) |
71 ((uint64_t)(args & 0xfffffffffULL) << 0);
72 octeon_write_csr(addr, value);
73 }
74
75 /* ---- operation primitives */
76
77 /*
78 * Fetch-and-Add Operations
79 */
80
81 /* Load Operations */
82
83 /* Load Physical Address for FAU Operations */
84
85 static inline int64_t
86 octeon_fau_op_load_paddr(int incval, int tagwait, int reg)
87 {
88 uint64_t args;
89
90 args =
91 ((uint64_t)(incval & 0x3fffff) << 14) |
92 ((uint64_t)(tagwait & 0x1) << 13) |
93 ((uint64_t)(reg & 0x7ff) << 0);
94 return octeon_fau_op_load(args);
95 }
96
97 /* Store Operations */
98
99 /* Store Physical Address for FAU Operations */
100
101 static inline void
102 octeon_fau_op_store_paddr(int noadd, int reg, int64_t value)
103 {
104 uint64_t args;
105
106 args =
107 ((uint64_t)(noadd & 0x1) << 13) |
108 ((uint64_t)(reg & 0x7ff) << 0);
109 octeon_fau_op_store(args, value);
110 }
111
112 /* ---- API */
113
114 void
115 octeon_fau_op_init(struct octeon_fau_desc *fd, size_t scroff, size_t regno)
116 {
117 fd->fd_scroff = scroff;
118 fd->fd_regno = regno;
119 }
120
121 uint64_t
122 octeon_fau_op_save(struct octeon_fau_desc *fd)
123 {
124 OCTEON_SYNCIOBDMA/* XXX */;
125 return octeon_cvmseg_read_8(fd->fd_scroff);
126 }
127
128 void
129 octeon_fau_op_restore(struct octeon_fau_desc *fd, uint64_t backup)
130 {
131 octeon_cvmseg_write_8(fd->fd_scroff, backup);
132 }
133
134 int64_t
135 octeon_fau_op_inc_8(struct octeon_fau_desc *fd, int64_t v)
136 {
137 octeon_fau_op_iobdma_store_data(fd->fd_scroff, v, 0, OCT_FAU_OP_SIZE_64/* XXX */,
138 fd->fd_regno);
139 OCTEON_SYNCIOBDMA/* XXX */;
140 return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
141 }
142
143 int64_t
144 octeon_fau_op_incwait_8(struct octeon_fau_desc *fd, int v)
145 {
146 octeon_fau_op_iobdma_store_data(fd->fd_scroff, v, 1, OCT_FAU_OP_SIZE_64/* XXX */,
147 fd->fd_regno);
148 /* XXX */
149 OCTEON_SYNCIOBDMA/* XXX */;
150 /* XXX */
151 return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
152 }
153
154 void
155 octeon_fau_op_add_8(struct octeon_fau_desc *fd, int64_t v)
156 {
157 octeon_fau_op_store_paddr(0, fd->fd_regno, v);
158 }
159
160 void
161 octeon_fau_op_set_8(struct octeon_fau_desc *fd, int64_t v)
162 {
163 octeon_fau_op_store_paddr(1, fd->fd_regno, v);
164 }
165