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