File Index
Files and directories
Sign in
FILE

engine.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c C
  1/* SPDX-License-Identifier: MIT
  2 *
  3 * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
  4 */
  5#include "engine.h"
  6#include "gpu.h"
  7
  8#include <core/object.h>
  9#include <engine/fifo/chan.h>
 10
 11struct nvkm_rm_engine {
 12	struct nvkm_engine engine;
 13
 14	struct nvkm_engine_func func;
 15};
 16
 17struct nvkm_rm_engine_obj {
 18	struct nvkm_object object;
 19	struct nvkm_gsp_object rm;
 20};
 21
 22static void*
 23nvkm_rm_engine_obj_dtor(struct nvkm_object *object)
 24{
 25	struct nvkm_rm_engine_obj *obj = container_of(object, typeof(*obj), object);
 26
 27	nvkm_gsp_rm_free(&obj->rm);
 28	return obj;
 29}
 30
 31static const struct nvkm_object_func
 32nvkm_rm_engine_obj = {
 33	.dtor = nvkm_rm_engine_obj_dtor,
 34};
 35
 36int
 37nvkm_rm_engine_obj_new(struct nvkm_gsp_object *chan, int chid, const struct nvkm_oclass *oclass,
 38		       struct nvkm_object **pobject)
 39{
 40	struct nvkm_rm *rm = chan->client->gsp->rm;
 41	const int inst = oclass->engine->subdev.inst;
 42	const u32 class = oclass->base.oclass;
 43	const u32 handle = oclass->handle;
 44	struct nvkm_rm_engine_obj *obj;
 45	int ret;
 46
 47	obj = kzalloc(sizeof(*obj), GFP_KERNEL);
 48	if (!obj)
 49		return -ENOMEM;
 50
 51	switch (oclass->engine->subdev.type) {
 52	case NVKM_ENGINE_CE:
 53		ret = rm->api->ce->alloc(chan, handle, class, inst, &obj->rm);
 54		break;
 55	case NVKM_ENGINE_GR:
 56		ret = nvkm_gsp_rm_alloc(chan, handle, class, 0, &obj->rm);
 57		break;
 58	case NVKM_ENGINE_NVDEC:
 59		ret = rm->api->nvdec->alloc(chan, handle, class, inst, &obj->rm);
 60		break;
 61	case NVKM_ENGINE_NVENC:
 62		ret = rm->api->nvenc->alloc(chan, handle, class, inst, &obj->rm);
 63		break;
 64	case NVKM_ENGINE_NVJPG:
 65		ret = rm->api->nvjpg->alloc(chan, handle, class, inst, &obj->rm);
 66		break;
 67	case NVKM_ENGINE_OFA:
 68		ret = rm->api->ofa->alloc(chan, handle, class, inst, &obj->rm);
 69		break;
 70	default:
 71		ret = -EINVAL;
 72		WARN_ON(1);
 73		break;
 74	}
 75
 76	if (ret) {
 77		kfree(obj);
 78		return ret;
 79	}
 80
 81	nvkm_object_ctor(&nvkm_rm_engine_obj, oclass, &obj->object);
 82	*pobject = &obj->object;
 83	return 0;
 84}
 85
 86static int
 87nvkm_rm_engine_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc,
 88			struct nvkm_object **pobject)
 89{
 90	struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent);
 91
 92	return nvkm_rm_engine_obj_new(&chan->rm.object, chan->id, oclass, pobject);
 93}
 94
 95static void *
 96nvkm_rm_engine_dtor(struct nvkm_engine *engine)
 97{
 98	kfree(engine->func);
 99	return engine;
100}
101
102int
103nvkm_rm_engine_ctor(void *(*dtor)(struct nvkm_engine *), struct nvkm_rm *rm,
104		    enum nvkm_subdev_type type, int inst,
105		    const u32 *class, int nclass, struct nvkm_engine *engine)
106{
107	struct nvkm_engine_func *func;
108
109	func = kzalloc(struct_size(func, sclass, nclass + 1), GFP_KERNEL);
110	if (!func)
111		return -ENOMEM;
112
113	func->dtor = dtor;
114
115	for (int i = 0; i < nclass; i++) {
116		func->sclass[i].oclass = class[i];
117		func->sclass[i].minver = -1;
118		func->sclass[i].maxver = 0;
119		func->sclass[i].ctor = nvkm_rm_engine_obj_ctor;
120	}
121
122	nvkm_engine_ctor(func, rm->device, type, inst, true, engine);
123	return 0;
124}
125
126static int
127nvkm_rm_engine_new_(struct nvkm_rm *rm, enum nvkm_subdev_type type, int inst, u32 class,
128		    struct nvkm_engine **pengine)
129{
130	struct nvkm_engine *engine;
131	int ret;
132
133	engine = kzalloc(sizeof(*engine), GFP_KERNEL);
134	if (!engine)
135		return -ENOMEM;
136
137	ret = nvkm_rm_engine_ctor(nvkm_rm_engine_dtor, rm, type, inst, &class, 1, engine);
138	if (ret) {
139		kfree(engine);
140		return ret;
141	}
142
143	*pengine = engine;
144	return 0;
145}
146
147int
148nvkm_rm_engine_new(struct nvkm_rm *rm, enum nvkm_subdev_type type, int inst)
149{
150	const struct nvkm_rm_gpu *gpu = rm->gpu;
151	struct nvkm_device *device = rm->device;
152
153	switch (type) {
154	case NVKM_ENGINE_CE:
155		if (WARN_ON(inst >= ARRAY_SIZE(device->ce)))
156			return -EINVAL;
157
158		return nvkm_rm_engine_new_(rm, type, inst, gpu->ce.class, &device->ce[inst]);
159	case NVKM_ENGINE_GR:
160		if (inst != 0)
161			return -ENODEV; /* MiG not supported, just ignore. */
162
163		return nvkm_rm_gr_new(rm);
164	case NVKM_ENGINE_NVDEC:
165		if (WARN_ON(inst >= ARRAY_SIZE(device->nvdec)))
166			return -EINVAL;
167
168		return nvkm_rm_nvdec_new(rm, inst);
169	case NVKM_ENGINE_NVENC:
170		if (WARN_ON(inst >= ARRAY_SIZE(device->nvenc)))
171			return -EINVAL;
172
173		return nvkm_rm_nvenc_new(rm, inst);
174	case NVKM_ENGINE_NVJPG:
175		if (WARN_ON(inst >= ARRAY_SIZE(device->nvjpg)))
176			return -EINVAL;
177
178		return nvkm_rm_engine_new_(rm, type, inst, gpu->nvjpg.class, &device->nvjpg[inst]);
179	case NVKM_ENGINE_OFA:
180		if (WARN_ON(inst >= ARRAY_SIZE(device->ofa)))
181			return -EINVAL;
182
183		return nvkm_rm_engine_new_(rm, type, inst, gpu->ofa.class, &device->ofa[inst]);
184	default:
185		break;
186	}
187
188	return -ENODEV;
189}
~/ Read-only file preview.