summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-06-04 09:26:25 +0200
committerThierry Reding <treding@nvidia.com>2014-06-04 12:12:33 +0200
commita7426b06952338f3a10b30f22039780a493c7a61 (patch)
tree29b721727c7dd309c09af62ad91b41719189dfde
parent01de722e4387b7d227c8063e39504dddebec884b (diff)
HACK: drm/nouveau: prime: Pin buffer objects to VRAMHEADmaster
This is currently required to work around the lack of proper SMMU support on Tegra. Ideally buffer objects could always be pinned to GART and the SMMU will take care of mapping them to a linear I/O virtual address range for importers. Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_prime.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
index 1f51008e4d2..d90c7b20a96 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -27,12 +27,37 @@
#include "nouveau_drm.h"
#include "nouveau_gem.h"
+#include "subdev/fb.h"
+
struct sg_table *nouveau_gem_prime_get_sg_table(struct drm_gem_object *obj)
{
struct nouveau_bo *nvbo = nouveau_gem_object(obj);
- int npages = nvbo->bo.num_pages;
+ struct nouveau_mem *mem = nvbo->bo.mem.mm_node;
+ unsigned int npages = nvbo->bo.num_pages;
+ struct sg_table *sgt;
+
+ if (nvbo->bo.ttm) {
+ sgt = drm_prime_pages_to_sg(nvbo->bo.ttm->pages, npages);
+ } else {
+ struct page *page = phys_to_page(mem->offset);
+
+ sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
+ if (!sgt)
+ goto out;
+
+ if (sg_alloc_table(sgt, 1, GFP_KERNEL)) {
+ kfree(sgt);
+ sgt = NULL;
+ goto out;
+ }
+
+ sg_set_page(sgt->sgl, page, PAGE_SIZE, 0);
+ sg_dma_address(sgt->sgl) = mem->offset;
+ sg_dma_len(sgt->sgl) = mem->size * PAGE_SIZE;
+ }
- return drm_prime_pages_to_sg(nvbo->bo.ttm->pages, npages);
+out:
+ return sgt;
}
void *nouveau_gem_prime_vmap(struct drm_gem_object *obj)
@@ -89,7 +114,11 @@ int nouveau_gem_prime_pin(struct drm_gem_object *obj)
int ret;
/* pin buffer into GTT */
+#if 0
ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_TT);
+#else
+ ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM);
+#endif
if (ret)
return -EINVAL;