From 48e5c07fe0d9ffd9057690985362632e97c97ee9 Mon Sep 17 00:00:00 2001 From: Guangming Cao Date: Wed, 15 Sep 2021 14:26:47 +0800 Subject: [PATCH] ANDROID: dma_heap: add dma_parms for uncached heap In system_heap_do_allocate, we will use uncached heap device to call dma_map_sgtable & dma_unmap_sgtable to do implicitly flush. However, device of uncached heap is not set dma_parms, default value(64KB) is too small for dma_heap buffer, it will cause some warning log below when CONFIG_DMA_API_DEBUG_SG is enabled. warning log sample: |DMA-API: dma_heap system-uncached: mapping sg segment longer than device claims to support [len=1048576] [max=65536] |WARNING: CPU: 4 PID: 576 at kernel/dma/debug.c:1173 debug_dma_map_sg+0x214/0x438 |...... Bug: 199986022 Change-Id: I97076de329f4a50d035d43d69cb17606064c3151 Signed-off-by: Guangming Cao --- drivers/dma-buf/heaps/system_heap.c | 34 +++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index 2aa3b5eafaff..a9a9abfd4bb1 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -543,10 +543,37 @@ static struct dma_heap_ops system_uncached_heap_ops = { .allocate = system_uncached_heap_not_initialized, }; +static int set_heap_dev_dma(struct device *heap_dev) +{ + int err = 0; + + if (!heap_dev) + return -EINVAL; + + dma_coerce_mask_and_coherent(heap_dev, DMA_BIT_MASK(64)); + + if (!heap_dev->dma_parms) { + heap_dev->dma_parms = devm_kzalloc(heap_dev, + sizeof(*heap_dev->dma_parms), + GFP_KERNEL); + if (!heap_dev->dma_parms) + return -ENOMEM; + + err = dma_set_max_seg_size(heap_dev, (unsigned int)DMA_BIT_MASK(64)); + if (err) { + devm_kfree(heap_dev, heap_dev->dma_parms); + dev_err(heap_dev, "Failed to set DMA segment size, err:%d\n", err); + return err; + } + } + + return 0; +} + static int system_heap_create(void) { struct dma_heap_export_info exp_info; - int i; + int i, err = 0; for (i = 0; i < NUM_ORDERS; i++) { pools[i] = dmabuf_page_pool_create(order_flags[i], orders[i]); @@ -577,7 +604,10 @@ static int system_heap_create(void) if (IS_ERR(sys_uncached_heap)) return PTR_ERR(sys_uncached_heap); - dma_coerce_mask_and_coherent(dma_heap_get_dev(sys_uncached_heap), DMA_BIT_MASK(64)); + err = set_heap_dev_dma(dma_heap_get_dev(sys_uncached_heap)); + if (err) + return err; + mb(); /* make sure we only set allocate after dma_mask is set */ system_uncached_heap_ops.allocate = system_uncached_heap_allocate;