diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h index f13f8e6fc017cc74bd04ddbab8c7bd067cec14e2..c67cea6aae4d548d41e86b3cba04838ca6572eb3 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h @@ -1,5 +1,6 @@ #ifndef __NVKM_PM_H__ #define __NVKM_PM_H__ +#define nvkm_pm(p) container_of((p), struct nvkm_pm, engine) #include struct nvkm_perfdom; @@ -7,20 +8,13 @@ struct nvkm_perfctr; struct nvkm_pm { struct nvkm_engine engine; - struct nvkm_perfctx *context; - void *profile_data; + struct nvkm_object *perfmon; struct list_head domains; struct list_head sources; u32 sequence; }; -static inline struct nvkm_pm * -nvkm_pm(void *obj) -{ - return (void *)nvkm_engine(obj, NVDEV_ENGINE_PM); -} - extern struct nvkm_oclass *nv40_pm_oclass; extern struct nvkm_oclass *nv50_pm_oclass; extern struct nvkm_oclass *g84_pm_oclass; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c index 90a7d89cc019b81ab93f6a3f38d663864e173297..5b4ab63809beeadf028d7c15381e90d4f44598ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -304,11 +303,11 @@ nvkm_perfdom_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) return -EINVAL; } -static void -nvkm_perfdom_dtor(struct nvkm_object *object) +static void * +nvkm_perfdom_dtor(struct nvkm_object *base) { - struct nvkm_pm *pm = (void *)object->engine; - struct nvkm_perfdom *dom = (void *)object; + struct nvkm_perfdom *dom = nvkm_perfdom(base); + struct nvkm_pm *pm = dom->perfmon->pm; int i; for (i = 0; i < 4; i++) { @@ -320,7 +319,8 @@ nvkm_perfdom_dtor(struct nvkm_object *object) } kfree(ctr); } - nvkm_object_destroy(&dom->base); + + return dom; } static int @@ -353,15 +353,22 @@ nvkm_perfctr_new(struct nvkm_perfdom *dom, int slot, u8 domain, return 0; } +static const struct nvkm_object_func +nvkm_perfdom = { + .dtor = nvkm_perfdom_dtor, + .mthd = nvkm_perfdom_mthd, +}; + static int -nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine, - struct nvkm_oclass *oclass, void *data, u32 size, +nvkm_perfdom_new_(struct nvkm_perfmon *perfmon, + const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { union { struct nvif_perfdom_v0 v0; } *args = data; - struct nvkm_pm *pm = (void *)engine; + struct nvkm_pm *pm = perfmon->pm; + struct nvkm_object *parent = oclass->parent; struct nvkm_perfdom *sdom = NULL; struct nvkm_perfctr *ctr[4] = {}; struct nvkm_perfdom *dom; @@ -403,10 +410,11 @@ nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine, if (!sdom) return -EINVAL; - ret = nvkm_object_create(parent, engine, oclass, 0, &dom); - *pobject = nv_object(dom); - if (ret) - return ret; + if (!(dom = kzalloc(sizeof(*dom), GFP_KERNEL))) + return -ENOMEM; + nvkm_object_ctor(&nvkm_perfdom, oclass, &dom->object); + dom->perfmon = perfmon; + *pobject = &dom->object; dom->func = sdom->func; dom->addr = sdom->addr; @@ -416,25 +424,18 @@ nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine, return 0; } -static struct nvkm_ofuncs -nvkm_perfdom_ofuncs = { - .ctor = nvkm_perfdom_ctor, - .dtor = nvkm_perfdom_dtor, - .init = _nvkm_object_init, - .fini = _nvkm_object_fini, - .mthd = nvkm_perfdom_mthd, -}; - /******************************************************************************* * Perfmon object classes ******************************************************************************/ static int -nvkm_perfmon_mthd_query_domain(struct nvkm_object *object, void *data, u32 size) +nvkm_perfmon_mthd_query_domain(struct nvkm_perfmon *perfmon, + void *data, u32 size) { union { struct nvif_perfmon_query_domain_v0 v0; } *args = data; - struct nvkm_pm *pm = (void *)object->engine; + struct nvkm_object *object = &perfmon->object; + struct nvkm_pm *pm = perfmon->pm; struct nvkm_perfdom *dom; u8 domain_nr; int di, ret; @@ -475,13 +476,15 @@ nvkm_perfmon_mthd_query_domain(struct nvkm_object *object, void *data, u32 size) } static int -nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size) +nvkm_perfmon_mthd_query_signal(struct nvkm_perfmon *perfmon, + void *data, u32 size) { union { struct nvif_perfmon_query_signal_v0 v0; } *args = data; - struct nvkm_device *device = nv_device(object); - struct nvkm_pm *pm = (void *)object->engine; + struct nvkm_object *object = &perfmon->object; + struct nvkm_pm *pm = perfmon->pm; + struct nvkm_device *device = pm->engine.subdev.device; struct nvkm_perfdom *dom; struct nvkm_perfsig *sig; const bool all = nvkm_boolopt(device->cfgopt, "NvPmShowAll", false); @@ -527,12 +530,14 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size) } static int -nvkm_perfmon_mthd_query_source(struct nvkm_object *object, void *data, u32 size) +nvkm_perfmon_mthd_query_source(struct nvkm_perfmon *perfmon, + void *data, u32 size) { union { struct nvif_perfmon_query_source_v0 v0; } *args = data; - struct nvkm_pm *pm = (void *)object->engine; + struct nvkm_object *object = &perfmon->object; + struct nvkm_pm *pm = perfmon->pm; struct nvkm_perfdom *dom = NULL; struct nvkm_perfsig *sig; struct nvkm_perfsrc *src; @@ -579,117 +584,118 @@ nvkm_perfmon_mthd_query_source(struct nvkm_object *object, void *data, u32 size) static int nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) { + struct nvkm_perfmon *perfmon = nvkm_perfmon(object); switch (mthd) { case NVIF_PERFMON_V0_QUERY_DOMAIN: - return nvkm_perfmon_mthd_query_domain(object, data, size); + return nvkm_perfmon_mthd_query_domain(perfmon, data, size); case NVIF_PERFMON_V0_QUERY_SIGNAL: - return nvkm_perfmon_mthd_query_signal(object, data, size); + return nvkm_perfmon_mthd_query_signal(perfmon, data, size); case NVIF_PERFMON_V0_QUERY_SOURCE: - return nvkm_perfmon_mthd_query_source(object, data, size); + return nvkm_perfmon_mthd_query_source(perfmon, data, size); default: break; } return -EINVAL; } -static struct nvkm_oclass -nvkm_perfmon_sclass[] = { - { .handle = NVIF_IOCTL_NEW_V0_PERFDOM, - .ofuncs = &nvkm_perfdom_ofuncs, - }, - {} -}; +static int +nvkm_perfmon_child_new(const struct nvkm_oclass *oclass, void *data, u32 size, + struct nvkm_object **pobject) +{ + struct nvkm_perfmon *perfmon = nvkm_perfmon(oclass->parent); + return nvkm_perfdom_new_(perfmon, oclass, data, size, pobject); +} static int -nvkm_perfmon_ctor(struct nvkm_object *parent, struct nvkm_object *engine, - struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +nvkm_perfmon_child_get(struct nvkm_object *base, int index, + struct nvkm_oclass *oclass) { - struct nvkm_parent *perfmon; - int ret = nvkm_parent_create(parent, engine, oclass, 0, - nvkm_perfmon_sclass, 0, &perfmon); - *pobject = perfmon ? &perfmon->object : NULL; - return ret; + if (index == 0) { + oclass->base.oclass = NVIF_IOCTL_NEW_V0_PERFDOM; + oclass->base.minver = 0; + oclass->base.maxver = 0; + oclass->ctor = nvkm_perfmon_child_new; + return 0; + } + return -EINVAL; } -static struct nvkm_ofuncs -nvkm_perfmon_ofuncs = { - .ctor = nvkm_perfmon_ctor, - .dtor = _nvkm_parent_dtor, - .init = _nvkm_parent_init, - .fini = _nvkm_parent_fini, - .mthd = nvkm_perfmon_mthd, -}; +static void * +nvkm_perfmon_dtor(struct nvkm_object *base) +{ + struct nvkm_perfmon *perfmon = nvkm_perfmon(base); + struct nvkm_pm *pm = perfmon->pm; + mutex_lock(&pm->engine.subdev.mutex); + if (pm->perfmon == &perfmon->object) + pm->perfmon = NULL; + mutex_unlock(&pm->engine.subdev.mutex); + return perfmon; +} -struct nvkm_oclass -nvkm_pm_sclass[] = { - { - .handle = NVIF_IOCTL_NEW_V0_PERFMON, - .ofuncs = &nvkm_perfmon_ofuncs, - }, - {}, +static struct nvkm_object_func +nvkm_perfmon = { + .dtor = nvkm_perfmon_dtor, + .mthd = nvkm_perfmon_mthd, + .sclass = nvkm_perfmon_child_get, }; -/******************************************************************************* - * PPM context - ******************************************************************************/ -static void -nvkm_perfctx_dtor(struct nvkm_object *object) +static int +nvkm_perfmon_new(struct nvkm_pm *pm, const struct nvkm_oclass *oclass, + void *data, u32 size, struct nvkm_object **pobject) { - struct nvkm_pm *pm = (void *)object->engine; - struct nvkm_perfctx *ctx = (void *)object; + struct nvkm_perfmon *perfmon; - nvkm_gpuobj_destroy(&ctx->base); - mutex_lock(&nv_subdev(pm)->mutex); - if (pm->context == ctx) - pm->context = NULL; - mutex_unlock(&nv_subdev(pm)->mutex); + if (!(perfmon = kzalloc(sizeof(*perfmon), GFP_KERNEL))) + return -ENOMEM; + nvkm_object_ctor(&nvkm_perfmon, oclass, &perfmon->object); + perfmon->pm = pm; + *pobject = &perfmon->object; + return 0; } +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ + static int -nvkm_perfctx_ctor(struct nvkm_object *parent, struct nvkm_object *engine, - struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +nvkm_pm_oclass_new(struct nvkm_device *device, const struct nvkm_oclass *oclass, + void *data, u32 size, struct nvkm_object **pobject) { - struct nvkm_pm *pm = (void *)engine; - struct nvkm_perfctx *ctx; + struct nvkm_pm *pm = nvkm_pm(oclass->engine); int ret; - /* no context needed for perfdom objects... */ - if (parent->parent != &nvkm_client(parent)->object) { - atomic_inc(&parent->refcount); - *pobject = parent; - return 1; - } - - ret = nvkm_gpuobj_create(parent, engine, oclass, 0, NULL, 0, 0, 0, &ctx); - *pobject = nv_object(ctx); + ret = nvkm_perfmon_new(pm, oclass, data, size, pobject); if (ret) return ret; - mutex_lock(&nv_subdev(pm)->mutex); - if (pm->context == NULL) - pm->context = ctx; - if (ctx != pm->context) - ret = -EBUSY; - mutex_unlock(&nv_subdev(pm)->mutex); - + mutex_lock(&pm->engine.subdev.mutex); + if (pm->perfmon == NULL) + pm->perfmon = *pobject; + ret = (pm->perfmon == *pobject) ? 0 : -EBUSY; + mutex_unlock(&pm->engine.subdev.mutex); return ret; } -struct nvkm_oclass -nvkm_pm_cclass = { - .ofuncs = &(struct nvkm_ofuncs) { - .ctor = nvkm_perfctx_ctor, - .dtor = nvkm_perfctx_dtor, - .init = _nvkm_gpuobj_init, - .fini = _nvkm_gpuobj_fini, - }, +static const struct nvkm_device_oclass +nvkm_pm_oclass = { + .base.oclass = NVIF_IOCTL_NEW_V0_PERFMON, + .base.minver = -1, + .base.maxver = -1, + .ctor = nvkm_pm_oclass_new, }; -/******************************************************************************* - * PPM engine/subdev functions - ******************************************************************************/ +static int +nvkm_pm_oclass_get(struct nvkm_oclass *oclass, int index, + const struct nvkm_device_oclass **class) +{ + if (index == 0) { + oclass->base = nvkm_pm_oclass.base; + *class = &nvkm_pm_oclass; + return index; + } + return 1; +} + int nvkm_perfsrc_new(struct nvkm_pm *pm, struct nvkm_perfsig *sig, const struct nvkm_specsrc *spec) @@ -845,6 +851,11 @@ _nvkm_pm_dtor(struct nvkm_object *object) nvkm_engine_destroy(&pm->engine); } +static const struct nvkm_engine_func +nvkm_pm = { + .base.sclass = nvkm_pm_oclass_get, +}; + int nvkm_pm_create_(struct nvkm_object *parent, struct nvkm_object *engine, struct nvkm_oclass *oclass, int length, void **pobject) @@ -858,6 +869,8 @@ nvkm_pm_create_(struct nvkm_object *parent, struct nvkm_object *engine, if (ret) return ret; + pm->engine.func = &nvkm_pm; + INIT_LIST_HEAD(&pm->domains); INIT_LIST_HEAD(&pm->sources); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.c index 75a9e6286101ddd8de3e9b63c63b5f5b31ab0881..18e0ed51424959af692d58f71adff0bd8137b306 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.c @@ -226,8 +226,6 @@ gf100_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine, if (ret) return ret; - nv_engine(pm)->cclass = &nvkm_pm_cclass; - nv_engine(pm)->sclass = nvkm_pm_sclass; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk110.c index 3177ba4d2f571a46ed8eff4a2719db380f763854..44df8d31107074a90e019d20b29f43519a62f1ef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk110.c @@ -36,8 +36,6 @@ gk110_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine, if (ret) return ret; - nv_engine(pm)->cclass = &nvkm_pm_cclass; - nv_engine(pm)->sclass = nvkm_pm_sclass; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c index b37c024f078381c0686665aa79cc15ca4cc2f4d2..a4660dc14259348a6ae8bc6257697a6ca500f82f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c @@ -112,8 +112,6 @@ nv40_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine, if (ret) return ret; - nv_engine(pm)->cclass = &nvkm_pm_cclass; - nv_engine(pm)->sclass = nvkm_pm_sclass; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h index 2af3a501309636f58a6b6c40f2b84672f0793206..889dca2e87bea3617762eea883d24bd996807bfa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h @@ -12,16 +12,6 @@ struct nvkm_perfctr { u32 ctr; }; -extern struct nvkm_oclass nvkm_pm_sclass[]; - -#include - -struct nvkm_perfctx { - struct nvkm_gpuobj base; -}; - -extern struct nvkm_oclass nvkm_pm_cclass; - struct nvkm_specmux { u32 mask; u8 shift; @@ -68,8 +58,11 @@ struct nvkm_specdom { const struct nvkm_funcdom *func; }; +#define nvkm_perfdom(p) container_of((p), struct nvkm_perfdom, object) + struct nvkm_perfdom { - struct nvkm_object base; + struct nvkm_object object; + struct nvkm_perfmon *perfmon; struct list_head head; struct list_head list; const struct nvkm_funcdom *func; @@ -93,6 +86,13 @@ struct nvkm_funcdom { int nvkm_perfdom_new(struct nvkm_pm *, const char *, u32, u32, u32, u32, const struct nvkm_specdom *); +#define nvkm_perfmon(p) container_of((p), struct nvkm_perfmon, object) + +struct nvkm_perfmon { + struct nvkm_object object; + struct nvkm_pm *pm; +}; + #define nvkm_pm_create(p,e,o,d) \ nvkm_pm_create_((p), (e), (o), sizeof(**d), (void **)d) #define nvkm_pm_dtor(p) ({ \