1 #ifndef __NVKM_OBJECT_H__
2 #define __NVKM_OBJECT_H__
3 #include <core/os.h>
4 #include <core/debug.h>
5 
6 #define NV_PARENT_CLASS 0x80000000
7 #define NV_NAMEDB_CLASS 0x40000000
8 #define NV_CLIENT_CLASS 0x20000000
9 #define NV_SUBDEV_CLASS 0x10000000
10 #define NV_ENGINE_CLASS 0x08000000
11 #define NV_MEMOBJ_CLASS 0x04000000
12 #define NV_GPUOBJ_CLASS 0x02000000
13 #define NV_ENGCTX_CLASS 0x01000000
14 #define NV_OBJECT_CLASS 0x0000ffff
15 
16 struct nvkm_object {
17 	struct nvkm_oclass *oclass;
18 	struct nvkm_object *parent;
19 	struct nvkm_engine *engine;
20 	atomic_t refcount;
21 	atomic_t usecount;
22 #if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
23 #define NVKM_OBJECT_MAGIC 0x75ef0bad
24 	struct list_head list;
25 	u32 _magic;
26 #endif
27 };
28 
29 int nvkm_object_rd08(struct nvkm_object *, u64 addr, u8  *data);
30 int nvkm_object_rd16(struct nvkm_object *, u64 addr, u16 *data);
31 int nvkm_object_rd32(struct nvkm_object *, u64 addr, u32 *data);
32 int nvkm_object_wr08(struct nvkm_object *, u64 addr, u8   data);
33 int nvkm_object_wr16(struct nvkm_object *, u64 addr, u16  data);
34 int nvkm_object_wr32(struct nvkm_object *, u64 addr, u32  data);
35 
36 static inline struct nvkm_object *
37 nv_object(void *obj)
38 {
39 #if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
40 	if (likely(obj)) {
41 		struct nvkm_object *object = obj;
42 		BUG_ON(object->_magic != NVKM_OBJECT_MAGIC);
43 	}
44 #endif
45 	return obj;
46 }
47 
48 #define nvkm_object_create(p,e,c,s,d)                                       \
49 	nvkm_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d)
50 int  nvkm_object_create_(struct nvkm_object *, struct nvkm_object *,
51 			    struct nvkm_oclass *, u32, int size, void **);
52 void nvkm_object_destroy(struct nvkm_object *);
53 int  nvkm_object_init(struct nvkm_object *);
54 int  nvkm_object_fini(struct nvkm_object *, bool suspend);
55 
56 int _nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *,
57 			 struct nvkm_oclass *, void *, u32,
58 			 struct nvkm_object **);
59 
60 extern struct nvkm_ofuncs nvkm_object_ofuncs;
61 
62 /* Don't allocate dynamically, because lockdep needs lock_class_keys to be in
63  * ".data". */
64 struct nvkm_oclass {
65 	u32 handle;
66 	struct nvkm_ofuncs * const ofuncs;
67 	struct nvkm_omthds * const omthds;
68 	struct lock_class_key lock_class_key;
69 };
70 
71 #define nv_oclass(o)    nv_object(o)->oclass
72 #define nv_hclass(o)    nv_oclass(o)->handle
73 #define nv_iclass(o,i) (nv_hclass(o) & (i))
74 #define nv_mclass(o)    nv_iclass(o, NV_OBJECT_CLASS)
75 
76 static inline struct nvkm_object *
77 nv_pclass(struct nvkm_object *parent, u32 oclass)
78 {
79 	while (parent && !nv_iclass(parent, oclass))
80 		parent = parent->parent;
81 	return parent;
82 }
83 
84 struct nvkm_omthds {
85 	u32 start;
86 	u32 limit;
87 	int (*call)(struct nvkm_object *, u32, void *, u32);
88 };
89 
90 struct nvkm_event;
91 struct nvkm_ofuncs {
92 	int  (*ctor)(struct nvkm_object *, struct nvkm_object *,
93 		     struct nvkm_oclass *, void *data, u32 size,
94 		     struct nvkm_object **);
95 	void (*dtor)(struct nvkm_object *);
96 	int  (*init)(struct nvkm_object *);
97 	int  (*fini)(struct nvkm_object *, bool suspend);
98 	int  (*mthd)(struct nvkm_object *, u32, void *, u32);
99 	int  (*ntfy)(struct nvkm_object *, u32, struct nvkm_event **);
100 	int  (* map)(struct nvkm_object *, u64 *, u32 *);
101 	u8   (*rd08)(struct nvkm_object *, u64 offset);
102 	u16  (*rd16)(struct nvkm_object *, u64 offset);
103 	u32  (*rd32)(struct nvkm_object *, u64 offset);
104 	void (*wr08)(struct nvkm_object *, u64 offset, u8 data);
105 	void (*wr16)(struct nvkm_object *, u64 offset, u16 data);
106 	void (*wr32)(struct nvkm_object *, u64 offset, u32 data);
107 };
108 
109 static inline struct nvkm_ofuncs *
110 nv_ofuncs(void *obj)
111 {
112 	return nv_oclass(obj)->ofuncs;
113 }
114 
115 int  nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *,
116 		      struct nvkm_oclass *, void *, u32,
117 		      struct nvkm_object **);
118 void nvkm_object_ref(struct nvkm_object *, struct nvkm_object **);
119 int  nvkm_object_inc(struct nvkm_object *);
120 int  nvkm_object_dec(struct nvkm_object *, bool suspend);
121 
122 static inline int
123 nv_exec(void *obj, u32 mthd, void *data, u32 size)
124 {
125 	struct nvkm_omthds *method = nv_oclass(obj)->omthds;
126 
127 	while (method && method->call) {
128 		if (mthd >= method->start && mthd <= method->limit)
129 			return method->call(obj, mthd, data, size);
130 		method++;
131 	}
132 
133 	return -EINVAL;
134 }
135 
136 static inline int
137 nv_call(void *obj, u32 mthd, u32 data)
138 {
139 	return nv_exec(obj, mthd, &data, sizeof(data));
140 }
141 #endif
142