1 #include "nouveau_device.h"
2
3 #include "nouveau_context.h"
4
5 #include "nvidia/g_nv_name_released.h"
6
7 #include "drm-uapi/nouveau_drm.h"
8 #include "util/hash_table.h"
9 #include "util/u_debug.h"
10 #include "util/os_file.h"
11 #include "util/os_misc.h"
12
13 #include <fcntl.h>
14 #include "nvif/cl0080.h"
15 #include "nvif/class.h"
16 #include "nvif/ioctl.h"
17 #include <unistd.h>
18 #include <xf86drm.h>
19
20 static const char *
name_for_chip(uint32_t dev_id,uint16_t subsystem_id,uint16_t subsystem_vendor_id)21 name_for_chip(uint32_t dev_id,
22 uint16_t subsystem_id,
23 uint16_t subsystem_vendor_id)
24 {
25 const char *name = NULL;
26 for (uint32_t i = 0; i < ARRAY_SIZE(sChipsReleased); i++) {
27 const CHIPS_RELEASED *chip = &sChipsReleased[i];
28
29 if (dev_id != chip->devID)
30 continue;
31
32 if (chip->subSystemID == 0 && chip->subSystemVendorID == 0) {
33 /* When subSystemID and subSystemVendorID are both 0, this is the
34 * default name for the given chip. A more specific name may exist
35 * elsewhere in the list.
36 */
37 assert(name == NULL);
38 name = chip->name;
39 continue;
40 }
41
42 /* If we find a specific name, return it */
43 if (chip->subSystemID == subsystem_id &&
44 chip->subSystemVendorID == subsystem_vendor_id)
45 return chip->name;
46 }
47
48 return name;
49 }
50
51 static uint8_t
sm_for_chipset(uint16_t chipset)52 sm_for_chipset(uint16_t chipset)
53 {
54 if (chipset >= 0x190)
55 return 89;
56 // GH100 is older than AD10X, but is SM90
57 else if (chipset >= 0x180)
58 return 90;
59 else if (chipset == 0x17b)
60 return 87;
61 else if (chipset >= 0x172)
62 return 86;
63 else if (chipset >= 0x170)
64 return 80;
65 else if (chipset >= 0x160)
66 return 75;
67 else if (chipset >= 0x14b)
68 return 72;
69 else if (chipset >= 0x140)
70 return 70;
71 else if (chipset >= 0x13b)
72 return 62;
73 else if (chipset >= 0x132)
74 return 61;
75 else if (chipset >= 0x130)
76 return 60;
77 else if (chipset >= 0x12b)
78 return 53;
79 else if (chipset >= 0x120)
80 return 52;
81 else if (chipset >= 0x110)
82 return 50;
83 // TODO: 37
84 else if (chipset >= 0x0f0)
85 return 35;
86 else if (chipset >= 0x0ea)
87 return 32;
88 else if (chipset >= 0x0e0)
89 return 30;
90 // GF110 is SM20
91 else if (chipset == 0x0c8)
92 return 20;
93 else if (chipset >= 0x0c1)
94 return 21;
95 else if (chipset >= 0x0c0)
96 return 20;
97 else if (chipset >= 0x0a3)
98 return 12;
99 // GT200 is SM13
100 else if (chipset >= 0x0a0)
101 return 13;
102 else if (chipset >= 0x080)
103 return 11;
104 // this has to be == because 0x63 is older than 0x50 and has no compute
105 else if (chipset == 0x050)
106 return 10;
107 // no compute
108 return 0x00;
109 }
110
111 static uint8_t
max_warps_per_mp_for_sm(uint8_t sm)112 max_warps_per_mp_for_sm(uint8_t sm)
113 {
114 switch (sm) {
115 case 10:
116 case 11:
117 return 24;
118 case 12:
119 case 13:
120 case 75:
121 return 32;
122 case 20:
123 case 21:
124 case 86:
125 case 87:
126 case 89:
127 return 48;
128 case 30:
129 case 32:
130 case 35:
131 case 37:
132 case 50:
133 case 52:
134 case 53:
135 case 60:
136 case 61:
137 case 62:
138 case 70:
139 case 72:
140 case 80:
141 case 90:
142 return 64;
143 default:
144 assert(!"unkown SM version");
145 // return the biggest known value
146 return 64;
147 }
148 }
149
150 static uint8_t
mp_per_tpc_for_chipset(uint16_t chipset)151 mp_per_tpc_for_chipset(uint16_t chipset)
152 {
153 // GP100 is special and has two, otherwise it's a Volta and newer thing to have two
154 if (chipset == 0x130 || chipset >= 0x140)
155 return 2;
156 return 1;
157 }
158
159 static int
nouveau_ws_param(int fd,uint64_t param,uint64_t * value)160 nouveau_ws_param(int fd, uint64_t param, uint64_t *value)
161 {
162 struct drm_nouveau_getparam data = { .param = param };
163
164 int ret = drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &data, sizeof(data));
165 if (ret)
166 return ret;
167
168 *value = data.value;
169 return 0;
170 }
171
172 static int
nouveau_ws_device_alloc(int fd,struct nouveau_ws_device * dev)173 nouveau_ws_device_alloc(int fd, struct nouveau_ws_device *dev)
174 {
175 struct {
176 struct nvif_ioctl_v0 ioctl;
177 struct nvif_ioctl_new_v0 new;
178 struct nv_device_v0 dev;
179 } args = {
180 .ioctl = {
181 .object = 0,
182 .owner = NVIF_IOCTL_V0_OWNER_ANY,
183 .route = 0x00,
184 .type = NVIF_IOCTL_V0_NEW,
185 .version = 0,
186 },
187 .new = {
188 .handle = 0,
189 .object = (uintptr_t)dev,
190 .oclass = NV_DEVICE,
191 .route = NVIF_IOCTL_V0_ROUTE_NVIF,
192 .token = (uintptr_t)dev,
193 .version = 0,
194 },
195 .dev = {
196 .device = ~0ULL,
197 },
198 };
199
200 return drmCommandWrite(fd, DRM_NOUVEAU_NVIF, &args, sizeof(args));
201 }
202
203 static int
nouveau_ws_device_info(int fd,struct nouveau_ws_device * dev)204 nouveau_ws_device_info(int fd, struct nouveau_ws_device *dev)
205 {
206 struct {
207 struct nvif_ioctl_v0 ioctl;
208 struct nvif_ioctl_mthd_v0 mthd;
209 struct nv_device_info_v0 info;
210 } args = {
211 .ioctl = {
212 .object = (uintptr_t)dev,
213 .owner = NVIF_IOCTL_V0_OWNER_ANY,
214 .route = 0x00,
215 .type = NVIF_IOCTL_V0_MTHD,
216 .version = 0,
217 },
218 .mthd = {
219 .method = NV_DEVICE_V0_INFO,
220 .version = 0,
221 },
222 .info = {
223 .version = 0,
224 },
225 };
226
227 int ret = drmCommandWriteRead(fd, DRM_NOUVEAU_NVIF, &args, sizeof(args));
228 if (ret)
229 return ret;
230
231 dev->info.chipset = args.info.chipset;
232 dev->info.vram_size_B = args.info.ram_user;
233
234 switch (args.info.platform) {
235 case NV_DEVICE_INFO_V0_IGP:
236 dev->info.type = NV_DEVICE_TYPE_IGP;
237 break;
238 case NV_DEVICE_INFO_V0_SOC:
239 dev->info.type = NV_DEVICE_TYPE_SOC;
240 break;
241 case NV_DEVICE_INFO_V0_PCI:
242 case NV_DEVICE_INFO_V0_AGP:
243 case NV_DEVICE_INFO_V0_PCIE:
244 default:
245 dev->info.type = NV_DEVICE_TYPE_DIS;
246 break;
247 }
248
249 STATIC_ASSERT(sizeof(dev->info.device_name) >= sizeof(args.info.name));
250 memcpy(dev->info.device_name, args.info.name, sizeof(args.info.name));
251
252 STATIC_ASSERT(sizeof(dev->info.chipset_name) >= sizeof(args.info.chip));
253 memcpy(dev->info.chipset_name, args.info.chip, sizeof(args.info.chip));
254
255 return 0;
256 }
257
258 struct nouveau_ws_device *
nouveau_ws_device_new(drmDevicePtr drm_device)259 nouveau_ws_device_new(drmDevicePtr drm_device)
260 {
261 const char *path = drm_device->nodes[DRM_NODE_RENDER];
262 struct nouveau_ws_device *device = CALLOC_STRUCT(nouveau_ws_device);
263 uint64_t value = 0;
264 drmVersionPtr ver = NULL;
265
266 int fd = open(path, O_RDWR | O_CLOEXEC);
267 if (fd < 0)
268 goto out_open;
269
270 ver = drmGetVersion(fd);
271 if (!ver)
272 goto out_err;
273
274 if (strncmp("nouveau", ver->name, ver->name_len) != 0) {
275 fprintf(stderr,
276 "DRM kernel driver '%.*s' in use. NVK requires nouveau.\n",
277 ver->name_len, ver->name);
278 goto out_err;
279 }
280
281 uint32_t version =
282 ver->version_major << 24 |
283 ver->version_minor << 8 |
284 ver->version_patchlevel;
285 drmFreeVersion(ver);
286 ver = NULL;
287
288 if (version < 0x01000301)
289 goto out_err;
290
291 const uint64_t KERN = NOUVEAU_WS_DEVICE_KERNEL_RESERVATION_START;
292 const uint64_t TOP = 1ull << 40;
293 struct drm_nouveau_vm_init vminit = { KERN, TOP-KERN };
294 int ret = drmCommandWrite(fd, DRM_NOUVEAU_VM_INIT, &vminit, sizeof(vminit));
295 if (ret == 0)
296 device->has_vm_bind = true;
297
298 if (nouveau_ws_device_alloc(fd, device))
299 goto out_err;
300
301 if (nouveau_ws_param(fd, NOUVEAU_GETPARAM_PCI_DEVICE, &value))
302 goto out_err;
303
304 device->info.device_id = value;
305
306 if (nouveau_ws_device_info(fd, device))
307 goto out_err;
308
309 const char *name;
310 if (drm_device->bustype == DRM_BUS_PCI) {
311 assert(device->info.type != NV_DEVICE_TYPE_SOC);
312 assert(device->info.device_id == drm_device->deviceinfo.pci->device_id);
313
314 device->info.pci.domain = drm_device->businfo.pci->domain;
315 device->info.pci.bus = drm_device->businfo.pci->bus;
316 device->info.pci.dev = drm_device->businfo.pci->dev;
317 device->info.pci.func = drm_device->businfo.pci->func;
318 device->info.pci.revision_id = drm_device->deviceinfo.pci->revision_id;
319
320 name = name_for_chip(drm_device->deviceinfo.pci->device_id,
321 drm_device->deviceinfo.pci->subdevice_id,
322 drm_device->deviceinfo.pci->subvendor_id);
323 } else {
324 name = name_for_chip(device->info.device_id, 0, 0);
325 }
326
327 if (name != NULL) {
328 size_t end = sizeof(device->info.device_name) - 1;
329 strncpy(device->info.device_name, name, end);
330 device->info.device_name[end] = 0;
331 }
332
333 device->fd = fd;
334
335 if (nouveau_ws_param(fd, NOUVEAU_GETPARAM_EXEC_PUSH_MAX, &value))
336 device->max_push = NOUVEAU_GEM_MAX_PUSH;
337 else
338 device->max_push = value;
339
340 if (drm_device->bustype == DRM_BUS_PCI &&
341 !nouveau_ws_param(fd, NOUVEAU_GETPARAM_VRAM_BAR_SIZE, &value))
342 device->info.bar_size_B = value;
343
344 if (nouveau_ws_param(fd, NOUVEAU_GETPARAM_GRAPH_UNITS, &value))
345 goto out_err;
346
347 device->info.gpc_count = (value >> 0) & 0x000000ff;
348 device->info.tpc_count = (value >> 8) & 0x0000ffff;
349
350 struct nouveau_ws_context *tmp_ctx;
351 if (nouveau_ws_context_create(device, ~0, &tmp_ctx))
352 goto out_err;
353
354 device->info.sm = sm_for_chipset(device->info.chipset);
355 device->info.cls_copy = tmp_ctx->copy.cls;
356 device->info.cls_eng2d = tmp_ctx->eng2d.cls;
357 device->info.cls_eng3d = tmp_ctx->eng3d.cls;
358 device->info.cls_m2mf = tmp_ctx->m2mf.cls;
359 device->info.cls_compute = tmp_ctx->compute.cls;
360
361 // for now we hardcode those values, but in the future Nouveau could provide that information to
362 // us instead.
363 device->info.max_warps_per_mp = max_warps_per_mp_for_sm(device->info.sm);
364 device->info.mp_per_tpc = mp_per_tpc_for_chipset(device->info.chipset);
365
366 nouveau_ws_context_destroy(tmp_ctx);
367
368 simple_mtx_init(&device->bos_lock, mtx_plain);
369 device->bos = _mesa_pointer_hash_table_create(NULL);
370
371 return device;
372
373 out_err:
374 if (ver)
375 drmFreeVersion(ver);
376 out_open:
377 FREE(device);
378 close(fd);
379 return NULL;
380 }
381
382 void
nouveau_ws_device_destroy(struct nouveau_ws_device * device)383 nouveau_ws_device_destroy(struct nouveau_ws_device *device)
384 {
385 if (!device)
386 return;
387
388 _mesa_hash_table_destroy(device->bos, NULL);
389 simple_mtx_destroy(&device->bos_lock);
390
391 close(device->fd);
392 FREE(device);
393 }
394
395 uint64_t
nouveau_ws_device_vram_used(struct nouveau_ws_device * device)396 nouveau_ws_device_vram_used(struct nouveau_ws_device *device)
397 {
398 uint64_t used = 0;
399 if (nouveau_ws_param(device->fd, NOUVEAU_GETPARAM_VRAM_USED, &used))
400 return 0;
401
402 /* Zero memory used would be very strange given that it includes kernel
403 * internal allocations.
404 */
405 assert(used > 0);
406
407 return used;
408 }
409
410 uint64_t
nouveau_ws_device_timestamp(struct nouveau_ws_device * device)411 nouveau_ws_device_timestamp(struct nouveau_ws_device *device)
412 {
413 uint64_t timestamp = 0;
414 if (nouveau_ws_param(device->fd, NOUVEAU_GETPARAM_PTIMER_TIME, ×tamp))
415 return 0;
416
417 return timestamp;
418 }
419
420 bool
nouveau_ws_device_has_tiled_bo(struct nouveau_ws_device * device)421 nouveau_ws_device_has_tiled_bo(struct nouveau_ws_device *device)
422 {
423 uint64_t has = 0;
424 if (nouveau_ws_param(device->fd, NOUVEAU_GETPARAM_HAS_VMA_TILEMODE, &has))
425 return false;
426
427 return has != 0;
428 }
429