diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 55 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 5 |
2 files changed, 50 insertions, 10 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 954249c6..036f1472 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |||
@@ -1532,16 +1532,30 @@ int gk20a_gmmu_alloc_attr(struct gk20a *g, enum dma_attr attr, size_t size, stru | |||
1532 | if (attr) { | 1532 | if (attr) { |
1533 | DEFINE_DMA_ATTRS(attrs); | 1533 | DEFINE_DMA_ATTRS(attrs); |
1534 | dma_set_attr(attr, &attrs); | 1534 | dma_set_attr(attr, &attrs); |
1535 | mem->cpu_va = | 1535 | if (attr == DMA_ATTR_NO_KERNEL_MAPPING) { |
1536 | dma_alloc_attrs(d, size, &iova, GFP_KERNEL, &attrs); | 1536 | mem->pages = dma_alloc_attrs(d, |
1537 | size, &iova, GFP_KERNEL, &attrs); | ||
1538 | if (!mem->pages) | ||
1539 | return -ENOMEM; | ||
1540 | } else { | ||
1541 | mem->cpu_va = dma_alloc_attrs(d, | ||
1542 | size, &iova, GFP_KERNEL, &attrs); | ||
1543 | if (!mem->cpu_va) | ||
1544 | return -ENOMEM; | ||
1545 | } | ||
1537 | } else { | 1546 | } else { |
1538 | mem->cpu_va = dma_alloc_coherent(d, size, &iova, GFP_KERNEL); | 1547 | mem->cpu_va = dma_alloc_coherent(d, size, &iova, GFP_KERNEL); |
1548 | if (!mem->cpu_va) | ||
1549 | return -ENOMEM; | ||
1539 | } | 1550 | } |
1540 | 1551 | ||
1541 | if (!mem->cpu_va) | 1552 | if (attr == DMA_ATTR_NO_KERNEL_MAPPING) |
1542 | return -ENOMEM; | 1553 | err = gk20a_get_sgtable_from_pages(d, &mem->sgt, mem->pages, |
1543 | 1554 | iova, size); | |
1544 | err = gk20a_get_sgtable(d, &mem->sgt, mem->cpu_va, iova, size); | 1555 | else { |
1556 | err = gk20a_get_sgtable(d, &mem->sgt, mem->cpu_va, iova, size); | ||
1557 | memset(mem->cpu_va, 0, size); | ||
1558 | } | ||
1545 | if (err) | 1559 | if (err) |
1546 | goto fail_free; | 1560 | goto fail_free; |
1547 | 1561 | ||
@@ -1559,19 +1573,40 @@ fail_free: | |||
1559 | return err; | 1573 | return err; |
1560 | } | 1574 | } |
1561 | 1575 | ||
1562 | void gk20a_gmmu_free(struct gk20a *g, struct mem_desc *mem) | 1576 | void gk20a_gmmu_free_attr(struct gk20a *g, enum dma_attr attr, |
1577 | struct mem_desc *mem) | ||
1563 | { | 1578 | { |
1564 | struct device *d = dev_from_gk20a(g); | 1579 | struct device *d = dev_from_gk20a(g); |
1565 | 1580 | ||
1566 | if (mem->cpu_va) | 1581 | if (mem->cpu_va) { |
1567 | dma_free_coherent(d, mem->size, mem->cpu_va, | 1582 | if (attr) { |
1583 | DEFINE_DMA_ATTRS(attrs); | ||
1584 | dma_set_attr(attr, &attrs); | ||
1585 | if (attr == DMA_ATTR_NO_KERNEL_MAPPING) | ||
1586 | dma_free_attrs(d, mem->size, mem->pages, | ||
1587 | sg_dma_address(mem->sgt->sgl), | ||
1588 | &attrs); | ||
1589 | else | ||
1590 | dma_free_attrs(d, mem->size, mem->cpu_va, | ||
1591 | sg_dma_address(mem->sgt->sgl), | ||
1592 | &attrs); | ||
1593 | } else { | ||
1594 | dma_free_coherent(d, mem->size, mem->cpu_va, | ||
1568 | sg_dma_address(mem->sgt->sgl)); | 1595 | sg_dma_address(mem->sgt->sgl)); |
1569 | mem->cpu_va = NULL; | 1596 | } |
1597 | |||
1598 | mem->cpu_va = NULL; | ||
1599 | } | ||
1570 | 1600 | ||
1571 | if (mem->sgt) | 1601 | if (mem->sgt) |
1572 | gk20a_free_sgtable(&mem->sgt); | 1602 | gk20a_free_sgtable(&mem->sgt); |
1573 | } | 1603 | } |
1574 | 1604 | ||
1605 | void gk20a_gmmu_free(struct gk20a *g, struct mem_desc *mem) | ||
1606 | { | ||
1607 | return gk20a_gmmu_free_attr(g, 0, mem); | ||
1608 | } | ||
1609 | |||
1575 | int gk20a_gmmu_alloc_map(struct vm_gk20a *vm, size_t size, struct mem_desc *mem) | 1610 | int gk20a_gmmu_alloc_map(struct vm_gk20a *vm, size_t size, struct mem_desc *mem) |
1576 | { | 1611 | { |
1577 | return gk20a_gmmu_alloc_map_attr(vm, 0, size, mem); | 1612 | return gk20a_gmmu_alloc_map_attr(vm, 0, size, mem); |
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 2e0842f2..56e3a356 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | struct mem_desc { | 47 | struct mem_desc { |
48 | void *cpu_va; | 48 | void *cpu_va; |
49 | struct page **pages; | ||
49 | struct sg_table *sgt; | 50 | struct sg_table *sgt; |
50 | size_t size; | 51 | size_t size; |
51 | u64 gpu_va; | 52 | u64 gpu_va; |
@@ -416,6 +417,10 @@ int gk20a_gmmu_alloc_attr(struct gk20a *g, | |||
416 | void gk20a_gmmu_free(struct gk20a *g, | 417 | void gk20a_gmmu_free(struct gk20a *g, |
417 | struct mem_desc *mem); | 418 | struct mem_desc *mem); |
418 | 419 | ||
420 | void gk20a_gmmu_free_attr(struct gk20a *g, | ||
421 | enum dma_attr attr, | ||
422 | struct mem_desc *mem); | ||
423 | |||
419 | static inline phys_addr_t gk20a_mem_phys(struct mem_desc *mem) | 424 | static inline phys_addr_t gk20a_mem_phys(struct mem_desc *mem) |
420 | { | 425 | { |
421 | return sg_phys(mem->sgt->sgl); | 426 | return sg_phys(mem->sgt->sgl); |