1*ca987d46SWarner Losh /*-
2*ca987d46SWarner Losh * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
3*ca987d46SWarner Losh *
4*ca987d46SWarner Losh * Redistribution and use in source and binary forms, with or without
5*ca987d46SWarner Losh * modification, are permitted provided that the following conditions
6*ca987d46SWarner Losh * are met:
7*ca987d46SWarner Losh * 1. Redistributions of source code must retain the above copyright
8*ca987d46SWarner Losh * notice, this list of conditions and the following disclaimer.
9*ca987d46SWarner Losh * 2. Redistributions in binary form must reproduce the above copyright
10*ca987d46SWarner Losh * notice, this list of conditions and the following disclaimer in the
11*ca987d46SWarner Losh * documentation and/or other materials provided with the distribution.
12*ca987d46SWarner Losh *
13*ca987d46SWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14*ca987d46SWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15*ca987d46SWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16*ca987d46SWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17*ca987d46SWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18*ca987d46SWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19*ca987d46SWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20*ca987d46SWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21*ca987d46SWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22*ca987d46SWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23*ca987d46SWarner Losh * SUCH DAMAGE.
24*ca987d46SWarner Losh */
25*ca987d46SWarner Losh
26*ca987d46SWarner Losh #include <bsd_kernel.h>
27*ca987d46SWarner Losh
28*ca987d46SWarner Losh struct burst {
29*ca987d46SWarner Losh uint32_t dw0;
30*ca987d46SWarner Losh uint32_t dw1;
31*ca987d46SWarner Losh uint32_t dw2;
32*ca987d46SWarner Losh uint32_t dw3;
33*ca987d46SWarner Losh uint32_t dw4;
34*ca987d46SWarner Losh uint32_t dw5;
35*ca987d46SWarner Losh uint32_t dw6;
36*ca987d46SWarner Losh uint32_t dw7;
37*ca987d46SWarner Losh };
38*ca987d46SWarner Losh
39*ca987d46SWarner Losh int
bus_space_subregion(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,bus_size_t size,bus_space_handle_t * nbshp)40*ca987d46SWarner Losh bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
41*ca987d46SWarner Losh bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
42*ca987d46SWarner Losh {
43*ca987d46SWarner Losh
44*ca987d46SWarner Losh *nbshp = bsh + offset;
45*ca987d46SWarner Losh return (0);
46*ca987d46SWarner Losh }
47*ca987d46SWarner Losh
48*ca987d46SWarner Losh void
bus_space_read_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t * datap,bus_size_t count)49*ca987d46SWarner Losh bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h,
50*ca987d46SWarner Losh bus_size_t offset, uint8_t *datap, bus_size_t count)
51*ca987d46SWarner Losh {
52*ca987d46SWarner Losh while (count--) {
53*ca987d46SWarner Losh *datap++ = bus_space_read_1(t, h, offset);
54*ca987d46SWarner Losh }
55*ca987d46SWarner Losh }
56*ca987d46SWarner Losh
57*ca987d46SWarner Losh void
bus_space_read_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint16_t * datap,bus_size_t count)58*ca987d46SWarner Losh bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h,
59*ca987d46SWarner Losh bus_size_t offset, uint16_t *datap, bus_size_t count)
60*ca987d46SWarner Losh {
61*ca987d46SWarner Losh while (count--) {
62*ca987d46SWarner Losh *datap++ = bus_space_read_2(t, h, offset);
63*ca987d46SWarner Losh }
64*ca987d46SWarner Losh }
65*ca987d46SWarner Losh
66*ca987d46SWarner Losh void
bus_space_read_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t * datap,bus_size_t count)67*ca987d46SWarner Losh bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h,
68*ca987d46SWarner Losh bus_size_t offset, uint32_t *datap, bus_size_t count)
69*ca987d46SWarner Losh {
70*ca987d46SWarner Losh h += offset;
71*ca987d46SWarner Losh
72*ca987d46SWarner Losh while (count--) {
73*ca987d46SWarner Losh *datap++ = *((volatile uint32_t *)h);
74*ca987d46SWarner Losh }
75*ca987d46SWarner Losh }
76*ca987d46SWarner Losh
77*ca987d46SWarner Losh void
bus_space_write_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t * datap,bus_size_t count)78*ca987d46SWarner Losh bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h,
79*ca987d46SWarner Losh bus_size_t offset, uint8_t *datap, bus_size_t count)
80*ca987d46SWarner Losh {
81*ca987d46SWarner Losh while (count--) {
82*ca987d46SWarner Losh uint8_t temp = *datap++;
83*ca987d46SWarner Losh
84*ca987d46SWarner Losh bus_space_write_1(t, h, offset, temp);
85*ca987d46SWarner Losh }
86*ca987d46SWarner Losh }
87*ca987d46SWarner Losh
88*ca987d46SWarner Losh void
bus_space_write_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint16_t * datap,bus_size_t count)89*ca987d46SWarner Losh bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h,
90*ca987d46SWarner Losh bus_size_t offset, uint16_t *datap, bus_size_t count)
91*ca987d46SWarner Losh {
92*ca987d46SWarner Losh while (count--) {
93*ca987d46SWarner Losh uint16_t temp = *datap++;
94*ca987d46SWarner Losh
95*ca987d46SWarner Losh bus_space_write_2(t, h, offset, temp);
96*ca987d46SWarner Losh }
97*ca987d46SWarner Losh }
98*ca987d46SWarner Losh
99*ca987d46SWarner Losh void
bus_space_write_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t * datap,bus_size_t count)100*ca987d46SWarner Losh bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h,
101*ca987d46SWarner Losh bus_size_t offset, uint32_t *datap, bus_size_t count)
102*ca987d46SWarner Losh {
103*ca987d46SWarner Losh h += offset;
104*ca987d46SWarner Losh
105*ca987d46SWarner Losh while (count--) {
106*ca987d46SWarner Losh *((volatile uint32_t *)h) = *datap++;
107*ca987d46SWarner Losh }
108*ca987d46SWarner Losh }
109*ca987d46SWarner Losh
110*ca987d46SWarner Losh void
bus_space_write_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t data)111*ca987d46SWarner Losh bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h,
112*ca987d46SWarner Losh bus_size_t offset, uint8_t data)
113*ca987d46SWarner Losh {
114*ca987d46SWarner Losh *((volatile uint8_t *)(h + offset)) = data;
115*ca987d46SWarner Losh }
116*ca987d46SWarner Losh
117*ca987d46SWarner Losh void
bus_space_write_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint16_t data)118*ca987d46SWarner Losh bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h,
119*ca987d46SWarner Losh bus_size_t offset, uint16_t data)
120*ca987d46SWarner Losh {
121*ca987d46SWarner Losh *((volatile uint16_t *)(h + offset)) = data;
122*ca987d46SWarner Losh }
123*ca987d46SWarner Losh
124*ca987d46SWarner Losh void
bus_space_write_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t data)125*ca987d46SWarner Losh bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h,
126*ca987d46SWarner Losh bus_size_t offset, uint32_t data)
127*ca987d46SWarner Losh {
128*ca987d46SWarner Losh *((volatile uint32_t *)(h + offset)) = data;
129*ca987d46SWarner Losh }
130*ca987d46SWarner Losh
131*ca987d46SWarner Losh uint8_t
bus_space_read_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset)132*ca987d46SWarner Losh bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
133*ca987d46SWarner Losh {
134*ca987d46SWarner Losh return (*((volatile uint8_t *)(h + offset)));
135*ca987d46SWarner Losh }
136*ca987d46SWarner Losh
137*ca987d46SWarner Losh uint16_t
bus_space_read_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset)138*ca987d46SWarner Losh bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
139*ca987d46SWarner Losh {
140*ca987d46SWarner Losh return (*((volatile uint16_t *)(h + offset)));
141*ca987d46SWarner Losh }
142*ca987d46SWarner Losh
143*ca987d46SWarner Losh uint32_t
bus_space_read_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset)144*ca987d46SWarner Losh bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
145*ca987d46SWarner Losh {
146*ca987d46SWarner Losh return (*((volatile uint32_t *)(h + offset)));
147*ca987d46SWarner Losh }
148*ca987d46SWarner Losh
149*ca987d46SWarner Losh void
bus_space_read_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t * datap,bus_size_t count)150*ca987d46SWarner Losh bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h,
151*ca987d46SWarner Losh bus_size_t offset, uint8_t *datap, bus_size_t count)
152*ca987d46SWarner Losh {
153*ca987d46SWarner Losh h += offset;
154*ca987d46SWarner Losh
155*ca987d46SWarner Losh while (count--) {
156*ca987d46SWarner Losh *datap++ = *((volatile uint8_t *)h);
157*ca987d46SWarner Losh h += 1;
158*ca987d46SWarner Losh }
159*ca987d46SWarner Losh }
160*ca987d46SWarner Losh
161*ca987d46SWarner Losh void
bus_space_write_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t * datap,bus_size_t count)162*ca987d46SWarner Losh bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h,
163*ca987d46SWarner Losh bus_size_t offset, uint8_t *datap, bus_size_t count)
164*ca987d46SWarner Losh {
165*ca987d46SWarner Losh h += offset;
166*ca987d46SWarner Losh
167*ca987d46SWarner Losh while (count--) {
168*ca987d46SWarner Losh *((volatile uint8_t *)h) = *datap++;
169*ca987d46SWarner Losh h += 1;
170*ca987d46SWarner Losh }
171*ca987d46SWarner Losh }
172*ca987d46SWarner Losh
173*ca987d46SWarner Losh void
bus_space_read_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t * datap,bus_size_t count)174*ca987d46SWarner Losh bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h,
175*ca987d46SWarner Losh bus_size_t offset, uint32_t *datap, bus_size_t count)
176*ca987d46SWarner Losh {
177*ca987d46SWarner Losh enum { BURST = sizeof(struct burst) / 4 };
178*ca987d46SWarner Losh
179*ca987d46SWarner Losh h += offset;
180*ca987d46SWarner Losh
181*ca987d46SWarner Losh while (count >= BURST) {
182*ca987d46SWarner Losh *(struct burst *)datap = *((/* volatile */ struct burst *)h);
183*ca987d46SWarner Losh
184*ca987d46SWarner Losh h += BURST * 4;
185*ca987d46SWarner Losh datap += BURST;
186*ca987d46SWarner Losh count -= BURST;
187*ca987d46SWarner Losh }
188*ca987d46SWarner Losh
189*ca987d46SWarner Losh while (count--) {
190*ca987d46SWarner Losh *datap++ = *((volatile uint32_t *)h);
191*ca987d46SWarner Losh h += 4;
192*ca987d46SWarner Losh }
193*ca987d46SWarner Losh }
194*ca987d46SWarner Losh
195*ca987d46SWarner Losh void
bus_space_write_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t * datap,bus_size_t count)196*ca987d46SWarner Losh bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h,
197*ca987d46SWarner Losh bus_size_t offset, uint32_t *datap, bus_size_t count)
198*ca987d46SWarner Losh {
199*ca987d46SWarner Losh enum { BURST = sizeof(struct burst) / 4 };
200*ca987d46SWarner Losh
201*ca987d46SWarner Losh h += offset;
202*ca987d46SWarner Losh
203*ca987d46SWarner Losh while (count >= BURST) {
204*ca987d46SWarner Losh *((/* volatile */ struct burst *)h) = *(struct burst *)datap;
205*ca987d46SWarner Losh
206*ca987d46SWarner Losh h += BURST * 4;
207*ca987d46SWarner Losh datap += BURST;
208*ca987d46SWarner Losh count -= BURST;
209*ca987d46SWarner Losh }
210*ca987d46SWarner Losh
211*ca987d46SWarner Losh while (count--) {
212*ca987d46SWarner Losh *((volatile uint32_t *)h) = *datap++;
213*ca987d46SWarner Losh h += 4;
214*ca987d46SWarner Losh }
215*ca987d46SWarner Losh }
216