15025407bSBen Skeggs #ifndef __NVKM_OBJECT_H__ 25025407bSBen Skeggs #define __NVKM_OBJECT_H__ 3c39f472eSBen Skeggs #include <core/os.h> 453003941SBen Skeggs #include <core/debug.h> 5c39f472eSBen Skeggs 6c39f472eSBen Skeggs #define NV_PARENT_CLASS 0x80000000 7c39f472eSBen Skeggs #define NV_NAMEDB_CLASS 0x40000000 8c39f472eSBen Skeggs #define NV_CLIENT_CLASS 0x20000000 9c39f472eSBen Skeggs #define NV_SUBDEV_CLASS 0x10000000 10c39f472eSBen Skeggs #define NV_ENGINE_CLASS 0x08000000 11c39f472eSBen Skeggs #define NV_MEMOBJ_CLASS 0x04000000 12c39f472eSBen Skeggs #define NV_GPUOBJ_CLASS 0x02000000 13c39f472eSBen Skeggs #define NV_ENGCTX_CLASS 0x01000000 14c39f472eSBen Skeggs #define NV_OBJECT_CLASS 0x0000ffff 15c39f472eSBen Skeggs 165025407bSBen Skeggs struct nvkm_object { 175025407bSBen Skeggs struct nvkm_oclass *oclass; 185025407bSBen Skeggs struct nvkm_object *parent; 195025407bSBen Skeggs struct nvkm_engine *engine; 20c39f472eSBen Skeggs atomic_t refcount; 21c39f472eSBen Skeggs atomic_t usecount; 22c39f472eSBen Skeggs #if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA 235025407bSBen Skeggs #define NVKM_OBJECT_MAGIC 0x75ef0bad 24c39f472eSBen Skeggs struct list_head list; 25c39f472eSBen Skeggs u32 _magic; 26c39f472eSBen Skeggs #endif 27c39f472eSBen Skeggs }; 28c39f472eSBen Skeggs 295025407bSBen Skeggs static inline struct nvkm_object * 30c39f472eSBen Skeggs nv_object(void *obj) 31c39f472eSBen Skeggs { 32c39f472eSBen Skeggs #if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA 33c39f472eSBen Skeggs if (likely(obj)) { 345025407bSBen Skeggs struct nvkm_object *object = obj; 3553003941SBen Skeggs BUG_ON(object->_magic != NVKM_OBJECT_MAGIC); 36c39f472eSBen Skeggs } 37c39f472eSBen Skeggs #endif 38c39f472eSBen Skeggs return obj; 39c39f472eSBen Skeggs } 40c39f472eSBen Skeggs 415025407bSBen Skeggs #define nvkm_object_create(p,e,c,s,d) \ 425025407bSBen Skeggs nvkm_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d) 435025407bSBen Skeggs int nvkm_object_create_(struct nvkm_object *, struct nvkm_object *, 445025407bSBen Skeggs struct nvkm_oclass *, u32, int size, void **); 455025407bSBen Skeggs void nvkm_object_destroy(struct nvkm_object *); 465025407bSBen Skeggs int nvkm_object_init(struct nvkm_object *); 475025407bSBen Skeggs int nvkm_object_fini(struct nvkm_object *, bool suspend); 48c39f472eSBen Skeggs 495025407bSBen Skeggs int _nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *, 505025407bSBen Skeggs struct nvkm_oclass *, void *, u32, 515025407bSBen Skeggs struct nvkm_object **); 52c39f472eSBen Skeggs 535025407bSBen Skeggs extern struct nvkm_ofuncs nvkm_object_ofuncs; 54c39f472eSBen Skeggs 55c39f472eSBen Skeggs /* Don't allocate dynamically, because lockdep needs lock_class_keys to be in 56c39f472eSBen Skeggs * ".data". */ 575025407bSBen Skeggs struct nvkm_oclass { 58c39f472eSBen Skeggs u32 handle; 595025407bSBen Skeggs struct nvkm_ofuncs * const ofuncs; 605025407bSBen Skeggs struct nvkm_omthds * const omthds; 61c39f472eSBen Skeggs struct lock_class_key lock_class_key; 62c39f472eSBen Skeggs }; 63c39f472eSBen Skeggs 64c39f472eSBen Skeggs #define nv_oclass(o) nv_object(o)->oclass 65c39f472eSBen Skeggs #define nv_hclass(o) nv_oclass(o)->handle 66c39f472eSBen Skeggs #define nv_iclass(o,i) (nv_hclass(o) & (i)) 67c39f472eSBen Skeggs #define nv_mclass(o) nv_iclass(o, NV_OBJECT_CLASS) 68c39f472eSBen Skeggs 695025407bSBen Skeggs static inline struct nvkm_object * 705025407bSBen Skeggs nv_pclass(struct nvkm_object *parent, u32 oclass) 71c39f472eSBen Skeggs { 72c39f472eSBen Skeggs while (parent && !nv_iclass(parent, oclass)) 73c39f472eSBen Skeggs parent = parent->parent; 74c39f472eSBen Skeggs return parent; 75c39f472eSBen Skeggs } 76c39f472eSBen Skeggs 775025407bSBen Skeggs struct nvkm_omthds { 78c39f472eSBen Skeggs u32 start; 79c39f472eSBen Skeggs u32 limit; 805025407bSBen Skeggs int (*call)(struct nvkm_object *, u32, void *, u32); 81c39f472eSBen Skeggs }; 82c39f472eSBen Skeggs 83c39f472eSBen Skeggs struct nvkm_event; 845025407bSBen Skeggs struct nvkm_ofuncs { 855025407bSBen Skeggs int (*ctor)(struct nvkm_object *, struct nvkm_object *, 865025407bSBen Skeggs struct nvkm_oclass *, void *data, u32 size, 875025407bSBen Skeggs struct nvkm_object **); 885025407bSBen Skeggs void (*dtor)(struct nvkm_object *); 895025407bSBen Skeggs int (*init)(struct nvkm_object *); 905025407bSBen Skeggs int (*fini)(struct nvkm_object *, bool suspend); 915025407bSBen Skeggs int (*mthd)(struct nvkm_object *, u32, void *, u32); 925025407bSBen Skeggs int (*ntfy)(struct nvkm_object *, u32, struct nvkm_event **); 935025407bSBen Skeggs int (* map)(struct nvkm_object *, u64 *, u32 *); 945025407bSBen Skeggs u8 (*rd08)(struct nvkm_object *, u64 offset); 955025407bSBen Skeggs u16 (*rd16)(struct nvkm_object *, u64 offset); 965025407bSBen Skeggs u32 (*rd32)(struct nvkm_object *, u64 offset); 975025407bSBen Skeggs void (*wr08)(struct nvkm_object *, u64 offset, u8 data); 985025407bSBen Skeggs void (*wr16)(struct nvkm_object *, u64 offset, u16 data); 995025407bSBen Skeggs void (*wr32)(struct nvkm_object *, u64 offset, u32 data); 100c39f472eSBen Skeggs }; 101c39f472eSBen Skeggs 1025025407bSBen Skeggs static inline struct nvkm_ofuncs * 103c39f472eSBen Skeggs nv_ofuncs(void *obj) 104c39f472eSBen Skeggs { 105c39f472eSBen Skeggs return nv_oclass(obj)->ofuncs; 106c39f472eSBen Skeggs } 107c39f472eSBen Skeggs 1085025407bSBen Skeggs int nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *, 1095025407bSBen Skeggs struct nvkm_oclass *, void *, u32, 1105025407bSBen Skeggs struct nvkm_object **); 1115025407bSBen Skeggs void nvkm_object_ref(struct nvkm_object *, struct nvkm_object **); 1125025407bSBen Skeggs int nvkm_object_inc(struct nvkm_object *); 1135025407bSBen Skeggs int nvkm_object_dec(struct nvkm_object *, bool suspend); 114c39f472eSBen Skeggs 115c39f472eSBen Skeggs static inline int 116c39f472eSBen Skeggs nv_exec(void *obj, u32 mthd, void *data, u32 size) 117c39f472eSBen Skeggs { 1185025407bSBen Skeggs struct nvkm_omthds *method = nv_oclass(obj)->omthds; 119c39f472eSBen Skeggs 120c39f472eSBen Skeggs while (method && method->call) { 121c39f472eSBen Skeggs if (mthd >= method->start && mthd <= method->limit) 122c39f472eSBen Skeggs return method->call(obj, mthd, data, size); 123c39f472eSBen Skeggs method++; 124c39f472eSBen Skeggs } 125c39f472eSBen Skeggs 126c39f472eSBen Skeggs return -EINVAL; 127c39f472eSBen Skeggs } 128c39f472eSBen Skeggs 129c39f472eSBen Skeggs static inline int 130c39f472eSBen Skeggs nv_call(void *obj, u32 mthd, u32 data) 131c39f472eSBen Skeggs { 132c39f472eSBen Skeggs return nv_exec(obj, mthd, &data, sizeof(data)); 133c39f472eSBen Skeggs } 134c39f472eSBen Skeggs 135c39f472eSBen Skeggs static inline u8 136c39f472eSBen Skeggs nv_ro08(void *obj, u64 addr) 137c39f472eSBen Skeggs { 138c39f472eSBen Skeggs u8 data = nv_ofuncs(obj)->rd08(obj, addr); 139c39f472eSBen Skeggs return data; 140c39f472eSBen Skeggs } 141c39f472eSBen Skeggs 142c39f472eSBen Skeggs static inline u16 143c39f472eSBen Skeggs nv_ro16(void *obj, u64 addr) 144c39f472eSBen Skeggs { 145c39f472eSBen Skeggs u16 data = nv_ofuncs(obj)->rd16(obj, addr); 146c39f472eSBen Skeggs return data; 147c39f472eSBen Skeggs } 148c39f472eSBen Skeggs 149c39f472eSBen Skeggs static inline u32 150c39f472eSBen Skeggs nv_ro32(void *obj, u64 addr) 151c39f472eSBen Skeggs { 152c39f472eSBen Skeggs u32 data = nv_ofuncs(obj)->rd32(obj, addr); 153c39f472eSBen Skeggs return data; 154c39f472eSBen Skeggs } 155c39f472eSBen Skeggs 156c39f472eSBen Skeggs static inline void 157c39f472eSBen Skeggs nv_wo08(void *obj, u64 addr, u8 data) 158c39f472eSBen Skeggs { 159c39f472eSBen Skeggs nv_ofuncs(obj)->wr08(obj, addr, data); 160c39f472eSBen Skeggs } 161c39f472eSBen Skeggs 162c39f472eSBen Skeggs static inline void 163c39f472eSBen Skeggs nv_wo16(void *obj, u64 addr, u16 data) 164c39f472eSBen Skeggs { 165c39f472eSBen Skeggs nv_ofuncs(obj)->wr16(obj, addr, data); 166c39f472eSBen Skeggs } 167c39f472eSBen Skeggs 168c39f472eSBen Skeggs static inline void 169c39f472eSBen Skeggs nv_wo32(void *obj, u64 addr, u32 data) 170c39f472eSBen Skeggs { 171c39f472eSBen Skeggs nv_ofuncs(obj)->wr32(obj, addr, data); 172c39f472eSBen Skeggs } 173c39f472eSBen Skeggs 174c39f472eSBen Skeggs static inline u32 175c39f472eSBen Skeggs nv_mo32(void *obj, u64 addr, u32 mask, u32 data) 176c39f472eSBen Skeggs { 177c39f472eSBen Skeggs u32 temp = nv_ro32(obj, addr); 178c39f472eSBen Skeggs nv_wo32(obj, addr, (temp & ~mask) | data); 179c39f472eSBen Skeggs return temp; 180c39f472eSBen Skeggs } 181c39f472eSBen Skeggs 182c39f472eSBen Skeggs static inline int 183c39f472eSBen Skeggs nv_memcmp(void *obj, u32 addr, const char *str, u32 len) 184c39f472eSBen Skeggs { 185c39f472eSBen Skeggs unsigned char c1, c2; 186c39f472eSBen Skeggs 187c39f472eSBen Skeggs while (len--) { 188c39f472eSBen Skeggs c1 = nv_ro08(obj, addr++); 189c39f472eSBen Skeggs c2 = *(str++); 190c39f472eSBen Skeggs if (c1 != c2) 191c39f472eSBen Skeggs return c1 - c2; 192c39f472eSBen Skeggs } 193c39f472eSBen Skeggs return 0; 194c39f472eSBen Skeggs } 195c39f472eSBen Skeggs #endif 196