From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/video/rockchip/rga/rga_mmu_info.c | 2448 ++++++++++++++++++++++++++++++----------------------------- 1 files changed, 1,239 insertions(+), 1,209 deletions(-) diff --git a/kernel/drivers/video/rockchip/rga/rga_mmu_info.c b/kernel/drivers/video/rockchip/rga/rga_mmu_info.c index a8d7e62..9dcffa5 100644 --- a/kernel/drivers/video/rockchip/rga/rga_mmu_info.c +++ b/kernel/drivers/video/rockchip/rga/rga_mmu_info.c @@ -1,253 +1,298 @@ /* SPDX-License-Identifier: GPL-2.0 */ - - -#include <linux/version.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/sched.h> -#include <linux/signal.h> -#include <linux/pagemap.h> -#include <linux/seq_file.h> -#include <linux/mm.h> -#include <linux/mman.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/memory.h> -#include <linux/dma-mapping.h> -#include <asm/memory.h> -#include <asm/atomic.h> -#include <asm/cacheflush.h> -#include "rga_mmu_info.h" -#include <linux/delay.h> - -extern rga_service_info rga_service; -extern struct rga_mmu_buf_t rga_mmu_buf; + + +#include <linux/version.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/sched.h> +#include <linux/signal.h> +#include <linux/pagemap.h> +#include <linux/seq_file.h> +#include <linux/mm.h> +#include <linux/mman.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/memory.h> +#include <linux/dma-mapping.h> +#include <asm/memory.h> +#include <asm/atomic.h> +#include <asm/cacheflush.h> +#include "rga_mmu_info.h" +#include <linux/delay.h> + +extern rga_service_info rga_service; +extern struct rga_mmu_buf_t rga_mmu_buf; #if RGA_DEBUGFS extern int RGA_CHECK_MODE; #endif - -#define KERNEL_SPACE_VALID 0xc0000000 - -static int rga_mmu_buf_get(struct rga_mmu_buf_t *t, uint32_t size) -{ - mutex_lock(&rga_service.lock); - t->front += size; - mutex_unlock(&rga_service.lock); - - return 0; -} - -static int rga_mmu_buf_get_try(struct rga_mmu_buf_t *t, uint32_t size) -{ - int ret = 0; - - mutex_lock(&rga_service.lock); - if ((t->back - t->front) > t->size) { - if(t->front + size > t->back - t->size) { - ret = -ENOMEM; - goto out; - } - } else { - if ((t->front + size) > t->back) { - ret = -ENOMEM; - goto out; - } - if (t->front + size > t->size) { - if (size > (t->back - t->size)) { - ret = -ENOMEM; - goto out; - } - t->front = 0; - } - } - -out: - mutex_unlock(&rga_service.lock); - return ret; -} - -static int rga_mem_size_cal(unsigned long Mem, uint32_t MemSize, unsigned long *StartAddr) -{ - unsigned long start, end; - uint32_t pageCount; - - end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT; - start = Mem >> PAGE_SHIFT; - pageCount = end - start; - *StartAddr = start; - return pageCount; -} - -static int rga_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, unsigned long v_addr, - int format, uint32_t w, uint32_t h, unsigned long *StartAddr ) -{ - uint32_t size_yrgb = 0; - uint32_t size_uv = 0; - uint32_t size_v = 0; - uint32_t stride = 0; - unsigned long start, end; - uint32_t pageCount; - - switch(format) - { - case RK_FORMAT_RGBA_8888 : - stride = (w * 4 + 3) & (~3); - size_yrgb = stride*h; - start = yrgb_addr >> PAGE_SHIFT; - pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; - break; - case RK_FORMAT_RGBX_8888 : - stride = (w * 4 + 3) & (~3); - size_yrgb = stride*h; - start = yrgb_addr >> PAGE_SHIFT; - pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; - break; - case RK_FORMAT_RGB_888 : - stride = (w * 3 + 3) & (~3); - size_yrgb = stride*h; - start = yrgb_addr >> PAGE_SHIFT; - pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; - break; - case RK_FORMAT_BGRA_8888 : - size_yrgb = w*h*4; - start = yrgb_addr >> PAGE_SHIFT; - pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; - break; - case RK_FORMAT_RGB_565 : - stride = (w*2 + 3) & (~3); - size_yrgb = stride * h; - start = yrgb_addr >> PAGE_SHIFT; - pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; - break; - case RK_FORMAT_RGBA_5551 : - stride = (w*2 + 3) & (~3); - size_yrgb = stride * h; - start = yrgb_addr >> PAGE_SHIFT; - pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; - break; - case RK_FORMAT_RGBA_4444 : - stride = (w*2 + 3) & (~3); - size_yrgb = stride * h; - start = yrgb_addr >> PAGE_SHIFT; - pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; - break; - case RK_FORMAT_BGR_888 : - stride = (w*3 + 3) & (~3); - size_yrgb = stride * h; - start = yrgb_addr >> PAGE_SHIFT; - pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; - break; - - /* YUV FORMAT */ - case RK_FORMAT_YCbCr_422_SP : - stride = (w + 3) & (~3); - size_yrgb = stride * h; - size_uv = stride * h; - start = MIN(yrgb_addr, uv_addr); - - start >>= PAGE_SHIFT; - end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); - end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - pageCount = end - start; - break; - case RK_FORMAT_YCbCr_422_P : - stride = (w + 3) & (~3); - size_yrgb = stride * h; - size_uv = ((stride >> 1) * h); - size_v = ((stride >> 1) * h); - start = MIN(MIN(yrgb_addr, uv_addr), v_addr); - start = start >> PAGE_SHIFT; - end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); - end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - pageCount = end - start; - break; - case RK_FORMAT_YCbCr_420_SP : - stride = (w + 3) & (~3); - size_yrgb = stride * h; - size_uv = (stride * (h >> 1)); - start = MIN(yrgb_addr, uv_addr); - start >>= PAGE_SHIFT; - end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); - end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - pageCount = end - start; - break; - case RK_FORMAT_YCbCr_420_P : - stride = (w + 3) & (~3); - size_yrgb = stride * h; - size_uv = ((stride >> 1) * (h >> 1)); - size_v = ((stride >> 1) * (h >> 1)); - start = MIN(MIN(yrgb_addr, uv_addr), v_addr); - start >>= PAGE_SHIFT; - end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); - end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - pageCount = end - start; - break; - - case RK_FORMAT_YCrCb_422_SP : - stride = (w + 3) & (~3); - size_yrgb = stride * h; - size_uv = stride * h; - start = MIN(yrgb_addr, uv_addr); - start >>= PAGE_SHIFT; - end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); - end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - pageCount = end - start; - break; - case RK_FORMAT_YCrCb_422_P : - stride = (w + 3) & (~3); - size_yrgb = stride * h; - size_uv = ((stride >> 1) * h); - size_v = ((stride >> 1) * h); - start = MIN(MIN(yrgb_addr, uv_addr), v_addr); - start >>= PAGE_SHIFT; - end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); - end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - pageCount = end - start; - break; - - case RK_FORMAT_YCrCb_420_SP : - stride = (w + 3) & (~3); - size_yrgb = stride * h; - size_uv = (stride * (h >> 1)); - start = MIN(yrgb_addr, uv_addr); - start >>= PAGE_SHIFT; - end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); - end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - pageCount = end - start; - break; - case RK_FORMAT_YCrCb_420_P : - stride = (w + 3) & (~3); - size_yrgb = stride * h; - size_uv = ((stride >> 1) * (h >> 1)); - size_v = ((stride >> 1) * (h >> 1)); - start = MIN(MIN(yrgb_addr, uv_addr), v_addr); - start >>= PAGE_SHIFT; - end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); - end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - pageCount = end - start; - break; - #if 0 - case RK_FORMAT_BPP1 : - break; - case RK_FORMAT_BPP2 : - break; - case RK_FORMAT_BPP4 : - break; - case RK_FORMAT_BPP8 : - break; - #endif - default : - pageCount = 0; - start = 0; - break; - } - - *StartAddr = start; - return pageCount; -} - + +#define KERNEL_SPACE_VALID 0xc0000000 + +void rga_dma_flush_range(void *pstart, void *pend) +{ + dma_sync_single_for_device(rga_drvdata->dev, virt_to_phys(pstart), pend - pstart, DMA_TO_DEVICE); +} + +static int rga_mmu_buf_get(struct rga_mmu_buf_t *t, uint32_t size) +{ + mutex_lock(&rga_service.lock); + t->front += size; + mutex_unlock(&rga_service.lock); + + return 0; +} + +static void rga_current_mm_read_lock(struct mm_struct *mm) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + mmap_read_lock(mm); +#else + down_read(&mm->mmap_sem); +#endif +} + +static void rga_current_mm_read_unlock(struct mm_struct *mm) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + mmap_read_unlock(mm); +#else + up_read(&mm->mmap_sem); +#endif +} + +static long rga_get_user_pages(struct page **pages, unsigned long Memory, + uint32_t pageCount, int writeFlag, + struct mm_struct *current_mm) +{ + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 168) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) + return get_user_pages(current, current_mm, Memory << PAGE_SHIFT, + pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL); + #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) + return get_user_pages(current, current_mm, Memory << PAGE_SHIFT, + pageCount, writeFlag ? FOLL_WRITE : 0, 0, pages, NULL); + #elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + return get_user_pages_remote(current, current_mm, Memory << PAGE_SHIFT, + pageCount, writeFlag ? FOLL_WRITE : 0, pages, + NULL, NULL); + #else + return get_user_pages_remote(current_mm, Memory << PAGE_SHIFT, + pageCount, writeFlag ? FOLL_WRITE : 0, pages, + NULL, NULL); + #endif +} + +static int rga_mmu_buf_get_try(struct rga_mmu_buf_t *t, uint32_t size) +{ + int ret = 0; + + mutex_lock(&rga_service.lock); + if ((t->back - t->front) > t->size) { + if(t->front + size > t->back - t->size) { + ret = -ENOMEM; + goto out; + } + } else { + if ((t->front + size) > t->back) { + ret = -ENOMEM; + goto out; + } + if (t->front + size > t->size) { + if (size > (t->back - t->size)) { + ret = -ENOMEM; + goto out; + } + t->front = 0; + } + } + +out: + mutex_unlock(&rga_service.lock); + return ret; +} + +static int rga_mem_size_cal(unsigned long Mem, uint32_t MemSize, unsigned long *StartAddr) +{ + unsigned long start, end; + uint32_t pageCount; + + end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT; + start = Mem >> PAGE_SHIFT; + pageCount = end - start; + *StartAddr = start; + return pageCount; +} + +static int rga_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, unsigned long v_addr, + int format, uint32_t w, uint32_t h, unsigned long *StartAddr ) +{ + uint32_t size_yrgb = 0; + uint32_t size_uv = 0; + uint32_t size_v = 0; + uint32_t stride = 0; + unsigned long start, end; + uint32_t pageCount; + + switch(format) + { + case RK_FORMAT_RGBA_8888 : + stride = (w * 4 + 3) & (~3); + size_yrgb = stride*h; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; + break; + case RK_FORMAT_RGBX_8888 : + stride = (w * 4 + 3) & (~3); + size_yrgb = stride*h; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; + break; + case RK_FORMAT_RGB_888 : + stride = (w * 3 + 3) & (~3); + size_yrgb = stride*h; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; + break; + case RK_FORMAT_BGRA_8888 : + size_yrgb = w*h*4; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; + break; + case RK_FORMAT_RGB_565 : + stride = (w*2 + 3) & (~3); + size_yrgb = stride * h; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; + break; + case RK_FORMAT_RGBA_5551 : + stride = (w*2 + 3) & (~3); + size_yrgb = stride * h; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; + break; + case RK_FORMAT_RGBA_4444 : + stride = (w*2 + 3) & (~3); + size_yrgb = stride * h; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; + break; + case RK_FORMAT_BGR_888 : + stride = (w*3 + 3) & (~3); + size_yrgb = stride * h; + start = yrgb_addr >> PAGE_SHIFT; + pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; + break; + + /* YUV FORMAT */ + case RK_FORMAT_YCbCr_422_SP : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = stride * h; + start = MIN(yrgb_addr, uv_addr); + + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCbCr_422_P : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = ((stride >> 1) * h); + size_v = ((stride >> 1) * h); + start = MIN(MIN(yrgb_addr, uv_addr), v_addr); + start = start >> PAGE_SHIFT; + end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCbCr_420_SP : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = (stride * (h >> 1)); + start = MIN(yrgb_addr, uv_addr); + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCbCr_420_P : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = ((stride >> 1) * (h >> 1)); + size_v = ((stride >> 1) * (h >> 1)); + start = MIN(MIN(yrgb_addr, uv_addr), v_addr); + start >>= PAGE_SHIFT; + end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + + case RK_FORMAT_YCrCb_422_SP : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = stride * h; + start = MIN(yrgb_addr, uv_addr); + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCrCb_422_P : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = ((stride >> 1) * h); + size_v = ((stride >> 1) * h); + start = MIN(MIN(yrgb_addr, uv_addr), v_addr); + start >>= PAGE_SHIFT; + end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + + case RK_FORMAT_YCrCb_420_SP : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = (stride * (h >> 1)); + start = MIN(yrgb_addr, uv_addr); + start >>= PAGE_SHIFT; + end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + case RK_FORMAT_YCrCb_420_P : + stride = (w + 3) & (~3); + size_yrgb = stride * h; + size_uv = ((stride >> 1) * (h >> 1)); + size_v = ((stride >> 1) * (h >> 1)); + start = MIN(MIN(yrgb_addr, uv_addr), v_addr); + start >>= PAGE_SHIFT; + end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); + end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + pageCount = end - start; + break; + #if 0 + case RK_FORMAT_BPP1 : + break; + case RK_FORMAT_BPP2 : + break; + case RK_FORMAT_BPP4 : + break; + case RK_FORMAT_BPP8 : + break; + #endif + default : + pageCount = 0; + start = 0; + break; + } + + *StartAddr = start; + return pageCount; +} + #if RGA_DEBUGFS static int rga_usermemory_cheeck(struct page **pages, u32 w, u32 h, u32 format, int flag) { @@ -314,289 +359,304 @@ } #endif -static int rga_MapUserMemory(struct page **pages, - uint32_t *pageTable, - unsigned long Memory, - uint32_t pageCount) -{ - int32_t result; - uint32_t i; - uint32_t status; - unsigned long Address; - - status = 0; - Address = 0; - - do { - down_read(¤t->mm->mmap_sem); -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) - result = get_user_pages(current, current->mm, - Memory << PAGE_SHIFT, pageCount, 1, 0, - pages, NULL); -#else - result = get_user_pages_remote(current, current->mm, - Memory << PAGE_SHIFT, pageCount, 1, pages, NULL, NULL); +static int rga_MapUserMemory(struct page **pages, + uint32_t *pageTable, + unsigned long Memory, + uint32_t pageCount) +{ + int32_t result; + uint32_t i; + uint32_t status; + unsigned long Address; + + status = 0; + Address = 0; + + do { + rga_current_mm_read_lock(current->mm); + + result = rga_get_user_pages(pages, Memory, pageCount, 1, current->mm); + + rga_current_mm_read_unlock(current->mm); + + #if 0 + if(result <= 0 || result < pageCount) + { + status = 0; + + for(i=0; i<pageCount; i++) + { + temp = armv7_va_to_pa((Memory + i) << PAGE_SHIFT); + if (temp == 0xffffffff) + { + printk("rga find mmu phy ddr error\n "); + status = RGA_OUT_OF_RESOURCES; + break; + } + + pageTable[i] = temp; + } + + return status; + } + #else + if(result <= 0 || result < pageCount) + { + struct vm_area_struct *vma; + + if (result>0) { + rga_current_mm_read_lock(current->mm); + + for (i = 0; i < result; i++) + put_page(pages[i]); + + rga_current_mm_read_unlock(current->mm); + } + + for(i=0; i<pageCount; i++) + { + vma = find_vma(current->mm, (Memory + i) << PAGE_SHIFT); + + if (vma)//&& (vma->vm_flags & VM_PFNMAP) ) + { + do + { + pte_t * pte; + spinlock_t * ptl; + unsigned long pfn; + pgd_t * pgd; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + p4d_t * p4d; #endif - up_read(¤t->mm->mmap_sem); - - #if 0 - if(result <= 0 || result < pageCount) - { - status = 0; - - for(i=0; i<pageCount; i++) - { - temp = armv7_va_to_pa((Memory + i) << PAGE_SHIFT); - if (temp == 0xffffffff) - { - printk("rga find mmu phy ddr error\n "); - status = RGA_OUT_OF_RESOURCES; - break; - } - - pageTable[i] = temp; - } - - return status; - } - #else - if(result <= 0 || result < pageCount) - { - struct vm_area_struct *vma; - - if (result>0) { - down_read(¤t->mm->mmap_sem); - for (i = 0; i < result; i++) - put_page(pages[i]); - up_read(¤t->mm->mmap_sem); - } - - for(i=0; i<pageCount; i++) - { - vma = find_vma(current->mm, (Memory + i) << PAGE_SHIFT); - - if (vma)//&& (vma->vm_flags & VM_PFNMAP) ) - { - do - { - pte_t * pte; - spinlock_t * ptl; - unsigned long pfn; - pgd_t * pgd; - pud_t * pud; - - pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT); - - if(pgd_val(*pgd) == 0) - { - //printk("rga pgd value is zero \n"); - break; - } - - pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT); - if (pud) - { - pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT); - if (pmd) - { - pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl); - if (!pte) - { - pte_unmap_unlock(pte, ptl); - break; - } - } - else - { - break; - } - } - else - { - break; - } - - pfn = pte_pfn(*pte); - Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK)); - pte_unmap_unlock(pte, ptl); - } - while (0); - - pageTable[i] = Address; - } - else - { - status = RGA_OUT_OF_RESOURCES; - break; - } - } - - return status; - } - #endif - - /* Fill the page table. */ - for(i=0; i<pageCount; i++) - { - /* Get the physical address from page struct. */ - pageTable[i] = page_to_phys(pages[i]); - } - - down_read(¤t->mm->mmap_sem); - for (i = 0; i < result; i++) - put_page(pages[i]); - up_read(¤t->mm->mmap_sem); - - return 0; - } - while(0); - - return status; -} - -static int rga_MapION(struct sg_table *sg, - uint32_t *Memory, - int32_t pageCount, - uint32_t offset) -{ - uint32_t i; - uint32_t status; - unsigned long Address; - uint32_t mapped_size = 0; - uint32_t len = 0; - struct scatterlist *sgl = sg->sgl; - uint32_t sg_num = 0; - - status = 0; - Address = 0; - offset = offset >> PAGE_SHIFT; - if (offset != 0) { - do { - len += (sg_dma_len(sgl) >> PAGE_SHIFT); - if (len == offset) { - sg_num += 1; - break; - } - else { - if (len > offset) - break; - } - sg_num += 1; - } - while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents)); - - sgl = sg->sgl; - len = 0; - do { - len += (sg_dma_len(sgl) >> PAGE_SHIFT); - sgl = sg_next(sgl); - } - while(--sg_num); - - offset -= len; - - len = sg_dma_len(sgl) >> PAGE_SHIFT; - Address = sg_phys(sgl); - Address += offset; - - for(i=offset; i<len; i++) { - Memory[i - offset] = Address + (i << PAGE_SHIFT); - } - mapped_size += (len - offset); - sg_num = 1; - sgl = sg_next(sgl); - do { - len = sg_dma_len(sgl) >> PAGE_SHIFT; - Address = sg_phys(sgl); - - for(i=0; i<len; i++) { - Memory[mapped_size + i] = Address + (i << PAGE_SHIFT); - } - - mapped_size += len; - sg_num += 1; - } - while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents)); - } - else { - do { - len = sg_dma_len(sgl) >> PAGE_SHIFT; - Address = sg_phys(sgl); - for(i=0; i<len; i++) { - Memory[mapped_size + i] = Address + (i << PAGE_SHIFT); - } - mapped_size += len; - sg_num += 1; - } - while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents)); - } - return 0; -} - - -static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) -{ - int SrcMemSize, DstMemSize; - unsigned long SrcStart, DstStart; - uint32_t i; - uint32_t AllSize; - uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; - int ret; - int status; - uint32_t uv_size, v_size; - - struct page **pages = NULL; - - MMU_Base = NULL; - - SrcMemSize = 0; - DstMemSize = 0; - - do { - /* cal src buf mmu info */ - SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, - req->src.format, req->src.vir_w, req->src.act_h + req->src.y_offset, - &SrcStart); - if(SrcMemSize == 0) { - return -EINVAL; - } - - /* cal dst buf mmu info */ - - DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, - req->dst.format, req->dst.vir_w, req->dst.vir_h, - &DstStart); - if(DstMemSize == 0) - return -EINVAL; - - /* Cal out the needed mem size */ - SrcMemSize = (SrcMemSize + 15) & (~15); - DstMemSize = (DstMemSize + 15) & (~15); - AllSize = SrcMemSize + DstMemSize; - - if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { - pr_err("RGA Get MMU mem failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - mutex_lock(&rga_service.lock); - MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); - MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); - mutex_unlock(&rga_service.lock); - - pages = rga_mmu_buf.pages; - - if((req->mmu_info.mmu_flag >> 8) & 1) { - if (req->sg_src) { - ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize, req->line_draw_info.flag); - } - else { - ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); - if (ret < 0) { - pr_err("rga map src memory failed\n"); - status = ret; - break; + pud_t * pud; + + pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT); + + if(pgd_val(*pgd) == 0) + { + //printk("rga pgd value is zero \n"); + break; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + /* In the four-level page table, it will do nothing and return pgd. */ + p4d = p4d_offset(pgd, (Memory + i) << PAGE_SHIFT); + if (p4d_none(*p4d) || unlikely(p4d_bad(*p4d))) { + pr_err("RGA2 failed to get p4d, result = %d, pageCount = %d\n", + result, pageCount); + status = RGA_OUT_OF_RESOURCES; + break; + } + + pud = pud_offset(p4d, (Memory + i) << PAGE_SHIFT); +#else + pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT); +#endif + if (pud) + { + pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT); + if (pmd) + { + pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl); + if (!pte) + { + pte_unmap_unlock(pte, ptl); + break; + } + } + else + { + break; + } + } + else + { + break; + } + + pfn = pte_pfn(*pte); + Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK)); + pte_unmap_unlock(pte, ptl); + } + while (0); + + pageTable[i] = Address; + } + else + { + status = RGA_OUT_OF_RESOURCES; + break; + } + } + + return status; + } + #endif + + /* Fill the page table. */ + for(i=0; i<pageCount; i++) + { + /* Get the physical address from page struct. */ + pageTable[i] = page_to_phys(pages[i]); + } + + rga_current_mm_read_lock(current->mm); + + for (i = 0; i < result; i++) + put_page(pages[i]); + + rga_current_mm_read_unlock(current->mm); + + return 0; + } + while(0); + + return status; +} + +static int rga_MapION(struct sg_table *sg, + uint32_t *Memory, + int32_t pageCount, + uint32_t offset) +{ + uint32_t i; + uint32_t status; + unsigned long Address; + uint32_t mapped_size = 0; + uint32_t len = 0; + struct scatterlist *sgl = sg->sgl; + uint32_t sg_num = 0; + + status = 0; + Address = 0; + offset = offset >> PAGE_SHIFT; + if (offset != 0) { + do { + len += (sg_dma_len(sgl) >> PAGE_SHIFT); + if (len == offset) { + sg_num += 1; + break; + } + else { + if (len > offset) + break; + } + sg_num += 1; + } + while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents)); + + sgl = sg->sgl; + len = 0; + do { + len += (sg_dma_len(sgl) >> PAGE_SHIFT); + sgl = sg_next(sgl); + } + while(--sg_num); + + offset -= len; + + len = sg_dma_len(sgl) >> PAGE_SHIFT; + Address = sg_phys(sgl); + Address += offset; + + for(i=offset; i<len; i++) { + Memory[i - offset] = Address + (i << PAGE_SHIFT); + } + mapped_size += (len - offset); + sg_num = 1; + sgl = sg_next(sgl); + do { + len = sg_dma_len(sgl) >> PAGE_SHIFT; + Address = sg_phys(sgl); + + for(i=0; i<len; i++) { + Memory[mapped_size + i] = Address + (i << PAGE_SHIFT); + } + + mapped_size += len; + sg_num += 1; + } + while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents)); + } + else { + do { + len = sg_dma_len(sgl) >> PAGE_SHIFT; + Address = sg_phys(sgl); + for(i=0; i<len; i++) { + Memory[mapped_size + i] = Address + (i << PAGE_SHIFT); + } + mapped_size += len; + sg_num += 1; + } + while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents)); + } + return 0; +} + + +static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) +{ + int SrcMemSize, DstMemSize; + unsigned long SrcStart, DstStart; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; + int ret; + int status; + uint32_t uv_size, v_size; + + struct page **pages = NULL; + + MMU_Base = NULL; + + SrcMemSize = 0; + DstMemSize = 0; + + do { + /* cal src buf mmu info */ + SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, + req->src.format, req->src.vir_w, req->src.act_h + req->src.y_offset, + &SrcStart); + if(SrcMemSize == 0) { + return -EINVAL; + } + + /* cal dst buf mmu info */ + + DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, + req->dst.format, req->dst.vir_w, req->dst.vir_h, + &DstStart); + if(DstMemSize == 0) + return -EINVAL; + + /* Cal out the needed mem size */ + SrcMemSize = (SrcMemSize + 15) & (~15); + DstMemSize = (DstMemSize + 15) & (~15); + AllSize = SrcMemSize + DstMemSize; + + if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { + pr_err("RGA Get MMU mem failed\n"); + status = RGA_MALLOC_ERROR; + break; + } + + mutex_lock(&rga_service.lock); + MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); + MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); + mutex_unlock(&rga_service.lock); + + pages = rga_mmu_buf.pages; + + if((req->mmu_info.mmu_flag >> 8) & 1) { + if (req->sg_src) { + ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize, req->line_draw_info.flag); + } + else { + ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); + if (ret < 0) { + pr_err("rga map src memory failed\n"); + status = ret; + break; } #if RGA_DEBUGFS @@ -604,692 +664,662 @@ rga_usermemory_cheeck(&pages[0], req->src.vir_w, req->src.vir_h, req->src.format, 1); #endif - } - } - else { - MMU_p = MMU_Base; - - if(req->src.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { - for(i=0; i<SrcMemSize; i++) - MMU_p[i] = rga_service.pre_scale_buf[i]; - } - else { - for(i=0; i<SrcMemSize; i++) - MMU_p[i] = (uint32_t)((SrcStart + i) << PAGE_SHIFT); - } - } - - if ((req->mmu_info.mmu_flag >> 10) & 1) { - if (req->sg_dst) { - ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width); - } - else { - ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize); - if (ret < 0) { - pr_err("rga map dst memory failed\n"); - status = ret; - break; - } + } + } + else { + MMU_p = MMU_Base; + + if(req->src.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { + for(i=0; i<SrcMemSize; i++) + MMU_p[i] = rga_service.pre_scale_buf[i]; + } + else { + for(i=0; i<SrcMemSize; i++) + MMU_p[i] = (uint32_t)((SrcStart + i) << PAGE_SHIFT); + } + } + + if ((req->mmu_info.mmu_flag >> 10) & 1) { + if (req->sg_dst) { + ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width); + } + else { + ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize); + if (ret < 0) { + pr_err("rga map dst memory failed\n"); + status = ret; + break; + } #if RGA_DEBUGFS if (RGA_CHECK_MODE) rga_usermemory_cheeck(&pages[0], req->src.vir_w, req->src.vir_h, req->src.format, 2); #endif - } - } - else { - MMU_p = MMU_Base + SrcMemSize; - for(i=0; i<DstMemSize; i++) - MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT); - } - - MMU_Base[AllSize] = MMU_Base[AllSize-1]; - - /* zsq - * change the buf address in req struct - */ - - req->mmu_info.base_addr = (unsigned long)MMU_Base_phys >> 2; - - uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; - v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; - - req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); - req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT); - req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); - - uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; - - req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT); - req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); - - /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize + 1)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - #endif - - rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); - reg->MMU_len = AllSize + 16; - - status = 0; - - return status; - } - while(0); - - return status; -} - -static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req) -{ - int SrcMemSize, DstMemSize, CMDMemSize; - unsigned long SrcStart, DstStart, CMDStart; - struct page **pages = NULL; - uint32_t i; - uint32_t AllSize; - uint32_t *MMU_Base = NULL, *MMU_Base_phys = NULL; - uint32_t *MMU_p; - int ret, status = 0; - uint32_t stride; - - uint8_t shift; - uint16_t sw, byte_num; - - shift = 3 - (req->palette_mode & 3); - sw = req->src.vir_w; - byte_num = sw >> shift; - stride = (byte_num + 3) & (~3); - - do { - SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart); - if(SrcMemSize == 0) { - return -EINVAL; - } - - DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, - req->dst.format, req->dst.vir_w, req->dst.vir_h, - &DstStart); - if(DstMemSize == 0) { - return -EINVAL; - } - - CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); - if(CMDMemSize == 0) { - return -EINVAL; - } - - SrcMemSize = (SrcMemSize + 15) & (~15); - DstMemSize = (DstMemSize + 15) & (~15); - CMDMemSize = (CMDMemSize + 15) & (~15); - - AllSize = SrcMemSize + DstMemSize + CMDMemSize; - - if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { - pr_err("RGA Get MMU mem failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - mutex_lock(&rga_service.lock); - MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); - MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); - mutex_unlock(&rga_service.lock); - - pages = rga_mmu_buf.pages; - - /* map CMD addr */ - for(i=0; i<CMDMemSize; i++) { - MMU_Base[i] = (uint32_t)virt_to_phys((uint32_t *)((CMDStart + i)<<PAGE_SHIFT)); - } - - /* map src addr */ - if (req->src.yrgb_addr < KERNEL_SPACE_VALID) { - ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); - if (ret < 0) { - pr_err("rga map src memory failed\n"); - status = ret; - break; - } - } - else { - MMU_p = MMU_Base + CMDMemSize; - - for(i=0; i<SrcMemSize; i++) - { - MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT)); - } - } - - /* map dst addr */ - if (req->src.yrgb_addr < KERNEL_SPACE_VALID) { - ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize); - if (ret < 0) { - pr_err("rga map dst memory failed\n"); - status = ret; - break; - } - } - else { - MMU_p = MMU_Base + CMDMemSize + SrcMemSize; - for(i=0; i<DstMemSize; i++) - MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT)); - } - - - /* zsq - * change the buf address in req struct - * for the reason of lie to MMU - */ - req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2); - req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); - req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT); - - /*record the malloc buf for the cmd end to release*/ - reg->MMU_base = MMU_Base; - - /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - #endif - - rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); - reg->MMU_len = AllSize + 16; - + } + } + else { + MMU_p = MMU_Base + SrcMemSize; + for(i=0; i<DstMemSize; i++) + MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT); + } + + MMU_Base[AllSize] = MMU_Base[AllSize-1]; + + /* zsq + * change the buf address in req struct + */ + + req->mmu_info.base_addr = (unsigned long)MMU_Base_phys >> 2; + + uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; + v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; + + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); + req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT); + req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); + + uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; + + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT); + req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); + + /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); + + rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); + reg->MMU_len = AllSize + 16; + + status = 0; + return status; - - } - while(0); - - return 0; -} - -static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req) -{ - int DstMemSize; - unsigned long DstStart; - struct page **pages = NULL; - uint32_t i; - uint32_t AllSize; - uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; - int ret; - int status; - - MMU_Base = NULL; - - do { - DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, - req->dst.format, req->dst.vir_w, req->dst.vir_h, - &DstStart); - if(DstMemSize == 0) { - return -EINVAL; - } - - AllSize = (DstMemSize + 15) & (~15); - - pages = rga_mmu_buf.pages; - - if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { - pr_err("RGA Get MMU mem failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - mutex_lock(&rga_service.lock); - MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); - MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); - mutex_unlock(&rga_service.lock); - - if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) { - if (req->sg_dst) { - ret = rga_MapION(req->sg_dst, &MMU_Base[0], DstMemSize, req->line_draw_info.line_width); - } - else { - ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize); - if (ret < 0) { - pr_err("rga map dst memory failed\n"); - status = ret; - break; - } - } - } - else { - MMU_p = MMU_Base; - for(i=0; i<DstMemSize; i++) - MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT); - } - - MMU_Base[AllSize] = MMU_Base[AllSize - 1]; - - /* zsq - * change the buf address in req struct - */ - - req->mmu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); - req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)); - - /*record the malloc buf for the cmd end to release*/ - reg->MMU_base = MMU_Base; - - /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - #endif - - rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); - reg->MMU_len = AllSize + 16; - - return 0; - } - while(0); - - return status; -} - - -static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req) -{ - return 0; -} - -static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req) -{ - return 0; -} - - - -static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) -{ - int SrcMemSize, DstMemSize; - unsigned long SrcStart, DstStart; - struct page **pages = NULL; - uint32_t i; - uint32_t AllSize; - uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; - int ret; - int status; - uint32_t uv_size, v_size; - - MMU_Base = NULL; - - do { - /* cal src buf mmu info */ - SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, - req->src.format, req->src.vir_w, req->src.vir_h, - &SrcStart); - if(SrcMemSize == 0) { - return -EINVAL; - } - - /* cal dst buf mmu info */ - DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, - req->dst.format, req->dst.vir_w, req->dst.vir_h, - &DstStart); - if(DstMemSize == 0) { - return -EINVAL; - } - - SrcMemSize = (SrcMemSize + 15) & (~15); - DstMemSize = (DstMemSize + 15) & (~15); - - AllSize = SrcMemSize + DstMemSize; - - pages = rga_mmu_buf.pages; - - if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { - pr_err("RGA Get MMU mem failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - mutex_lock(&rga_service.lock); - MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); - MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); - mutex_unlock(&rga_service.lock); - - /* map src pages */ - if ((req->mmu_info.mmu_flag >> 8) & 1) { - if (req->sg_src) { - ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize,req->line_draw_info.flag); - } - else { - ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); - if (ret < 0) { - pr_err("rga map src memory failed\n"); - status = ret; - break; - } - } - } - else { - MMU_p = MMU_Base; - - for(i=0; i<SrcMemSize; i++) - MMU_p[i] = (uint32_t)((SrcStart + i) << PAGE_SHIFT); - } - - if((req->mmu_info.mmu_flag >> 10) & 1) { - if (req->sg_dst) { - ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width); - } - else { - ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize); - if (ret < 0) { - pr_err("rga map dst memory failed\n"); - status = ret; - break; - } - } - } - else - { - /* kernel space */ - MMU_p = MMU_Base + SrcMemSize; - - if(req->dst.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { - for(i=0; i<DstMemSize; i++) - MMU_p[i] = rga_service.pre_scale_buf[i]; - } - else { - for(i=0; i<DstMemSize; i++) - MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT); - } - } - - MMU_Base[AllSize] = MMU_Base[AllSize]; - - /* zsq - * change the buf address in req struct - * for the reason of lie to MMU - */ - - req->mmu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); - - uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; - v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; - - req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); - req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT); - req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); - - uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; - v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; - - req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((SrcMemSize) << PAGE_SHIFT); - req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); - req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT); - - /*record the malloc buf for the cmd end to release*/ - reg->MMU_base = MMU_Base; - - /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - #endif - - rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); - reg->MMU_len = AllSize + 16; - - return 0; - } - while(0); - - return status; -} - - -static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req) -{ - int SrcMemSize, CMDMemSize; - unsigned long SrcStart, CMDStart; - struct page **pages = NULL; - uint32_t i; - uint32_t AllSize; - uint32_t *MMU_Base, *MMU_p; - int ret, status; - - MMU_Base = NULL; - - do { - /* cal src buf mmu info */ - SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart); - if(SrcMemSize == 0) { - return -EINVAL; - } - - /* cal cmd buf mmu info */ - CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); - if(CMDMemSize == 0) { - return -EINVAL; - } - - AllSize = SrcMemSize + CMDMemSize; - - pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc pages mem failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc MMU_Base point failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - for(i=0; i<CMDMemSize; i++) { - MMU_Base[i] = (uint32_t)virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT)); - } - - if (req->src.yrgb_addr < KERNEL_SPACE_VALID) - { - ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); - if (ret < 0) { - pr_err("rga map src memory failed\n"); - return -EINVAL; - } - } - else - { - MMU_p = MMU_Base + CMDMemSize; - - for(i=0; i<SrcMemSize; i++) - { - MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT)); - } - } - - /* zsq - * change the buf address in req struct - * for the reason of lie to MMU - */ - req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); - - req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); - - /*record the malloc buf for the cmd end to release*/ - reg->MMU_base = MMU_Base; - - /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); - #endif - - - if (pages != NULL) { - /* Free the page table */ - kfree(pages); - } - - return 0; - } - while(0); - - if (pages != NULL) - kfree(pages); - - if (MMU_Base != NULL) - kfree(MMU_Base); - - return status; -} - -static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req) -{ - int SrcMemSize, CMDMemSize; - unsigned long SrcStart, CMDStart; - struct page **pages = NULL; - uint32_t i; - uint32_t AllSize; - uint32_t *MMU_Base, *MMU_p; - int ret, status; - - MMU_Base = MMU_p = 0; - - do - { - - /* cal src buf mmu info */ - SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart); - if(SrcMemSize == 0) { - return -EINVAL; - } - - /* cal cmd buf mmu info */ - CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); - if(CMDMemSize == 0) { - return -EINVAL; - } - - AllSize = SrcMemSize + CMDMemSize; - - pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); - if(pages == NULL) { - pr_err("RGA MMU malloc pages mem failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); - if(MMU_Base == NULL) { - pr_err("RGA MMU malloc MMU_Base point failed\n"); - status = RGA_MALLOC_ERROR; - break; - } - - for(i=0; i<CMDMemSize; i++) { - MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT)); - } - - if (req->src.yrgb_addr < KERNEL_SPACE_VALID) - { - ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); - if (ret < 0) { - pr_err("rga map src memory failed\n"); - status = ret; - break; - } - } - else - { - MMU_p = MMU_Base + CMDMemSize; - - for(i=0; i<SrcMemSize; i++) - { - MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT)); - } - } - - /* zsq - * change the buf address in req struct - * for the reason of lie to MMU - */ - req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); - - req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); - - /*record the malloc buf for the cmd end to release*/ - reg->MMU_base = MMU_Base; - - /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); - #endif - - if (pages != NULL) { - /* Free the page table */ - kfree(pages); - } - - return 0; - - } - while(0); - - if (pages != NULL) - kfree(pages); - - if (MMU_Base != NULL) - kfree(MMU_Base); - - return status; -} - -int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req) -{ - int ret; - - switch (req->render_mode) { - case bitblt_mode : - ret = rga_mmu_info_BitBlt_mode(reg, req); - break; - case color_palette_mode : - ret = rga_mmu_info_color_palette_mode(reg, req); - break; - case color_fill_mode : - ret = rga_mmu_info_color_fill_mode(reg, req); - break; - case line_point_drawing_mode : - ret = rga_mmu_info_line_point_drawing_mode(reg, req); - break; - case blur_sharp_filter_mode : - ret = rga_mmu_info_blur_sharp_filter_mode(reg, req); - break; - case pre_scaling_mode : - ret = rga_mmu_info_pre_scale_mode(reg, req); - break; - case update_palette_table_mode : - ret = rga_mmu_info_update_palette_table_mode(reg, req); - break; - case update_patten_buff_mode : - ret = rga_mmu_info_update_patten_buff_mode(reg, req); - break; - default : - ret = -1; - break; - } - - return ret; -} - + } + while(0); + + return status; +} + +static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req) +{ + int SrcMemSize, DstMemSize, CMDMemSize; + unsigned long SrcStart, DstStart, CMDStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base = NULL, *MMU_Base_phys = NULL; + uint32_t *MMU_p; + int ret, status = 0; + uint32_t stride; + + uint8_t shift; + uint16_t sw, byte_num; + + shift = 3 - (req->palette_mode & 3); + sw = req->src.vir_w; + byte_num = sw >> shift; + stride = (byte_num + 3) & (~3); + + do { + SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart); + if(SrcMemSize == 0) { + return -EINVAL; + } + + DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, + req->dst.format, req->dst.vir_w, req->dst.vir_h, + &DstStart); + if(DstMemSize == 0) { + return -EINVAL; + } + + CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + SrcMemSize = (SrcMemSize + 15) & (~15); + DstMemSize = (DstMemSize + 15) & (~15); + CMDMemSize = (CMDMemSize + 15) & (~15); + + AllSize = SrcMemSize + DstMemSize + CMDMemSize; + + if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { + pr_err("RGA Get MMU mem failed\n"); + status = RGA_MALLOC_ERROR; + break; + } + + mutex_lock(&rga_service.lock); + MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); + MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); + mutex_unlock(&rga_service.lock); + + pages = rga_mmu_buf.pages; + + /* map CMD addr */ + for(i=0; i<CMDMemSize; i++) { + MMU_Base[i] = (uint32_t)virt_to_phys((uint32_t *)((CMDStart + i)<<PAGE_SHIFT)); + } + + /* map src addr */ + if (req->src.yrgb_addr < KERNEL_SPACE_VALID) { + ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); + if (ret < 0) { + pr_err("rga map src memory failed\n"); + status = ret; + break; + } + } + else { + MMU_p = MMU_Base + CMDMemSize; + + for(i=0; i<SrcMemSize; i++) + { + MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT)); + } + } + + /* map dst addr */ + if (req->src.yrgb_addr < KERNEL_SPACE_VALID) { + ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize); + if (ret < 0) { + pr_err("rga map dst memory failed\n"); + status = ret; + break; + } + } + else { + MMU_p = MMU_Base + CMDMemSize + SrcMemSize; + for(i=0; i<DstMemSize; i++) + MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT)); + } + + + /* zsq + * change the buf address in req struct + * for the reason of lie to MMU + */ + req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2); + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); + + rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); + reg->MMU_len = AllSize + 16; + + return status; + + } + while(0); + + return 0; +} + +static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req) +{ + int DstMemSize; + unsigned long DstStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; + int ret; + int status; + + MMU_Base = NULL; + + do { + DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, + req->dst.format, req->dst.vir_w, req->dst.vir_h, + &DstStart); + if(DstMemSize == 0) { + return -EINVAL; + } + + AllSize = (DstMemSize + 15) & (~15); + + pages = rga_mmu_buf.pages; + + if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { + pr_err("RGA Get MMU mem failed\n"); + status = RGA_MALLOC_ERROR; + break; + } + + mutex_lock(&rga_service.lock); + MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); + MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); + mutex_unlock(&rga_service.lock); + + if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) { + if (req->sg_dst) { + ret = rga_MapION(req->sg_dst, &MMU_Base[0], DstMemSize, req->line_draw_info.line_width); + } + else { + ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize); + if (ret < 0) { + pr_err("rga map dst memory failed\n"); + status = ret; + break; + } + } + } + else { + MMU_p = MMU_Base; + for(i=0; i<DstMemSize; i++) + MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT); + } + + MMU_Base[AllSize] = MMU_Base[AllSize - 1]; + + /* zsq + * change the buf address in req struct + */ + + req->mmu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); + + rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); + reg->MMU_len = AllSize + 16; + + return 0; + } + while(0); + + return status; +} + + +static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req) +{ + return 0; +} + +static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req) +{ + return 0; +} + + + +static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) +{ + int SrcMemSize, DstMemSize; + unsigned long SrcStart, DstStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; + int ret; + int status; + uint32_t uv_size, v_size; + + MMU_Base = NULL; + + do { + /* cal src buf mmu info */ + SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, + req->src.format, req->src.vir_w, req->src.vir_h, + &SrcStart); + if(SrcMemSize == 0) { + return -EINVAL; + } + + /* cal dst buf mmu info */ + DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, + req->dst.format, req->dst.vir_w, req->dst.vir_h, + &DstStart); + if(DstMemSize == 0) { + return -EINVAL; + } + + SrcMemSize = (SrcMemSize + 15) & (~15); + DstMemSize = (DstMemSize + 15) & (~15); + + AllSize = SrcMemSize + DstMemSize; + + pages = rga_mmu_buf.pages; + + if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { + pr_err("RGA Get MMU mem failed\n"); + status = RGA_MALLOC_ERROR; + break; + } + + mutex_lock(&rga_service.lock); + MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); + MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); + mutex_unlock(&rga_service.lock); + + /* map src pages */ + if ((req->mmu_info.mmu_flag >> 8) & 1) { + if (req->sg_src) { + ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize,req->line_draw_info.flag); + } + else { + ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); + if (ret < 0) { + pr_err("rga map src memory failed\n"); + status = ret; + break; + } + } + } + else { + MMU_p = MMU_Base; + + for(i=0; i<SrcMemSize; i++) + MMU_p[i] = (uint32_t)((SrcStart + i) << PAGE_SHIFT); + } + + if((req->mmu_info.mmu_flag >> 10) & 1) { + if (req->sg_dst) { + ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width); + } + else { + ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize); + if (ret < 0) { + pr_err("rga map dst memory failed\n"); + status = ret; + break; + } + } + } + else + { + /* kernel space */ + MMU_p = MMU_Base + SrcMemSize; + + if(req->dst.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { + for(i=0; i<DstMemSize; i++) + MMU_p[i] = rga_service.pre_scale_buf[i]; + } + else { + for(i=0; i<DstMemSize; i++) + MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT); + } + } + + MMU_Base[AllSize] = MMU_Base[AllSize]; + + /* zsq + * change the buf address in req struct + * for the reason of lie to MMU + */ + + req->mmu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); + + uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; + v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; + + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); + req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT); + req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); + + uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; + v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; + + req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((SrcMemSize) << PAGE_SHIFT); + req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); + req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); + + rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); + reg->MMU_len = AllSize + 16; + + return 0; + } + while(0); + + return status; +} + + +static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req) +{ + int SrcMemSize, CMDMemSize; + unsigned long SrcStart, CMDStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base, *MMU_p; + int ret, status; + + MMU_Base = NULL; + + do { + /* cal src buf mmu info */ + SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart); + if(SrcMemSize == 0) { + return -EINVAL; + } + + /* cal cmd buf mmu info */ + CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = SrcMemSize + CMDMemSize; + + pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed\n"); + status = RGA_MALLOC_ERROR; + break; + } + + MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed\n"); + status = RGA_MALLOC_ERROR; + break; + } + + for(i=0; i<CMDMemSize; i++) { + MMU_Base[i] = (uint32_t)virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT)); + } + + if (req->src.yrgb_addr < KERNEL_SPACE_VALID) + { + ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); + if (ret < 0) { + pr_err("rga map src memory failed\n"); + return -EINVAL; + } + } + else + { + MMU_p = MMU_Base + CMDMemSize; + + for(i=0; i<SrcMemSize; i++) + { + MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT)); + } + } + + /* zsq + * change the buf address in req struct + * for the reason of lie to MMU + */ + req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); + + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize)); + + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; + } + while(0); + + if (pages != NULL) + kfree(pages); + + if (MMU_Base != NULL) + kfree(MMU_Base); + + return status; +} + +static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req) +{ + int SrcMemSize, CMDMemSize; + unsigned long SrcStart, CMDStart; + struct page **pages = NULL; + uint32_t i; + uint32_t AllSize; + uint32_t *MMU_Base, *MMU_p; + int ret, status; + + MMU_Base = MMU_p = 0; + + do + { + + /* cal src buf mmu info */ + SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart); + if(SrcMemSize == 0) { + return -EINVAL; + } + + /* cal cmd buf mmu info */ + CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); + if(CMDMemSize == 0) { + return -EINVAL; + } + + AllSize = SrcMemSize + CMDMemSize; + + pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + if(pages == NULL) { + pr_err("RGA MMU malloc pages mem failed\n"); + status = RGA_MALLOC_ERROR; + break; + } + + MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + if(MMU_Base == NULL) { + pr_err("RGA MMU malloc MMU_Base point failed\n"); + status = RGA_MALLOC_ERROR; + break; + } + + for(i=0; i<CMDMemSize; i++) { + MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT)); + } + + if (req->src.yrgb_addr < KERNEL_SPACE_VALID) + { + ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); + if (ret < 0) { + pr_err("rga map src memory failed\n"); + status = ret; + break; + } + } + else + { + MMU_p = MMU_Base + CMDMemSize; + + for(i=0; i<SrcMemSize; i++) + { + MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT)); + } + } + + /* zsq + * change the buf address in req struct + * for the reason of lie to MMU + */ + req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); + + req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); + + /*record the malloc buf for the cmd end to release*/ + reg->MMU_base = MMU_Base; + + /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize)); + + if (pages != NULL) { + /* Free the page table */ + kfree(pages); + } + + return 0; + + } + while(0); + + if (pages != NULL) + kfree(pages); + + if (MMU_Base != NULL) + kfree(MMU_Base); + + return status; +} + +int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req) +{ + int ret; + + switch (req->render_mode) { + case bitblt_mode : + ret = rga_mmu_info_BitBlt_mode(reg, req); + break; + case color_palette_mode : + ret = rga_mmu_info_color_palette_mode(reg, req); + break; + case color_fill_mode : + ret = rga_mmu_info_color_fill_mode(reg, req); + break; + case line_point_drawing_mode : + ret = rga_mmu_info_line_point_drawing_mode(reg, req); + break; + case blur_sharp_filter_mode : + ret = rga_mmu_info_blur_sharp_filter_mode(reg, req); + break; + case pre_scaling_mode : + ret = rga_mmu_info_pre_scale_mode(reg, req); + break; + case update_palette_table_mode : + ret = rga_mmu_info_update_palette_table_mode(reg, req); + break; + case update_patten_buff_mode : + ret = rga_mmu_info_update_patten_buff_mode(reg, req); + break; + default : + ret = -1; + break; + } + + return ret; +} + -- Gitblit v1.6.2