msm: kgsl: set the dma_address field of scatterlists
Ion carveout and content protect heap buffers do not
have a struct page associated with them. Thus
sg_phys() will not work reliably on these buffers.
Set the dma_address field on physically contiguous
buffers. When mapping a scatterlist to the gpummu
use sg_dma_address() first and if it returns 0
then use sg_phys().
Change-Id: Ie5f19986446be4383dfbfffa2534136b592e8e46
Signed-off-by: Jeremy Gebben <jgebben@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index 97b5ef1..98216f8 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -682,7 +682,7 @@
flushtlb = 1;
for_each_sg(memdesc->sg, s, memdesc->sglen, i) {
- unsigned int paddr = sg_phys(s);
+ unsigned int paddr = kgsl_get_sg_pa(s);
unsigned int j;
/* Each sg entry might be multiple pages long */
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index f61a196..d083702 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -284,7 +284,7 @@
int i;
for_each_sg(sg, s, sglen, i) {
- unsigned int paddr = sg_phys(s);
+ unsigned int paddr = kgsl_get_sg_pa(s);
_outer_cache_range_op(op, paddr, s->length);
}
}
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index af0d74d..a1e4c91 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -80,12 +80,22 @@
int kgsl_sharedmem_init_sysfs(void);
void kgsl_sharedmem_uninit_sysfs(void);
+static inline unsigned int kgsl_get_sg_pa(struct scatterlist *sg)
+{
+ /*
+ * Try sg_dma_address first to support ion carveout
+ * regions which do not work with sg_phys().
+ */
+ unsigned int pa = sg_dma_address(sg);
+ if (pa == 0)
+ pa = sg_phys(sg);
+ return pa;
+}
+
static inline int
memdesc_sg_phys(struct kgsl_memdesc *memdesc,
unsigned int physaddr, unsigned int size)
{
- struct page *page = phys_to_page(physaddr);
-
memdesc->sg = vmalloc(sizeof(struct scatterlist) * 1);
if (memdesc->sg == NULL)
return -ENOMEM;
@@ -94,7 +104,9 @@
memdesc->sglen = 1;
sg_init_table(memdesc->sg, 1);
- sg_set_page(&memdesc->sg[0], page, size, 0);
+ memdesc->sg[0].length = size;
+ memdesc->sg[0].offset = 0;
+ memdesc->sg[0].dma_address = physaddr;
return 0;
}