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 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 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 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 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 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 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 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 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 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