1 /* $NetBSD: drm_iomap_netbsd.h,v 1.1 2018/08/27 05:34:49 riastradh Exp $ */
2
3 /*-
4 * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef _DRM_DRM_IOMAP_NETBSD_H_
33 #define _DRM_DRM_IOMAP_NETBSD_H_
34
35 #include <sys/bus.h>
36 #include <sys/endian.h>
37
38 #include <drm/drm_legacy.h>
39
40 static inline bool
DRM_IS_BUS_SPACE(struct drm_local_map * map)41 DRM_IS_BUS_SPACE(struct drm_local_map *map)
42 {
43 switch (map->type) {
44 case _DRM_FRAME_BUFFER:
45 panic("I don't know how to access drm frame buffer memory!");
46
47 case _DRM_REGISTERS:
48 return true;
49
50 case _DRM_SHM:
51 panic("I don't know how to access drm shared memory!");
52
53 case _DRM_AGP:
54 panic("I don't know how to access drm agp memory!");
55
56 case _DRM_SCATTER_GATHER:
57 panic("I don't know how to access drm scatter-gather memory!");
58
59 case _DRM_CONSISTENT:
60 /*
61 * XXX Old drm uses bus space access for this, but
62 * consistent maps don't have bus space handles! They
63 * do, however, have kernel virtual addresses in the
64 * map->handle, so maybe that's right.
65 */
66 #if 0
67 return false;
68 #endif
69 panic("I don't know how to access drm consistent memory!");
70
71 default:
72 panic("I don't know what kind of memory you mean!");
73 }
74 }
75
76 static inline uint8_t
DRM_READ8(struct drm_local_map * map,bus_size_t offset)77 DRM_READ8(struct drm_local_map *map, bus_size_t offset)
78 {
79 if (DRM_IS_BUS_SPACE(map))
80 return bus_space_read_1(map->lm_data.bus_space.bst,
81 map->lm_data.bus_space.bsh, offset);
82 else
83 return *(volatile uint8_t *)((vaddr_t)map->handle + offset);
84 }
85
86 static inline uint16_t
DRM_READ16(struct drm_local_map * map,bus_size_t offset)87 DRM_READ16(struct drm_local_map *map, bus_size_t offset)
88 {
89 if (DRM_IS_BUS_SPACE(map))
90 return bus_space_read_2(map->lm_data.bus_space.bst,
91 map->lm_data.bus_space.bsh, offset);
92 else
93 return *(volatile uint16_t *)((vaddr_t)map->handle + offset);
94 }
95
96 static inline uint32_t
DRM_READ32(struct drm_local_map * map,bus_size_t offset)97 DRM_READ32(struct drm_local_map *map, bus_size_t offset)
98 {
99 if (DRM_IS_BUS_SPACE(map))
100 return bus_space_read_4(map->lm_data.bus_space.bst,
101 map->lm_data.bus_space.bsh, offset);
102 else
103 return *(volatile uint32_t *)((vaddr_t)map->handle + offset);
104 }
105
106 static inline uint64_t
DRM_READ64(struct drm_local_map * map,bus_size_t offset)107 DRM_READ64(struct drm_local_map *map, bus_size_t offset)
108 {
109 if (DRM_IS_BUS_SPACE(map)) {
110 #if _LP64 /* XXX How to detect bus_space_read_8? */
111 return bus_space_read_8(map->lm_data.bus_space.bst,
112 map->lm_data.bus_space.bsh, offset);
113 #elif _BYTE_ORDER == _LITTLE_ENDIAN
114 /* XXX Yes, this is sketchy. */
115 return bus_space_read_4(map->lm_data.bus_space.bst,
116 map->lm_data.bus_space.bsh, offset) |
117 ((uint64_t)bus_space_read_4(map->lm_data.bus_space.bst,
118 map->lm_data.bus_space.bsh, (offset + 4)) << 32);
119 #else
120 /* XXX Yes, this is sketchy. */
121 return bus_space_read_4(map->lm_data.bus_space.bst,
122 map->lm_data.bus_space.bsh, (offset + 4)) |
123 ((uint64_t)bus_space_read_4(map->lm_data.bus_space.bst,
124 map->lm_data.bus_space.bsh, offset) << 32);
125 #endif
126 } else {
127 return *(volatile uint64_t *)((vaddr_t)map->handle + offset);
128 }
129 }
130
131 static inline void
DRM_WRITE8(struct drm_local_map * map,bus_size_t offset,uint8_t value)132 DRM_WRITE8(struct drm_local_map *map, bus_size_t offset, uint8_t value)
133 {
134 if (DRM_IS_BUS_SPACE(map))
135 bus_space_write_1(map->lm_data.bus_space.bst,
136 map->lm_data.bus_space.bsh, offset, value);
137 else
138 *(volatile uint8_t *)((vaddr_t)map->handle + offset) = value;
139 }
140
141 static inline void
DRM_WRITE16(struct drm_local_map * map,bus_size_t offset,uint16_t value)142 DRM_WRITE16(struct drm_local_map *map, bus_size_t offset, uint16_t value)
143 {
144 if (DRM_IS_BUS_SPACE(map))
145 bus_space_write_2(map->lm_data.bus_space.bst,
146 map->lm_data.bus_space.bsh, offset, value);
147 else
148 *(volatile uint16_t *)((vaddr_t)map->handle + offset) = value;
149 }
150
151 static inline void
DRM_WRITE32(struct drm_local_map * map,bus_size_t offset,uint32_t value)152 DRM_WRITE32(struct drm_local_map *map, bus_size_t offset, uint32_t value)
153 {
154 if (DRM_IS_BUS_SPACE(map))
155 bus_space_write_4(map->lm_data.bus_space.bst,
156 map->lm_data.bus_space.bsh, offset, value);
157 else
158 *(volatile uint32_t *)((vaddr_t)map->handle + offset) = value;
159 }
160
161 static inline void
DRM_WRITE64(struct drm_local_map * map,bus_size_t offset,uint64_t value)162 DRM_WRITE64(struct drm_local_map *map, bus_size_t offset, uint64_t value)
163 {
164 if (DRM_IS_BUS_SPACE(map)) {
165 #if _LP64 /* XXX How to detect bus_space_write_8? */
166 bus_space_write_8(map->lm_data.bus_space.bst,
167 map->lm_data.bus_space.bsh, offset, value);
168 #elif _BYTE_ORDER == _LITTLE_ENDIAN
169 bus_space_write_4(map->lm_data.bus_space.bst,
170 map->lm_data.bus_space.bsh, offset, (value & 0xffffffffU));
171 bus_space_write_4(map->lm_data.bus_space.bst,
172 map->lm_data.bus_space.bsh, (offset + 4), (value >> 32));
173 #else
174 bus_space_write_4(map->lm_data.bus_space.bst,
175 map->lm_data.bus_space.bsh, offset, (value >> 32));
176 bus_space_write_4(map->lm_data.bus_space.bst,
177 map->lm_data.bus_space.bsh, (offset + 4),
178 (value & 0xffffffffU));
179 #endif
180 } else {
181 *(volatile uint64_t *)((vaddr_t)map->handle + offset) = value;
182 }
183 }
184
185 #endif /* _DRM_DRM_IOMAP_NETBSD_H_ */
186