1 /* $NetBSD: object.h,v 1.10 2021/12/19 10:51:56 riastradh Exp $ */ 2 3 /* SPDX-License-Identifier: MIT */ 4 #ifndef __NVIF_OBJECT_H__ 5 #define __NVIF_OBJECT_H__ 6 7 #include <nvif/os.h> 8 9 struct nvif_sclass { 10 s32 oclass; 11 int minver; 12 int maxver; 13 }; 14 15 #ifdef __NetBSD__ 16 # define __nvif_iomem volatile 17 # define __iomem __nvif_iomem 18 #endif 19 20 struct nvif_object { 21 struct nvif_client *client; 22 u32 handle; 23 s32 oclass; 24 void *priv; /*XXX: hack */ 25 struct { 26 #ifdef __NetBSD__ 27 bus_space_tag_t tag; 28 bus_space_handle_t handle; 29 bus_addr_t addr; 30 #endif 31 void __iomem *ptr; 32 u64 size; 33 } map; 34 }; 35 36 #ifdef __NetBSD__ 37 # undef __iomem 38 #endif 39 40 int nvif_object_init(struct nvif_object *, u32 handle, s32 oclass, void *, u32, 41 struct nvif_object *); 42 void nvif_object_fini(struct nvif_object *); 43 int nvif_object_ioctl(struct nvif_object *, void *, u32, void **); 44 int nvif_object_sclass_get(struct nvif_object *, struct nvif_sclass **); 45 void nvif_object_sclass_put(struct nvif_sclass **); 46 u32 nvif_object_rd(struct nvif_object *, int, u64); 47 void nvif_object_wr(struct nvif_object *, int, u64, u32); 48 int nvif_object_mthd(struct nvif_object *, u32, void *, u32); 49 int nvif_object_map_handle(struct nvif_object *, void *, u32, 50 #ifdef __NetBSD__ 51 bus_space_tag_t *, 52 #endif 53 u64 *handle, u64 *length); 54 void nvif_object_unmap_handle(struct nvif_object *); 55 int nvif_object_map(struct nvif_object *, void *, u32); 56 void nvif_object_unmap(struct nvif_object *); 57 58 #define nvif_handle(a) (unsigned long)(void *)(a) 59 #define nvif_object(a) (a)->object 60 61 #ifdef __NetBSD__ 62 static inline uint8_t 63 nvif_rd08(struct nvif_object *obj, uint64_t offset) 64 { 65 if (obj->map.ptr) 66 return bus_space_read_1(obj->map.tag, obj->map.handle, 67 offset); 68 else 69 return nvif_object_rd(obj, 1, offset); 70 } 71 static inline uint16_t 72 nvif_rd16(struct nvif_object *obj, uint64_t offset) 73 { 74 if (obj->map.ptr) 75 return bus_space_read_stream_2(obj->map.tag, obj->map.handle, 76 offset); 77 else 78 return nvif_object_rd(obj, 2, offset); 79 } 80 static inline uint32_t 81 nvif_rd32(struct nvif_object *obj, uint64_t offset) 82 { 83 if (obj->map.ptr) 84 return bus_space_read_stream_4(obj->map.tag, obj->map.handle, 85 offset); 86 else 87 return nvif_object_rd(obj, 4, offset); 88 } 89 static inline void 90 nvif_wr08(struct nvif_object *obj, uint64_t offset, uint8_t v) 91 { 92 if (obj->map.ptr) 93 bus_space_write_1(obj->map.tag, obj->map.handle, offset, v); 94 else 95 nvif_object_wr(obj, 1, offset, v); 96 } 97 static inline void 98 nvif_wr16(struct nvif_object *obj, uint64_t offset, uint16_t v) 99 { 100 if (obj->map.ptr) 101 bus_space_write_stream_2(obj->map.tag, obj->map.handle, offset, 102 v); 103 else 104 nvif_object_wr(obj, 2, offset, v); 105 } 106 static inline void 107 nvif_wr32(struct nvif_object *obj, uint64_t offset, uint32_t v) 108 { 109 if (obj->map.ptr) 110 bus_space_write_stream_4(obj->map.tag, obj->map.handle, offset, 111 v); 112 else 113 nvif_object_wr(obj, 4, offset, v); 114 } 115 #else 116 #define nvif_rd(a,f,b,c) ({ \ 117 struct nvif_object *_object = (a); \ 118 u32 _data; \ 119 if (likely(_object->map.ptr)) \ 120 _data = f((u8 __iomem *)_object->map.ptr + (c)); \ 121 else \ 122 _data = nvif_object_rd(_object, (b), (c)); \ 123 _data; \ 124 }) 125 #define nvif_wr(a,f,b,c,d) ({ \ 126 struct nvif_object *_object = (a); \ 127 if (likely(_object->map.ptr)) \ 128 f((d), (u8 __iomem *)_object->map.ptr + (c)); \ 129 else \ 130 nvif_object_wr(_object, (b), (c), (d)); \ 131 }) 132 #define nvif_rd08(a,b) ({ ((u8)nvif_rd((a), ioread8, 1, (b))); }) 133 #define nvif_rd16(a,b) ({ ((u16)nvif_rd((a), ioread16_native, 2, (b))); }) 134 #define nvif_rd32(a,b) ({ ((u32)nvif_rd((a), ioread32_native, 4, (b))); }) 135 #define nvif_wr08(a,b,c) nvif_wr((a), iowrite8, 1, (b), (u8)(c)) 136 #define nvif_wr16(a,b,c) nvif_wr((a), iowrite16_native, 2, (b), (u16)(c)) 137 #define nvif_wr32(a,b,c) nvif_wr((a), iowrite32_native, 4, (b), (u32)(c)) 138 #endif 139 #define nvif_mask(a,b,c,d) ({ \ 140 struct nvif_object *__object = (a); \ 141 u32 _addr = (b), _data = nvif_rd32(__object, _addr); \ 142 nvif_wr32(__object, _addr, (_data & ~(c)) | (d)); \ 143 _data; \ 144 }) 145 146 #define nvif_mthd(a,b,c,d) nvif_object_mthd((a), (b), (c), (d)) 147 148 struct nvif_mclass { 149 s32 oclass; 150 int version; 151 }; 152 153 #define nvif_mclass(o,m) ({ \ 154 struct nvif_object *object = (o); \ 155 struct nvif_sclass *sclass; \ 156 typeof(m[0]) *mclass = (m); \ 157 int ret = -ENODEV; \ 158 int cnt, i, j; \ 159 \ 160 cnt = nvif_object_sclass_get(object, &sclass); \ 161 if (cnt >= 0) { \ 162 for (i = 0; ret < 0 && mclass[i].oclass; i++) { \ 163 for (j = 0; j < cnt; j++) { \ 164 if (mclass[i].oclass == sclass[j].oclass && \ 165 mclass[i].version >= sclass[j].minver && \ 166 mclass[i].version <= sclass[j].maxver) { \ 167 ret = i; \ 168 break; \ 169 } \ 170 } \ 171 } \ 172 nvif_object_sclass_put(&sclass); \ 173 } \ 174 ret; \ 175 }) 176 177 #define nvif_sclass(o,m,u) ({ \ 178 const typeof(m[0]) *_mclass = (m); \ 179 s32 _oclass = (u); \ 180 int _cid; \ 181 if (_oclass) { \ 182 for (_cid = 0; _mclass[_cid].oclass; _cid++) { \ 183 if (_mclass[_cid].oclass == _oclass) \ 184 break; \ 185 } \ 186 _cid = _mclass[_cid].oclass ? _cid : -ENOSYS; \ 187 } else { \ 188 _cid = nvif_mclass((o), _mclass); \ 189 } \ 190 _cid; \ 191 }) 192 193 /*XXX*/ 194 #include <core/object.h> 195 #define nvxx_object(a) ({ \ 196 struct nvif_object *_object = (a); \ 197 (struct nvkm_object *)_object->priv; \ 198 }) 199 #endif 200