xref: /netbsd-src/sys/arch/mips/cavium/dev/octeon_fau.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: octeon_fau.c,v 1.1 2015/04/29 08:32:01 hikaru 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 2015/04/29 08:32:01 hikaru 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