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