1 /* $NetBSD: nouveau_nvkm_core_oproxy.c,v 1.6 2021/12/19 10:51:57 riastradh Exp $ */
2
3 /*
4 * Copyright 2015 Red Hat Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Ben Skeggs <bskeggs@redhat.com>
25 */
26 #include <sys/cdefs.h>
27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_core_oproxy.c,v 1.6 2021/12/19 10:51:57 riastradh Exp $");
28
29 #include <core/oproxy.h>
30
31 static int
nvkm_oproxy_mthd(struct nvkm_object * object,u32 mthd,void * data,u32 size)32 nvkm_oproxy_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
33 {
34 return nvkm_object_mthd(nvkm_oproxy(object)->object, mthd, data, size);
35 }
36
37 static int
nvkm_oproxy_ntfy(struct nvkm_object * object,u32 mthd,struct nvkm_event ** pevent)38 nvkm_oproxy_ntfy(struct nvkm_object *object, u32 mthd,
39 struct nvkm_event **pevent)
40 {
41 return nvkm_object_ntfy(nvkm_oproxy(object)->object, mthd, pevent);
42 }
43
44 #ifdef __NetBSD__
45 static int
nvkm_oproxy_map(struct nvkm_object * object,void * argv,u32 argc,enum nvkm_object_map * type,bus_space_tag_t * tagp,u64 * addr,u64 * size)46 nvkm_oproxy_map(struct nvkm_object *object, void *argv, u32 argc,
47 enum nvkm_object_map *type, bus_space_tag_t *tagp, u64 *addr, u64 *size)
48 {
49 return nvkm_object_map(nvkm_oproxy(object)->object, argv, argc, type,
50 tagp, addr, size);
51 }
52 #else
53 static int
nvkm_oproxy_map(struct nvkm_object * object,void * argv,u32 argc,enum nvkm_object_map * type,u64 * addr,u64 * size)54 nvkm_oproxy_map(struct nvkm_object *object, void *argv, u32 argc,
55 enum nvkm_object_map *type, u64 *addr, u64 *size)
56 {
57 struct nvkm_oproxy *oproxy = nvkm_oproxy(object);
58 return nvkm_object_map(oproxy->object, argv, argc, type, addr, size);
59 }
60 #endif
61
62 static int
nvkm_oproxy_unmap(struct nvkm_object * object)63 nvkm_oproxy_unmap(struct nvkm_object *object)
64 {
65 return nvkm_object_unmap(nvkm_oproxy(object)->object);
66 }
67
68 static int
nvkm_oproxy_rd08(struct nvkm_object * object,u64 addr,u8 * data)69 nvkm_oproxy_rd08(struct nvkm_object *object, u64 addr, u8 *data)
70 {
71 return nvkm_object_rd08(nvkm_oproxy(object)->object, addr, data);
72 }
73
74 static int
nvkm_oproxy_rd16(struct nvkm_object * object,u64 addr,u16 * data)75 nvkm_oproxy_rd16(struct nvkm_object *object, u64 addr, u16 *data)
76 {
77 return nvkm_object_rd16(nvkm_oproxy(object)->object, addr, data);
78 }
79
80 static int
nvkm_oproxy_rd32(struct nvkm_object * object,u64 addr,u32 * data)81 nvkm_oproxy_rd32(struct nvkm_object *object, u64 addr, u32 *data)
82 {
83 return nvkm_object_rd32(nvkm_oproxy(object)->object, addr, data);
84 }
85
86 static int
nvkm_oproxy_wr08(struct nvkm_object * object,u64 addr,u8 data)87 nvkm_oproxy_wr08(struct nvkm_object *object, u64 addr, u8 data)
88 {
89 return nvkm_object_wr08(nvkm_oproxy(object)->object, addr, data);
90 }
91
92 static int
nvkm_oproxy_wr16(struct nvkm_object * object,u64 addr,u16 data)93 nvkm_oproxy_wr16(struct nvkm_object *object, u64 addr, u16 data)
94 {
95 return nvkm_object_wr16(nvkm_oproxy(object)->object, addr, data);
96 }
97
98 static int
nvkm_oproxy_wr32(struct nvkm_object * object,u64 addr,u32 data)99 nvkm_oproxy_wr32(struct nvkm_object *object, u64 addr, u32 data)
100 {
101 return nvkm_object_wr32(nvkm_oproxy(object)->object, addr, data);
102 }
103
104 static int
nvkm_oproxy_bind(struct nvkm_object * object,struct nvkm_gpuobj * parent,int align,struct nvkm_gpuobj ** pgpuobj)105 nvkm_oproxy_bind(struct nvkm_object *object, struct nvkm_gpuobj *parent,
106 int align, struct nvkm_gpuobj **pgpuobj)
107 {
108 return nvkm_object_bind(nvkm_oproxy(object)->object,
109 parent, align, pgpuobj);
110 }
111
112 static int
nvkm_oproxy_sclass(struct nvkm_object * object,int index,struct nvkm_oclass * oclass)113 nvkm_oproxy_sclass(struct nvkm_object *object, int index,
114 struct nvkm_oclass *oclass)
115 {
116 struct nvkm_oproxy *oproxy = nvkm_oproxy(object);
117 oclass->parent = oproxy->object;
118 if (!oproxy->object->func->sclass)
119 return -ENODEV;
120 return oproxy->object->func->sclass(oproxy->object, index, oclass);
121 }
122
123 static int
nvkm_oproxy_fini(struct nvkm_object * object,bool suspend)124 nvkm_oproxy_fini(struct nvkm_object *object, bool suspend)
125 {
126 struct nvkm_oproxy *oproxy = nvkm_oproxy(object);
127 int ret;
128
129 if (oproxy->func->fini[0]) {
130 ret = oproxy->func->fini[0](oproxy, suspend);
131 if (ret && suspend)
132 return ret;
133 }
134
135 if (oproxy->object->func->fini) {
136 ret = oproxy->object->func->fini(oproxy->object, suspend);
137 if (ret && suspend)
138 return ret;
139 }
140
141 if (oproxy->func->fini[1]) {
142 ret = oproxy->func->fini[1](oproxy, suspend);
143 if (ret && suspend)
144 return ret;
145 }
146
147 return 0;
148 }
149
150 static int
nvkm_oproxy_init(struct nvkm_object * object)151 nvkm_oproxy_init(struct nvkm_object *object)
152 {
153 struct nvkm_oproxy *oproxy = nvkm_oproxy(object);
154 int ret;
155
156 if (oproxy->func->init[0]) {
157 ret = oproxy->func->init[0](oproxy);
158 if (ret)
159 return ret;
160 }
161
162 if (oproxy->object->func->init) {
163 ret = oproxy->object->func->init(oproxy->object);
164 if (ret)
165 return ret;
166 }
167
168 if (oproxy->func->init[1]) {
169 ret = oproxy->func->init[1](oproxy);
170 if (ret)
171 return ret;
172 }
173
174 return 0;
175 }
176
177 static void *
nvkm_oproxy_dtor(struct nvkm_object * object)178 nvkm_oproxy_dtor(struct nvkm_object *object)
179 {
180 struct nvkm_oproxy *oproxy = nvkm_oproxy(object);
181 if (oproxy->func->dtor[0])
182 oproxy->func->dtor[0](oproxy);
183 nvkm_object_del(&oproxy->object);
184 if (oproxy->func->dtor[1])
185 oproxy->func->dtor[1](oproxy);
186 return oproxy;
187 }
188
189 static const struct nvkm_object_func
190 nvkm_oproxy_func = {
191 .dtor = nvkm_oproxy_dtor,
192 .init = nvkm_oproxy_init,
193 .fini = nvkm_oproxy_fini,
194 .mthd = nvkm_oproxy_mthd,
195 .ntfy = nvkm_oproxy_ntfy,
196 .map = nvkm_oproxy_map,
197 .unmap = nvkm_oproxy_unmap,
198 .rd08 = nvkm_oproxy_rd08,
199 .rd16 = nvkm_oproxy_rd16,
200 .rd32 = nvkm_oproxy_rd32,
201 .wr08 = nvkm_oproxy_wr08,
202 .wr16 = nvkm_oproxy_wr16,
203 .wr32 = nvkm_oproxy_wr32,
204 .bind = nvkm_oproxy_bind,
205 .sclass = nvkm_oproxy_sclass,
206 };
207
208 void
nvkm_oproxy_ctor(const struct nvkm_oproxy_func * func,const struct nvkm_oclass * oclass,struct nvkm_oproxy * oproxy)209 nvkm_oproxy_ctor(const struct nvkm_oproxy_func *func,
210 const struct nvkm_oclass *oclass, struct nvkm_oproxy *oproxy)
211 {
212 nvkm_object_ctor(&nvkm_oproxy_func, oclass, &oproxy->base);
213 oproxy->func = func;
214 }
215
216 int
nvkm_oproxy_new_(const struct nvkm_oproxy_func * func,const struct nvkm_oclass * oclass,struct nvkm_oproxy ** poproxy)217 nvkm_oproxy_new_(const struct nvkm_oproxy_func *func,
218 const struct nvkm_oclass *oclass, struct nvkm_oproxy **poproxy)
219 {
220 if (!(*poproxy = kzalloc(sizeof(**poproxy), GFP_KERNEL)))
221 return -ENOMEM;
222 nvkm_oproxy_ctor(func, oclass, *poproxy);
223 return 0;
224 }
225