From 102a0743326a03cd1a1202ceda21e175b7d3575c Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 20 Feb 2024 01:20:52 +0000 Subject: [PATCH] add new system file --- kernel/drivers/video/rockchip/rga/rga_drv.c | 1164 ++++++++++++++++++++++++++++----------------------------- 1 files changed, 572 insertions(+), 592 deletions(-) diff --git a/kernel/drivers/video/rockchip/rga/rga_drv.c b/kernel/drivers/video/rockchip/rga/rga_drv.c index 28c552d..353857f 100644 --- a/kernel/drivers/video/rockchip/rga/rga_drv.c +++ b/kernel/drivers/video/rockchip/rga/rga_drv.c @@ -1,47 +1,47 @@ -/* - * Copyright (C) 2012 ROCKCHIP, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#define pr_fmt(fmt) "rga: " fmt -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/sched.h> -#include <linux/mutex.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <asm/delay.h> -#include <linux/dma-mapping.h> -#include <linux/delay.h> -#include <asm/io.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -//#include <mach/io.h> -//#include <mach/irqs.h> -#include <linux/fs.h> -#include <linux/uaccess.h> -#include <linux/miscdevice.h> -#include <linux/poll.h> -#include <linux/delay.h> -#include <linux/wait.h> -#include <linux/syscalls.h> -#include <linux/timer.h> -#include <linux/time.h> -#include <asm/cacheflush.h> -#include <linux/slab.h> -#include <linux/fb.h> -#include <linux/wakelock.h> +/* + * Copyright (C) 2012 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#define pr_fmt(fmt) "rga: " fmt +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/sched.h> +#include <linux/mutex.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <asm/delay.h> +#include <linux/dma-mapping.h> +#include <linux/delay.h> +#include <asm/io.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +//#include <mach/io.h> +//#include <mach/irqs.h> +#include <linux/fs.h> +#include <linux/uaccess.h> +#include <linux/miscdevice.h> +#include <linux/poll.h> +#include <linux/delay.h> +#include <linux/wait.h> +#include <linux/syscalls.h> +#include <linux/timer.h> +#include <linux/time.h> +#include <asm/cacheflush.h> +#include <linux/slab.h> +#include <linux/fb.h> +#include <linux/wakelock.h> #include <linux/version.h> #include <linux/debugfs.h> #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) @@ -53,41 +53,42 @@ #include <linux/rockchip_ion.h> #endif -#include "rga.h" -#include "rga_reg_info.h" -#include "rga_mmu_info.h" -#include "RGA_API.h" - -#define RGA_TEST_CASE 0 - -#define RGA_TEST_FLUSH_TIME 0 -#define RGA_INFO_BUS_ERROR 1 - -#define PRE_SCALE_BUF_SIZE 2048*1024*4 - -#define RGA_POWER_OFF_DELAY 4*HZ /* 4s */ -#define RGA_TIMEOUT_DELAY 2*HZ /* 2s */ - -#define RGA_MAJOR 255 - -#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) -#define RK30_RGA_PHYS RK2928_RGA_PHYS -#define RK30_RGA_SIZE RK2928_RGA_SIZE -#endif -#define RGA_RESET_TIMEOUT 1000 - -/* Driver information */ -#define DRIVER_DESC "RGA Device Driver" -#define DRIVER_NAME "rga" - - -ktime_t rga_start; -ktime_t rga_end; - -rga_session rga_session_global; - -long (*rga_ioctl_kernel_p)(struct rga_req *); - +#include "rga.h" +#include "rga_reg_info.h" +#include "rga_mmu_info.h" +#include "RGA_API.h" + +#define RGA_TEST_CASE 0 + +#define RGA_TEST_FLUSH_TIME 0 +#define RGA_INFO_BUS_ERROR 1 + +#define RGA_PRE_SCALE_BUF_SIZE (2048 * 2048 * 4) +#define RGA_PRE_SCALE_PAGE_SIZE (RGA_PRE_SCALE_BUF_SIZE >> PAGE_SHIFT) + +#define RGA_POWER_OFF_DELAY 4*HZ /* 4s */ +#define RGA_TIMEOUT_DELAY 2*HZ /* 2s */ + +#define RGA_MAJOR 255 + +#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) +#define RK30_RGA_PHYS RK2928_RGA_PHYS +#define RK30_RGA_SIZE RK2928_RGA_SIZE +#endif +#define RGA_RESET_TIMEOUT 1000 + +/* Driver information */ +#define DRIVER_DESC "RGA Device Driver" +#define DRIVER_NAME "rga" + + +ktime_t rga_start; +ktime_t rga_end; + +static rga_session rga_session_global; + +long (*rga_ioctl_kernel_p)(struct rga_req *); + #if RGA_DEBUGFS unsigned char RGA_TEST_REG; unsigned char RGA_TEST_MSG; @@ -96,56 +97,36 @@ unsigned char RGA_NONUSE; unsigned char RGA_INT_FLAG; #endif - -struct rga_drvdata { - struct miscdevice miscdev; - struct device *dev; - void *rga_base; - int irq; - - struct delayed_work power_off_work; - void (*rga_irq_callback)(int rga_retval); //callback function used by aync call - struct wake_lock wake_lock; - - struct clk *pd_rga; - struct clk *aclk_rga; - struct clk *hclk_rga; - - //#if defined(CONFIG_ION_ROCKCHIP) - struct ion_client *ion_client; - //#endif - char *version; -}; - -static struct rga_drvdata *drvdata; -rga_service_info rga_service; -struct rga_mmu_buf_t rga_mmu_buf; - - -#if defined(CONFIG_ION_ROCKCHIP) -extern struct ion_client *rockchip_ion_client_create(const char * name); -#endif - -static int rga_blit_async(rga_session *session, struct rga_req *req); -static void rga_del_running_list(void); -static void rga_del_running_list_timeout(void); -static void rga_try_set_reg(void); - - -/* Logging */ -#define RGA_DEBUG 1 -#if RGA_DEBUG -#define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) -#define ERR(format, args...) printk(KERN_ERR "%s: " format, DRIVER_NAME, ## args) -#define WARNING(format, args...) printk(KERN_WARN "%s: " format, DRIVER_NAME, ## args) -#define INFO(format, args...) printk(KERN_INFO "%s: " format, DRIVER_NAME, ## args) -#else -#define DBG(format, args...) -#define ERR(format, args...) -#define WARNING(format, args...) -#define INFO(format, args...) -#endif - + +struct rga_drvdata *rga_drvdata; +rga_service_info rga_service; +struct rga_mmu_buf_t rga_mmu_buf; + + +#if defined(CONFIG_ION_ROCKCHIP) +extern struct ion_client *rockchip_ion_client_create(const char * name); +#endif + +static int rga_blit_async(rga_session *session, struct rga_req *req); +static void rga_del_running_list(void); +static void rga_del_running_list_timeout(void); +static void rga_try_set_reg(void); + + +/* Logging */ +#define RGA_DEBUG 1 +#if RGA_DEBUG +#define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#define ERR(format, args...) printk(KERN_ERR "%s: " format, DRIVER_NAME, ## args) +#define WARNING(format, args...) printk(KERN_WARN "%s: " format, DRIVER_NAME, ## args) +#define INFO(format, args...) printk(KERN_INFO "%s: " format, DRIVER_NAME, ## args) +#else +#define DBG(format, args...) +#define ERR(format, args...) +#define WARNING(format, args...) +#define INFO(format, args...) +#endif + #if RGA_DEBUGFS static const char *rga_get_cmd_mode_str(u32 cmd) { @@ -219,6 +200,7 @@ else if (req_rga->sina == -65536 && req_rga->cosa == 0) /* totate 270 */ return "rotate 270 "; + return "UNF"; case 0x2: return "xmirror"; case 0x3: @@ -427,180 +409,180 @@ } #endif -static inline void rga_write(u32 b, u32 r) -{ - __raw_writel(b, drvdata->rga_base + r); -} - -static inline u32 rga_read(u32 r) -{ - return __raw_readl(drvdata->rga_base + r); -} - -static void rga_soft_reset(void) -{ - u32 i; - u32 reg; - - rga_write(1, RGA_SYS_CTRL); //RGA_SYS_CTRL - - for(i = 0; i < RGA_RESET_TIMEOUT; i++) - { - reg = rga_read(RGA_SYS_CTRL) & 1; //RGA_SYS_CTRL - - if(reg == 0) - break; - - udelay(1); - } - - if(i == RGA_RESET_TIMEOUT) - ERR("soft reset timeout.\n"); -} - -static void rga_dump(void) -{ - int running; - struct rga_reg *reg, *reg_tmp; - rga_session *session, *session_tmp; - - running = atomic_read(&rga_service.total_running); - printk("rga total_running %d\n", running); - - #if 0 - - /* Dump waiting list info */ - if (!list_empty(&rga_service.waiting)) - { - list_head *next; - - next = &rga_service.waiting; - - printk("rga_service dump waiting list\n"); - - do - { - reg = list_entry(next->next, struct rga_reg, status_link); - running = atomic_read(®->session->task_running); - num_done = atomic_read(®->session->num_done); - printk("rga session pid %d, done %d, running %d\n", reg->session->pid, num_done, running); - next = next->next; - } - while(!list_empty(next)); - } - - /* Dump running list info */ - if (!list_empty(&rga_service.running)) - { - printk("rga_service dump running list\n"); - - list_head *next; - - next = &rga_service.running; - do - { - reg = list_entry(next->next, struct rga_reg, status_link); - running = atomic_read(®->session->task_running); - num_done = atomic_read(®->session->num_done); - printk("rga session pid %d, done %d, running %d:\n", reg->session->pid, num_done, running); - next = next->next; - } - while(!list_empty(next)); - } - #endif - - list_for_each_entry_safe(session, session_tmp, &rga_service.session, list_session) - { - printk("session pid %d:\n", session->pid); - running = atomic_read(&session->task_running); - printk("task_running %d\n", running); - list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link) - { +static inline void rga_write(u32 b, u32 r) +{ + __raw_writel(b, rga_drvdata->rga_base + r); +} + +static inline u32 rga_read(u32 r) +{ + return __raw_readl(rga_drvdata->rga_base + r); +} + +static void rga_soft_reset(void) +{ + u32 i; + u32 reg; + + rga_write(1, RGA_SYS_CTRL); //RGA_SYS_CTRL + + for(i = 0; i < RGA_RESET_TIMEOUT; i++) + { + reg = rga_read(RGA_SYS_CTRL) & 1; //RGA_SYS_CTRL + + if(reg == 0) + break; + + udelay(1); + } + + if(i == RGA_RESET_TIMEOUT) + ERR("soft reset timeout.\n"); +} + +static void rga_dump(void) +{ + int running; + struct rga_reg *reg, *reg_tmp; + rga_session *session, *session_tmp; + + running = atomic_read(&rga_service.total_running); + printk("rga total_running %d\n", running); + + #if 0 + + /* Dump waiting list info */ + if (!list_empty(&rga_service.waiting)) + { + list_head *next; + + next = &rga_service.waiting; + + printk("rga_service dump waiting list\n"); + + do + { + reg = list_entry(next->next, struct rga_reg, status_link); + running = atomic_read(®->session->task_running); + num_done = atomic_read(®->session->num_done); + printk("rga session pid %d, done %d, running %d\n", reg->session->pid, num_done, running); + next = next->next; + } + while(!list_empty(next)); + } + + /* Dump running list info */ + if (!list_empty(&rga_service.running)) + { + printk("rga_service dump running list\n"); + + list_head *next; + + next = &rga_service.running; + do + { + reg = list_entry(next->next, struct rga_reg, status_link); + running = atomic_read(®->session->task_running); + num_done = atomic_read(®->session->num_done); + printk("rga session pid %d, done %d, running %d:\n", reg->session->pid, num_done, running); + next = next->next; + } + while(!list_empty(next)); + } + #endif + + list_for_each_entry_safe(session, session_tmp, &rga_service.session, list_session) + { + printk("session pid %d:\n", session->pid); + running = atomic_read(&session->task_running); + printk("task_running %d\n", running); + list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link) + { printk("waiting register set 0x %.lu\n", (unsigned long)reg); - } - list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link) - { + } + list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link) + { printk("running register set 0x %.lu\n", (unsigned long)reg); - } - } -} - -static inline void rga_queue_power_off_work(void) -{ + } + } +} + +static inline void rga_queue_power_off_work(void) +{ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - queue_delayed_work(system_wq, &drvdata->power_off_work, RGA_POWER_OFF_DELAY); + queue_delayed_work(system_wq, &rga_drvdata->power_off_work, RGA_POWER_OFF_DELAY); #else - queue_delayed_work(system_nrt_wq, &drvdata->power_off_work, RGA_POWER_OFF_DELAY); + queue_delayed_work(system_nrt_wq, &rga_drvdata->power_off_work, RGA_POWER_OFF_DELAY); #endif -} - -/* Caller must hold rga_service.lock */ -static void rga_power_on(void) -{ - static ktime_t last; - ktime_t now = ktime_get(); - - if (ktime_to_ns(ktime_sub(now, last)) > NSEC_PER_SEC) { - cancel_delayed_work_sync(&drvdata->power_off_work); - rga_queue_power_off_work(); - last = now; - } - if (rga_service.enable) - return; - +} + +/* Caller must hold rga_service.lock */ +static void rga_power_on(void) +{ + static ktime_t last; + ktime_t now = ktime_get(); + + if (ktime_to_ns(ktime_sub(now, last)) > NSEC_PER_SEC) { + cancel_delayed_work_sync(&rga_drvdata->power_off_work); + rga_queue_power_off_work(); + last = now; + } + if (rga_service.enable) + return; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - clk_prepare_enable(drvdata->aclk_rga); - clk_prepare_enable(drvdata->hclk_rga); - pm_runtime_get_sync(drvdata->dev); + clk_prepare_enable(rga_drvdata->aclk_rga); + clk_prepare_enable(rga_drvdata->hclk_rga); + pm_runtime_get_sync(rga_drvdata->dev); #else - clk_prepare_enable(drvdata->aclk_rga); - clk_prepare_enable(drvdata->hclk_rga); - if (drvdata->pd_rga) - clk_prepare_enable(drvdata->pd_rga); + clk_prepare_enable(rga_drvdata->aclk_rga); + clk_prepare_enable(rga_drvdata->hclk_rga); + if (rga_drvdata->pd_rga) + clk_prepare_enable(rga_drvdata->pd_rga); #endif - wake_lock(&drvdata->wake_lock); - rga_service.enable = true; -} + wake_lock(&rga_drvdata->wake_lock); + rga_service.enable = true; +} -/* Caller must hold rga_service.lock */ -static void rga_power_off(void) -{ - int total_running; - - if (!rga_service.enable) { - return; - } - - total_running = atomic_read(&rga_service.total_running); - if (total_running) { - pr_err("power off when %d task running!!\n", total_running); - mdelay(50); - pr_err("delay 50 ms for running task\n"); - rga_dump(); - } - +/* Caller must hold rga_service.lock */ +static void rga_power_off(void) +{ + int total_running; + + if (!rga_service.enable) { + return; + } + + total_running = atomic_read(&rga_service.total_running); + if (total_running) { + pr_err("power off when %d task running!!\n", total_running); + mdelay(50); + pr_err("delay 50 ms for running task\n"); + rga_dump(); + } + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - pm_runtime_put(drvdata->dev); - clk_disable_unprepare(drvdata->aclk_rga); - clk_disable_unprepare(drvdata->hclk_rga); + pm_runtime_put(rga_drvdata->dev); + clk_disable_unprepare(rga_drvdata->aclk_rga); + clk_disable_unprepare(rga_drvdata->hclk_rga); #else - if (drvdata->pd_rga) - clk_disable_unprepare(drvdata->pd_rga); - clk_disable_unprepare(drvdata->aclk_rga); - clk_disable_unprepare(drvdata->hclk_rga); + if (rga_drvdata->pd_rga) + clk_disable_unprepare(rga_drvdata->pd_rga); + clk_disable_unprepare(rga_drvdata->aclk_rga); + clk_disable_unprepare(rga_drvdata->hclk_rga); #endif - wake_unlock(&drvdata->wake_lock); - rga_service.enable = false; -} - -static void rga_power_off_work(struct work_struct *work) -{ - if (mutex_trylock(&rga_service.lock)) { - rga_power_off(); - mutex_unlock(&rga_service.lock); - } else { - /* Come back later if the device is busy... */ + wake_unlock(&rga_drvdata->wake_lock); + rga_service.enable = false; +} + +static void rga_power_off_work(struct work_struct *work) +{ + if (mutex_trylock(&rga_service.lock)) { + rga_power_off(); + mutex_unlock(&rga_service.lock); + } else { + /* Come back later if the device is busy... */ rga_queue_power_off_work(); } @@ -647,7 +629,7 @@ static int rga_get_result(rga_session *session, unsigned long arg) { - //printk("rga_get_result %d\n",drvdata->rga_result); + //printk("rga_get_result %d\n",rga_drvdata->rga_result); int ret = 0; @@ -734,7 +716,7 @@ cmd_buf = (uint32_t *)rga_service.cmd_buff + offset*32; reg_p = (uint32_t *)reg->cmd_reg; - for(i=0; i<32; i++) + for(i=0; i<32; i++) cmd_buf[i] = reg_p[i]; } @@ -842,12 +824,7 @@ rga_copy_reg(reg, 0); rga_reg_from_wait_to_run(reg); - #ifdef CONFIG_ARM - dmac_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[32]); - outer_flush_range(virt_to_phys(&rga_service.cmd_buff[0]),virt_to_phys(&rga_service.cmd_buff[32])); - #elif defined(CONFIG_ARM64) - __dma_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[32]); - #endif + rga_dma_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[32]); rga_soft_reset(); @@ -874,10 +851,10 @@ rga_write((0x1<<2)|(0x1<<3), RGA_SYS_CTRL); /* All CMD finish int */ - rga_write(rga_read(RGA_INT)|(0x1<<10)|(0x1<<8), RGA_INT); + rga_write(rga_read(RGA_INT)|(0x1<<10)|(0x1<<9)|(0x1<<8), RGA_INT); #if RGA_DEBUGFS - if (RGA_TEST_REG) + if (RGA_TEST_TIME) rga_start = ktime_get(); #endif @@ -1034,7 +1011,7 @@ dst_offset = req->line_draw_info.line_width; if (req->src.yrgb_addr) { - hdl = ion_import_dma_buf(drvdata->ion_client, req->src.yrgb_addr); + hdl = ion_import_dma_buf(rga_drvdata->ion_client, req->src.yrgb_addr); if (IS_ERR(hdl)) { ret = PTR_ERR(hdl); pr_err("RGA ERROR ion buf handle\n"); @@ -1049,26 +1026,26 @@ #if RGA_DEBUGFS if (RGA_CHECK_MODE) { - vaddr = ion_map_kernel(drvdata->ion_client, hdl); + vaddr = ion_map_kernel(rga_drvdata->ion_client, hdl); if (vaddr) rga_memory_check(vaddr, req->src.vir_h, req->src.vir_w, req->src.format, req->src.yrgb_addr); - ion_unmap_kernel(drvdata->ion_client, hdl); + ion_unmap_kernel(rga_drvdata->ion_client, hdl); } #endif if ((req->mmu_info.mmu_flag >> 8) & 1) { - req->sg_src = ion_sg_table(drvdata->ion_client, hdl); + req->sg_src = ion_sg_table(rga_drvdata->ion_client, hdl); req->src.yrgb_addr = req->src.uv_addr; req->src.uv_addr = req->src.yrgb_addr + (req->src.vir_w * req->src.vir_h); req->src.v_addr = req->src.uv_addr + (req->src.vir_w * req->src.vir_h)/4; } else { - ion_phys(drvdata->ion_client, hdl, &phy_addr, &len); + ion_phys(rga_drvdata->ion_client, hdl, &phy_addr, &len); req->src.yrgb_addr = phy_addr + src_offset; req->src.uv_addr = req->src.yrgb_addr + (req->src.vir_w * req->src.vir_h); req->src.v_addr = req->src.uv_addr + (req->src.vir_w * req->src.vir_h)/4; } - ion_free(drvdata->ion_client, hdl); + ion_free(rga_drvdata->ion_client, hdl); } else { req->src.yrgb_addr = req->src.uv_addr; @@ -1077,7 +1054,7 @@ } if(req->dst.yrgb_addr) { - hdl = ion_import_dma_buf(drvdata->ion_client, req->dst.yrgb_addr); + hdl = ion_import_dma_buf(rga_drvdata->ion_client, req->dst.yrgb_addr); if (IS_ERR(hdl)) { ret = PTR_ERR(hdl); printk("RGA2 ERROR ion buf handle\n"); @@ -1092,26 +1069,26 @@ #if RGA_DEBUGFS if (RGA_CHECK_MODE) { - vaddr = ion_map_kernel(drvdata->ion_client, hdl); + vaddr = ion_map_kernel(rga_drvdata->ion_client, hdl); if (vaddr) rga_memory_check(vaddr, req->src.vir_h, req->src.vir_w, req->src.format, req->src.yrgb_addr); - ion_unmap_kernel(drvdata->ion_client, hdl); + ion_unmap_kernel(rga_drvdata->ion_client, hdl); } #endif if ((req->mmu_info.mmu_flag >> 10) & 1) { - req->sg_dst = ion_sg_table(drvdata->ion_client, hdl); + req->sg_dst = ion_sg_table(rga_drvdata->ion_client, hdl); req->dst.yrgb_addr = req->dst.uv_addr; req->dst.uv_addr = req->dst.yrgb_addr + (req->dst.vir_w * req->dst.vir_h); req->dst.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h)/4; } else { - ion_phys(drvdata->ion_client, hdl, &phy_addr, &len); + ion_phys(rga_drvdata->ion_client, hdl, &phy_addr, &len); req->dst.yrgb_addr = phy_addr + dst_offset; req->dst.uv_addr = req->dst.yrgb_addr + (req->dst.vir_w * req->dst.vir_h); req->dst.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h)/4; } - ion_free(drvdata->ion_client, hdl); + ion_free(rga_drvdata->ion_client, hdl); } else { req->dst.yrgb_addr = req->dst.uv_addr; @@ -1138,7 +1115,7 @@ int ret = 0; void *vaddr = NULL; - rga_dev = drvdata->dev; + rga_dev = rga_drvdata->dev; yrgb_addr = (int)img->yrgb_addr; vir_w = img->vir_w; vir_h = img->vir_h; @@ -1590,7 +1567,7 @@ if (RGA_TEST_TIME) { rga_end = ktime_get(); rga_end = ktime_sub(rga_end, rga_start); - DBG("sync one cmd end time %d\n", (int)ktime_to_us(rga_end)); + DBG("sync one cmd end time %d us\n", (int)ktime_to_us(rga_end)); } #endif @@ -1618,7 +1595,7 @@ memset(&req, 0x0, sizeof(req)); #if RGA_DEBUGFS if (RGA_TEST_MSG) - DBG("cmd is %s\n", rga_get_cmd_mode_str(cmd)); + DBG("cmd is %s(0x%x)\n", rga_get_cmd_mode_str(cmd), cmd); if (RGA_NONUSE) { mutex_unlock(&rga_service.mutex); return 0; @@ -1658,24 +1635,23 @@ ret = rga_get_result(session, arg); break; case RGA_GET_VERSION: - if (!drvdata->version) { - drvdata->version = kzalloc(16, GFP_KERNEL); - if (!drvdata->version) { + if (!rga_drvdata->version) { + rga_drvdata->version = kzalloc(16, GFP_KERNEL); + if (!rga_drvdata->version) { ret = -ENOMEM; break; } rga_power_on(); udelay(1); if (rga_read(RGA_VERSION) == 0x02018632) - snprintf(drvdata->version, 16, "1.6"); + snprintf(rga_drvdata->version, 16, "1.6"); else - snprintf(drvdata->version, 16, "1.003"); + snprintf(rga_drvdata->version, 16, "1.003"); } - ret = copy_to_user((void *)arg, drvdata->version, 16); + ret = copy_to_user((void *)arg, rga_drvdata->version, 16); break; default: - ERR("unknown ioctl cmd!\n"); ret = -EINVAL; break; } @@ -1764,7 +1740,6 @@ { pr_err("rga_service session %d still has %d task running when closing\n", session->pid, task_running); msleep(100); - /*ͬ��*/ } wake_up(&session->wait); @@ -1801,12 +1776,12 @@ DBG("irq INT[%x], STATS[%x]\n", rga_read(RGA_INT), rga_read(RGA_STATUS)); #endif /*if error interrupt then soft reset hardware*/ - if (rga_read(RGA_INT) & 0x01) { + if (rga_read(RGA_INT) & 0x03) { pr_err("Err irq INT[%x], STATS[%x]\n", rga_read(RGA_INT), rga_read(RGA_STATUS)); rga_soft_reset(); } /*clear INT */ - rga_write(rga_read(RGA_INT) | (0x1<<6) | (0x1<<7) | (0x1<<4), RGA_INT); + rga_write(rga_read(RGA_INT) | (0x1<<6) | (0x1<<7) | (0x1<<5) | (0x1<<4), RGA_INT); return IRQ_WAKE_THREAD; } @@ -1892,7 +1867,7 @@ platform_set_drvdata(pdev, data); data->dev = &pdev->dev; - drvdata = data; + rga_drvdata = data; #if defined(CONFIG_ION_ROCKCHIP) data->ion_client = rockchip_ion_client_create("rga"); @@ -2094,7 +2069,7 @@ unsigned int *pstd; unsigned int *pnow; - data = drvdata; + data = rga_drvdata; srcW = 1280; srcH = 720; dstW = 1280; @@ -2235,15 +2210,7 @@ memset(src1_buf, 0x50, 400 * 200 * 4); memset(dst1_buf, 0x00, 400 * 200 * 4); -#ifdef CONFIG_ARM - dmac_flush_range(&src1_buf[0], &src1_buf[400 * 200]); - outer_flush_range(virt_to_phys(&src1_buf[0]), virt_to_phys(&src1_buf[400 * 200])); - dmac_flush_range(&dst1_buf[0], &dst1_buf[400 * 200]); - outer_flush_range(virt_to_phys(&dst1_buf[0]), virt_to_phys(&dst1_buf[400 * 200])); -#elif defined(CONFIG_ARM64) - __dma_flush_range(&src1_buf[0], &src1_buf[400 * 200]); - __dma_flush_range(&dst1_buf[0], &dst1_buf[400 * 200]); -#endif + rga_dma_flush_range(&src1_buf[0], &src1_buf[400 * 200]); DBG("\n********************************\n"); DBG("************ RGA_TEST ************\n"); @@ -2304,279 +2271,292 @@ } #endif #endif - -void rga_test_0(void); -void rga_test_1(void); - -static int __init rga_init(void) -{ - int ret; - uint32_t *mmu_buf; - unsigned long *mmu_buf_virtual; - uint32_t i; - uint32_t *buf_p; - uint32_t *buf; - /* malloc pre scale mid buf mmu table */ - mmu_buf = kzalloc(1024*8, GFP_KERNEL); - mmu_buf_virtual = kzalloc(1024*2*sizeof(unsigned long), GFP_KERNEL); - if(mmu_buf == NULL) { - printk(KERN_ERR "RGA get Pre Scale buff failed. \n"); - return -1; - } - if (mmu_buf_virtual == NULL) { - return -1; - } - - /* malloc 4 M buf */ - for(i=0; i<1024; i++) { - buf_p = (uint32_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO); - if(buf_p == NULL) { - printk(KERN_ERR "RGA init pre scale buf falied\n"); - return -ENOMEM; - } - mmu_buf[i] = virt_to_phys((void *)((unsigned long)buf_p)); - mmu_buf_virtual[i] = (unsigned long)buf_p; - } - - rga_service.pre_scale_buf = (uint32_t *)mmu_buf; - rga_service.pre_scale_buf_virtual = (unsigned long *)mmu_buf_virtual; - - buf_p = kmalloc(1024*256, GFP_KERNEL); - rga_mmu_buf.buf_virtual = buf_p; +void rga_test_0(void); +void rga_test_1(void); + +static int __init rga_init(void) +{ + int i, ret; + void * pre_scale_page_buf; + uint32_t *pre_scale_page_table; + uint32_t *mmu_base; + struct page **pages; + + /* malloc pre scale mid buf mmu table */ + pre_scale_page_table = kzalloc(RGA_PRE_SCALE_PAGE_SIZE * sizeof(*pre_scale_page_table), + GFP_KERNEL); + if(pre_scale_page_table == NULL) { + pr_err("RGA alloc pre-scale page table failed.\n"); + return -ENOMEM; + } + + /* alloc reserved pre-scale buf */ + for(i = 0; i < RGA_PRE_SCALE_PAGE_SIZE; i++) { + pre_scale_page_buf = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); + if(pre_scale_page_buf == NULL) { + printk(KERN_ERR "RGA init pre scale page_table[%d] falied\n", i); + ret = -ENOMEM; + goto free_pre_scale_page_table; + } + pre_scale_page_table[i] = (uint32_t)virt_to_phys(pre_scale_page_buf); + } + + mmu_base = kmalloc(1024 * 256, GFP_KERNEL); + if (mmu_base == NULL) { + pr_err("RGA alloc mmu buffer failed.\n"); + ret = -ENOMEM; + goto free_pre_scale_page_table; + } + + pages = kmalloc((32768)* sizeof(struct page *), GFP_KERNEL); + if (pages == NULL) { + pr_err("RGA alloc pages buffer failed.\n"); + ret = -ENOMEM; + goto free_mmu_base; + } + + ret = platform_driver_register(&rga_driver); + if (ret != 0) { + printk(KERN_ERR "Platform device register failed (%d).\n", ret); + goto free_pages_buf; + } + + rga_service.pre_scale_buf = pre_scale_page_table; + + rga_mmu_buf.buf_virtual = mmu_base; #if (defined(CONFIG_ARM) && defined(CONFIG_ARM_LPAE)) - buf = (uint32_t *)(uint32_t)virt_to_phys((void *)((unsigned long)buf_p)); + rga_mmu_buf.buf = (uint32_t *)(uint32_t)virt_to_phys((void *)((unsigned long)mmu_base)); #else - buf = (uint32_t *)virt_to_phys((void *)((unsigned long)buf_p)); + rga_mmu_buf.buf = (uint32_t *)virt_to_phys((void *)((unsigned long)mmu_base)); #endif - rga_mmu_buf.buf = buf; - rga_mmu_buf.front = 0; - rga_mmu_buf.back = 64*1024; - rga_mmu_buf.size = 64*1024; - - rga_mmu_buf.pages = kmalloc((32768)* sizeof(struct page *), GFP_KERNEL); - - if ((ret = platform_driver_register(&rga_driver)) != 0) - { - printk(KERN_ERR "Platform device register failed (%d).\n", ret); - return ret; - } - - { - rga_session_global.pid = 0x0000ffff; - INIT_LIST_HEAD(&rga_session_global.waiting); - INIT_LIST_HEAD(&rga_session_global.running); - INIT_LIST_HEAD(&rga_session_global.list_session); - - INIT_LIST_HEAD(&rga_service.waiting); - INIT_LIST_HEAD(&rga_service.running); - INIT_LIST_HEAD(&rga_service.done); - INIT_LIST_HEAD(&rga_service.session); - - init_waitqueue_head(&rga_session_global.wait); - //mutex_lock(&rga_service.lock); - list_add_tail(&rga_session_global.list_session, &rga_service.session); - //mutex_unlock(&rga_service.lock); - atomic_set(&rga_session_global.task_running, 0); - atomic_set(&rga_session_global.num_done, 0); - } - - #if RGA_TEST_CASE + rga_mmu_buf.front = 0; + rga_mmu_buf.back = 64*1024; + rga_mmu_buf.size = 64*1024; + + rga_mmu_buf.pages = pages; + + rga_session_global.pid = 0x0000ffff; + INIT_LIST_HEAD(&rga_session_global.waiting); + INIT_LIST_HEAD(&rga_session_global.running); + INIT_LIST_HEAD(&rga_session_global.list_session); + + INIT_LIST_HEAD(&rga_service.waiting); + INIT_LIST_HEAD(&rga_service.running); + INIT_LIST_HEAD(&rga_service.done); + INIT_LIST_HEAD(&rga_service.session); + + init_waitqueue_head(&rga_session_global.wait); + //mutex_lock(&rga_service.lock); + list_add_tail(&rga_session_global.list_session, &rga_service.session); + //mutex_unlock(&rga_service.lock); + atomic_set(&rga_session_global.task_running, 0); + atomic_set(&rga_session_global.num_done, 0); + +#if RGA_TEST_CASE rga_test_0(); #endif #if RGA_DEBUGFS rga_debugfs_add(); #endif - - INFO("Module initialized.\n"); - - return 0; -} - -static void __exit rga_exit(void) -{ - uint32_t i; - - rga_power_off(); - - for(i=0; i<1024; i++) - { - if((unsigned long)rga_service.pre_scale_buf_virtual[i]) - { - __free_page((void *)rga_service.pre_scale_buf_virtual[i]); - } - } - - if(rga_service.pre_scale_buf != NULL) { - kfree((uint8_t *)rga_service.pre_scale_buf); - } - - kfree(rga_mmu_buf.buf_virtual); + INFO("RGA Module initialized.\n"); + + return 0; + +free_pages_buf: + kfree(pages); + +free_mmu_base: + kfree(mmu_base); + +free_pre_scale_page_table: + for (i = 0; i < RGA_PRE_SCALE_PAGE_SIZE; i++) + if (pre_scale_page_table[i] != 0) + kfree(phys_to_virt((phys_addr_t)pre_scale_page_table[i])); + + kfree(pre_scale_page_table); + + return ret; +} + +static void __exit rga_exit(void) +{ + phys_addr_t pre_scale_buf; + + rga_power_off(); + + if (rga_service.pre_scale_buf != NULL) { + pre_scale_buf = (phys_addr_t)rga_service.pre_scale_buf[0]; + if (pre_scale_buf) + kfree(phys_to_virt(pre_scale_buf)); + kfree(rga_service.pre_scale_buf); + } + kfree(rga_mmu_buf.buf_virtual); kfree(rga_mmu_buf.pages); - platform_driver_unregister(&rga_driver); -} + platform_driver_unregister(&rga_driver); +} #if RGA_TEST_CASE -extern struct fb_info * rk_get_fb(int fb_id); -EXPORT_SYMBOL(rk_get_fb); - -extern void rk_direct_fb_show(struct fb_info * fbi); -EXPORT_SYMBOL(rk_direct_fb_show); - -unsigned int src_buf[1920*1080]; -unsigned int dst_buf[1920*1080]; -//unsigned int tmp_buf[1920*1080 * 2]; - -void rga_test_0(void) -{ - struct rga_req req; - rga_session session; - unsigned int *src, *dst; - uint32_t i, j; - uint8_t *p; - uint8_t t; - uint32_t *dst0, *dst1, *dst2; - - struct fb_info *fb; - - session.pid = current->pid; - INIT_LIST_HEAD(&session.waiting); - INIT_LIST_HEAD(&session.running); - INIT_LIST_HEAD(&session.list_session); - init_waitqueue_head(&session.wait); - /* no need to protect */ - list_add_tail(&session.list_session, &rga_service.session); - atomic_set(&session.task_running, 0); - atomic_set(&session.num_done, 0); - //file->private_data = (void *)session; - - fb = rk_get_fb(0); - - memset(&req, 0, sizeof(struct rga_req)); - src = src_buf; - dst = dst_buf; - - memset(src_buf, 0x80, 1024*600*4); - - dmac_flush_range(&src_buf[0], &src_buf[1024*600]); - outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[1024*600])); - - - #if 0 - memset(src_buf, 0x80, 800*480*4); - memset(dst_buf, 0xcc, 800*480*4); - - dmac_flush_range(&dst_buf[0], &dst_buf[800*480]); - outer_flush_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[800*480])); - #endif - - dst0 = &dst_buf[0]; - //dst1 = &dst_buf[1280*800*4]; - //dst2 = &dst_buf[1280*800*4*2]; - - i = j = 0; - - printk("\n********************************\n"); - printk("************ RGA_TEST ************\n"); - printk("********************************\n\n"); - - req.src.act_w = 1024; - req.src.act_h = 600; - - req.src.vir_w = 1024; - req.src.vir_h = 600; - req.src.yrgb_addr = (uint32_t)virt_to_phys(src); - req.src.uv_addr = (uint32_t)(req.src.yrgb_addr + 1080*1920); - req.src.v_addr = (uint32_t)virt_to_phys(src); - req.src.format = RK_FORMAT_RGBA_8888; - - req.dst.act_w = 600; - req.dst.act_h = 352; - - req.dst.vir_w = 1280; - req.dst.vir_h = 800; - req.dst.x_offset = 600; - req.dst.y_offset = 0; - - dst = dst0; - - req.dst.yrgb_addr = ((uint32_t)virt_to_phys(dst)); - - //req.dst.format = RK_FORMAT_RGB_565; - - req.clip.xmin = 0; - req.clip.xmax = 1279; - req.clip.ymin = 0; - req.clip.ymax = 799; - - //req.render_mode = color_fill_mode; - //req.fg_color = 0x80ffffff; - - req.rotate_mode = 1; - //req.scale_mode = 2; - - //req.alpha_rop_flag = 0; - //req.alpha_rop_mode = 0x19; - //req.PD_mode = 3; - - req.sina = 65536; - req.cosa = 0; - - //req.mmu_info.mmu_flag = 0x21; - //req.mmu_info.mmu_en = 1; - - //printk("src = %.8x\n", req.src.yrgb_addr); - //printk("src = %.8x\n", req.src.uv_addr); - //printk("dst = %.8x\n", req.dst.yrgb_addr); - - - rga_blit_sync(&session, &req); - - #if 1 - fb->var.bits_per_pixel = 32; - - fb->var.xres = 1280; - fb->var.yres = 800; - - fb->var.red.length = 8; - fb->var.red.offset = 0; - fb->var.red.msb_right = 0; - - fb->var.green.length = 8; - fb->var.green.offset = 8; - fb->var.green.msb_right = 0; - - fb->var.blue.length = 8; - - fb->var.blue.offset = 16; - fb->var.blue.msb_right = 0; - - fb->var.transp.length = 8; - fb->var.transp.offset = 24; - fb->var.transp.msb_right = 0; - - fb->var.nonstd &= (~0xff); - fb->var.nonstd |= 1; - - fb->fix.smem_start = virt_to_phys(dst); - - rk_direct_fb_show(fb); - #endif - -} - -#endif +extern struct fb_info * rk_get_fb(int fb_id); +EXPORT_SYMBOL(rk_get_fb); + +extern void rk_direct_fb_show(struct fb_info * fbi); +EXPORT_SYMBOL(rk_direct_fb_show); + +unsigned int src_buf[1920*1080]; +unsigned int dst_buf[1920*1080]; +//unsigned int tmp_buf[1920*1080 * 2]; + +void rga_test_0(void) +{ + struct rga_req req; + rga_session session; + unsigned int *src, *dst; + uint32_t i, j; + uint8_t *p; + uint8_t t; + uint32_t *dst0, *dst1, *dst2; + + struct fb_info *fb; + + session.pid = current->pid; + INIT_LIST_HEAD(&session.waiting); + INIT_LIST_HEAD(&session.running); + INIT_LIST_HEAD(&session.list_session); + init_waitqueue_head(&session.wait); + /* no need to protect */ + list_add_tail(&session.list_session, &rga_service.session); + atomic_set(&session.task_running, 0); + atomic_set(&session.num_done, 0); + //file->private_data = (void *)session; + + fb = rk_get_fb(0); + + memset(&req, 0, sizeof(struct rga_req)); + src = src_buf; + dst = dst_buf; + + memset(src_buf, 0x80, 1024*600*4); + + dmac_flush_range(&src_buf[0], &src_buf[1024*600]); + outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[1024*600])); + + + #if 0 + memset(src_buf, 0x80, 800*480*4); + memset(dst_buf, 0xcc, 800*480*4); + + dmac_flush_range(&dst_buf[0], &dst_buf[800*480]); + outer_flush_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[800*480])); + #endif + + dst0 = &dst_buf[0]; + //dst1 = &dst_buf[1280*800*4]; + //dst2 = &dst_buf[1280*800*4*2]; + + i = j = 0; + + printk("\n********************************\n"); + printk("************ RGA_TEST ************\n"); + printk("********************************\n\n"); + + req.src.act_w = 1024; + req.src.act_h = 600; + + req.src.vir_w = 1024; + req.src.vir_h = 600; + req.src.yrgb_addr = (uint32_t)virt_to_phys(src); + req.src.uv_addr = (uint32_t)(req.src.yrgb_addr + 1080*1920); + req.src.v_addr = (uint32_t)virt_to_phys(src); + req.src.format = RK_FORMAT_RGBA_8888; + + req.dst.act_w = 600; + req.dst.act_h = 352; + + req.dst.vir_w = 1280; + req.dst.vir_h = 800; + req.dst.x_offset = 600; + req.dst.y_offset = 0; + + dst = dst0; + + req.dst.yrgb_addr = ((uint32_t)virt_to_phys(dst)); + + //req.dst.format = RK_FORMAT_RGB_565; + + req.clip.xmin = 0; + req.clip.xmax = 1279; + req.clip.ymin = 0; + req.clip.ymax = 799; + + //req.render_mode = color_fill_mode; + //req.fg_color = 0x80ffffff; + + req.rotate_mode = 1; + //req.scale_mode = 2; + + //req.alpha_rop_flag = 0; + //req.alpha_rop_mode = 0x19; + //req.PD_mode = 3; + + req.sina = 65536; + req.cosa = 0; + + //req.mmu_info.mmu_flag = 0x21; + //req.mmu_info.mmu_en = 1; + + //printk("src = %.8x\n", req.src.yrgb_addr); + //printk("src = %.8x\n", req.src.uv_addr); + //printk("dst = %.8x\n", req.dst.yrgb_addr); + + + rga_blit_sync(&session, &req); + + #if 1 + fb->var.bits_per_pixel = 32; + + fb->var.xres = 1280; + fb->var.yres = 800; + + fb->var.red.length = 8; + fb->var.red.offset = 0; + fb->var.red.msb_right = 0; + + fb->var.green.length = 8; + fb->var.green.offset = 8; + fb->var.green.msb_right = 0; + + fb->var.blue.length = 8; + + fb->var.blue.offset = 16; + fb->var.blue.msb_right = 0; + + fb->var.transp.length = 8; + fb->var.transp.offset = 24; + fb->var.transp.msb_right = 0; + + fb->var.nonstd &= (~0xff); + fb->var.nonstd |= 1; + + fb->fix.smem_start = virt_to_phys(dst); + + rk_direct_fb_show(fb); + #endif + +} + +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)) fs_initcall(rga_init); #else module_init(rga_init); #endif -module_exit(rga_exit); - -/* Module information */ -MODULE_AUTHOR("zsq@rock-chips.com"); -MODULE_DESCRIPTION("Driver for rga device"); -MODULE_LICENSE("GPL"); +module_exit(rga_exit); + +/* Module information */ +MODULE_AUTHOR("zsq@rock-chips.com"); +MODULE_DESCRIPTION("Driver for rga device"); +MODULE_LICENSE("GPL"); -- Gitblit v1.6.2