summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/nvgpu_mem.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/nvgpu_mem.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
index b46dbb6b..58488067 100644
--- a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
+++ b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
@@ -297,3 +297,41 @@ int nvgpu_mem_create_from_mem(struct gk20a *g,
297 297
298 return ret; 298 return ret;
299} 299}
300
301int __nvgpu_mem_create_from_pages(struct gk20a *g, struct nvgpu_mem *dest,
302 struct page **pages, int nr_pages)
303{
304 struct sg_table *sgt;
305 struct page **our_pages =
306 nvgpu_kmalloc(g, sizeof(struct page *) * nr_pages);
307
308 if (!our_pages)
309 return -ENOMEM;
310
311 memcpy(our_pages, pages, sizeof(struct page *) * nr_pages);
312
313 if (nvgpu_get_sgtable_from_pages(g, &sgt, pages, 0,
314 nr_pages * PAGE_SIZE)) {
315 nvgpu_kfree(g, our_pages);
316 return -ENOMEM;
317 }
318
319 /*
320 * If we are making an SGT from physical pages we can be reasonably
321 * certain that this should bypass the SMMU - thus we set the DMA (aka
322 * IOVA) address to 0. This tells the GMMU mapping code to not make a
323 * mapping directed to the SMMU.
324 */
325 sg_dma_address(sgt->sgl) = 0;
326
327 dest->mem_flags = __NVGPU_MEM_FLAG_NO_DMA;
328 dest->aperture = APERTURE_SYSMEM;
329 dest->skip_wmb = 0;
330 dest->size = PAGE_SIZE * nr_pages;
331
332 dest->priv.flags = 0;
333 dest->priv.pages = our_pages;
334 dest->priv.sgt = sgt;
335
336 return 0;
337}