From d779a08a0f7ca3cdde16941720ddc7af96e74520 Mon Sep 17 00:00:00 2001 From: Kristofer Jonsson Date: Wed, 4 Jan 2023 17:09:47 +0100 Subject: Converting Ethos-U driver to rpmsg The Ethos-U kernel driver has been converted from a platform driver with a custom firmware interface into a rpmsg driver. Change-Id: I9ae449f5e79eb02924e6630611d0893e5fec86be --- kernel/ethosu_buffer.c | 90 +++++++++++++++----------------------------------- 1 file changed, 26 insertions(+), 64 deletions(-) (limited to 'kernel/ethosu_buffer.c') diff --git a/kernel/ethosu_buffer.c b/kernel/ethosu_buffer.c index ac32aca..a83a95a 100644 --- a/kernel/ethosu_buffer.c +++ b/kernel/ethosu_buffer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022 Arm Limited. + * Copyright 2020-2023 Arm Limited and/or its affiliates * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software @@ -32,6 +32,7 @@ #include #include #include +#include #include /**************************************************************************** @@ -61,59 +62,22 @@ static const struct file_operations ethosu_buffer_fops = { * Functions ****************************************************************************/ -/* - * The 'dma-ranges' device tree property for shared dma memory does not seem - * to be fully supported for coherent memory. Therefor we apply the DMA range - * offset ourselves. - */ -static dma_addr_t ethosu_buffer_dma_ranges(struct device *dev, - dma_addr_t dma_addr, - size_t dma_buf_size) +__attribute__((used)) +static dma_addr_t ethosu_pa_to_da(struct device *dev, + phys_addr_t pa, + size_t len) { - struct device_node *node = dev->of_node; - const __be32 *ranges; - int len; - int naddr; - int nsize; - int inc; - int i; - - if (!node) - return dma_addr; - - /* Get the #address-cells and #size-cells properties */ - naddr = of_n_addr_cells(node); - nsize = of_n_size_cells(node); - - /* Read the 'dma-ranges' property */ - ranges = of_get_property(node, "dma-ranges", &len); - if (!ranges || len <= 0) - return dma_addr; - - dev_dbg(dev, "ranges=%p, len=%d, naddr=%d, nsize=%d\n", - ranges, len, naddr, nsize); - - len /= sizeof(*ranges); - inc = naddr + naddr + nsize; - - for (i = 0; (i + inc) <= len; i += inc) { - dma_addr_t daddr; - dma_addr_t paddr; - dma_addr_t size; - - daddr = of_read_number(&ranges[i], naddr); - paddr = of_read_number(&ranges[i + naddr], naddr); - size = of_read_number(&ranges[i + naddr + naddr], nsize); - - dev_dbg(dev, "daddr=0x%llx, paddr=0x%llx, size=0x%llx\n", - daddr, paddr, size); - - if (dma_addr >= paddr && - (dma_addr + dma_buf_size) < (paddr + size)) - return dma_addr + daddr - paddr; + struct rproc *rproc = rproc_get_by_child(dev); + struct rproc_mem_entry *mem; + + list_for_each_entry(mem, &rproc->carveouts, node) { + ssize_t offset = pa - mem->dma; + + if (offset >= 0 && offset + len <= mem->len) + return mem->da + offset; } - return dma_addr; + return (dma_addr_t)-1; } static bool ethosu_buffer_verify(struct file *file) @@ -128,8 +92,8 @@ static void ethosu_buffer_destroy(struct kref *kref) dev_info(buf->edev->dev, "Buffer destroy. buf=0x%pK\n", buf); - dma_free_coherent(buf->edev->dev, buf->capacity, buf->cpu_addr, - buf->dma_addr_orig); + dma_free_coherent(buf->dev, buf->capacity, buf->cpu_addr, + buf->dma_addr); devm_kfree(buf->edev->dev, buf); } @@ -157,8 +121,7 @@ static int ethosu_buffer_mmap(struct file *file, file, buf); ret = dma_mmap_coherent(buf->edev->dev, vma, buf->cpu_addr, - buf->dma_addr_orig, - buf->capacity); + buf->dma_addr, buf->capacity); return ret; } @@ -224,6 +187,8 @@ static long ethosu_buffer_ioctl(struct file *file, int ethosu_buffer_create(struct ethosu_device *edev, size_t capacity) { + struct rproc *rproc = rproc_get_by_child(edev->dev); + struct device *dev = rproc->dev.parent; struct ethosu_buffer *buf; int ret = -ENOMEM; @@ -235,20 +200,17 @@ int ethosu_buffer_create(struct ethosu_device *edev, return -ENOMEM; buf->edev = edev; + buf->dev = dev; buf->capacity = capacity; buf->offset = 0; buf->size = 0; kref_init(&buf->kref); - buf->cpu_addr = dma_alloc_coherent(buf->edev->dev, capacity, - &buf->dma_addr_orig, GFP_KERNEL); + buf->cpu_addr = dma_alloc_coherent(dev, capacity, + &buf->dma_addr, GFP_KERNEL); if (!buf->cpu_addr) goto free_buf; - buf->dma_addr = ethosu_buffer_dma_ranges(buf->edev->dev, - buf->dma_addr_orig, - buf->capacity); - ret = anon_inode_getfd("ethosu-buffer", ðosu_buffer_fops, buf, O_RDWR | O_CLOEXEC); if (ret < 0) @@ -258,15 +220,15 @@ int ethosu_buffer_create(struct ethosu_device *edev, fput(buf->file); dev_info(buf->edev->dev, - "Buffer create. file=0x%pK, fd=%d, buf=0x%pK, capacity=%zu, cpu_addr=0x%pK, dma_addr=0x%llx, dma_addr_orig=0x%llx, phys_addr=0x%llx\n", + "Buffer create. file=0x%pK, fd=%d, buf=0x%pK, capacity=%zu, cpu_addr=0x%pK, dma_addr=0x%llx, phys_addr=0x%llx\n", buf->file, ret, buf, capacity, buf->cpu_addr, buf->dma_addr, - buf->dma_addr_orig, virt_to_phys(buf->cpu_addr)); + virt_to_phys(buf->cpu_addr)); return ret; free_dma: dma_free_coherent(buf->edev->dev, buf->capacity, buf->cpu_addr, - buf->dma_addr_orig); + buf->dma_addr); free_buf: devm_kfree(buf->edev->dev, buf); -- cgit v1.2.1