linux/drivers/gpu/drm/nouveau/core/include/core/object.h
<<
>>
Prefs
   1#ifndef __NOUVEAU_OBJECT_H__
   2#define __NOUVEAU_OBJECT_H__
   3
   4#include <core/os.h>
   5#include <core/printk.h>
   6
   7#define NV_PARENT_CLASS 0x80000000
   8#define NV_NAMEDB_CLASS 0x40000000
   9#define NV_CLIENT_CLASS 0x20000000
  10#define NV_SUBDEV_CLASS 0x10000000
  11#define NV_ENGINE_CLASS 0x08000000
  12#define NV_MEMOBJ_CLASS 0x04000000
  13#define NV_GPUOBJ_CLASS 0x02000000
  14#define NV_ENGCTX_CLASS 0x01000000
  15#define NV_OBJECT_CLASS 0x0000ffff
  16
  17struct nouveau_object {
  18        struct nouveau_oclass *oclass;
  19        struct nouveau_object *parent;
  20        struct nouveau_object *engine;
  21        atomic_t refcount;
  22        atomic_t usecount;
  23#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
  24#define NOUVEAU_OBJECT_MAGIC 0x75ef0bad
  25        struct list_head list;
  26        u32 _magic;
  27#endif
  28};
  29
  30static inline struct nouveau_object *
  31nv_object(void *obj)
  32{
  33#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
  34        if (likely(obj)) {
  35                struct nouveau_object *object = obj;
  36                if (unlikely(object->_magic != NOUVEAU_OBJECT_MAGIC))
  37                        nv_assert("BAD CAST -> NvObject, invalid magic");
  38        }
  39#endif
  40        return obj;
  41}
  42
  43#define nouveau_object_create(p,e,c,s,d)                                       \
  44        nouveau_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d)
  45int  nouveau_object_create_(struct nouveau_object *, struct nouveau_object *,
  46                            struct nouveau_oclass *, u32, int size, void **);
  47void nouveau_object_destroy(struct nouveau_object *);
  48int  nouveau_object_init(struct nouveau_object *);
  49int  nouveau_object_fini(struct nouveau_object *, bool suspend);
  50
  51int _nouveau_object_ctor(struct nouveau_object *, struct nouveau_object *,
  52                         struct nouveau_oclass *, void *, u32,
  53                         struct nouveau_object **);
  54
  55extern struct nouveau_ofuncs nouveau_object_ofuncs;
  56
  57/* Don't allocate dynamically, because lockdep needs lock_class_keys to be in
  58 * ".data". */
  59struct nouveau_oclass {
  60        u32 handle;
  61        struct nouveau_ofuncs * const ofuncs;
  62        struct nouveau_omthds * const omthds;
  63        struct lock_class_key lock_class_key;
  64};
  65
  66#define nv_oclass(o)    nv_object(o)->oclass
  67#define nv_hclass(o)    nv_oclass(o)->handle
  68#define nv_iclass(o,i) (nv_hclass(o) & (i))
  69#define nv_mclass(o)    nv_iclass(o, NV_OBJECT_CLASS)
  70
  71static inline struct nouveau_object *
  72nv_pclass(struct nouveau_object *parent, u32 oclass)
  73{
  74        while (parent && !nv_iclass(parent, oclass))
  75                parent = parent->parent;
  76        return parent;
  77}
  78
  79struct nouveau_omthds {
  80        u32 start;
  81        u32 limit;
  82        int (*call)(struct nouveau_object *, u32, void *, u32);
  83};
  84
  85struct nvkm_event;
  86struct nouveau_ofuncs {
  87        int  (*ctor)(struct nouveau_object *, struct nouveau_object *,
  88                     struct nouveau_oclass *, void *data, u32 size,
  89                     struct nouveau_object **);
  90        void (*dtor)(struct nouveau_object *);
  91        int  (*init)(struct nouveau_object *);
  92        int  (*fini)(struct nouveau_object *, bool suspend);
  93        int  (*mthd)(struct nouveau_object *, u32, void *, u32);
  94        int  (*ntfy)(struct nouveau_object *, u32, struct nvkm_event **);
  95        int  (* map)(struct nouveau_object *, u64 *, u32 *);
  96        u8   (*rd08)(struct nouveau_object *, u64 offset);
  97        u16  (*rd16)(struct nouveau_object *, u64 offset);
  98        u32  (*rd32)(struct nouveau_object *, u64 offset);
  99        void (*wr08)(struct nouveau_object *, u64 offset, u8 data);
 100        void (*wr16)(struct nouveau_object *, u64 offset, u16 data);
 101        void (*wr32)(struct nouveau_object *, u64 offset, u32 data);
 102};
 103
 104static inline struct nouveau_ofuncs *
 105nv_ofuncs(void *obj)
 106{
 107        return nv_oclass(obj)->ofuncs;
 108}
 109
 110int  nouveau_object_ctor(struct nouveau_object *, struct nouveau_object *,
 111                         struct nouveau_oclass *, void *, u32,
 112                         struct nouveau_object **);
 113void nouveau_object_ref(struct nouveau_object *, struct nouveau_object **);
 114int nouveau_object_inc(struct nouveau_object *);
 115int nouveau_object_dec(struct nouveau_object *, bool suspend);
 116
 117void nouveau_object_debug(void);
 118
 119static inline int
 120nv_exec(void *obj, u32 mthd, void *data, u32 size)
 121{
 122        struct nouveau_omthds *method = nv_oclass(obj)->omthds;
 123
 124        while (method && method->call) {
 125                if (mthd >= method->start && mthd <= method->limit)
 126                        return method->call(obj, mthd, data, size);
 127                method++;
 128        }
 129
 130        return -EINVAL;
 131}
 132
 133static inline int
 134nv_call(void *obj, u32 mthd, u32 data)
 135{
 136        return nv_exec(obj, mthd, &data, sizeof(data));
 137}
 138
 139static inline u8
 140nv_ro08(void *obj, u64 addr)
 141{
 142        u8 data = nv_ofuncs(obj)->rd08(obj, addr);
 143        nv_spam(obj, "nv_ro08 0x%08llx 0x%02x\n", addr, data);
 144        return data;
 145}
 146
 147static inline u16
 148nv_ro16(void *obj, u64 addr)
 149{
 150        u16 data = nv_ofuncs(obj)->rd16(obj, addr);
 151        nv_spam(obj, "nv_ro16 0x%08llx 0x%04x\n", addr, data);
 152        return data;
 153}
 154
 155static inline u32
 156nv_ro32(void *obj, u64 addr)
 157{
 158        u32 data = nv_ofuncs(obj)->rd32(obj, addr);
 159        nv_spam(obj, "nv_ro32 0x%08llx 0x%08x\n", addr, data);
 160        return data;
 161}
 162
 163static inline void
 164nv_wo08(void *obj, u64 addr, u8 data)
 165{
 166        nv_spam(obj, "nv_wo08 0x%08llx 0x%02x\n", addr, data);
 167        nv_ofuncs(obj)->wr08(obj, addr, data);
 168}
 169
 170static inline void
 171nv_wo16(void *obj, u64 addr, u16 data)
 172{
 173        nv_spam(obj, "nv_wo16 0x%08llx 0x%04x\n", addr, data);
 174        nv_ofuncs(obj)->wr16(obj, addr, data);
 175}
 176
 177static inline void
 178nv_wo32(void *obj, u64 addr, u32 data)
 179{
 180        nv_spam(obj, "nv_wo32 0x%08llx 0x%08x\n", addr, data);
 181        nv_ofuncs(obj)->wr32(obj, addr, data);
 182}
 183
 184static inline u32
 185nv_mo32(void *obj, u64 addr, u32 mask, u32 data)
 186{
 187        u32 temp = nv_ro32(obj, addr);
 188        nv_wo32(obj, addr, (temp & ~mask) | data);
 189        return temp;
 190}
 191
 192static inline int
 193nv_memcmp(void *obj, u32 addr, const char *str, u32 len)
 194{
 195        unsigned char c1, c2;
 196
 197        while (len--) {
 198                c1 = nv_ro08(obj, addr++);
 199                c2 = *(str++);
 200                if (c1 != c2)
 201                        return c1 - c2;
 202        }
 203        return 0;
 204}
 205
 206#include <core/handle.h>
 207
 208static inline int
 209nouveau_object_new(struct nouveau_object *client, u32 parent, u32 handle,
 210                   u16 oclass, void *data, u32 size,
 211                   struct nouveau_object **pobject)
 212{
 213        return nouveau_handle_new(client, parent, handle, oclass,
 214                                  data, size, pobject);
 215}
 216
 217static inline int
 218nouveau_object_del(struct nouveau_object *client, u32 parent, u32 handle)
 219{
 220        return nouveau_handle_del(client, parent, handle);
 221}
 222
 223#endif
 224