summaryrefslogtreecommitdiff
path: root/drm
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-06-04 09:26:25 +0200
committerAlexandre Courbot <acourbot@nvidia.com>2014-11-04 11:30:09 +0900
commite51342b86a94c6d2f49a1d0e81440ad9081f2d4b (patch)
tree1aa710e0e27fe54a49d11ec7011a4e77219f2d45 /drm
parent47084a2b0c585c8fab36116eed5fa60837bdb164 (diff)
downloadnouveau-e51342b86a94c6d2f49a1d0e81440ad9081f2d4b.tar.gz
HACK: drm/nouveau: prime: Pin buffer objects to VRAM
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>
Diffstat (limited to 'drm')
-rw-r--r--drm/nouveau_prime.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drm/nouveau_prime.c b/drm/nouveau_prime.c
index 228226ab2..0ff64ec6c 100644
--- a/drm/nouveau_prime.c
+++ b/drm/nouveau_prime.c
@@ -28,12 +28,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)
@@ -93,7 +118,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;