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 <Guangming.Cao@mediatek.com>
This commit is contained in:
Guangming Cao
2021-09-15 14:26:47 +08:00
committed by Hridya Valsaraju
parent a0345d4590
commit 48e5c07fe0

View File

@@ -543,10 +543,37 @@ static struct dma_heap_ops system_uncached_heap_ops = {
.allocate = system_uncached_heap_not_initialized, .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) static int system_heap_create(void)
{ {
struct dma_heap_export_info exp_info; struct dma_heap_export_info exp_info;
int i; int i, err = 0;
for (i = 0; i < NUM_ORDERS; i++) { for (i = 0; i < NUM_ORDERS; i++) {
pools[i] = dmabuf_page_pool_create(order_flags[i], 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)) if (IS_ERR(sys_uncached_heap))
return PTR_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 */ mb(); /* make sure we only set allocate after dma_mask is set */
system_uncached_heap_ops.allocate = system_uncached_heap_allocate; system_uncached_heap_ops.allocate = system_uncached_heap_allocate;