1246145Shselasky/* $FreeBSD$ */
2246145Shselasky/*-
3246145Shselasky * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
4246145Shselasky *
5246145Shselasky * Redistribution and use in source and binary forms, with or without
6246145Shselasky * modification, are permitted provided that the following conditions
7246145Shselasky * are met:
8246145Shselasky * 1. Redistributions of source code must retain the above copyright
9246145Shselasky *    notice, this list of conditions and the following disclaimer.
10246145Shselasky * 2. Redistributions in binary form must reproduce the above copyright
11246145Shselasky *    notice, this list of conditions and the following disclaimer in the
12246145Shselasky *    documentation and/or other materials provided with the distribution.
13246145Shselasky *
14246145Shselasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15246145Shselasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16246145Shselasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17246145Shselasky * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18246145Shselasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19246145Shselasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20246145Shselasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21246145Shselasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22246145Shselasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23246145Shselasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24246145Shselasky * SUCH DAMAGE.
25246145Shselasky */
26246145Shselasky
27246145Shselasky#include <bsd_kernel.h>
28246145Shselasky
29246145Shselaskystruct burst {
30246145Shselasky	uint32_t dw0;
31246145Shselasky	uint32_t dw1;
32246145Shselasky	uint32_t dw2;
33246145Shselasky	uint32_t dw3;
34246145Shselasky	uint32_t dw4;
35246145Shselasky	uint32_t dw5;
36246145Shselasky	uint32_t dw6;
37246145Shselasky	uint32_t dw7;
38246145Shselasky};
39246145Shselasky
40246145Shselaskyvoid
41246145Shselaskybus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h,
42246145Shselasky    bus_size_t offset, uint8_t *datap, bus_size_t count)
43246145Shselasky{
44246145Shselasky	while (count--) {
45246145Shselasky		*datap++ = bus_space_read_1(t, h, offset);
46246145Shselasky	}
47246145Shselasky}
48246145Shselasky
49246145Shselaskyvoid
50246145Shselaskybus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h,
51246145Shselasky    bus_size_t offset, uint16_t *datap, bus_size_t count)
52246145Shselasky{
53246145Shselasky	while (count--) {
54246145Shselasky		*datap++ = bus_space_read_2(t, h, offset);
55246145Shselasky	}
56246145Shselasky}
57246145Shselasky
58246145Shselaskyvoid
59246145Shselaskybus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h,
60246145Shselasky    bus_size_t offset, uint32_t *datap, bus_size_t count)
61246145Shselasky{
62246145Shselasky	h += offset;
63246145Shselasky
64246145Shselasky	while (count--) {
65246145Shselasky		*datap++ = *((volatile uint32_t *)h);
66246145Shselasky	}
67246145Shselasky}
68246145Shselasky
69246145Shselaskyvoid
70246145Shselaskybus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h,
71246145Shselasky    bus_size_t offset, uint8_t *datap, bus_size_t count)
72246145Shselasky{
73246145Shselasky	while (count--) {
74246145Shselasky		uint8_t temp = *datap++;
75246145Shselasky
76246145Shselasky		bus_space_write_1(t, h, offset, temp);
77246145Shselasky	}
78246145Shselasky}
79246145Shselasky
80246145Shselaskyvoid
81246145Shselaskybus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h,
82246145Shselasky    bus_size_t offset, uint16_t *datap, bus_size_t count)
83246145Shselasky{
84246145Shselasky	while (count--) {
85246145Shselasky		uint16_t temp = *datap++;
86246145Shselasky
87246145Shselasky		bus_space_write_2(t, h, offset, temp);
88246145Shselasky	}
89246145Shselasky}
90246145Shselasky
91246145Shselaskyvoid
92246145Shselaskybus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h,
93246145Shselasky    bus_size_t offset, uint32_t *datap, bus_size_t count)
94246145Shselasky{
95246145Shselasky	h += offset;
96246145Shselasky
97246145Shselasky	while (count--) {
98246145Shselasky		*((volatile uint32_t *)h) = *datap++;
99246145Shselasky	}
100246145Shselasky}
101246145Shselasky
102246145Shselaskyvoid
103246145Shselaskybus_space_write_1(bus_space_tag_t t, bus_space_handle_t h,
104246145Shselasky    bus_size_t offset, uint8_t data)
105246145Shselasky{
106246145Shselasky	*((volatile uint8_t *)(h + offset)) = data;
107246145Shselasky}
108246145Shselasky
109246145Shselaskyvoid
110246145Shselaskybus_space_write_2(bus_space_tag_t t, bus_space_handle_t h,
111246145Shselasky    bus_size_t offset, uint16_t data)
112246145Shselasky{
113246145Shselasky	*((volatile uint16_t *)(h + offset)) = data;
114246145Shselasky}
115246145Shselasky
116246145Shselaskyvoid
117246145Shselaskybus_space_write_4(bus_space_tag_t t, bus_space_handle_t h,
118246145Shselasky    bus_size_t offset, uint32_t data)
119246145Shselasky{
120246145Shselasky	*((volatile uint32_t *)(h + offset)) = data;
121246145Shselasky}
122246145Shselasky
123246145Shselaskyuint8_t
124246145Shselaskybus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
125246145Shselasky{
126246145Shselasky	return (*((volatile uint8_t *)(h + offset)));
127246145Shselasky}
128246145Shselasky
129246145Shselaskyuint16_t
130246145Shselaskybus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
131246145Shselasky{
132246145Shselasky	return (*((volatile uint16_t *)(h + offset)));
133246145Shselasky}
134246145Shselasky
135246145Shselaskyuint32_t
136246145Shselaskybus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
137246145Shselasky{
138246145Shselasky	return (*((volatile uint32_t *)(h + offset)));
139246145Shselasky}
140246145Shselasky
141246145Shselaskyvoid
142246145Shselaskybus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h,
143246145Shselasky    bus_size_t offset, uint8_t *datap, bus_size_t count)
144246145Shselasky{
145246145Shselasky	h += offset;
146246145Shselasky
147246145Shselasky	while (count--) {
148246145Shselasky		*datap++ = *((volatile uint8_t *)h);
149246145Shselasky		h += 1;
150246145Shselasky	}
151246145Shselasky}
152246145Shselasky
153246145Shselaskyvoid
154246145Shselaskybus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h,
155246145Shselasky    bus_size_t offset, uint8_t *datap, bus_size_t count)
156246145Shselasky{
157246145Shselasky	h += offset;
158246145Shselasky
159246145Shselasky	while (count--) {
160246145Shselasky		*((volatile uint8_t *)h) = *datap++;
161246145Shselasky		h += 1;
162246145Shselasky	}
163246145Shselasky}
164246145Shselasky
165246145Shselaskyvoid
166246145Shselaskybus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h,
167246145Shselasky    bus_size_t offset, uint32_t *datap, bus_size_t count)
168246145Shselasky{
169246145Shselasky	enum { BURST = sizeof(struct burst) / 4 };
170246145Shselasky
171246145Shselasky	h += offset;
172246145Shselasky
173246145Shselasky	while (count >= BURST) {
174246145Shselasky		*(struct burst *)datap = *((/* volatile */ struct burst *)h);
175246145Shselasky
176246145Shselasky		h += BURST * 4;
177246145Shselasky		datap += BURST;
178246145Shselasky		count -= BURST;
179246145Shselasky	}
180246145Shselasky
181246145Shselasky	while (count--) {
182246145Shselasky		*datap++ = *((volatile uint32_t *)h);
183246145Shselasky		h += 4;
184246145Shselasky	}
185246145Shselasky}
186246145Shselasky
187246145Shselaskyvoid
188246145Shselaskybus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h,
189246145Shselasky    bus_size_t offset, uint32_t *datap, bus_size_t count)
190246145Shselasky{
191246145Shselasky	enum { BURST = sizeof(struct burst) / 4 };
192246145Shselasky
193246145Shselasky	h += offset;
194246145Shselasky
195246145Shselasky	while (count >= BURST) {
196246145Shselasky		*((/* volatile */ struct burst *)h) = *(struct burst *)datap;
197246145Shselasky
198246145Shselasky		h += BURST * 4;
199246145Shselasky		datap += BURST;
200246145Shselasky		count -= BURST;
201246145Shselasky	}
202246145Shselasky
203246145Shselasky	while (count--) {
204246145Shselasky		*((volatile uint32_t *)h) = *datap++;
205246145Shselasky		h += 4;
206246145Shselasky	}
207246145Shselasky}
208