1#ifndef __NVKM_OBJECT_H__ 2#define __NVKM_OBJECT_H__ 3#include <core/os.h> 4#include <core/printk.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 16struct 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 29static inline struct nvkm_object * 30nv_object(void *obj) 31{ 32#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA 33 if (likely(obj)) { 34 struct nvkm_object *object = obj; 35 if (unlikely(object->_magic != NVKM_OBJECT_MAGIC)) 36 nv_assert("BAD CAST -> NvObject, invalid magic"); 37 } 38#endif 39 return obj; 40} 41 42#define nvkm_object_create(p,e,c,s,d) \ 43 nvkm_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d) 44int nvkm_object_create_(struct nvkm_object *, struct nvkm_object *, 45 struct nvkm_oclass *, u32, int size, void **); 46void nvkm_object_destroy(struct nvkm_object *); 47int nvkm_object_init(struct nvkm_object *); 48int nvkm_object_fini(struct nvkm_object *, bool suspend); 49 50int _nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *, 51 struct nvkm_oclass *, void *, u32, 52 struct nvkm_object **); 53 54extern struct nvkm_ofuncs nvkm_object_ofuncs; 55 56/* Don't allocate dynamically, because lockdep needs lock_class_keys to be in 57 * ".data". */ 58struct nvkm_oclass { 59 u32 handle; 60 struct nvkm_ofuncs * const ofuncs; 61 struct nvkm_omthds * const omthds; 62 struct lock_class_key lock_class_key; 63}; 64 65#define nv_oclass(o) nv_object(o)->oclass 66#define nv_hclass(o) nv_oclass(o)->handle 67#define nv_iclass(o,i) (nv_hclass(o) & (i)) 68#define nv_mclass(o) nv_iclass(o, NV_OBJECT_CLASS) 69 70static inline struct nvkm_object * 71nv_pclass(struct nvkm_object *parent, u32 oclass) 72{ 73 while (parent && !nv_iclass(parent, oclass)) 74 parent = parent->parent; 75 return parent; 76} 77 78struct nvkm_omthds { 79 u32 start; 80 u32 limit; 81 int (*call)(struct nvkm_object *, u32, void *, u32); 82}; 83 84struct nvkm_event; 85struct nvkm_ofuncs { 86 int (*ctor)(struct nvkm_object *, struct nvkm_object *, 87 struct nvkm_oclass *, void *data, u32 size, 88 struct nvkm_object **); 89 void (*dtor)(struct nvkm_object *); 90 int (*init)(struct nvkm_object *); 91 int (*fini)(struct nvkm_object *, bool suspend); 92 int (*mthd)(struct nvkm_object *, u32, void *, u32); 93 int (*ntfy)(struct nvkm_object *, u32, struct nvkm_event **); 94 int (* map)(struct nvkm_object *, u64 *, u32 *); 95 u8 (*rd08)(struct nvkm_object *, u64 offset); 96 u16 (*rd16)(struct nvkm_object *, u64 offset); 97 u32 (*rd32)(struct nvkm_object *, u64 offset); 98 void (*wr08)(struct nvkm_object *, u64 offset, u8 data); 99 void (*wr16)(struct nvkm_object *, u64 offset, u16 data); 100 void (*wr32)(struct nvkm_object *, u64 offset, u32 data); 101}; 102 103static inline struct nvkm_ofuncs * 104nv_ofuncs(void *obj) 105{ 106 return nv_oclass(obj)->ofuncs; 107} 108 109int nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *, 110 struct nvkm_oclass *, void *, u32, 111 struct nvkm_object **); 112void nvkm_object_ref(struct nvkm_object *, struct nvkm_object **); 113int nvkm_object_inc(struct nvkm_object *); 114int nvkm_object_dec(struct nvkm_object *, bool suspend); 115void nvkm_object_debug(void); 116 117static inline int 118nv_exec(void *obj, u32 mthd, void *data, u32 size) 119{ 120 struct nvkm_omthds *method = nv_oclass(obj)->omthds; 121 122 while (method && method->call) { 123 if (mthd >= method->start && mthd <= method->limit) 124 return method->call(obj, mthd, data, size); 125 method++; 126 } 127 128 return -EINVAL; 129} 130 131static inline int 132nv_call(void *obj, u32 mthd, u32 data) 133{ 134 return nv_exec(obj, mthd, &data, sizeof(data)); 135} 136 137static inline u8 138nv_ro08(void *obj, u64 addr) 139{ 140 u8 data = nv_ofuncs(obj)->rd08(obj, addr); 141 nv_spam(obj, "nv_ro08 0x%08llx 0x%02x\n", addr, data); 142 return data; 143} 144 145static inline u16 146nv_ro16(void *obj, u64 addr) 147{ 148 u16 data = nv_ofuncs(obj)->rd16(obj, addr); 149 nv_spam(obj, "nv_ro16 0x%08llx 0x%04x\n", addr, data); 150 return data; 151} 152 153static inline u32 154nv_ro32(void *obj, u64 addr) 155{ 156 u32 data = nv_ofuncs(obj)->rd32(obj, addr); 157 nv_spam(obj, "nv_ro32 0x%08llx 0x%08x\n", addr, data); 158 return data; 159} 160 161static inline void 162nv_wo08(void *obj, u64 addr, u8 data) 163{ 164 nv_spam(obj, "nv_wo08 0x%08llx 0x%02x\n", addr, data); 165 nv_ofuncs(obj)->wr08(obj, addr, data); 166} 167 168static inline void 169nv_wo16(void *obj, u64 addr, u16 data) 170{ 171 nv_spam(obj, "nv_wo16 0x%08llx 0x%04x\n", addr, data); 172 nv_ofuncs(obj)->wr16(obj, addr, data); 173} 174 175static inline void 176nv_wo32(void *obj, u64 addr, u32 data) 177{ 178 nv_spam(obj, "nv_wo32 0x%08llx 0x%08x\n", addr, data); 179 nv_ofuncs(obj)->wr32(obj, addr, data); 180} 181 182static inline u32 183nv_mo32(void *obj, u64 addr, u32 mask, u32 data) 184{ 185 u32 temp = nv_ro32(obj, addr); 186 nv_wo32(obj, addr, (temp & ~mask) | data); 187 return temp; 188} 189 190static inline int 191nv_memcmp(void *obj, u32 addr, const char *str, u32 len) 192{ 193 unsigned char c1, c2; 194 195 while (len--) { 196 c1 = nv_ro08(obj, addr++); 197 c2 = *(str++); 198 if (c1 != c2) 199 return c1 - c2; 200 } 201 return 0; 202} 203#endif 204