2 * Copyright 2012 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
24 #define nvkm_udevice(p) container_of((p), struct nvkm_udevice, object)
28 #include <core/client.h>
29 #include <subdev/fb.h>
30 #include <subdev/instmem.h>
31 #include <subdev/timer.h>
33 #include <nvif/class.h>
34 #include <nvif/cl0080.h>
35 #include <nvif/unpack.h>
38 struct nvkm_object object
;
39 struct nvkm_device
*device
;
43 nvkm_udevice_info(struct nvkm_udevice
*udev
, void *data
, u32 size
)
45 struct nvkm_object
*object
= &udev
->object
;
46 struct nvkm_device
*device
= udev
->device
;
47 struct nvkm_fb
*fb
= device
->fb
;
48 struct nvkm_instmem
*imem
= device
->imem
;
50 struct nv_device_info_v0 v0
;
54 nvif_ioctl(object
, "device info size %d\n", size
);
55 if (!(ret
= nvif_unpack(ret
, &data
, &size
, args
->v0
, 0, 0, false))) {
56 nvif_ioctl(object
, "device info vers %d\n", args
->v0
.version
);
60 switch (device
->chipset
) {
71 args
->v0
.platform
= NV_DEVICE_INFO_V0_IGP
;
74 switch (device
->type
) {
76 args
->v0
.platform
= NV_DEVICE_INFO_V0_PCI
;
79 args
->v0
.platform
= NV_DEVICE_INFO_V0_AGP
;
81 case NVKM_DEVICE_PCIE
:
82 args
->v0
.platform
= NV_DEVICE_INFO_V0_PCIE
;
84 case NVKM_DEVICE_TEGRA
:
85 args
->v0
.platform
= NV_DEVICE_INFO_V0_SOC
;
94 switch (device
->card_type
) {
95 case NV_04
: args
->v0
.family
= NV_DEVICE_INFO_V0_TNT
; break;
97 case NV_11
: args
->v0
.family
= NV_DEVICE_INFO_V0_CELSIUS
; break;
98 case NV_20
: args
->v0
.family
= NV_DEVICE_INFO_V0_KELVIN
; break;
99 case NV_30
: args
->v0
.family
= NV_DEVICE_INFO_V0_RANKINE
; break;
100 case NV_40
: args
->v0
.family
= NV_DEVICE_INFO_V0_CURIE
; break;
101 case NV_50
: args
->v0
.family
= NV_DEVICE_INFO_V0_TESLA
; break;
102 case NV_C0
: args
->v0
.family
= NV_DEVICE_INFO_V0_FERMI
; break;
103 case NV_E0
: args
->v0
.family
= NV_DEVICE_INFO_V0_KEPLER
; break;
104 case GM100
: args
->v0
.family
= NV_DEVICE_INFO_V0_MAXWELL
; break;
105 case GP100
: args
->v0
.family
= NV_DEVICE_INFO_V0_PASCAL
; break;
111 args
->v0
.chipset
= device
->chipset
;
112 args
->v0
.revision
= device
->chiprev
;
114 args
->v0
.ram_size
= args
->v0
.ram_user
= fb
->ram
->size
;
116 args
->v0
.ram_size
= args
->v0
.ram_user
= 0;
117 if (imem
&& args
->v0
.ram_size
> 0)
118 args
->v0
.ram_user
= args
->v0
.ram_user
- imem
->reserved
;
120 strncpy(args
->v0
.chip
, device
->chip
->name
, sizeof(args
->v0
.chip
));
121 strncpy(args
->v0
.name
, device
->name
, sizeof(args
->v0
.name
));
126 nvkm_udevice_time(struct nvkm_udevice
*udev
, void *data
, u32 size
)
128 struct nvkm_object
*object
= &udev
->object
;
129 struct nvkm_device
*device
= udev
->device
;
131 struct nv_device_time_v0 v0
;
135 nvif_ioctl(object
, "device time size %d\n", size
);
136 if (!(ret
= nvif_unpack(ret
, &data
, &size
, args
->v0
, 0, 0, false))) {
137 nvif_ioctl(object
, "device time vers %d\n", args
->v0
.version
);
138 args
->v0
.time
= nvkm_timer_read(device
->timer
);
145 nvkm_udevice_mthd(struct nvkm_object
*object
, u32 mthd
, void *data
, u32 size
)
147 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
148 nvif_ioctl(object
, "device mthd %08x\n", mthd
);
150 case NV_DEVICE_V0_INFO
:
151 return nvkm_udevice_info(udev
, data
, size
);
152 case NV_DEVICE_V0_TIME
:
153 return nvkm_udevice_time(udev
, data
, size
);
161 nvkm_udevice_rd08(struct nvkm_object
*object
, u64 addr
, u8
*data
)
163 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
164 *data
= nvkm_rd08(udev
->device
, addr
);
169 nvkm_udevice_rd16(struct nvkm_object
*object
, u64 addr
, u16
*data
)
171 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
172 *data
= nvkm_rd16(udev
->device
, addr
);
177 nvkm_udevice_rd32(struct nvkm_object
*object
, u64 addr
, u32
*data
)
179 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
180 *data
= nvkm_rd32(udev
->device
, addr
);
185 nvkm_udevice_wr08(struct nvkm_object
*object
, u64 addr
, u8 data
)
187 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
188 nvkm_wr08(udev
->device
, addr
, data
);
193 nvkm_udevice_wr16(struct nvkm_object
*object
, u64 addr
, u16 data
)
195 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
196 nvkm_wr16(udev
->device
, addr
, data
);
201 nvkm_udevice_wr32(struct nvkm_object
*object
, u64 addr
, u32 data
)
203 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
204 nvkm_wr32(udev
->device
, addr
, data
);
209 nvkm_udevice_map(struct nvkm_object
*object
, void *argv
, u32 argc
,
210 enum nvkm_object_map
*type
, u64
*addr
, u64
*size
)
212 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
213 struct nvkm_device
*device
= udev
->device
;
214 *type
= NVKM_OBJECT_MAP_IO
;
215 *addr
= device
->func
->resource_addr(device
, 0);
216 *size
= device
->func
->resource_size(device
, 0);
221 nvkm_udevice_fini(struct nvkm_object
*object
, bool suspend
)
223 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
224 struct nvkm_device
*device
= udev
->device
;
227 mutex_lock(&device
->mutex
);
228 if (!--device
->refcount
) {
229 ret
= nvkm_device_fini(device
, suspend
);
230 if (ret
&& suspend
) {
237 mutex_unlock(&device
->mutex
);
242 nvkm_udevice_init(struct nvkm_object
*object
)
244 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
245 struct nvkm_device
*device
= udev
->device
;
248 mutex_lock(&device
->mutex
);
249 if (!device
->refcount
++) {
250 ret
= nvkm_device_init(device
);
258 mutex_unlock(&device
->mutex
);
263 nvkm_udevice_child_new(const struct nvkm_oclass
*oclass
,
264 void *data
, u32 size
, struct nvkm_object
**pobject
)
266 struct nvkm_udevice
*udev
= nvkm_udevice(oclass
->parent
);
267 const struct nvkm_device_oclass
*sclass
= oclass
->priv
;
268 return sclass
->ctor(udev
->device
, oclass
, data
, size
, pobject
);
272 nvkm_udevice_child_get(struct nvkm_object
*object
, int index
,
273 struct nvkm_oclass
*oclass
)
275 struct nvkm_udevice
*udev
= nvkm_udevice(object
);
276 struct nvkm_device
*device
= udev
->device
;
277 struct nvkm_engine
*engine
;
278 u64 mask
= (1ULL << NVKM_ENGINE_DMAOBJ
) |
279 (1ULL << NVKM_ENGINE_FIFO
) |
280 (1ULL << NVKM_ENGINE_DISP
) |
281 (1ULL << NVKM_ENGINE_PM
);
282 const struct nvkm_device_oclass
*sclass
= NULL
;
285 for (; i
= __ffs64(mask
), mask
&& !sclass
; mask
&= ~(1ULL << i
)) {
286 if (!(engine
= nvkm_device_engine(device
, i
)) ||
287 !(engine
->func
->base
.sclass
))
289 oclass
->engine
= engine
;
291 index
-= engine
->func
->base
.sclass(oclass
, index
, &sclass
);
296 case 0: sclass
= &nvkm_control_oclass
; break;
300 sclass
= &device
->mmu
->user
;
305 oclass
->base
= sclass
->base
;
308 oclass
->ctor
= nvkm_udevice_child_new
;
309 oclass
->priv
= sclass
;
313 static const struct nvkm_object_func
314 nvkm_udevice_super
= {
315 .init
= nvkm_udevice_init
,
316 .fini
= nvkm_udevice_fini
,
317 .mthd
= nvkm_udevice_mthd
,
318 .map
= nvkm_udevice_map
,
319 .rd08
= nvkm_udevice_rd08
,
320 .rd16
= nvkm_udevice_rd16
,
321 .rd32
= nvkm_udevice_rd32
,
322 .wr08
= nvkm_udevice_wr08
,
323 .wr16
= nvkm_udevice_wr16
,
324 .wr32
= nvkm_udevice_wr32
,
325 .sclass
= nvkm_udevice_child_get
,
328 static const struct nvkm_object_func
330 .init
= nvkm_udevice_init
,
331 .fini
= nvkm_udevice_fini
,
332 .mthd
= nvkm_udevice_mthd
,
333 .sclass
= nvkm_udevice_child_get
,
337 nvkm_udevice_new(const struct nvkm_oclass
*oclass
, void *data
, u32 size
,
338 struct nvkm_object
**pobject
)
341 struct nv_device_v0 v0
;
343 struct nvkm_client
*client
= oclass
->client
;
344 struct nvkm_object
*parent
= &client
->object
;
345 const struct nvkm_object_func
*func
;
346 struct nvkm_udevice
*udev
;
349 nvif_ioctl(parent
, "create device size %d\n", size
);
350 if (!(ret
= nvif_unpack(ret
, &data
, &size
, args
->v0
, 0, 0, false))) {
351 nvif_ioctl(parent
, "create device v%d device %016llx\n",
352 args
->v0
.version
, args
->v0
.device
);
356 /* give priviledged clients register access */
358 func
= &nvkm_udevice_super
;
360 func
= &nvkm_udevice
;
362 if (!(udev
= kzalloc(sizeof(*udev
), GFP_KERNEL
)))
364 nvkm_object_ctor(func
, oclass
, &udev
->object
);
365 *pobject
= &udev
->object
;
367 /* find the device that matches what the client requested */
368 if (args
->v0
.device
!= ~0)
369 udev
->device
= nvkm_device_find(args
->v0
.device
);
371 udev
->device
= nvkm_device_find(client
->device
);
378 const struct nvkm_sclass
379 nvkm_udevice_sclass
= {
383 .ctor
= nvkm_udevice_new
,