drm/nouveau/device: decouple from engine machinery
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
a1bfb29a33
commit
a1e8873622
|
@ -4,7 +4,6 @@
|
|||
#include <core/event.h>
|
||||
|
||||
enum nvkm_devidx {
|
||||
NVDEV_ENGINE_DEVICE,
|
||||
NVDEV_SUBDEV_VBIOS,
|
||||
|
||||
/* All subdevs from DEVINIT to DEVINIT_LAST will be created before
|
||||
|
@ -65,7 +64,10 @@ enum nvkm_devidx {
|
|||
|
||||
struct nvkm_device {
|
||||
struct nvkm_engine engine;
|
||||
|
||||
struct list_head head;
|
||||
struct mutex mutex;
|
||||
int refcount;
|
||||
|
||||
struct pci_dev *pdev;
|
||||
struct platform_device *platformdev;
|
||||
|
@ -210,11 +212,15 @@ enum nv_bus_type {
|
|||
NVKM_BUS_PLATFORM,
|
||||
};
|
||||
|
||||
extern struct nvkm_ofuncs nvkm_udevice_ofuncs;
|
||||
|
||||
int nvkm_device_new(void *, enum nv_bus_type type, u64 name,
|
||||
const char *sname, const char *cfg, const char *dbg,
|
||||
bool detect, bool mmio, u64 subdev_mask,
|
||||
struct nvkm_device **);
|
||||
void nvkm_device_del(struct nvkm_device **);
|
||||
int nvkm_device_init(struct nvkm_device *);
|
||||
int nvkm_device_fini(struct nvkm_device *, bool suspend);
|
||||
|
||||
/* device logging */
|
||||
#define nvdev_printk_(d,l,p,f,a...) do { \
|
||||
|
|
|
@ -226,6 +226,12 @@ nvkm_client_del(struct nvkm_client **pclient)
|
|||
}
|
||||
}
|
||||
|
||||
static struct nvkm_oclass
|
||||
nvkm_client_sclass[] = {
|
||||
{ NV_DEVICE, &nvkm_udevice_ofuncs },
|
||||
{}
|
||||
};
|
||||
|
||||
int
|
||||
nvkm_client_new(const char *name, u64 devname, const char *cfg,
|
||||
const char *dbg, struct nvkm_client **pclient)
|
||||
|
@ -239,9 +245,8 @@ nvkm_client_new(const char *name, u64 devname, const char *cfg,
|
|||
return -ENODEV;
|
||||
|
||||
ret = nvkm_namedb_create(NULL, NULL, &nvkm_client_oclass,
|
||||
NV_CLIENT_CLASS, NULL,
|
||||
(1ULL << NVDEV_ENGINE_DEVICE),
|
||||
&client);
|
||||
NV_CLIENT_CLASS, nvkm_client_sclass,
|
||||
0, &client);
|
||||
*pclient = client;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -216,7 +216,6 @@ nvkm_gpuobj_new(struct nvkm_object *parent, struct nvkm_object *pargpu,
|
|||
u32 size, u32 align, u32 flags,
|
||||
struct nvkm_gpuobj **pgpuobj)
|
||||
{
|
||||
struct nvkm_object *engine = parent;
|
||||
struct nvkm_gpuobj_class args = {
|
||||
.pargpu = pargpu,
|
||||
.size = size,
|
||||
|
@ -224,12 +223,8 @@ nvkm_gpuobj_new(struct nvkm_object *parent, struct nvkm_object *pargpu,
|
|||
.flags = flags,
|
||||
};
|
||||
|
||||
if (!nv_iclass(engine, NV_SUBDEV_CLASS))
|
||||
engine = &engine->engine->subdev.object;
|
||||
BUG_ON(engine == NULL);
|
||||
|
||||
return nvkm_object_ctor(parent, engine, &_nvkm_gpuobj_oclass,
|
||||
&args, sizeof(args),
|
||||
return nvkm_object_ctor(parent, &parent->engine->subdev.object,
|
||||
&_nvkm_gpuobj_oclass, &args, sizeof(args),
|
||||
(struct nvkm_object **)pgpuobj);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ nvkm_subdev(void *obj, int idx)
|
|||
struct nvkm_object *object = nv_object(obj);
|
||||
while (object && !nv_iclass(object, NV_SUBDEV_CLASS))
|
||||
object = object->parent;
|
||||
if (object == NULL || nv_subidx(nv_subdev(object)) != idx)
|
||||
if (object == NULL || !object->parent || nv_subidx(nv_subdev(object)) != idx)
|
||||
object = nv_device(obj)->subdev[idx];
|
||||
return object ? nv_subdev(object) : NULL;
|
||||
}
|
||||
|
|
|
@ -61,13 +61,24 @@ nvkm_device_list(u64 *name, int size)
|
|||
return nr;
|
||||
}
|
||||
|
||||
#include <core/parent.h>
|
||||
|
||||
struct nvkm_device *
|
||||
nv_device(void *obj)
|
||||
{
|
||||
struct nvkm_object *device = nv_object(obj);
|
||||
|
||||
if (device->engine == NULL) {
|
||||
while (device && device->parent)
|
||||
while (device && device->parent) {
|
||||
if (nv_mclass(device) == 0x0080) {
|
||||
struct {
|
||||
struct nvkm_parent base;
|
||||
struct nvkm_device *device;
|
||||
} *udevice = (void *)device;
|
||||
return udevice->device;
|
||||
}
|
||||
device = device->parent;
|
||||
}
|
||||
} else {
|
||||
device = &nv_object(obj)->engine->subdev.object;
|
||||
if (device && device->parent)
|
||||
|
@ -79,12 +90,6 @@ nv_device(void *obj)
|
|||
return (void *)device;
|
||||
}
|
||||
|
||||
static struct nvkm_oclass
|
||||
nvkm_device_sclass[] = {
|
||||
{ 0x0080, &nvkm_udevice_ofuncs },
|
||||
{}
|
||||
};
|
||||
|
||||
static int
|
||||
nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size,
|
||||
struct nvkm_notify *notify)
|
||||
|
@ -103,10 +108,9 @@ nvkm_device_event_func = {
|
|||
.ctor = nvkm_device_event_ctor,
|
||||
};
|
||||
|
||||
static int
|
||||
nvkm_device_fini(struct nvkm_object *object, bool suspend)
|
||||
int
|
||||
nvkm_device_fini(struct nvkm_device *device, bool suspend)
|
||||
{
|
||||
struct nvkm_device *device = (void *)object;
|
||||
struct nvkm_object *subdev;
|
||||
int ret, i;
|
||||
|
||||
|
@ -136,10 +140,9 @@ nvkm_device_fini(struct nvkm_object *object, bool suspend)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_device_init(struct nvkm_object *object)
|
||||
int
|
||||
nvkm_device_init(struct nvkm_device *device)
|
||||
{
|
||||
struct nvkm_device *device = (void *)object;
|
||||
struct nvkm_object *subdev;
|
||||
int ret, i = 0, c;
|
||||
|
||||
|
@ -147,7 +150,7 @@ nvkm_device_init(struct nvkm_object *object)
|
|||
if (ret)
|
||||
goto fail;
|
||||
|
||||
for (i = 1, c = 1; i < NVDEV_SUBDEV_NR; i++) {
|
||||
for (i = 0, c = 0; i < NVDEV_SUBDEV_NR; i++) {
|
||||
#define _(s,m) case s: if (device->oclass[s] && !device->subdev[s]) { \
|
||||
ret = nvkm_object_ctor(nv_object(device), NULL, \
|
||||
device->oclass[s], NULL, (s), \
|
||||
|
@ -286,10 +289,7 @@ nv_device_get_irq(struct nvkm_device *device, bool stall)
|
|||
|
||||
static struct nvkm_oclass
|
||||
nvkm_device_oclass = {
|
||||
.handle = NV_ENGINE(DEVICE, 0x00),
|
||||
.ofuncs = &(struct nvkm_ofuncs) {
|
||||
.init = nvkm_device_init,
|
||||
.fini = nvkm_device_fini,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -356,7 +356,6 @@ nvkm_device_new(void *dev, enum nv_bus_type type, u64 name,
|
|||
device->name = sname;
|
||||
|
||||
nv_subdev(device)->debug = nvkm_dbgopt(device->dbgopt, "DEVICE");
|
||||
nv_engine(device)->sclass = nvkm_device_sclass;
|
||||
list_add_tail(&device->head, &nv_devices);
|
||||
|
||||
ret = nvkm_event_init(&nvkm_device_event_func, 1, 1, &device->event);
|
||||
|
@ -482,6 +481,8 @@ nvkm_device_new(void *dev, enum nv_bus_type type, u64 name,
|
|||
device->oclass[i] = NULL;
|
||||
}
|
||||
|
||||
atomic_set(&device->engine.subdev.object.usecount, 2);
|
||||
mutex_init(&device->mutex);
|
||||
done:
|
||||
mutex_unlock(&nv_devices_mutex);
|
||||
return ret;
|
||||
|
|
|
@ -13,6 +13,4 @@ int nv50_identify(struct nvkm_device *);
|
|||
int gf100_identify(struct nvkm_device *);
|
||||
int gk104_identify(struct nvkm_device *);
|
||||
int gm100_identify(struct nvkm_device *);
|
||||
|
||||
extern struct nvkm_ofuncs nvkm_udevice_ofuncs;
|
||||
#endif
|
||||
|
|
|
@ -173,13 +173,55 @@ nvkm_udevice_map(struct nvkm_object *object, u64 *addr, u32 *size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_udevice_fini(struct nvkm_object *object, bool suspend)
|
||||
{
|
||||
struct nvkm_udevice *udev = (void *)object;
|
||||
struct nvkm_device *device = udev->device;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&device->mutex);
|
||||
if (!--device->refcount) {
|
||||
ret = nvkm_device_fini(device, suspend);
|
||||
if (ret && suspend) {
|
||||
device->refcount++;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&device->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_udevice_init(struct nvkm_object *object)
|
||||
{
|
||||
struct nvkm_udevice *udev = (void *)object;
|
||||
struct nvkm_device *device = udev->device;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&device->mutex);
|
||||
if (!device->refcount++) {
|
||||
ret = nvkm_device_init(device);
|
||||
if (ret) {
|
||||
device->refcount--;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&device->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct nvkm_oclass
|
||||
nvkm_udevice_oclass_super = {
|
||||
.handle = NV_DEVICE,
|
||||
.ofuncs = &(struct nvkm_ofuncs) {
|
||||
.dtor = _nvkm_parent_dtor,
|
||||
.init = _nvkm_parent_init,
|
||||
.fini = _nvkm_parent_fini,
|
||||
.init = nvkm_udevice_init,
|
||||
.fini = nvkm_udevice_fini,
|
||||
.mthd = nvkm_udevice_mthd,
|
||||
.map = nvkm_udevice_map,
|
||||
.rd08 = nvkm_udevice_rd08,
|
||||
|
@ -223,8 +265,7 @@ nvkm_udevice_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = nvkm_parent_create(parent, nv_object(device), oclass, 0,
|
||||
nvkm_control_oclass,
|
||||
ret = nvkm_parent_create(parent, NULL, oclass, 0, nvkm_control_oclass,
|
||||
(1ULL << NVDEV_ENGINE_DMAOBJ) |
|
||||
(1ULL << NVDEV_ENGINE_FIFO) |
|
||||
(1ULL << NVDEV_ENGINE_DISP) |
|
||||
|
@ -241,7 +282,7 @@ struct nvkm_ofuncs
|
|||
nvkm_udevice_ofuncs = {
|
||||
.ctor = nvkm_udevice_ctor,
|
||||
.dtor = _nvkm_parent_dtor,
|
||||
.init = _nvkm_parent_init,
|
||||
.fini = _nvkm_parent_fini,
|
||||
.init = nvkm_udevice_init,
|
||||
.fini = nvkm_udevice_fini,
|
||||
.mthd = nvkm_udevice_mthd,
|
||||
};
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "outpdp.h"
|
||||
|
||||
#include <core/client.h>
|
||||
#include <core/engctx.h>
|
||||
#include <core/gpuobj.h>
|
||||
#include <core/enum.h>
|
||||
#include <core/handle.h>
|
||||
#include <core/ramht.h>
|
||||
|
@ -1292,8 +1292,8 @@ nv50_disp_data_ctor(struct nvkm_object *parent,
|
|||
struct nvkm_object **pobject)
|
||||
{
|
||||
struct nv50_disp *disp = (void *)engine;
|
||||
struct nvkm_engctx *ectx;
|
||||
int ret = -EBUSY;
|
||||
struct nvkm_gpuobj *gpuobj;
|
||||
int ret;
|
||||
|
||||
/* no context needed for channel objects... */
|
||||
if (nv_mclass(parent) != NV_DEVICE) {
|
||||
|
@ -1303,26 +1303,26 @@ nv50_disp_data_ctor(struct nvkm_object *parent,
|
|||
}
|
||||
|
||||
/* allocate display hardware to client */
|
||||
ret = nvkm_gpuobj_create(parent, engine, oclass, 0, NULL,
|
||||
0x10000, 0x10000, NVOBJ_FLAG_HEAP,
|
||||
&gpuobj);
|
||||
*pobject = nv_object(gpuobj);
|
||||
mutex_lock(&nv_subdev(disp)->mutex);
|
||||
if (list_empty(&nv_engine(disp)->contexts)) {
|
||||
ret = nvkm_engctx_create(parent, engine, oclass, NULL, 0x10000,
|
||||
0x10000, NVOBJ_FLAG_HEAP, &ectx);
|
||||
*pobject = nv_object(ectx);
|
||||
}
|
||||
if (!list_empty(&nv_engine(disp)->contexts))
|
||||
ret = -EBUSY;
|
||||
mutex_unlock(&nv_subdev(disp)->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct nvkm_oclass
|
||||
nv50_disp_cclass = {
|
||||
.handle = NV_ENGCTX(DISP, 0x50),
|
||||
.ofuncs = &(struct nvkm_ofuncs) {
|
||||
.ctor = nv50_disp_data_ctor,
|
||||
.dtor = _nvkm_engctx_dtor,
|
||||
.init = _nvkm_engctx_init,
|
||||
.fini = _nvkm_engctx_fini,
|
||||
.rd32 = _nvkm_engctx_rd32,
|
||||
.wr32 = _nvkm_engctx_wr32,
|
||||
.dtor = _nvkm_gpuobj_dtor,
|
||||
.init = _nvkm_gpuobj_init,
|
||||
.fini = _nvkm_gpuobj_fini,
|
||||
.rd32 = _nvkm_gpuobj_rd32,
|
||||
.wr32 = _nvkm_gpuobj_wr32,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -639,7 +639,7 @@ nvkm_perfctx_dtor(struct nvkm_object *object)
|
|||
struct nvkm_perfctx *ctx = (void *)object;
|
||||
|
||||
mutex_lock(&nv_subdev(pm)->mutex);
|
||||
nvkm_engctx_destroy(&ctx->base);
|
||||
nvkm_gpuobj_destroy(&ctx->base);
|
||||
if (pm->context == ctx)
|
||||
pm->context = NULL;
|
||||
mutex_unlock(&nv_subdev(pm)->mutex);
|
||||
|
@ -661,7 +661,7 @@ nvkm_perfctx_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
|
|||
return 1;
|
||||
}
|
||||
|
||||
ret = nvkm_engctx_create(parent, engine, oclass, NULL, 0, 0, 0, &ctx);
|
||||
ret = nvkm_gpuobj_create(parent, engine, oclass, 0, NULL, 0, 0, 0, &ctx);
|
||||
*pobject = nv_object(ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -678,12 +678,11 @@ nvkm_perfctx_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
|
|||
|
||||
struct nvkm_oclass
|
||||
nvkm_pm_cclass = {
|
||||
.handle = NV_ENGCTX(PM, 0x00),
|
||||
.ofuncs = &(struct nvkm_ofuncs) {
|
||||
.ctor = nvkm_perfctx_ctor,
|
||||
.dtor = nvkm_perfctx_dtor,
|
||||
.init = _nvkm_engctx_init,
|
||||
.fini = _nvkm_engctx_fini,
|
||||
.init = _nvkm_gpuobj_init,
|
||||
.fini = _nvkm_gpuobj_fini,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@ struct nvkm_perfctr {
|
|||
|
||||
extern struct nvkm_oclass nvkm_pm_sclass[];
|
||||
|
||||
#include <core/engctx.h>
|
||||
#include <core/gpuobj.h>
|
||||
|
||||
struct nvkm_perfctx {
|
||||
struct nvkm_engctx base;
|
||||
struct nvkm_gpuobj base;
|
||||
};
|
||||
|
||||
extern struct nvkm_oclass nvkm_pm_cclass;
|
||||
|
|
Loading…
Reference in New Issue