From 1c055e55a242a33e574e48be530e06770a210dcd Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 19 Feb 2024 03:26:26 +0000 Subject: [PATCH] add r8169 read mac form eeprom --- kernel/drivers/rknpu/rknpu_gem.c | 446 +++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 328 insertions(+), 118 deletions(-) diff --git a/kernel/drivers/rknpu/rknpu_gem.c b/kernel/drivers/rknpu/rknpu_gem.c index 6e0e442..415d3a4 100644 --- a/kernel/drivers/rknpu/rknpu_gem.c +++ b/kernel/drivers/rknpu/rknpu_gem.c @@ -13,7 +13,6 @@ #include <linux/shmem_fs.h> #include <linux/dma-buf.h> #include <linux/iommu.h> -#include <linux/dma-iommu.h> #include <linux/pfn_t.h> #include <linux/version.h> #include <asm/cacheflush.h> @@ -25,6 +24,7 @@ #include "rknpu_drv.h" #include "rknpu_ioctl.h" #include "rknpu_gem.h" +#include "rknpu_iommu.h" #define RKNPU_GEM_ALLOC_FROM_PAGES 1 @@ -67,6 +67,7 @@ rknpu_obj->size); goto free_sgt; } + iommu_flush_iotlb_all(iommu_get_domain_for_dev(drm->dev)); if (rknpu_obj->flags & RKNPU_MEM_KERNEL_MAPPING) { rknpu_obj->cookie = vmap(rknpu_obj->pages, rknpu_obj->num_pages, @@ -115,15 +116,14 @@ rknpu_obj->kv_addr = NULL; } - dma_unmap_sg(drm->dev, rknpu_obj->sgt->sgl, rknpu_obj->sgt->nents, - DMA_BIDIRECTIONAL); - - drm_gem_put_pages(&rknpu_obj->base, rknpu_obj->pages, true, true); - if (rknpu_obj->sgt != NULL) { + dma_unmap_sg(drm->dev, rknpu_obj->sgt->sgl, + rknpu_obj->sgt->nents, DMA_BIDIRECTIONAL); sg_free_table(rknpu_obj->sgt); kfree(rknpu_obj->sgt); } + + drm_gem_put_pages(&rknpu_obj->base, rknpu_obj->pages, true, true); } #endif @@ -182,7 +182,9 @@ if (rknpu_obj->flags & RKNPU_MEM_ZEROING) gfp_mask |= __GFP_ZERO; - if (!(rknpu_obj->flags & RKNPU_MEM_NON_DMA32)) { + if (!rknpu_dev->iommu_en || + rknpu_dev->config->dma_mask <= DMA_BIT_MASK(32) || + (rknpu_obj->flags & RKNPU_MEM_DMA32)) { gfp_mask &= ~__GFP_HIGHMEM; gfp_mask |= __GFP_DMA32; } @@ -253,10 +255,15 @@ i, &s->dma_address, s->length); } - if (drm_prime_sg_to_page_addr_arrays(sgt, rknpu_obj->pages, NULL, - nr_pages)) { - LOG_DEV_ERROR(drm->dev, "invalid sgtable.\n"); - ret = -EINVAL; +#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE + ret = drm_prime_sg_to_page_addr_arrays(sgt, rknpu_obj->pages, NULL, + nr_pages); +#else + ret = drm_prime_sg_to_page_array(sgt, rknpu_obj->pages, nr_pages); +#endif + + if (ret < 0) { + LOG_DEV_ERROR(drm->dev, "invalid sgtable, ret: %d\n", ret); goto err_free_sg_table; } @@ -335,9 +342,28 @@ return drm_gem_handle_delete(file_priv, handle); } +#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE +static const struct vm_operations_struct vm_ops = { + .fault = rknpu_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct drm_gem_object_funcs rknpu_gem_object_funcs = { + .free = rknpu_gem_free_object, + .export = drm_gem_prime_export, + .get_sg_table = rknpu_gem_prime_get_sg_table, + .vmap = rknpu_gem_prime_vmap, + .vunmap = rknpu_gem_prime_vunmap, + .mmap = rknpu_gem_mmap_obj, + .vm_ops = &vm_ops, +}; +#endif + static struct rknpu_gem_object *rknpu_gem_init(struct drm_device *drm, unsigned long size) { + struct rknpu_device *rknpu_dev = drm->dev_private; struct rknpu_gem_object *rknpu_obj = NULL; struct drm_gem_object *obj = NULL; gfp_t gfp_mask; @@ -348,6 +374,9 @@ return ERR_PTR(-ENOMEM); obj = &rknpu_obj->base; +#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE + obj->funcs = &rknpu_gem_object_funcs; +#endif ret = drm_gem_object_init(drm, obj, size); if (ret < 0) { @@ -363,7 +392,9 @@ if (rknpu_obj->flags & RKNPU_MEM_ZEROING) gfp_mask |= __GFP_ZERO; - if (!(rknpu_obj->flags & RKNPU_MEM_NON_DMA32)) { + if (!rknpu_dev->iommu_en || + rknpu_dev->config->dma_mask <= DMA_BIT_MASK(32) || + (rknpu_obj->flags & RKNPU_MEM_DMA32)) { gfp_mask &= ~__GFP_HIGHMEM; gfp_mask |= __GFP_DMA32; } @@ -380,7 +411,8 @@ kfree(rknpu_obj); } -static int rknpu_gem_alloc_buf_with_sram(struct rknpu_gem_object *rknpu_obj) +static int rknpu_gem_alloc_buf_with_cache(struct rknpu_gem_object *rknpu_obj, + enum rknpu_cache_type cache_type) { struct drm_device *drm = rknpu_obj->base.dev; struct rknpu_device *rknpu_dev = drm->dev_private; @@ -393,18 +425,37 @@ unsigned long offset = 0; int i = 0; int ret = -EINVAL; + phys_addr_t cache_start = 0; + unsigned long cache_offset = 0; + unsigned long cache_size = 0; - /* iova map to sram */ + switch (cache_type) { + case RKNPU_CACHE_SRAM: + cache_start = rknpu_dev->sram_start; + cache_offset = rknpu_obj->sram_obj->range_start * + rknpu_dev->sram_mm->chunk_size; + cache_size = rknpu_obj->sram_size; + break; + case RKNPU_CACHE_NBUF: + cache_start = rknpu_dev->nbuf_start; + cache_offset = 0; + cache_size = rknpu_obj->nbuf_size; + break; + default: + LOG_ERROR("Unknown rknpu_cache_type: %d", cache_type); + return -EINVAL; + } + + /* iova map to cache */ domain = iommu_get_domain_for_dev(rknpu_dev->dev); if (!domain) { LOG_ERROR("failed to get iommu domain!"); return -EINVAL; } - cookie = domain->iova_cookie; + cookie = (void *)domain->iova_cookie; iovad = &cookie->iovad; - rknpu_obj->iova_size = - iova_align(iovad, rknpu_obj->sram_size + rknpu_obj->size); + rknpu_obj->iova_size = iova_align(iovad, cache_size + rknpu_obj->size); rknpu_obj->iova_start = rknpu_iommu_dma_alloc_iova( domain, rknpu_obj->iova_size, dma_get_mask(drm->dev), drm->dev); if (!rknpu_obj->iova_start) { @@ -416,20 +467,20 @@ &rknpu_obj->iova_start, rknpu_obj->iova_size); /* - * Overview SRAM + DDR map to IOVA + * Overview cache + DDR map to IOVA * -------- - * sram_size: rknpu_obj->sram_size - * - allocate from SRAM, this size value has been page-aligned + * cache_size: + * - allocate from CACHE, this size value has been page-aligned * size: rknpu_obj->size * - allocate from DDR pages, this size value has been page-aligned * iova_size: rknpu_obj->iova_size - * - from iova_align(sram_size + size) - * - it may be larger than the (sram_size + size), and the larger part is not mapped + * - from iova_align(cache_size + size) + * - it may be larger than the (cache_size + size), and the larger part is not mapped * -------- * - * |<- sram_size ->| |<- - - - size - - - ->| + * |<- cache_size ->| |<- - - - size - - - ->| * +---------------+ +----------------------+ - * | SRAM | | DDR | + * | CACHE | | DDR | * +---------------+ +----------------------+ * | | * | V | V | @@ -439,20 +490,18 @@ * |<- - - - - - - iova_size - - - - - - ->| * */ - offset = rknpu_obj->sram_obj->range_start * - rknpu_dev->sram_mm->chunk_size; ret = iommu_map(domain, rknpu_obj->iova_start, - rknpu_dev->sram_start + offset, rknpu_obj->sram_size, + cache_start + cache_offset, cache_size, IOMMU_READ | IOMMU_WRITE); if (ret) { - LOG_ERROR("sram iommu_map error: %d\n", ret); + LOG_ERROR("cache iommu_map error: %d\n", ret); goto free_iova; } rknpu_obj->dma_addr = rknpu_obj->iova_start; if (rknpu_obj->size == 0) { - LOG_INFO("allocate sram size: %lu\n", rknpu_obj->sram_size); + LOG_INFO("allocate cache size: %lu\n", cache_size); return 0; } @@ -460,7 +509,7 @@ if (IS_ERR(rknpu_obj->pages)) { ret = PTR_ERR(rknpu_obj->pages); LOG_ERROR("failed to get pages: %d\n", ret); - goto sram_unmap; + goto cache_unmap; } rknpu_obj->num_pages = rknpu_obj->size >> PAGE_SHIFT; @@ -479,7 +528,7 @@ } length = rknpu_obj->size; - offset = rknpu_obj->iova_start + rknpu_obj->sram_size; + offset = rknpu_obj->iova_start + cache_size; for_each_sg(rknpu_obj->sgt->sgl, s, rknpu_obj->sgt->nents, i) { size = (length < s->length) ? length : s->length; @@ -498,13 +547,13 @@ break; } - LOG_INFO("allocate size: %lu with sram size: %lu\n", rknpu_obj->size, - rknpu_obj->sram_size); + LOG_INFO("allocate size: %lu with cache size: %lu\n", rknpu_obj->size, + cache_size); return 0; sgl_unmap: - iommu_unmap(domain, rknpu_obj->iova_start + rknpu_obj->sram_size, + iommu_unmap(domain, rknpu_obj->iova_start + cache_size, rknpu_obj->size - length); sg_free_table(rknpu_obj->sgt); kfree(rknpu_obj->sgt); @@ -512,32 +561,43 @@ put_pages: drm_gem_put_pages(&rknpu_obj->base, rknpu_obj->pages, false, false); -sram_unmap: - iommu_unmap(domain, rknpu_obj->iova_start, rknpu_obj->sram_size); +cache_unmap: + iommu_unmap(domain, rknpu_obj->iova_start, cache_size); free_iova: - rknpu_iommu_dma_free_iova(domain->iova_cookie, rknpu_obj->iova_start, - rknpu_obj->iova_size); + rknpu_iommu_dma_free_iova((void *)domain->iova_cookie, + rknpu_obj->iova_start, rknpu_obj->iova_size); return ret; } -static void rknpu_gem_free_buf_with_sram(struct rknpu_gem_object *rknpu_obj) +static void rknpu_gem_free_buf_with_cache(struct rknpu_gem_object *rknpu_obj, + enum rknpu_cache_type cache_type) { struct drm_device *drm = rknpu_obj->base.dev; struct rknpu_device *rknpu_dev = drm->dev_private; struct iommu_domain *domain = NULL; + unsigned long cache_size = 0; + + switch (cache_type) { + case RKNPU_CACHE_SRAM: + cache_size = rknpu_obj->sram_size; + break; + case RKNPU_CACHE_NBUF: + cache_size = rknpu_obj->nbuf_size; + break; + default: + LOG_ERROR("Unknown rknpu_cache_type: %d", cache_type); + return; + } domain = iommu_get_domain_for_dev(rknpu_dev->dev); if (domain) { - iommu_unmap(domain, rknpu_obj->iova_start, - rknpu_obj->sram_size); + iommu_unmap(domain, rknpu_obj->iova_start, cache_size); if (rknpu_obj->size > 0) - iommu_unmap(domain, - rknpu_obj->iova_start + - rknpu_obj->sram_size, + iommu_unmap(domain, rknpu_obj->iova_start + cache_size, rknpu_obj->size); - rknpu_iommu_dma_free_iova(domain->iova_cookie, + rknpu_iommu_dma_free_iova((void *)domain->iova_cookie, rknpu_obj->iova_start, rknpu_obj->iova_size); } @@ -618,9 +678,35 @@ if (real_sram_size > 0) { rknpu_obj->sram_size = real_sram_size; - ret = rknpu_gem_alloc_buf_with_sram(rknpu_obj); + ret = rknpu_gem_alloc_buf_with_cache(rknpu_obj, + RKNPU_CACHE_SRAM); if (ret < 0) goto mm_free; + remain_ddr_size = 0; + } + } else if (IS_ENABLED(CONFIG_NO_GKI) && + (flags & RKNPU_MEM_TRY_ALLOC_NBUF) && + rknpu_dev->nbuf_size > 0) { + size_t nbuf_size = 0; + + rknpu_obj = rknpu_gem_init(drm, remain_ddr_size); + if (IS_ERR(rknpu_obj)) + return rknpu_obj; + + nbuf_size = remain_ddr_size <= rknpu_dev->nbuf_size ? + remain_ddr_size : + rknpu_dev->nbuf_size; + + /* set memory type and cache attribute from user side. */ + rknpu_obj->flags = flags; + + if (nbuf_size > 0) { + rknpu_obj->nbuf_size = nbuf_size; + + ret = rknpu_gem_alloc_buf_with_cache(rknpu_obj, + RKNPU_CACHE_NBUF); + if (ret < 0) + goto gem_release; remain_ddr_size = 0; } } @@ -640,9 +726,11 @@ if (rknpu_obj) LOG_DEBUG( - "created dma addr: %pad, cookie: %p, ddr size: %lu, sram size: %lu, attrs: %#lx, flags: %#x\n", - &rknpu_obj->dma_addr, rknpu_obj->cookie, rknpu_obj->size, - rknpu_obj->sram_size, rknpu_obj->dma_attrs, rknpu_obj->flags); + "created dma addr: %pad, cookie: %p, ddr size: %lu, sram size: %lu, nbuf size: %lu, attrs: %#lx, flags: %#x\n", + &rknpu_obj->dma_addr, rknpu_obj->cookie, + rknpu_obj->size, rknpu_obj->sram_size, + rknpu_obj->nbuf_size, rknpu_obj->dma_attrs, + rknpu_obj->flags); return rknpu_obj; @@ -683,7 +771,12 @@ if (rknpu_obj->sram_obj != NULL) rknpu_mm_free(rknpu_dev->sram_mm, rknpu_obj->sram_obj); - rknpu_gem_free_buf_with_sram(rknpu_obj); + rknpu_gem_free_buf_with_cache(rknpu_obj, + RKNPU_CACHE_SRAM); + } else if (IS_ENABLED(CONFIG_NO_GKI) && + rknpu_obj->nbuf_size > 0) { + rknpu_gem_free_buf_with_cache(rknpu_obj, + RKNPU_CACHE_NBUF); } else { rknpu_gem_free_buf(rknpu_obj); } @@ -808,6 +901,75 @@ } #endif +static int rknpu_gem_mmap_cache(struct rknpu_gem_object *rknpu_obj, + struct vm_area_struct *vma, + enum rknpu_cache_type cache_type) +{ + struct drm_device *drm = rknpu_obj->base.dev; +#if RKNPU_GEM_ALLOC_FROM_PAGES + struct rknpu_device *rknpu_dev = drm->dev_private; +#endif + unsigned long vm_size = 0; + int ret = -EINVAL; + unsigned long offset = 0; + unsigned long num_pages = 0; + int i = 0; + phys_addr_t cache_start = 0; + unsigned long cache_offset = 0; + unsigned long cache_size = 0; + + switch (cache_type) { + case RKNPU_CACHE_SRAM: + cache_start = rknpu_dev->sram_start; + cache_offset = rknpu_obj->sram_obj->range_start * + rknpu_dev->sram_mm->chunk_size; + cache_size = rknpu_obj->sram_size; + break; + case RKNPU_CACHE_NBUF: + cache_start = rknpu_dev->nbuf_start; + cache_offset = 0; + cache_size = rknpu_obj->nbuf_size; + break; + default: + LOG_ERROR("Unknown rknpu_cache_type: %d", cache_type); + return -EINVAL; + } + + vma->vm_flags |= VM_MIXEDMAP; + + vm_size = vma->vm_end - vma->vm_start; + + /* + * Convert a physical address in a cache area to a page frame number (PFN), + * and store the resulting PFN in the vm_pgoff field of the given VMA. + * + * NOTE: This conversion carries a risk because the resulting PFN is not a true + * page frame number and may not be valid or usable in all contexts. + */ + vma->vm_pgoff = __phys_to_pfn(cache_start + cache_offset); + + ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, cache_size, + vma->vm_page_prot); + if (ret) + return -EAGAIN; + + if (rknpu_obj->size == 0) + return 0; + + offset = cache_size; + + num_pages = (vm_size - cache_size) / PAGE_SIZE; + for (i = 0; i < num_pages; ++i) { + ret = vm_insert_page(vma, vma->vm_start + offset, + rknpu_obj->pages[i]); + if (ret < 0) + return ret; + offset += PAGE_SIZE; + } + + return 0; +} + static int rknpu_gem_mmap_buffer(struct rknpu_gem_object *rknpu_obj, struct vm_area_struct *vma) { @@ -823,6 +985,7 @@ * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map * the whole buffer. */ + vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP | VM_IO; vma->vm_flags &= ~VM_PFNMAP; vma->vm_pgoff = 0; @@ -832,38 +995,10 @@ if (vm_size > rknpu_obj->size) return -EINVAL; - if (rknpu_obj->sram_size > 0) { - unsigned long offset = 0; - unsigned long num_pages = 0; - int i = 0; - - vma->vm_flags |= VM_MIXEDMAP; - - offset = rknpu_obj->sram_obj->range_start * - rknpu_dev->sram_mm->chunk_size; - vma->vm_pgoff = __phys_to_pfn(rknpu_dev->sram_start + offset); - - ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - rknpu_obj->sram_size, vma->vm_page_prot); - if (ret) - return -EAGAIN; - - if (rknpu_obj->size == 0) - return 0; - - offset = rknpu_obj->sram_size; - - num_pages = (vm_size - rknpu_obj->sram_size) / PAGE_SIZE; - for (i = 0; i < num_pages; ++i) { - ret = vm_insert_page(vma, vma->vm_start + offset, - rknpu_obj->pages[i]); - if (ret < 0) - return ret; - offset += PAGE_SIZE; - } - - return 0; - } + if (rknpu_obj->sram_size > 0) + return rknpu_gem_mmap_cache(rknpu_obj, vma, RKNPU_CACHE_SRAM); + else if (rknpu_obj->nbuf_size > 0) + return rknpu_gem_mmap_cache(rknpu_obj, vma, RKNPU_CACHE_NBUF); #if RKNPU_GEM_ALLOC_FROM_PAGES if ((rknpu_obj->flags & RKNPU_MEM_NON_CONTIGUOUS) && @@ -1045,8 +1180,7 @@ } #endif -static int rknpu_gem_mmap_obj(struct drm_gem_object *obj, - struct vm_area_struct *vma) +int rknpu_gem_mmap_obj(struct drm_gem_object *obj, struct vm_area_struct *vma) { struct rknpu_gem_object *rknpu_obj = to_rknpu_obj(obj); int ret = -EINVAL; @@ -1143,8 +1277,12 @@ goto err; } +#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE ret = drm_prime_sg_to_page_addr_arrays(sgt, rknpu_obj->pages, NULL, npages); +#else + ret = drm_prime_sg_to_page_array(sgt, rknpu_obj->pages, npages); +#endif if (ret < 0) goto err_free_large; @@ -1172,6 +1310,7 @@ return ERR_PTR(ret); } +#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE void *rknpu_gem_prime_vmap(struct drm_gem_object *obj) { struct rknpu_gem_object *rknpu_obj = to_rknpu_obj(obj); @@ -1187,6 +1326,35 @@ { vunmap(vaddr); } +#else +int rknpu_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) +{ + struct rknpu_gem_object *rknpu_obj = to_rknpu_obj(obj); + void *vaddr = NULL; + + if (!rknpu_obj->pages) + return -EINVAL; + + vaddr = vmap(rknpu_obj->pages, rknpu_obj->num_pages, VM_MAP, + PAGE_KERNEL); + if (!vaddr) + return -ENOMEM; + + iosys_map_set_vaddr(map, vaddr); + + return 0; +} + +void rknpu_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map) +{ + struct rknpu_gem_object *rknpu_obj = to_rknpu_obj(obj); + + if (rknpu_obj->pages) { + vunmap(map->vaddr); + map->vaddr = NULL; + } +} +#endif int rknpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) { @@ -1199,14 +1367,68 @@ return rknpu_gem_mmap_obj(obj, vma); } +static int rknpu_cache_sync(struct rknpu_gem_object *rknpu_obj, + unsigned long *length, unsigned long *offset, + enum rknpu_cache_type cache_type) +{ +#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE + struct drm_gem_object *obj = &rknpu_obj->base; + struct rknpu_device *rknpu_dev = obj->dev->dev_private; + void __iomem *cache_base_io = NULL; + unsigned long cache_offset = 0; + unsigned long cache_size = 0; + + switch (cache_type) { + case RKNPU_CACHE_SRAM: + cache_base_io = rknpu_dev->sram_base_io; + cache_offset = rknpu_obj->sram_obj->range_start * + rknpu_dev->sram_mm->chunk_size; + cache_size = rknpu_obj->sram_size; + break; + case RKNPU_CACHE_NBUF: + cache_base_io = rknpu_dev->nbuf_base_io; + cache_offset = 0; + cache_size = rknpu_obj->nbuf_size; + break; + default: + LOG_ERROR("Unknown rknpu_cache_type: %d", cache_type); + return -EINVAL; + } + + if ((*offset + *length) <= cache_size) { + __dma_map_area(cache_base_io + *offset + cache_offset, *length, + DMA_TO_DEVICE); + __dma_unmap_area(cache_base_io + *offset + cache_offset, + *length, DMA_FROM_DEVICE); + *length = 0; + *offset = 0; + } else if (*offset >= cache_size) { + *offset -= cache_size; + } else { + unsigned long cache_length = cache_size - *offset; + + __dma_map_area(cache_base_io + *offset + cache_offset, + cache_length, DMA_TO_DEVICE); + __dma_unmap_area(cache_base_io + *offset + cache_offset, + cache_length, DMA_FROM_DEVICE); + *length -= cache_length; + *offset = 0; + } +#endif + + return 0; +} + int rknpu_gem_sync_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct rknpu_gem_object *rknpu_obj = NULL; + struct rknpu_device *rknpu_dev = dev->dev_private; struct rknpu_mem_sync *args = data; struct scatterlist *sg; + dma_addr_t sg_phys_addr; unsigned long length, offset = 0; - unsigned long sg_left, size = 0; + unsigned long sg_offset, sg_left, size = 0; unsigned long len = 0; int i; @@ -1230,38 +1452,20 @@ DMA_FROM_DEVICE); } } else { + WARN_ON(!rknpu_dev->fake_dev); + length = args->size; offset = args->offset; - if (IS_ENABLED(CONFIG_ROCKCHIP_RKNPU_SRAM) && rknpu_obj->sram_size > 0) { - struct drm_gem_object *obj = &rknpu_obj->base; - struct rknpu_device *rknpu_dev = obj->dev->dev_private; - unsigned long sram_offset = - rknpu_obj->sram_obj->range_start * - rknpu_dev->sram_mm->chunk_size; - if ((offset + length) <= rknpu_obj->sram_size) { - __dma_map_area(rknpu_dev->sram_base_io + - offset + sram_offset, - length, DMA_TO_DEVICE); - __dma_unmap_area(rknpu_dev->sram_base_io + - offset + sram_offset, - length, DMA_FROM_DEVICE); - length = 0; - offset = 0; - } else if (offset >= rknpu_obj->sram_size) { - offset -= rknpu_obj->sram_size; - } else { - unsigned long sram_length = - rknpu_obj->sram_size - offset; - __dma_map_area(rknpu_dev->sram_base_io + - offset + sram_offset, - sram_length, DMA_TO_DEVICE); - __dma_unmap_area(rknpu_dev->sram_base_io + - offset + sram_offset, - sram_length, DMA_FROM_DEVICE); - length -= sram_length; - offset = 0; - } + if (IS_ENABLED(CONFIG_NO_GKI) && + IS_ENABLED(CONFIG_ROCKCHIP_RKNPU_SRAM) && + rknpu_obj->sram_size > 0) { + rknpu_cache_sync(rknpu_obj, &length, &offset, + RKNPU_CACHE_SRAM); + } else if (IS_ENABLED(CONFIG_NO_GKI) && + rknpu_obj->nbuf_size > 0) { + rknpu_cache_sync(rknpu_obj, &length, &offset, + RKNPU_CACHE_NBUF); } for_each_sg(rknpu_obj->sgt->sgl, sg, rknpu_obj->sgt->nents, @@ -1273,17 +1477,23 @@ if (len <= offset) continue; + sg_phys_addr = sg_phys(sg); + sg_left = len - offset; + sg_offset = sg->length - sg_left; + size = (length < sg_left) ? length : sg_left; if (args->flags & RKNPU_MEM_SYNC_TO_DEVICE) { - dma_sync_sg_for_device(dev->dev, sg, 1, - DMA_TO_DEVICE); + dma_sync_single_range_for_device( + rknpu_dev->fake_dev, sg_phys_addr, + sg_offset, size, DMA_TO_DEVICE); } if (args->flags & RKNPU_MEM_SYNC_FROM_DEVICE) { - dma_sync_sg_for_cpu(dev->dev, sg, 1, - DMA_FROM_DEVICE); + dma_sync_single_range_for_cpu( + rknpu_dev->fake_dev, sg_phys_addr, + sg_offset, size, DMA_FROM_DEVICE); } offset += size; -- Gitblit v1.6.2