aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs2015-11-23 19:21:05 -0600
committerBen Skeggs2015-12-21 21:22:33 -0600
commit4c92a9d70725ec393899979bbfc21a37684e88d9 (patch)
tree5f6660f8bcb51fe2c58c5056b587dcf494485be9 /nouveau
parent4a68c5638e1b0dd62860f1211dbcd751005beb79 (diff)
downloadexternal-libgbm-4c92a9d70725ec393899979bbfc21a37684e88d9.tar.gz
external-libgbm-4c92a9d70725ec393899979bbfc21a37684e88d9.tar.xz
external-libgbm-4c92a9d70725ec393899979bbfc21a37684e88d9.zip
nouveau: add new interface to create a nouveau_device
Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Tested-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Diffstat (limited to 'nouveau')
-rwxr-xr-xnouveau/nouveau-symbol-check1
-rw-r--r--nouveau/nouveau.c133
-rw-r--r--nouveau/nouveau.h2
3 files changed, 89 insertions, 47 deletions
diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
index 275b6e7e..b265cea4 100755
--- a/nouveau/nouveau-symbol-check
+++ b/nouveau/nouveau-symbol-check
@@ -27,6 +27,7 @@ nouveau_bufctx_reset
27nouveau_client_del 27nouveau_client_del
28nouveau_client_new 28nouveau_client_new
29nouveau_device_del 29nouveau_device_del
30nouveau_device_new
30nouveau_device_open 31nouveau_device_open
31nouveau_device_open_existing 32nouveau_device_open_existing
32nouveau_device_wrap 33nouveau_device_wrap
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 56e00aca..fef338b6 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -45,6 +45,10 @@
45#include "nouveau.h" 45#include "nouveau.h"
46#include "private.h" 46#include "private.h"
47 47
48#include "nvif/class.h"
49#include "nvif/cl0080.h"
50#include "nvif/unpack.h"
51
48#ifdef DEBUG 52#ifdef DEBUG
49drm_private uint32_t nouveau_debug = 0; 53drm_private uint32_t nouveau_debug = 0;
50 54
@@ -231,75 +235,107 @@ nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd,
231} 235}
232 236
233int 237int
234nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev) 238nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
239 void *data, uint32_t size, struct nouveau_device **pdev)
235{ 240{
236 struct nouveau_drm *drm; 241 union {
242 struct nv_device_v0 v0;
243 } *args = data;
244 struct nouveau_drm *drm = nouveau_drm(parent);
237 struct nouveau_device_priv *nvdev; 245 struct nouveau_device_priv *nvdev;
238 struct nouveau_device *dev; 246 struct nouveau_device *dev;
239 uint64_t chipset, vram, gart, bousage; 247 uint64_t v;
240 int ret;
241 char *tmp; 248 char *tmp;
249 int ret = -ENOSYS;
250
251 if (oclass != NV_DEVICE ||
252 nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))
253 return ret;
242 254
243 if (!(nvdev = calloc(1, sizeof(*nvdev)))) 255 if (!(nvdev = calloc(1, sizeof(*nvdev))))
244 return -ENOMEM; 256 return -ENOMEM;
245 dev = &nvdev->base; 257 dev = *pdev = &nvdev->base;
258 dev->fd = -1;
246 259
247 ret = pthread_mutex_init(&nvdev->lock, NULL); 260 if (args->v0.device == ~0ULL) {
248 if (ret) { 261 nvdev->base.object.parent = &drm->client;
249 free(nvdev); 262 nvdev->base.object.handle = ~0ULL;
250 return ret; 263 nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
251 } 264 nvdev->base.object.length = ~0;
252
253 ret = nouveau_drm_new(fd, &drm);
254 if (ret) {
255 nouveau_device_del(&dev);
256 return ret;
257 }
258 drm->nvif = false;
259 265
260 nvdev->base.object.parent = &drm->client; 266 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &v);
261 nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS; 267 if (ret)
262 nvdev->base.object.length = ~0; 268 goto done;
263 nvdev->base.fd = drm->fd; 269 nvdev->base.chipset = v;
264 nvdev->base.drm_version = drm->drm_version;
265 nvdev->base.lib_version = drm->lib_version;
266 270
267 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &chipset); 271 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &v);
268 if (ret == 0) 272 if (ret == 0)
269 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &vram); 273 nvdev->have_bo_usage = (v != 0);
270 if (ret == 0) 274 } else
271 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &gart); 275 return -ENOSYS;
272 if (ret) {
273 nouveau_device_del(&dev);
274 return ret;
275 }
276 276
277 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &bousage); 277 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &v);
278 if (ret == 0) 278 if (ret)
279 nvdev->have_bo_usage = (bousage != 0); 279 goto done;
280 nvdev->base.vram_size = v;
280 281
281 nvdev->close = close; 282 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &v);
283 if (ret)
284 goto done;
285 nvdev->base.gart_size = v;
282 286
283 tmp = getenv("NOUVEAU_LIBDRM_VRAM_LIMIT_PERCENT"); 287 tmp = getenv("NOUVEAU_LIBDRM_VRAM_LIMIT_PERCENT");
284 if (tmp) 288 if (tmp)
285 nvdev->vram_limit_percent = atoi(tmp); 289 nvdev->vram_limit_percent = atoi(tmp);
286 else 290 else
287 nvdev->vram_limit_percent = 80; 291 nvdev->vram_limit_percent = 80;
292
293 nvdev->base.vram_limit =
294 (nvdev->base.vram_size * nvdev->vram_limit_percent) / 100;
295
288 tmp = getenv("NOUVEAU_LIBDRM_GART_LIMIT_PERCENT"); 296 tmp = getenv("NOUVEAU_LIBDRM_GART_LIMIT_PERCENT");
289 if (tmp) 297 if (tmp)
290 nvdev->gart_limit_percent = atoi(tmp); 298 nvdev->gart_limit_percent = atoi(tmp);
291 else 299 else
292 nvdev->gart_limit_percent = 80; 300 nvdev->gart_limit_percent = 80;
293 DRMINITLISTHEAD(&nvdev->bo_list); 301
294 nvdev->base.chipset = chipset;
295 nvdev->base.vram_size = vram;
296 nvdev->base.gart_size = gart;
297 nvdev->base.vram_limit =
298 (nvdev->base.vram_size * nvdev->vram_limit_percent) / 100;
299 nvdev->base.gart_limit = 302 nvdev->base.gart_limit =
300 (nvdev->base.gart_size * nvdev->gart_limit_percent) / 100; 303 (nvdev->base.gart_size * nvdev->gart_limit_percent) / 100;
301 304
302 *pdev = &nvdev->base; 305 ret = pthread_mutex_init(&nvdev->lock, NULL);
306 DRMINITLISTHEAD(&nvdev->bo_list);
307done:
308 if (ret)
309 nouveau_device_del(pdev);
310 return ret;
311}
312
313int
314nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
315{
316 struct nouveau_drm *drm;
317 struct nouveau_device_priv *nvdev;
318 int ret;
319
320 ret = nouveau_drm_new(fd, &drm);
321 if (ret)
322 return ret;
323 drm->nvif = false;
324
325 ret = nouveau_device_new(&drm->client, NV_DEVICE,
326 &(struct nv_device_v0) {
327 .device = ~0ULL,
328 }, sizeof(struct nv_device_v0), pdev);
329 if (ret) {
330 nouveau_drm_del(&drm);
331 return ret;
332 }
333
334 nvdev = nouveau_device(*pdev);
335 nvdev->base.fd = drm->fd;
336 nvdev->base.drm_version = drm->drm_version;
337 nvdev->base.lib_version = drm->lib_version;
338 nvdev->close = close;
303 return 0; 339 return 0;
304} 340}
305 341
@@ -320,12 +356,15 @@ nouveau_device_del(struct nouveau_device **pdev)
320{ 356{
321 struct nouveau_device_priv *nvdev = nouveau_device(*pdev); 357 struct nouveau_device_priv *nvdev = nouveau_device(*pdev);
322 if (nvdev) { 358 if (nvdev) {
323 struct nouveau_drm *drm = nouveau_drm(&nvdev->base.object);
324 free(nvdev->client); 359 free(nvdev->client);
325 nouveau_drm_del(&drm);
326 pthread_mutex_destroy(&nvdev->lock); 360 pthread_mutex_destroy(&nvdev->lock);
327 if (nvdev->close) 361 if (nvdev->base.fd >= 0) {
328 drmClose(nvdev->base.fd); 362 struct nouveau_drm *drm =
363 nouveau_drm(&nvdev->base.object);
364 nouveau_drm_del(&drm);
365 if (nvdev->close)
366 drmClose(nvdev->base.fd);
367 }
329 free(nvdev); 368 free(nvdev);
330 *pdev = NULL; 369 *pdev = NULL;
331 } 370 }
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index a693acff..f3cf8f58 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -122,6 +122,8 @@ struct nouveau_device {
122 uint64_t gart_limit; 122 uint64_t gart_limit;
123}; 123};
124 124
125int nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
126 void *data, uint32_t size, struct nouveau_device **);
125int nouveau_device_wrap(int fd, int close, struct nouveau_device **); 127int nouveau_device_wrap(int fd, int close, struct nouveau_device **);
126int nouveau_device_open(const char *busid, struct nouveau_device **); 128int nouveau_device_open(const char *busid, struct nouveau_device **);
127void nouveau_device_del(struct nouveau_device **); 129void nouveau_device_del(struct nouveau_device **);