xref: /openbsd/sys/arch/octeon/dev/cn30xxfau.c (revision 52334306)
1 /*	$OpenBSD: cn30xxfau.c,v 1.7 2022/12/28 01:39:21 yasuoka 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 AUTHORS 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 AUTHORS 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/param.h>
30 #include <sys/systm.h>
31 
32 #include <machine/octeonvar.h>
33 
34 #include <octeon/dev/cn30xxfaureg.h>
35 #include <octeon/dev/cn30xxfauvar.h>
36 
37 int64_t	cn30xxfau_op_load(uint64_t);
38 void	cn30xxfau_op_iobdma(int, uint64_t);
39 void	cn30xxfau_op_store(uint64_t, int64_t);
40 int64_t	cn30xxfau_op_load_paddr(int, int, int) __unused;
41 void	cn30xxfau_op_iobdma_store_data(int, int, int, int, int);
42 void	cn30xxfau_op_store_paddr(int, int, int64_t);
43 
44 
45 /* ---- utilities */
46 
47 int64_t
cn30xxfau_op_load(uint64_t args)48 cn30xxfau_op_load(uint64_t args)
49 {
50 	paddr_t addr;
51 
52 	addr =
53 	    ((uint64_t)1 << 48) |
54 	    ((uint64_t)(CN30XXFAU_MAJORDID & 0x1f) << 43) |
55 	    ((uint64_t)(CN30XXFAU_SUBDID & 0x7) << 40) |
56 	    ((uint64_t)(args & 0xfffffffffULL) << 0);
57 	return octeon_xkphys_read_8(addr);
58 }
59 
60 void
cn30xxfau_op_store(uint64_t args,int64_t value)61 cn30xxfau_op_store(uint64_t args, int64_t value)
62 {
63 	paddr_t addr;
64 
65 	addr =
66 	    ((uint64_t)1 << 48) |
67 	    ((uint64_t)(CN30XXFAU_MAJORDID & 0x1f) << 43) |
68 	    ((uint64_t)(CN30XXFAU_SUBDID & 0x7) << 40) |
69 	    ((uint64_t)(args & 0xfffffffffULL) << 0);
70 	octeon_xkphys_write_8(addr, value);
71 }
72 
73 /* ---- operation primitives */
74 
75 /*
76  * 3.4 Fetch-and-Add Operations
77  */
78 
79 /* 3.4.1 Load Operations */
80 
81 /* Load Physical Address for FAU Operations */
82 
83 int64_t
cn30xxfau_op_load_paddr(int incval,int tagwait,int reg)84 cn30xxfau_op_load_paddr(int incval, int tagwait, int reg)
85 {
86 	uint64_t args;
87 
88 	args =
89 	    ((uint64_t)(incval & 0x3fffff) << 14) |
90 	    ((uint64_t)(tagwait & 0x1) << 13) |
91 	    ((uint64_t)(reg & 0x7ff) << 0);
92 	return cn30xxfau_op_load(args);
93 }
94 
95 /* 3.4.3 Store Operations */
96 
97 /* Store Physical Address for FAU Operations */
98 
99 void
cn30xxfau_op_store_paddr(int noadd,int reg,int64_t value)100 cn30xxfau_op_store_paddr(int noadd, int reg, int64_t value)
101 {
102 	uint64_t args;
103 
104 	args =
105 	    ((uint64_t)(noadd & 0x1) << 13) |
106 	    ((uint64_t)(reg & 0x7ff) << 0);
107 	cn30xxfau_op_store(args, value);
108 }
109 
110 /* ---- API */
111 
112 void
cn30xxfau_op_init(struct cn30xxfau_desc * fd,size_t scroff,size_t regno)113 cn30xxfau_op_init(struct cn30xxfau_desc *fd, size_t scroff, size_t regno)
114 {
115 	fd->fd_scroff = scroff;
116 	fd->fd_regno = regno;
117 }
118 
119 uint64_t
cn30xxfau_op_save(struct cn30xxfau_desc * fd)120 cn30xxfau_op_save(struct cn30xxfau_desc *fd)
121 {
122 	octeon_synciobdma();
123 	return octeon_cvmseg_read_8(fd->fd_scroff);
124 }
125 
126 void
cn30xxfau_op_restore(struct cn30xxfau_desc * fd,uint64_t backup)127 cn30xxfau_op_restore(struct cn30xxfau_desc *fd, uint64_t backup)
128 {
129 	octeon_cvmseg_write_8(fd->fd_scroff, backup);
130 }
131 
132 int64_t
cn30xxfau_op_inc_8(struct cn30xxfau_desc * fd,int64_t v)133 cn30xxfau_op_inc_8(struct cn30xxfau_desc *fd, int64_t v)
134 {
135 	cn30xxfau_op_iobdma_store_data(fd->fd_scroff, v, 0, OCT_FAU_OP_SIZE_64/* XXX */,
136 	    fd->fd_regno);
137 	octeon_synciobdma();
138 	return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
139 }
140 
141 int64_t
cn30xxfau_op_incwait_8(struct cn30xxfau_desc * fd,int v)142 cn30xxfau_op_incwait_8(struct cn30xxfau_desc *fd, int v)
143 {
144 	cn30xxfau_op_iobdma_store_data(fd->fd_scroff, v, 1, OCT_FAU_OP_SIZE_64/* XXX */,
145 	    fd->fd_regno);
146 	octeon_synciobdma();
147 	return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
148 }
149 
150 void
cn30xxfau_op_add_8(struct cn30xxfau_desc * fd,int64_t v)151 cn30xxfau_op_add_8(struct cn30xxfau_desc *fd, int64_t v)
152 {
153 	cn30xxfau_op_store_paddr(0, fd->fd_regno, v);
154 }
155 
156 void
cn30xxfau_op_set_8(struct cn30xxfau_desc * fd,int64_t v)157 cn30xxfau_op_set_8(struct cn30xxfau_desc *fd, int64_t v)
158 {
159 	cn30xxfau_op_store_paddr(1, fd->fd_regno, v);
160 }
161