xref: /netbsd-src/sys/external/bsd/drm2/include/drm/drm_iomap_netbsd.h (revision c9f4f3fcfbec67fe5986c73a3940d1a2ddbe7b03)
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