Commit 5ffeb84b authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/pm: convert user classes to new-style nvkm_object



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 218f978d
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
#ifndef __NVKM_PM_H__
#define __NVKM_PM_H__
#define nvkm_pm(p) container_of((p), struct nvkm_pm, engine)
#include <core/engine.h>

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;
+119 −106
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@

#include <core/client.h>
#include <core/option.h>
#include <core/parent.h>

#include <nvif/class.h>
#include <nvif/ioctl.h>
@@ -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_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
		  struct nvkm_oclass *oclass, void *data, u32 size,
nvkm_perfmon_child_new(const struct nvkm_oclass *oclass, void *data, u32 size,
		       struct nvkm_object **pobject)
{
	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;
	struct nvkm_perfmon *perfmon = nvkm_perfmon(oclass->parent);
	return nvkm_perfdom_new_(perfmon, oclass, data, size, pobject);
}

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 int
nvkm_perfmon_child_get(struct nvkm_object *base, int index,
		       struct nvkm_oclass *oclass)
{
	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;
}

struct nvkm_oclass
nvkm_pm_sclass[] = {
static void *
nvkm_perfmon_dtor(struct nvkm_object *base)
{
	  .handle = NVIF_IOCTL_NEW_V0_PERFMON,
	  .ofuncs = &nvkm_perfmon_ofuncs,
	},
	{},
	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;
}

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;
+0 −2
Original line number Diff line number Diff line
@@ -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;
}

+0 −2
Original line number Diff line number Diff line
@@ -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;
}

+0 −2
Original line number Diff line number Diff line
@@ -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;
}

Loading