diff options
author | Krishna Reddy <vdumpa@nvidia.com> | 2012-01-22 23:21:39 -0800 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2012-01-30 11:37:58 -0800 |
commit | 14fd48c965abe96b31483f6c98f697046df31856 (patch) | |
tree | e8aed7749074aaa18dc6902687e3021941cd4d8e /drivers/gpu | |
parent | 49eceb5f3c1895edc34e20c8526949718e142315 (diff) |
HACK: gpu: ion: Add support to remap dma address.
Change-Id: Ica835fad10677ce61d812e00bb489034a8b06a36
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
Reviewed-on: http://git-master/r/76783
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Hiroshi Doyu <hdoyu@nvidia.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/ion/ion_iommu_heap.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c index 691d8c7ba37f..b75bb3132a2d 100644 --- a/drivers/gpu/ion/ion_iommu_heap.c +++ b/drivers/gpu/ion/ion_iommu_heap.c @@ -97,6 +97,53 @@ static void iommu_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buf) pr_debug("da:%p\n", buf->priv_virt); } +struct scatterlist *iommu_heap_remap_dma(struct ion_heap *heap, + struct ion_buffer *buf, + unsigned long addr) +{ + struct ion_iommu_heap *h = + container_of(heap, struct ion_iommu_heap, heap); + int err; + unsigned int i; + unsigned long da, da_to_free = (unsigned long)buf->priv_virt; + int npages = NUM_PAGES(buf); + + BUG_ON(!buf->priv_virt); + + da = gen_pool_alloc_addr(h->pool, buf->size, addr); + if (da == 0) { + pr_err("dma address alloc failed, addr=0x%lx", addr); + return ERR_PTR(-ENOMEM); + } else { + pr_err("iommu_heap_remap_dma passed, addr=0x%lx", + addr); + iommu_heap_unmap_dma(heap, buf); + gen_pool_free(h->pool, da_to_free, buf->size); + buf->priv_virt = (void *)da; + } + for (i = 0; i < npages; i++) { + phys_addr_t pa; + + pa = page_to_phys(buf->pages[i]); + err = iommu_map(h->domain, da, pa, 0, 0); + if (err) + goto err_out; + da += PAGE_SIZE; + } + + pr_debug("da:%p pa:%08x va:%p\n", + buf->priv_virt, page_to_phys(buf->pages[0]), buf->vaddr); + + return (struct scatterlist *)buf->pages; + +err_out: + if (i-- > 0) { + da = (unsigned long)buf->priv_virt; + iommu_unmap(h->domain, da + (i << PAGE_SHIFT), 0); + } + return ERR_PTR(err); +} + static int ion_buffer_allocate(struct ion_buffer *buf) { int i, npages = NUM_PAGES(buf); |