mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
drm/nouveau/object: implement support for new-style nvkm_object
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
89c651e221
commit
cbea21e2ab
10 changed files with 271 additions and 65 deletions
|
@ -68,8 +68,12 @@ void _nvkm_gpuobj_wr32(struct nvkm_object *, u64, u32);
|
||||||
struct nvkm_gpuobj *_gpuobj = (o); \
|
struct nvkm_gpuobj *_gpuobj = (o); \
|
||||||
(void)_gpuobj; \
|
(void)_gpuobj; \
|
||||||
} while(0)
|
} while(0)
|
||||||
#define nvkm_ro32(o,a) nv_ofuncs(o)->rd32(&(o)->object, (a))
|
#define nvkm_ro32(o,a) ({ \
|
||||||
#define nvkm_wo32(o,a,d) nv_ofuncs(o)->wr32(&(o)->object, (a), (d))
|
u32 _data; \
|
||||||
|
nvkm_object_rd32(&(o)->object, (a), &_data); \
|
||||||
|
_data; \
|
||||||
|
})
|
||||||
|
#define nvkm_wo32(o,a,d) nvkm_object_wr32(&(o)->object, (a), (d))
|
||||||
#define nvkm_mo32(o,a,m,d) ({ \
|
#define nvkm_mo32(o,a,m,d) ({ \
|
||||||
u32 _addr = (a), _data = nvkm_ro32((o), _addr); \
|
u32 _addr = (a), _data = nvkm_ro32((o), _addr); \
|
||||||
nvkm_wo32((o), _addr, (_data & ~(m)) | (d)); \
|
nvkm_wo32((o), _addr, (_data & ~(m)) | (d)); \
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#define __NVKM_OBJECT_H__
|
#define __NVKM_OBJECT_H__
|
||||||
#include <core/os.h>
|
#include <core/os.h>
|
||||||
#include <core/debug.h>
|
#include <core/debug.h>
|
||||||
|
struct nvkm_event;
|
||||||
|
struct nvkm_gpuobj;
|
||||||
|
|
||||||
#define NV_PARENT_CLASS 0x80000000
|
#define NV_PARENT_CLASS 0x80000000
|
||||||
#define NV_NAMEDB_CLASS 0x40000000
|
#define NV_NAMEDB_CLASS 0x40000000
|
||||||
|
@ -13,10 +15,14 @@
|
||||||
#define NV_ENGCTX_CLASS 0x01000000
|
#define NV_ENGCTX_CLASS 0x01000000
|
||||||
|
|
||||||
struct nvkm_object {
|
struct nvkm_object {
|
||||||
|
const struct nvkm_object_func *func;
|
||||||
|
struct nvkm_client *client;
|
||||||
|
struct nvkm_engine *engine;
|
||||||
|
u32 oclass_name;
|
||||||
|
u32 handle;
|
||||||
|
struct nvkm_object *parent;
|
||||||
struct nvkm_oclass *oclass;
|
struct nvkm_oclass *oclass;
|
||||||
u32 pclass;
|
u32 pclass;
|
||||||
struct nvkm_object *parent;
|
|
||||||
struct nvkm_engine *engine;
|
|
||||||
atomic_t refcount;
|
atomic_t refcount;
|
||||||
atomic_t usecount;
|
atomic_t usecount;
|
||||||
#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
|
#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
|
||||||
|
@ -26,12 +32,44 @@ struct nvkm_object {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nvkm_object_func {
|
||||||
|
void *(*dtor)(struct nvkm_object *);
|
||||||
|
int (*init)(struct nvkm_object *);
|
||||||
|
int (*fini)(struct nvkm_object *, bool suspend);
|
||||||
|
int (*mthd)(struct nvkm_object *, u32 mthd, void *data, u32 size);
|
||||||
|
int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **);
|
||||||
|
int (*map)(struct nvkm_object *, u64 *addr, u32 *size);
|
||||||
|
int (*rd08)(struct nvkm_object *, u64 addr, u8 *data);
|
||||||
|
int (*rd16)(struct nvkm_object *, u64 addr, u16 *data);
|
||||||
|
int (*rd32)(struct nvkm_object *, u64 addr, u32 *data);
|
||||||
|
int (*wr08)(struct nvkm_object *, u64 addr, u8 data);
|
||||||
|
int (*wr16)(struct nvkm_object *, u64 addr, u16 data);
|
||||||
|
int (*wr32)(struct nvkm_object *, u64 addr, u32 data);
|
||||||
|
int (*bind)(struct nvkm_object *, struct nvkm_gpuobj *, int align,
|
||||||
|
struct nvkm_gpuobj **);
|
||||||
|
int (*sclass)(struct nvkm_object *, int index, struct nvkm_oclass *);
|
||||||
|
};
|
||||||
|
|
||||||
|
void nvkm_object_ctor(const struct nvkm_object_func *,
|
||||||
|
const struct nvkm_oclass *, struct nvkm_object *);
|
||||||
|
int nvkm_object_new_(const struct nvkm_object_func *,
|
||||||
|
const struct nvkm_oclass *, void *data, u32 size,
|
||||||
|
struct nvkm_object **);
|
||||||
|
int nvkm_object_new(const struct nvkm_oclass *, void *data, u32 size,
|
||||||
|
struct nvkm_object **);
|
||||||
|
int nvkm_object_init(struct nvkm_object *);
|
||||||
|
int nvkm_object_fini(struct nvkm_object *, bool suspend);
|
||||||
|
int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size);
|
||||||
|
int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **);
|
||||||
|
int nvkm_object_map(struct nvkm_object *, u64 *addr, u32 *size);
|
||||||
int nvkm_object_rd08(struct nvkm_object *, u64 addr, u8 *data);
|
int nvkm_object_rd08(struct nvkm_object *, u64 addr, u8 *data);
|
||||||
int nvkm_object_rd16(struct nvkm_object *, u64 addr, u16 *data);
|
int nvkm_object_rd16(struct nvkm_object *, u64 addr, u16 *data);
|
||||||
int nvkm_object_rd32(struct nvkm_object *, u64 addr, u32 *data);
|
int nvkm_object_rd32(struct nvkm_object *, u64 addr, u32 *data);
|
||||||
int nvkm_object_wr08(struct nvkm_object *, u64 addr, u8 data);
|
int nvkm_object_wr08(struct nvkm_object *, u64 addr, u8 data);
|
||||||
int nvkm_object_wr16(struct nvkm_object *, u64 addr, u16 data);
|
int nvkm_object_wr16(struct nvkm_object *, u64 addr, u16 data);
|
||||||
int nvkm_object_wr32(struct nvkm_object *, u64 addr, u32 data);
|
int nvkm_object_wr32(struct nvkm_object *, u64 addr, u32 data);
|
||||||
|
int nvkm_object_bind(struct nvkm_object *, struct nvkm_gpuobj *, int align,
|
||||||
|
struct nvkm_gpuobj **);
|
||||||
|
|
||||||
static inline struct nvkm_object *
|
static inline struct nvkm_object *
|
||||||
nv_object(void *obj)
|
nv_object(void *obj)
|
||||||
|
@ -59,6 +97,15 @@ int _nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *,
|
||||||
|
|
||||||
extern struct nvkm_ofuncs nvkm_object_ofuncs;
|
extern struct nvkm_ofuncs nvkm_object_ofuncs;
|
||||||
|
|
||||||
|
struct nvkm_sclass {
|
||||||
|
int minver;
|
||||||
|
int maxver;
|
||||||
|
s32 oclass;
|
||||||
|
const struct nvkm_object_func *func;
|
||||||
|
int (*ctor)(const struct nvkm_oclass *, void *data, u32 size,
|
||||||
|
struct nvkm_object **);
|
||||||
|
};
|
||||||
|
|
||||||
/* Don't allocate dynamically, because lockdep needs lock_class_keys to be in
|
/* Don't allocate dynamically, because lockdep needs lock_class_keys to be in
|
||||||
* ".data". */
|
* ".data". */
|
||||||
struct nvkm_oclass {
|
struct nvkm_oclass {
|
||||||
|
@ -66,6 +113,16 @@ struct nvkm_oclass {
|
||||||
struct nvkm_ofuncs * const ofuncs;
|
struct nvkm_ofuncs * const ofuncs;
|
||||||
struct nvkm_omthds * const omthds;
|
struct nvkm_omthds * const omthds;
|
||||||
struct lock_class_key lock_class_key;
|
struct lock_class_key lock_class_key;
|
||||||
|
|
||||||
|
int (*ctor)(const struct nvkm_oclass *, void *data, u32 size,
|
||||||
|
struct nvkm_object **);
|
||||||
|
struct nvkm_sclass base;
|
||||||
|
const void *priv;
|
||||||
|
const void *engn;
|
||||||
|
u64 object;
|
||||||
|
struct nvkm_client *client;
|
||||||
|
struct nvkm_object *parent;
|
||||||
|
struct nvkm_engine *engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define nv_oclass(o) nv_object(o)->oclass
|
#define nv_oclass(o) nv_object(o)->oclass
|
||||||
|
@ -87,7 +144,6 @@ struct nvkm_omthds {
|
||||||
int (*call)(struct nvkm_object *, u32, void *, u32);
|
int (*call)(struct nvkm_object *, u32, void *, u32);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nvkm_event;
|
|
||||||
struct nvkm_ofuncs {
|
struct nvkm_ofuncs {
|
||||||
int (*ctor)(struct nvkm_object *, struct nvkm_object *,
|
int (*ctor)(struct nvkm_object *, struct nvkm_object *,
|
||||||
struct nvkm_oclass *, void *data, u32 size,
|
struct nvkm_oclass *, void *data, u32 size,
|
||||||
|
|
|
@ -182,20 +182,20 @@ u32
|
||||||
_nvkm_gpuobj_rd32(struct nvkm_object *object, u64 addr)
|
_nvkm_gpuobj_rd32(struct nvkm_object *object, u64 addr)
|
||||||
{
|
{
|
||||||
struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
|
struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
|
||||||
struct nvkm_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
|
u32 data;
|
||||||
if (gpuobj->node)
|
if (gpuobj->node)
|
||||||
addr += gpuobj->node->offset;
|
addr += gpuobj->node->offset;
|
||||||
return pfuncs->rd32(gpuobj->parent, addr);
|
nvkm_object_rd32(gpuobj->parent, addr, &data);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_nvkm_gpuobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
|
_nvkm_gpuobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
|
||||||
{
|
{
|
||||||
struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
|
struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
|
||||||
struct nvkm_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
|
|
||||||
if (gpuobj->node)
|
if (gpuobj->node)
|
||||||
addr += gpuobj->node->offset;
|
addr += gpuobj->node->offset;
|
||||||
pfuncs->wr32(gpuobj->parent, addr, data);
|
nvkm_object_wr32(gpuobj->parent, addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct nvkm_oclass
|
static struct nvkm_oclass
|
||||||
|
|
|
@ -152,6 +152,8 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail_ctor;
|
goto fail_ctor;
|
||||||
|
|
||||||
|
object->handle = _handle;
|
||||||
|
|
||||||
ret = nvkm_object_inc(object);
|
ret = nvkm_object_inc(object);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail_init;
|
goto fail_init;
|
||||||
|
@ -205,7 +207,6 @@ static int
|
||||||
nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size)
|
nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size)
|
||||||
{
|
{
|
||||||
struct nvkm_object *object = handle->object;
|
struct nvkm_object *object = handle->object;
|
||||||
struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
|
|
||||||
union {
|
union {
|
||||||
struct nvif_ioctl_mthd_v0 v0;
|
struct nvif_ioctl_mthd_v0 v0;
|
||||||
} *args = data;
|
} *args = data;
|
||||||
|
@ -215,8 +216,7 @@ nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size)
|
||||||
if (nvif_unpack(args->v0, 0, 0, true)) {
|
if (nvif_unpack(args->v0, 0, 0, true)) {
|
||||||
nvif_ioctl(object, "mthd vers %d mthd %02x\n",
|
nvif_ioctl(object, "mthd vers %d mthd %02x\n",
|
||||||
args->v0.version, args->v0.method);
|
args->v0.version, args->v0.method);
|
||||||
if (ret = -ENODEV, ofuncs->mthd)
|
ret = nvkm_object_mthd(object, args->v0.method, data, size);
|
||||||
ret = ofuncs->mthd(object, args->v0.method, data, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -296,7 +296,6 @@ static int
|
||||||
nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size)
|
nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size)
|
||||||
{
|
{
|
||||||
struct nvkm_object *object = handle->object;
|
struct nvkm_object *object = handle->object;
|
||||||
struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
|
|
||||||
union {
|
union {
|
||||||
struct nvif_ioctl_map_v0 v0;
|
struct nvif_ioctl_map_v0 v0;
|
||||||
} *args = data;
|
} *args = data;
|
||||||
|
@ -305,10 +304,8 @@ nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size)
|
||||||
nvif_ioctl(object, "map size %d\n", size);
|
nvif_ioctl(object, "map size %d\n", size);
|
||||||
if (nvif_unpack(args->v0, 0, 0, false)) {
|
if (nvif_unpack(args->v0, 0, 0, false)) {
|
||||||
nvif_ioctl(object, "map vers %d\n", args->v0.version);
|
nvif_ioctl(object, "map vers %d\n", args->v0.version);
|
||||||
if (ret = -ENODEV, ofuncs->map) {
|
ret = nvkm_object_map(object, &args->v0.handle,
|
||||||
ret = ofuncs->map(object, &args->v0.handle,
|
&args->v0.length);
|
||||||
&args->v0.length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -335,7 +332,6 @@ static int
|
||||||
nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size)
|
nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size)
|
||||||
{
|
{
|
||||||
struct nvkm_object *object = handle->object;
|
struct nvkm_object *object = handle->object;
|
||||||
struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
|
|
||||||
union {
|
union {
|
||||||
struct nvif_ioctl_ntfy_new_v0 v0;
|
struct nvif_ioctl_ntfy_new_v0 v0;
|
||||||
} *args = data;
|
} *args = data;
|
||||||
|
@ -346,8 +342,7 @@ nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size)
|
||||||
if (nvif_unpack(args->v0, 0, 0, true)) {
|
if (nvif_unpack(args->v0, 0, 0, true)) {
|
||||||
nvif_ioctl(object, "ntfy new vers %d event %02x\n",
|
nvif_ioctl(object, "ntfy new vers %d event %02x\n",
|
||||||
args->v0.version, args->v0.event);
|
args->v0.version, args->v0.event);
|
||||||
if (ret = -ENODEV, ofuncs->ntfy)
|
ret = nvkm_object_ntfy(object, args->v0.event, &event);
|
||||||
ret = ofuncs->ntfy(object, args->v0.event, &event);
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = nvkm_client_notify_new(object, event, data, size);
|
ret = nvkm_client_notify_new(object, event, data, size);
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
|
|
|
@ -24,73 +24,230 @@
|
||||||
#include <core/object.h>
|
#include <core/object.h>
|
||||||
#include <core/engine.h>
|
#include <core/engine.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
nvkm_object_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
|
||||||
|
{
|
||||||
|
if (object->oclass) {
|
||||||
|
if (object->oclass->ofuncs->mthd)
|
||||||
|
return object->oclass->ofuncs->mthd(object, mthd, data, size);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
if (likely(object->func->mthd))
|
||||||
|
return object->func->mthd(object, mthd, data, size);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvkm_object_ntfy(struct nvkm_object *object, u32 mthd,
|
||||||
|
struct nvkm_event **pevent)
|
||||||
|
{
|
||||||
|
if (object->oclass) {
|
||||||
|
if (object->oclass->ofuncs->ntfy)
|
||||||
|
return object->oclass->ofuncs->ntfy(object, mthd, pevent);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
if (likely(object->func->ntfy))
|
||||||
|
return object->func->ntfy(object, mthd, pevent);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvkm_object_map(struct nvkm_object *object, u64 *addr, u32 *size)
|
||||||
|
{
|
||||||
|
if (object->oclass) {
|
||||||
|
if (object->oclass->ofuncs->map)
|
||||||
|
return object->oclass->ofuncs->map(object, addr, size);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
if (likely(object->func->map))
|
||||||
|
return object->func->map(object, addr, size);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvkm_object_rd08(struct nvkm_object *object, u64 addr, u8 *data)
|
nvkm_object_rd08(struct nvkm_object *object, u64 addr, u8 *data)
|
||||||
{
|
{
|
||||||
const struct nvkm_oclass *oclass = object->oclass;
|
if (object->oclass) {
|
||||||
if (oclass->ofuncs && oclass->ofuncs->rd08) {
|
if (object->oclass->ofuncs->rd08) {
|
||||||
*data = oclass->ofuncs->rd08(object, addr);
|
*data = object->oclass->ofuncs->rd08(object, addr);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
*data = 0x00;
|
||||||
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
*data = 0x00;
|
if (likely(object->func->rd08))
|
||||||
|
return object->func->rd08(object, addr, data);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvkm_object_rd16(struct nvkm_object *object, u64 addr, u16 *data)
|
nvkm_object_rd16(struct nvkm_object *object, u64 addr, u16 *data)
|
||||||
{
|
{
|
||||||
const struct nvkm_oclass *oclass = object->oclass;
|
if (object->oclass) {
|
||||||
if (oclass->ofuncs && oclass->ofuncs->rd16) {
|
if (object->oclass->ofuncs->rd16) {
|
||||||
*data = oclass->ofuncs->rd16(object, addr);
|
*data = object->oclass->ofuncs->rd16(object, addr);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
*data = 0x0000;
|
||||||
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
*data = 0x0000;
|
if (likely(object->func->rd16))
|
||||||
|
return object->func->rd16(object, addr, data);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvkm_object_rd32(struct nvkm_object *object, u64 addr, u32 *data)
|
nvkm_object_rd32(struct nvkm_object *object, u64 addr, u32 *data)
|
||||||
{
|
{
|
||||||
const struct nvkm_oclass *oclass = object->oclass;
|
if (object->oclass) {
|
||||||
if (oclass->ofuncs && oclass->ofuncs->rd32) {
|
if (object->oclass->ofuncs->rd32) {
|
||||||
*data = oclass->ofuncs->rd32(object, addr);
|
*data = object->oclass->ofuncs->rd32(object, addr);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
*data = 0x00000000;
|
||||||
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
*data = 0x0000;
|
if (likely(object->func->rd32))
|
||||||
|
return object->func->rd32(object, addr, data);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvkm_object_wr08(struct nvkm_object *object, u64 addr, u8 data)
|
nvkm_object_wr08(struct nvkm_object *object, u64 addr, u8 data)
|
||||||
{
|
{
|
||||||
const struct nvkm_oclass *oclass = object->oclass;
|
if (object->oclass) {
|
||||||
if (oclass->ofuncs && oclass->ofuncs->wr08) {
|
if (object->oclass->ofuncs->wr08) {
|
||||||
oclass->ofuncs->wr08(object, addr, data);
|
object->oclass->ofuncs->wr08(object, addr, data);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
if (likely(object->func->wr08))
|
||||||
|
return object->func->wr08(object, addr, data);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvkm_object_wr16(struct nvkm_object *object, u64 addr, u16 data)
|
nvkm_object_wr16(struct nvkm_object *object, u64 addr, u16 data)
|
||||||
{
|
{
|
||||||
const struct nvkm_oclass *oclass = object->oclass;
|
if (object->oclass) {
|
||||||
if (oclass->ofuncs && oclass->ofuncs->wr16) {
|
if (object->oclass->ofuncs->wr16) {
|
||||||
oclass->ofuncs->wr16(object, addr, data);
|
object->oclass->ofuncs->wr16(object, addr, data);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
if (likely(object->func->wr16))
|
||||||
|
return object->func->wr16(object, addr, data);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvkm_object_wr32(struct nvkm_object *object, u64 addr, u32 data)
|
nvkm_object_wr32(struct nvkm_object *object, u64 addr, u32 data)
|
||||||
{
|
{
|
||||||
const struct nvkm_oclass *oclass = object->oclass;
|
if (object->oclass) {
|
||||||
if (oclass->ofuncs && oclass->ofuncs->wr32) {
|
if (object->oclass->ofuncs->wr32) {
|
||||||
oclass->ofuncs->wr32(object, addr, data);
|
object->oclass->ofuncs->wr32(object, addr, data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
if (likely(object->func->wr32))
|
||||||
|
return object->func->wr32(object, addr, data);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvkm_object_bind(struct nvkm_object *object, struct nvkm_gpuobj *gpuobj,
|
||||||
|
int align, struct nvkm_gpuobj **pgpuobj)
|
||||||
|
{
|
||||||
|
if (object->oclass)
|
||||||
|
return -ENODEV;
|
||||||
|
if (object->func->bind)
|
||||||
|
return object->func->bind(object, gpuobj, align, pgpuobj);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvkm_object_fini(struct nvkm_object *object, bool suspend)
|
||||||
|
{
|
||||||
|
if (object->oclass)
|
||||||
|
return object->oclass->ofuncs->fini(object, suspend);
|
||||||
|
if (object->func->fini)
|
||||||
|
return object->func->fini(object, suspend);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvkm_object_init(struct nvkm_object *object)
|
||||||
|
{
|
||||||
|
if (object->oclass)
|
||||||
|
return object->oclass->ofuncs->init(object);
|
||||||
|
if (object->func->init)
|
||||||
|
return object->func->init(object);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nvkm_object_del(struct nvkm_object **pobject)
|
||||||
|
{
|
||||||
|
struct nvkm_object *object = *pobject;
|
||||||
|
|
||||||
|
if (object && object->oclass) {
|
||||||
|
object->oclass->ofuncs->dtor(object);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object && !WARN_ON(!object->func)) {
|
||||||
|
if (object->func->dtor)
|
||||||
|
*pobject = object->func->dtor(object);
|
||||||
|
kfree(*pobject);
|
||||||
|
*pobject = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nvkm_object_ctor(const struct nvkm_object_func *func,
|
||||||
|
const struct nvkm_oclass *oclass, struct nvkm_object *object)
|
||||||
|
{
|
||||||
|
object->func = func;
|
||||||
|
object->client = oclass->client;
|
||||||
|
object->engine = oclass->engine;
|
||||||
|
object->oclass_name = oclass->base.oclass;
|
||||||
|
object->handle = oclass->handle;
|
||||||
|
object->parent = oclass->parent;
|
||||||
|
atomic_set(&object->refcount, 1);
|
||||||
|
atomic_set(&object->usecount, 0);
|
||||||
|
#ifdef NVKM_OBJECT_MAGIC
|
||||||
|
object->_magic = NVKM_OBJECT_MAGIC;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvkm_object_new_(const struct nvkm_object_func *func,
|
||||||
|
const struct nvkm_oclass *oclass, void *data, u32 size,
|
||||||
|
struct nvkm_object **pobject)
|
||||||
|
{
|
||||||
|
if (size == 0) {
|
||||||
|
if (!(*pobject = kzalloc(sizeof(**pobject), GFP_KERNEL)))
|
||||||
|
return -ENOMEM;
|
||||||
|
nvkm_object_ctor(func, oclass, *pobject);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -ENODEV;
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct nvkm_object_func
|
||||||
|
nvkm_object_func = {
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
nvkm_object_new(const struct nvkm_oclass *oclass, void *data, u32 size,
|
||||||
|
struct nvkm_object **pobject)
|
||||||
|
{
|
||||||
|
const struct nvkm_object_func *func =
|
||||||
|
oclass->base.func ? oclass->base.func : &nvkm_object_func;
|
||||||
|
return nvkm_object_new_(func, oclass, data, size, pobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -182,12 +339,6 @@ nvkm_object_old(struct nvkm_object *parent, struct nvkm_object *engine,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
nvkm_object_dtor(struct nvkm_object *object)
|
|
||||||
{
|
|
||||||
nv_ofuncs(object)->dtor(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref)
|
nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref)
|
||||||
{
|
{
|
||||||
|
@ -198,7 +349,7 @@ nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref)
|
||||||
if (*ref) {
|
if (*ref) {
|
||||||
int dead = atomic_dec_and_test(&(*ref)->refcount);
|
int dead = atomic_dec_and_test(&(*ref)->refcount);
|
||||||
if (dead)
|
if (dead)
|
||||||
nvkm_object_dtor(*ref);
|
nvkm_object_del(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
*ref = obj;
|
*ref = obj;
|
||||||
|
@ -227,7 +378,7 @@ nvkm_object_inc(struct nvkm_object *object)
|
||||||
goto fail_engine;
|
goto fail_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nv_ofuncs(object)->init(object);
|
ret = nvkm_object_init(object);
|
||||||
atomic_set(&object->usecount, 1);
|
atomic_set(&object->usecount, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail_self;
|
goto fail_self;
|
||||||
|
@ -251,7 +402,7 @@ fail_parent:
|
||||||
static int
|
static int
|
||||||
nvkm_object_decf(struct nvkm_object *object)
|
nvkm_object_decf(struct nvkm_object *object)
|
||||||
{
|
{
|
||||||
nv_ofuncs(object)->fini(object, false);
|
nvkm_object_fini(object, false);
|
||||||
atomic_set(&object->usecount, 0);
|
atomic_set(&object->usecount, 0);
|
||||||
|
|
||||||
if (object->engine) {
|
if (object->engine) {
|
||||||
|
@ -271,7 +422,7 @@ nvkm_object_decs(struct nvkm_object *object)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = nv_ofuncs(object)->fini(object, true);
|
ret = nvkm_object_fini(object, true);
|
||||||
atomic_set(&object->usecount, 0);
|
atomic_set(&object->usecount, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -300,7 +451,7 @@ fail_parent:
|
||||||
}
|
}
|
||||||
|
|
||||||
fail_engine:
|
fail_engine:
|
||||||
nv_ofuncs(object)->init(object);
|
nvkm_object_init(object);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ nvkm_ramht_new(struct nvkm_object *parent, struct nvkm_object *pargpu,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = nvkm_gpuobj_create(parent, parent->engine ?
|
ret = nvkm_gpuobj_create(parent, parent->engine ?
|
||||||
&parent->engine->subdev.object : parent, /* <nv50 ramht */
|
&parent->engine->subdev.object : NULL, /* <nv50 ramht */
|
||||||
&nvkm_ramht_oclass, 0, pargpu, size,
|
&nvkm_ramht_oclass, 0, pargpu, size,
|
||||||
align, NVOBJ_FLAG_ZERO_ALLOC, &ramht);
|
align, NVOBJ_FLAG_ZERO_ALLOC, &ramht);
|
||||||
*pramht = ramht;
|
*pramht = ramht;
|
||||||
|
|
|
@ -41,7 +41,7 @@ nvkm_subdev_reset(struct nvkm_object *obj)
|
||||||
{
|
{
|
||||||
struct nvkm_subdev *subdev = container_of(obj, typeof(*subdev), object);
|
struct nvkm_subdev *subdev = container_of(obj, typeof(*subdev), object);
|
||||||
nvkm_trace(subdev, "resetting...\n");
|
nvkm_trace(subdev, "resetting...\n");
|
||||||
nv_ofuncs(subdev)->fini(&subdev->object, false);
|
nvkm_object_fini(&subdev->object, false);
|
||||||
nvkm_trace(subdev, "reset\n");
|
nvkm_trace(subdev, "reset\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -451,8 +451,8 @@ gf100_fifo_recover_work(struct work_struct *work)
|
||||||
|
|
||||||
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
|
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
|
||||||
if ((engine = (void *)nvkm_engine(fifo, engn))) {
|
if ((engine = (void *)nvkm_engine(fifo, engn))) {
|
||||||
nv_ofuncs(engine)->fini(engine, false);
|
nvkm_object_fini(engine, false);
|
||||||
WARN_ON(nv_ofuncs(engine)->init(engine));
|
WARN_ON(nvkm_object_init(engine));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -497,8 +497,8 @@ gk104_fifo_recover_work(struct work_struct *work)
|
||||||
|
|
||||||
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
|
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
|
||||||
if ((engine = (void *)nvkm_engine(fifo, engn))) {
|
if ((engine = (void *)nvkm_engine(fifo, engn))) {
|
||||||
nv_ofuncs(engine)->fini(engine, false);
|
nvkm_object_fini(engine, false);
|
||||||
WARN_ON(nv_ofuncs(engine)->init(engine));
|
WARN_ON(nvkm_object_init(engine));
|
||||||
}
|
}
|
||||||
gk104_fifo_runlist_update(fifo, gk104_fifo_engidx(fifo, engn));
|
gk104_fifo_runlist_update(fifo, gk104_fifo_engidx(fifo, engn));
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ nv50_devinit_init(struct nvkm_object *object)
|
||||||
* the vbios engineers didn't make the scripts just work...
|
* the vbios engineers didn't make the scripts just work...
|
||||||
*/
|
*/
|
||||||
if (init->base.post && ibus)
|
if (init->base.post && ibus)
|
||||||
nv_ofuncs(ibus)->init(nv_object(ibus));
|
nvkm_object_init(&ibus->object);
|
||||||
|
|
||||||
ret = nvkm_devinit_init(&init->base);
|
ret = nvkm_devinit_init(&init->base);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Add table
Reference in a new issue