diff options
author | Dave Airlie <airlied@redhat.com> | 2010-08-22 18:34:59 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-08-22 18:34:59 -0400 |
commit | d03330383c9255cdb184dd33594e89c3542f191b (patch) | |
tree | 2b2e9676e5c0c7f365a68779cab7669ad009f48d /drivers/gpu/drm/nouveau/nouveau_gem.c | |
parent | 0537398b211b4f040564beec458e23571042d335 (diff) | |
parent | 625db6b7e34580b750a13fd36a211a4366f6c3e2 (diff) |
Merge remote branch 'nouveau/for-airlied' of /ssd/git/drm-nouveau-next into drm-core-next
* 'nouveau/for-airlied' of /ssd/git/drm-nouveau-next:
drm/nouveau: fix earlier mistake when fixing merge conflict
drm/nvc0: fix thinko in instmem suspend/resume
drm/nouveau: Workaround missing GPIO tables on an Apple iMac G4 NV18.
drm/nouveau: Add TV-out quirk for an MSI nForce2 IGP.
drm/nv50-nvc0: ramht_size is meant to be in bytes, not entries
drm/nouveau: punt some more log messages to debug level
drm/nouveau: remove warning about unknown tmds table revisions
drm/nouveau: check for error when allocating/mapping dummy page
drm/nouveau: fix race condition when under memory pressure
drm/nv50: fix minor thinko from nvc0 changes
drm/nouveau: Don't try DDC on the dummy I2C channel.
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_gem.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_gem.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 0f417ac1b696..79fc5ffff226 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -361,16 +361,11 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
361 | 361 | ||
362 | list_for_each_entry(nvbo, list, entry) { | 362 | list_for_each_entry(nvbo, list, entry) { |
363 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; | 363 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; |
364 | struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; | ||
365 | 364 | ||
366 | if (prev_fence && nouveau_fence_channel(prev_fence) != chan) { | 365 | ret = nouveau_bo_sync_gpu(nvbo, chan); |
367 | spin_lock(&nvbo->bo.lock); | 366 | if (unlikely(ret)) { |
368 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | 367 | NV_ERROR(dev, "fail pre-validate sync\n"); |
369 | spin_unlock(&nvbo->bo.lock); | 368 | return ret; |
370 | if (unlikely(ret)) { | ||
371 | NV_ERROR(dev, "fail wait other chan\n"); | ||
372 | return ret; | ||
373 | } | ||
374 | } | 369 | } |
375 | 370 | ||
376 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, | 371 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, |
@@ -381,7 +376,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
381 | return ret; | 376 | return ret; |
382 | } | 377 | } |
383 | 378 | ||
384 | nvbo->channel = chan; | 379 | nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan; |
385 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, | 380 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, |
386 | false, false, false); | 381 | false, false, false); |
387 | nvbo->channel = NULL; | 382 | nvbo->channel = NULL; |
@@ -390,6 +385,12 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
390 | return ret; | 385 | return ret; |
391 | } | 386 | } |
392 | 387 | ||
388 | ret = nouveau_bo_sync_gpu(nvbo, chan); | ||
389 | if (unlikely(ret)) { | ||
390 | NV_ERROR(dev, "fail post-validate sync\n"); | ||
391 | return ret; | ||
392 | } | ||
393 | |||
393 | if (nvbo->bo.offset == b->presumed.offset && | 394 | if (nvbo->bo.offset == b->presumed.offset && |
394 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && | 395 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && |
395 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || | 396 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || |
@@ -615,6 +616,21 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
615 | 616 | ||
616 | mutex_lock(&dev->struct_mutex); | 617 | mutex_lock(&dev->struct_mutex); |
617 | 618 | ||
619 | /* Mark push buffers as being used on PFIFO, the validation code | ||
620 | * will then make sure that if the pushbuf bo moves, that they | ||
621 | * happen on the kernel channel, which will in turn cause a sync | ||
622 | * to happen before we try and submit the push buffer. | ||
623 | */ | ||
624 | for (i = 0; i < req->nr_push; i++) { | ||
625 | if (push[i].bo_index >= req->nr_buffers) { | ||
626 | NV_ERROR(dev, "push %d buffer not in list\n", i); | ||
627 | ret = -EINVAL; | ||
628 | goto out; | ||
629 | } | ||
630 | |||
631 | bo[push[i].bo_index].read_domains |= (1 << 31); | ||
632 | } | ||
633 | |||
618 | /* Validate buffer list */ | 634 | /* Validate buffer list */ |
619 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, | 635 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, |
620 | req->nr_buffers, &op, &do_reloc); | 636 | req->nr_buffers, &op, &do_reloc); |