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 29cfdc4c44SBen Skeggs int nvkm_object_rd08(struct nvkm_object *, u64 addr, u8 *data); 30cfdc4c44SBen Skeggs int nvkm_object_rd16(struct nvkm_object *, u64 addr, u16 *data); 31cfdc4c44SBen Skeggs int nvkm_object_rd32(struct nvkm_object *, u64 addr, u32 *data); 32cfdc4c44SBen Skeggs int nvkm_object_wr08(struct nvkm_object *, u64 addr, u8 data); 33cfdc4c44SBen Skeggs int nvkm_object_wr16(struct nvkm_object *, u64 addr, u16 data); 34cfdc4c44SBen Skeggs int nvkm_object_wr32(struct nvkm_object *, u64 addr, u32 data); 35cfdc4c44SBen Skeggs 365025407bSBen Skeggs static inline struct nvkm_object * 37c39f472eSBen Skeggs nv_object(void *obj) 38c39f472eSBen Skeggs { 39c39f472eSBen Skeggs #if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA 40c39f472eSBen Skeggs if (likely(obj)) { 415025407bSBen Skeggs struct nvkm_object *object = obj; 4253003941SBen Skeggs BUG_ON(object->_magic != NVKM_OBJECT_MAGIC); 43c39f472eSBen Skeggs } 44c39f472eSBen Skeggs #endif 45c39f472eSBen Skeggs return obj; 46c39f472eSBen Skeggs } 47c39f472eSBen Skeggs 485025407bSBen Skeggs #define nvkm_object_create(p,e,c,s,d) \ 495025407bSBen Skeggs nvkm_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d) 505025407bSBen Skeggs int nvkm_object_create_(struct nvkm_object *, struct nvkm_object *, 515025407bSBen Skeggs struct nvkm_oclass *, u32, int size, void **); 525025407bSBen Skeggs void nvkm_object_destroy(struct nvkm_object *); 535025407bSBen Skeggs int nvkm_object_init(struct nvkm_object *); 545025407bSBen Skeggs int nvkm_object_fini(struct nvkm_object *, bool suspend); 55c39f472eSBen Skeggs 565025407bSBen Skeggs int _nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *, 575025407bSBen Skeggs struct nvkm_oclass *, void *, u32, 585025407bSBen Skeggs struct nvkm_object **); 59c39f472eSBen Skeggs 605025407bSBen Skeggs extern struct nvkm_ofuncs nvkm_object_ofuncs; 61c39f472eSBen Skeggs 62c39f472eSBen Skeggs /* Don't allocate dynamically, because lockdep needs lock_class_keys to be in 63c39f472eSBen Skeggs * ".data". */ 645025407bSBen Skeggs struct nvkm_oclass { 65c39f472eSBen Skeggs u32 handle; 665025407bSBen Skeggs struct nvkm_ofuncs * const ofuncs; 675025407bSBen Skeggs struct nvkm_omthds * const omthds; 68c39f472eSBen Skeggs struct lock_class_key lock_class_key; 69c39f472eSBen Skeggs }; 70c39f472eSBen Skeggs 71c39f472eSBen Skeggs #define nv_oclass(o) nv_object(o)->oclass 72c39f472eSBen Skeggs #define nv_hclass(o) nv_oclass(o)->handle 73c39f472eSBen Skeggs #define nv_iclass(o,i) (nv_hclass(o) & (i)) 74c39f472eSBen Skeggs #define nv_mclass(o) nv_iclass(o, NV_OBJECT_CLASS) 75c39f472eSBen Skeggs 765025407bSBen Skeggs static inline struct nvkm_object * 775025407bSBen Skeggs nv_pclass(struct nvkm_object *parent, u32 oclass) 78c39f472eSBen Skeggs { 79c39f472eSBen Skeggs while (parent && !nv_iclass(parent, oclass)) 80c39f472eSBen Skeggs parent = parent->parent; 81c39f472eSBen Skeggs return parent; 82c39f472eSBen Skeggs } 83c39f472eSBen Skeggs 845025407bSBen Skeggs struct nvkm_omthds { 85c39f472eSBen Skeggs u32 start; 86c39f472eSBen Skeggs u32 limit; 875025407bSBen Skeggs int (*call)(struct nvkm_object *, u32, void *, u32); 88c39f472eSBen Skeggs }; 89c39f472eSBen Skeggs 90c39f472eSBen Skeggs struct nvkm_event; 915025407bSBen Skeggs struct nvkm_ofuncs { 925025407bSBen Skeggs int (*ctor)(struct nvkm_object *, struct nvkm_object *, 935025407bSBen Skeggs struct nvkm_oclass *, void *data, u32 size, 945025407bSBen Skeggs struct nvkm_object **); 955025407bSBen Skeggs void (*dtor)(struct nvkm_object *); 965025407bSBen Skeggs int (*init)(struct nvkm_object *); 975025407bSBen Skeggs int (*fini)(struct nvkm_object *, bool suspend); 985025407bSBen Skeggs int (*mthd)(struct nvkm_object *, u32, void *, u32); 995025407bSBen Skeggs int (*ntfy)(struct nvkm_object *, u32, struct nvkm_event **); 1005025407bSBen Skeggs int (* map)(struct nvkm_object *, u64 *, u32 *); 1015025407bSBen Skeggs u8 (*rd08)(struct nvkm_object *, u64 offset); 1025025407bSBen Skeggs u16 (*rd16)(struct nvkm_object *, u64 offset); 1035025407bSBen Skeggs u32 (*rd32)(struct nvkm_object *, u64 offset); 1045025407bSBen Skeggs void (*wr08)(struct nvkm_object *, u64 offset, u8 data); 1055025407bSBen Skeggs void (*wr16)(struct nvkm_object *, u64 offset, u16 data); 1065025407bSBen Skeggs void (*wr32)(struct nvkm_object *, u64 offset, u32 data); 107c39f472eSBen Skeggs }; 108c39f472eSBen Skeggs 1095025407bSBen Skeggs static inline struct nvkm_ofuncs * 110c39f472eSBen Skeggs nv_ofuncs(void *obj) 111c39f472eSBen Skeggs { 112c39f472eSBen Skeggs return nv_oclass(obj)->ofuncs; 113c39f472eSBen Skeggs } 114c39f472eSBen Skeggs 1155025407bSBen Skeggs int nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *, 1165025407bSBen Skeggs struct nvkm_oclass *, void *, u32, 1175025407bSBen Skeggs struct nvkm_object **); 1185025407bSBen Skeggs void nvkm_object_ref(struct nvkm_object *, struct nvkm_object **); 1195025407bSBen Skeggs int nvkm_object_inc(struct nvkm_object *); 1205025407bSBen Skeggs int nvkm_object_dec(struct nvkm_object *, bool suspend); 121c39f472eSBen Skeggs 122c39f472eSBen Skeggs static inline int 123c39f472eSBen Skeggs nv_exec(void *obj, u32 mthd, void *data, u32 size) 124c39f472eSBen Skeggs { 1255025407bSBen Skeggs struct nvkm_omthds *method = nv_oclass(obj)->omthds; 126c39f472eSBen Skeggs 127c39f472eSBen Skeggs while (method && method->call) { 128c39f472eSBen Skeggs if (mthd >= method->start && mthd <= method->limit) 129c39f472eSBen Skeggs return method->call(obj, mthd, data, size); 130c39f472eSBen Skeggs method++; 131c39f472eSBen Skeggs } 132c39f472eSBen Skeggs 133c39f472eSBen Skeggs return -EINVAL; 134c39f472eSBen Skeggs } 135c39f472eSBen Skeggs 136c39f472eSBen Skeggs static inline int 137c39f472eSBen Skeggs nv_call(void *obj, u32 mthd, u32 data) 138c39f472eSBen Skeggs { 139c39f472eSBen Skeggs return nv_exec(obj, mthd, &data, sizeof(data)); 140c39f472eSBen Skeggs } 141c39f472eSBen Skeggs 142c39f472eSBen Skeggs static inline u8 143c39f472eSBen Skeggs nv_ro08(void *obj, u64 addr) 144c39f472eSBen Skeggs { 145c39f472eSBen Skeggs u8 data = nv_ofuncs(obj)->rd08(obj, addr); 146c39f472eSBen Skeggs return data; 147c39f472eSBen Skeggs } 148c39f472eSBen Skeggs 149c39f472eSBen Skeggs static inline u16 150c39f472eSBen Skeggs nv_ro16(void *obj, u64 addr) 151c39f472eSBen Skeggs { 152c39f472eSBen Skeggs u16 data = nv_ofuncs(obj)->rd16(obj, addr); 153c39f472eSBen Skeggs return data; 154c39f472eSBen Skeggs } 155c39f472eSBen Skeggs 156c39f472eSBen Skeggs static inline u32 157c39f472eSBen Skeggs nv_ro32(void *obj, u64 addr) 158c39f472eSBen Skeggs { 159c39f472eSBen Skeggs u32 data = nv_ofuncs(obj)->rd32(obj, addr); 160c39f472eSBen Skeggs return data; 161c39f472eSBen Skeggs } 162c39f472eSBen Skeggs 163c39f472eSBen Skeggs static inline void 164c39f472eSBen Skeggs nv_wo08(void *obj, u64 addr, u8 data) 165c39f472eSBen Skeggs { 166c39f472eSBen Skeggs nv_ofuncs(obj)->wr08(obj, addr, data); 167c39f472eSBen Skeggs } 168c39f472eSBen Skeggs 169c39f472eSBen Skeggs static inline void 170c39f472eSBen Skeggs nv_wo16(void *obj, u64 addr, u16 data) 171c39f472eSBen Skeggs { 172c39f472eSBen Skeggs nv_ofuncs(obj)->wr16(obj, addr, data); 173c39f472eSBen Skeggs } 174c39f472eSBen Skeggs 175c39f472eSBen Skeggs static inline void 176c39f472eSBen Skeggs nv_wo32(void *obj, u64 addr, u32 data) 177c39f472eSBen Skeggs { 178c39f472eSBen Skeggs nv_ofuncs(obj)->wr32(obj, addr, data); 179c39f472eSBen Skeggs } 180c39f472eSBen Skeggs 181c39f472eSBen Skeggs static inline u32 182c39f472eSBen Skeggs nv_mo32(void *obj, u64 addr, u32 mask, u32 data) 183c39f472eSBen Skeggs { 184c39f472eSBen Skeggs u32 temp = nv_ro32(obj, addr); 185c39f472eSBen Skeggs nv_wo32(obj, addr, (temp & ~mask) | data); 186c39f472eSBen Skeggs return temp; 187c39f472eSBen Skeggs } 188c39f472eSBen Skeggs #endif 189