mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
gdc: add gdc dmabuf 32bit compatible [2/2]
PD#SWPL-5685 Problem: gdc dmabuf not work under 32bit Solution: add gdc dmabuf 32bit compatible Verify: verified by w400 Change-Id: If26f41ff6cd679dc0220771f5bb2b50eba899aa9 Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
@@ -36,18 +36,65 @@
|
||||
#include "gdc_dmabuf.h"
|
||||
|
||||
static void clear_dma_buffer(struct aml_dma_buffer *buffer, int index);
|
||||
|
||||
static void *aml_mm_vmap(phys_addr_t phys, unsigned long size)
|
||||
{
|
||||
u32 offset, npages;
|
||||
struct page **pages = NULL;
|
||||
pgprot_t pgprot = PAGE_KERNEL;
|
||||
void *vaddr;
|
||||
int i;
|
||||
|
||||
offset = offset_in_page(phys);
|
||||
npages = DIV_ROUND_UP(size + offset, PAGE_SIZE);
|
||||
|
||||
pages = vmalloc(sizeof(struct page *) * npages);
|
||||
if (!pages)
|
||||
return NULL;
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages[i] = phys_to_page(phys);
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
/* pgprot = pgprot_writecombine(PAGE_KERNEL); */
|
||||
|
||||
vaddr = vmap(pages, npages, VM_MAP, pgprot);
|
||||
if (!vaddr) {
|
||||
pr_err("vmaped fail, size: %d\n",
|
||||
npages << PAGE_SHIFT);
|
||||
vfree(pages);
|
||||
return NULL;
|
||||
}
|
||||
vfree(pages);
|
||||
gdc_log(LOG_INFO, "[HIGH-MEM-MAP] pa(%lx) to va(%p), size: %d\n",
|
||||
(unsigned long)phys, vaddr, npages << PAGE_SHIFT);
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
static void *aml_map_phyaddr_to_virt(dma_addr_t phys, unsigned long size)
|
||||
{
|
||||
void *vaddr = NULL;
|
||||
|
||||
if (!PageHighMem(phys_to_page(phys)))
|
||||
return phys_to_virt(phys);
|
||||
vaddr = aml_mm_vmap(phys, size);
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
/* dma free*/
|
||||
static void aml_dma_put(void *buf_priv)
|
||||
{
|
||||
struct aml_dma_buf *buf = buf_priv;
|
||||
struct page *cma_pages = NULL;
|
||||
void *vaddr = (void *)(PAGE_MASK & (ulong)buf->vaddr);
|
||||
|
||||
if (!atomic_dec_and_test(&buf->refcount)) {
|
||||
gdc_log(LOG_INFO, "gdc aml_dma_put, refcont=%d\n",
|
||||
atomic_read(&buf->refcount));
|
||||
return;
|
||||
}
|
||||
cma_pages = virt_to_page(buf->vaddr);
|
||||
cma_pages = phys_to_page(buf->dma_addr);
|
||||
if (is_vmalloc_or_module_addr(vaddr))
|
||||
vunmap(vaddr);
|
||||
if (!dma_release_from_contiguous(buf->dev, cma_pages,
|
||||
buf->size >> PAGE_SHIFT)) {
|
||||
pr_err("failed to release cma buffer\n");
|
||||
@@ -85,7 +132,7 @@ static void *aml_dma_alloc(struct device *dev, unsigned long attrs,
|
||||
pr_err("failed to alloc cma pages.\n");
|
||||
return NULL;
|
||||
}
|
||||
buf->vaddr = phys_to_virt(paddr);
|
||||
buf->vaddr = aml_map_phyaddr_to_virt(paddr, size);
|
||||
buf->dev = get_device(dev);
|
||||
buf->size = size;
|
||||
buf->dma_dir = dma_dir;
|
||||
@@ -109,7 +156,7 @@ static int aml_dma_mmap(void *buf_priv, struct vm_area_struct *vma)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pfn = virt_to_phys(buf->vaddr) >> PAGE_SHIFT;
|
||||
pfn = buf->dma_addr >> PAGE_SHIFT;
|
||||
ret = remap_pfn_range(vma, vma->vm_start, pfn,
|
||||
vsize, vma->vm_page_prot);
|
||||
if (ret) {
|
||||
@@ -140,7 +187,7 @@ static int aml_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
|
||||
int num_pages = PAGE_ALIGN(buf->size) / PAGE_SIZE;
|
||||
struct sg_table *sgt;
|
||||
struct scatterlist *sg;
|
||||
void *vaddr = buf->vaddr;
|
||||
phys_addr_t phys = buf->dma_addr;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
@@ -158,7 +205,7 @@ static int aml_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
|
||||
return -ENOMEM;
|
||||
}
|
||||
for_each_sg(sgt->sgl, sg, sgt->nents, i) {
|
||||
struct page *page = virt_to_page(vaddr);
|
||||
struct page *page = phys_to_page(phys);
|
||||
|
||||
if (!page) {
|
||||
sg_free_table(sgt);
|
||||
@@ -166,7 +213,7 @@ static int aml_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
|
||||
return -ENOMEM;
|
||||
}
|
||||
sg_set_page(sg, page, PAGE_SIZE, 0);
|
||||
vaddr += PAGE_SIZE;
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
|
||||
attach->dma_dir = DMA_NONE;
|
||||
|
||||
Reference in New Issue
Block a user