From 2be1c5ce624dc0d46055cc61ba5f57168e3de7b9 Mon Sep 17 00:00:00 2001 From: Li Huang Date: Thu, 31 Mar 2022 14:21:25 +0800 Subject: [PATCH] video: rockchip: rga3: code optimization 1. rename rga_scheduler to scheduler 2. sort rga_internal_ctx_* func Signed-off-by: Li Huang Change-Id: I1a5fd7f1b8b400728ac00c55b684d401ad269dc1 --- drivers/video/rockchip/rga3/include/rga_drv.h | 14 +- drivers/video/rockchip/rga3/include/rga_job.h | 11 +- drivers/video/rockchip/rga3/rga2_reg_info.c | 6 +- drivers/video/rockchip/rga3/rga_debugger.c | 20 +- drivers/video/rockchip/rga3/rga_drv.c | 204 ++--- drivers/video/rockchip/rga3/rga_job.c | 751 +++++++++--------- drivers/video/rockchip/rga3/rga_mm.c | 42 +- drivers/video/rockchip/rga3/rga_policy.c | 6 +- 8 files changed, 527 insertions(+), 527 deletions(-) diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index 5c35553ad1fd..e314fa15ac3b 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -373,7 +373,7 @@ struct rga_drvdata_t { /* used by rga2's mmu lock */ struct mutex lock; - struct rga_scheduler_t *rga_scheduler[RGA_MAX_SCHEDULER]; + struct rga_scheduler_t *scheduler[RGA_MAX_SCHEDULER]; int num_of_scheduler; struct delayed_work power_off_work; @@ -405,18 +405,18 @@ struct rga_match_data_t { int num_irqs; }; -static inline int rga_read(int offset, struct rga_scheduler_t *rga_scheduler) +static inline int rga_read(int offset, struct rga_scheduler_t *scheduler) { - return readl(rga_scheduler->rga_base + offset); + return readl(scheduler->rga_base + offset); } -static inline void rga_write(int value, int offset, struct rga_scheduler_t *rga_scheduler) +static inline void rga_write(int value, int offset, struct rga_scheduler_t *scheduler) { - writel(value, rga_scheduler->rga_base + offset); + writel(value, scheduler->rga_base + offset); } -int rga_power_enable(struct rga_scheduler_t *rga_scheduler); -int rga_power_disable(struct rga_scheduler_t *rga_scheduler); +int rga_power_enable(struct rga_scheduler_t *scheduler); +int rga_power_disable(struct rga_scheduler_t *scheduler); int rga_kernel_commit(struct rga_req *cmd); diff --git a/drivers/video/rockchip/rga3/include/rga_job.h b/drivers/video/rockchip/rga3/include/rga_job.h index adc27aa97c08..4018a3aae438 100644 --- a/drivers/video/rockchip/rga3/include/rga_job.h +++ b/drivers/video/rockchip/rga3/include/rga_job.h @@ -23,7 +23,7 @@ enum job_flags { struct rga_scheduler_t *rga_job_get_scheduler(int core); -void rga_job_done(struct rga_scheduler_t *rga_scheduler, int ret); +void rga_job_done(struct rga_scheduler_t *scheduler, int ret); int rga_job_commit(struct rga_req *rga_command_base, struct rga_internal_ctx_t *ctx); int rga_job_mpi_commit(struct rga_req *rga_command_base, @@ -37,10 +37,11 @@ int rga_ctx_manager_remove(struct rga_pending_ctx_manager **ctx_manager_session) struct rga_internal_ctx_t * rga_internal_ctx_lookup(struct rga_pending_ctx_manager *ctx_manager, uint32_t id); uint32_t rga_internal_ctx_alloc_to_get_idr_id(uint32_t flags); -void rga_internel_ctx_kref_release(struct kref *ref); -int rga_job_config_by_user_ctx(struct rga_user_ctx_t *user_ctx); -int rga_job_commit_by_user_ctx(struct rga_user_ctx_t *user_ctx); -int rga_job_cancel_by_user_ctx(uint32_t ctx_id); +void rga_internal_ctx_kref_release(struct kref *ref); +int rga_internal_ctx_config_by_user_ctx(struct rga_user_ctx_t *user_ctx); +int rga_internal_ctx_commit_by_user_ctx(struct rga_user_ctx_t *user_ctx); +int rga_internal_ctx_cancel_by_user_ctx(uint32_t ctx_id); +int rga_internal_ctx_signal(struct rga_scheduler_t *scheduler, struct rga_job *job); struct rga_job * rga_scheduler_get_pending_job_list(struct rga_scheduler_t *scheduler); diff --git a/drivers/video/rockchip/rga3/rga2_reg_info.c b/drivers/video/rockchip/rga3/rga2_reg_info.c index bae042802514..d8a841f84e2f 100644 --- a/drivers/video/rockchip/rga3/rga2_reg_info.c +++ b/drivers/video/rockchip/rga3/rga2_reg_info.c @@ -2056,16 +2056,16 @@ static void rga_cmd_to_rga2_cmd(struct rga_scheduler_t *scheduler, } } -void rga2_soft_reset(struct rga_scheduler_t *rga_scheduler) +void rga2_soft_reset(struct rga_scheduler_t *scheduler) { u32 i; u32 reg; - rga_write((1 << 3) | (1 << 4) | (1 << 6), RGA2_SYS_CTRL, rga_scheduler); + rga_write((1 << 3) | (1 << 4) | (1 << 6), RGA2_SYS_CTRL, scheduler); for (i = 0; i < RGA_RESET_TIMEOUT; i++) { /* RGA_SYS_CTRL */ - reg = rga_read(RGA2_SYS_CTRL, rga_scheduler) & 1; + reg = rga_read(RGA2_SYS_CTRL, scheduler) & 1; if (reg == 0) break; diff --git a/drivers/video/rockchip/rga3/rga_debugger.c b/drivers/video/rockchip/rga3/rga_debugger.c index 13b8221b7d78..9e88e01f288f 100644 --- a/drivers/video/rockchip/rga3/rga_debugger.c +++ b/drivers/video/rockchip/rga3/rga_debugger.c @@ -157,7 +157,7 @@ static int rga_version_show(struct seq_file *m, void *data) static int rga_load_show(struct seq_file *m, void *data) { - struct rga_scheduler_t *rga_scheduler = NULL; + struct rga_scheduler_t *scheduler = NULL; unsigned long flags; int i; int load; @@ -167,16 +167,16 @@ static int rga_load_show(struct seq_file *m, void *data) seq_printf(m, "================= load ==================\n"); for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { - rga_scheduler = rga_drvdata->rga_scheduler[i]; + scheduler = rga_drvdata->scheduler[i]; seq_printf(m, "scheduler[%d]: %s\n", - i, dev_driver_string(rga_scheduler->dev)); + i, dev_driver_string(scheduler->dev)); - spin_lock_irqsave(&rga_scheduler->irq_lock, flags); + spin_lock_irqsave(&scheduler->irq_lock, flags); - busy_time_total = rga_scheduler->timer.busy_time_record; + busy_time_total = scheduler->timer.busy_time_record; - spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); + spin_unlock_irqrestore(&scheduler->irq_lock, flags); load = (busy_time_total * 100 / RGA_LOAD_INTERVAL_US); if (load > 100) @@ -190,19 +190,19 @@ static int rga_load_show(struct seq_file *m, void *data) static int rga_scheduler_show(struct seq_file *m, void *data) { - struct rga_scheduler_t *rga_scheduler = NULL; + struct rga_scheduler_t *scheduler = NULL; int i; seq_printf(m, "num of scheduler = %d\n", rga_drvdata->num_of_scheduler); seq_printf(m, "===================================\n"); for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { - rga_scheduler = rga_drvdata->rga_scheduler[i]; + scheduler = rga_drvdata->scheduler[i]; seq_printf(m, "scheduler[%d]: %s\n", - i, dev_driver_string(rga_scheduler->dev)); + i, dev_driver_string(scheduler->dev)); seq_printf(m, "-----------------------------------\n"); - seq_printf(m, "pd_ref = %d\n", rga_scheduler->pd_refcount); + seq_printf(m, "pd_ref = %d\n", scheduler->pd_refcount); } return 0; diff --git a/drivers/video/rockchip/rga3/rga_drv.c b/drivers/video/rockchip/rga3/rga_drv.c index be7ecf6bb499..019e9ac284f3 100644 --- a/drivers/video/rockchip/rga3/rga_drv.c +++ b/drivers/video/rockchip/rga3/rga_drv.c @@ -274,7 +274,7 @@ static enum hrtimer_restart hrtimer_handler(struct hrtimer *timer) ktime_t now = ktime_get(); for (i = 0; i < rga->num_of_scheduler; i++) { - scheduler = rga->rga_scheduler[i]; + scheduler = rga->scheduler[i]; spin_lock_irqsave(&scheduler->irq_lock, flags); @@ -311,58 +311,58 @@ static void rga_cancel_timer(void) } #ifndef CONFIG_ROCKCHIP_FPGA -int rga_power_enable(struct rga_scheduler_t *rga_scheduler) +int rga_power_enable(struct rga_scheduler_t *scheduler) { int ret = -EINVAL; int i; unsigned long flags; - pm_runtime_get_sync(rga_scheduler->dev); - pm_stay_awake(rga_scheduler->dev); + pm_runtime_get_sync(scheduler->dev); + pm_stay_awake(scheduler->dev); - for (i = 0; i < rga_scheduler->num_clks; i++) { - if (!IS_ERR(rga_scheduler->clks[i])) { - ret = clk_prepare_enable(rga_scheduler->clks[i]); + for (i = 0; i < scheduler->num_clks; i++) { + if (!IS_ERR(scheduler->clks[i])) { + ret = clk_prepare_enable(scheduler->clks[i]); if (ret < 0) goto err_enable_clk; } } - spin_lock_irqsave(&rga_scheduler->irq_lock, flags); + spin_lock_irqsave(&scheduler->irq_lock, flags); - rga_scheduler->pd_refcount++; + scheduler->pd_refcount++; - spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); + spin_unlock_irqrestore(&scheduler->irq_lock, flags); return 0; err_enable_clk: for (--i; i >= 0; --i) - if (!IS_ERR(rga_scheduler->clks[i])) - clk_disable_unprepare(rga_scheduler->clks[i]); + if (!IS_ERR(scheduler->clks[i])) + clk_disable_unprepare(scheduler->clks[i]); - pm_relax(rga_scheduler->dev); - pm_runtime_put_sync_suspend(rga_scheduler->dev); + pm_relax(scheduler->dev); + pm_runtime_put_sync_suspend(scheduler->dev); return ret; } -int rga_power_disable(struct rga_scheduler_t *rga_scheduler) +int rga_power_disable(struct rga_scheduler_t *scheduler) { int i; unsigned long flags; - for (i = rga_scheduler->num_clks - 1; i >= 0; i--) - if (!IS_ERR(rga_scheduler->clks[i])) - clk_disable_unprepare(rga_scheduler->clks[i]); + for (i = scheduler->num_clks - 1; i >= 0; i--) + if (!IS_ERR(scheduler->clks[i])) + clk_disable_unprepare(scheduler->clks[i]); - pm_relax(rga_scheduler->dev); - pm_runtime_put_sync_suspend(rga_scheduler->dev); + pm_relax(scheduler->dev); + pm_runtime_put_sync_suspend(scheduler->dev); - spin_lock_irqsave(&rga_scheduler->irq_lock, flags); + spin_lock_irqsave(&scheduler->irq_lock, flags); - rga_scheduler->pd_refcount--; + scheduler->pd_refcount--; - spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); + spin_unlock_irqrestore(&scheduler->irq_lock, flags); return 0; } @@ -374,7 +374,7 @@ static void rga_power_enable_all(void) int i; for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { - scheduler = rga_drvdata->rga_scheduler[i]; + scheduler = rga_drvdata->scheduler[i]; ret = rga_power_enable(scheduler); if (ret < 0) pr_err("power enable failed"); @@ -387,7 +387,7 @@ static void rga_power_disable_all(void) int i; for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { - scheduler = rga_drvdata->rga_scheduler[i]; + scheduler = rga_drvdata->scheduler[i]; rga_power_disable(scheduler); } } @@ -565,7 +565,7 @@ static long rga_ioctl_cmd_config(unsigned long arg) pr_info("config cmd id = %d", rga_user_ctx.id); /* find internal_ctx to set cmd by user ctx (internal ctx id) */ - ret = rga_job_config_by_user_ctx(&rga_user_ctx); + ret = rga_internal_ctx_config_by_user_ctx(&rga_user_ctx); if (ret < 0) { pr_err("config ctx id[%d] failed!\n", rga_user_ctx.id); return -EFAULT; @@ -589,7 +589,7 @@ static long rga_ioctl_cmd_end(unsigned long arg) pr_info("config end id = %d", rga_user_ctx.id); /* find internal_ctx to set cmd by user ctx (internal ctx id) */ - ret = rga_job_commit_by_user_ctx(&rga_user_ctx); + ret = rga_internal_ctx_commit_by_user_ctx(&rga_user_ctx); if (ret < 0) { pr_err("commit ctx id[%d] failed!\n", rga_user_ctx.id); return -EFAULT; @@ -619,7 +619,7 @@ static long rga_ioctl_cmd_cancel(unsigned long arg) pr_info("config cancel id = %d", rga_user_ctx_id); /* find internal_ctx to set cmd by user ctx (internal ctx id) */ - ret = rga_job_cancel_by_user_ctx(rga_user_ctx_id); + ret = rga_internal_ctx_cancel_by_user_ctx(rga_user_ctx_id); if (ret < 0) { pr_err("cancel ctx id[%d] failed!\n", rga_user_ctx_id); return -EFAULT; @@ -691,7 +691,7 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) case RGA_GET_RESULT: break; case RGA_GET_VERSION: - sscanf(rga->rga_scheduler[i]->version.str, "%x.%x.%*x", + sscanf(rga->scheduler[i]->version.str, "%x.%x.%*x", &major_version, &minor_version); snprintf(version, 5, "%x.%02x", major_version, minor_version); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) @@ -706,10 +706,10 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) break; case RGA2_GET_VERSION: for (i = 0; i < rga->num_of_scheduler; i++) { - if (rga->rga_scheduler[i]->ops == &rga2_ops) { + if (rga->scheduler[i]->ops == &rga2_ops) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - if (copy_to_user((void *)arg, rga->rga_scheduler[i]->version.str, - sizeof(rga->rga_scheduler[i]->version.str))) + if (copy_to_user((void *)arg, rga->scheduler[i]->version.str, + sizeof(rga->scheduler[i]->version.str))) ret = -EFAULT; #else if (copy_to_user((void *)arg, RGA3_VERSION, @@ -735,8 +735,8 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) RGA_HW_SIZE : rga->num_of_scheduler; for (i = 0; i < hw_versions.size; i++) { - memcpy(&hw_versions.version[i], &rga->rga_scheduler[i]->version, - sizeof(rga->rga_scheduler[i]->version)); + memcpy(&hw_versions.version[i], &rga->scheduler[i]->version, + sizeof(rga->scheduler[i]->version)); } if (copy_to_user((void *)arg, &hw_versions, sizeof(hw_versions))) @@ -874,7 +874,7 @@ static int rga_release(struct inode *inode, struct file *file) if (pid == ctx->pid) { pr_err("[pid:%d] destroy ctx[%d] when the user exits", pid, ctx->id); - kref_put(&ctx->refcount, rga_internel_ctx_kref_release); + kref_put(&ctx->refcount, rga_internal_ctx_kref_release); } mutex_lock(&ctx_manager->lock); @@ -887,29 +887,29 @@ static int rga_release(struct inode *inode, struct file *file) static irqreturn_t rga3_irq_handler(int irq, void *data) { - struct rga_scheduler_t *rga_scheduler = data; + struct rga_scheduler_t *scheduler = data; if (DEBUGGER_EN(INT_FLAG)) pr_info("irqthread INT[%x],STATS0[%x], STATS1[%x]\n", - rga_read(RGA3_INT_RAW, rga_scheduler), - rga_read(RGA3_STATUS0, rga_scheduler), - rga_read(RGA3_STATUS1, rga_scheduler)); + rga_read(RGA3_INT_RAW, scheduler), + rga_read(RGA3_STATUS0, scheduler), + rga_read(RGA3_STATUS1, scheduler)); /* TODO: if error interrupt then soft reset hardware */ - //rga_scheduler->ops->soft_reset(job->core); + //scheduler->ops->soft_reset(job->core); /*clear INT */ - rga_write(1, RGA3_INT_CLR, rga_scheduler); + rga_write(1, RGA3_INT_CLR, scheduler); return IRQ_WAKE_THREAD; } static irqreturn_t rga3_irq_thread(int irq, void *data) { - struct rga_scheduler_t *rga_scheduler = data; + struct rga_scheduler_t *scheduler = data; struct rga_job *job; - job = rga_scheduler->running_job; + job = scheduler->running_job; if (!job) { pr_err("running job is invaild on irq thread\n"); @@ -918,62 +918,62 @@ static irqreturn_t rga3_irq_thread(int irq, void *data) if (DEBUGGER_EN(INT_FLAG)) pr_info("irq INT[%x], STATS0[%x], STATS1[%x]\n", - rga_read(RGA3_INT_RAW, rga_scheduler), - rga_read(RGA3_STATUS0, rga_scheduler), - rga_read(RGA3_STATUS1, rga_scheduler)); + rga_read(RGA3_INT_RAW, scheduler), + rga_read(RGA3_STATUS0, scheduler), + rga_read(RGA3_STATUS1, scheduler)); - rga_job_done(rga_scheduler, 0); + rga_job_done(scheduler, 0); return IRQ_HANDLED; } static irqreturn_t rga2_irq_handler(int irq, void *data) { - struct rga_scheduler_t *rga_scheduler = data; + struct rga_scheduler_t *scheduler = data; if (DEBUGGER_EN(INT_FLAG)) pr_info("irqthread INT[%x],STATS0[%x]\n", - rga_read(RGA2_INT, rga_scheduler), rga_read(RGA2_STATUS, - rga_scheduler)); + rga_read(RGA2_INT, scheduler), rga_read(RGA2_STATUS, + scheduler)); /*if error interrupt then soft reset hardware */ //warning - if (rga_read(RGA2_INT, rga_scheduler) & 0x01) { + if (rga_read(RGA2_INT, scheduler) & 0x01) { pr_err("err irq! INT[%x],STATS0[%x]\n", - rga_read(RGA2_INT, rga_scheduler), - rga_read(RGA2_STATUS, rga_scheduler)); - rga_scheduler->ops->soft_reset(rga_scheduler); + rga_read(RGA2_INT, scheduler), + rga_read(RGA2_STATUS, scheduler)); + scheduler->ops->soft_reset(scheduler); } /*clear INT */ - rga_write(rga_read(RGA2_INT, rga_scheduler) | + rga_write(rga_read(RGA2_INT, scheduler) | (0x1 << 4) | (0x1 << 5) | (0x1 << 6) | (0x1 << 7) | - (0x1 << 15) | (0x1 << 16), RGA2_INT, rga_scheduler); + (0x1 << 15) | (0x1 << 16), RGA2_INT, scheduler); return IRQ_WAKE_THREAD; } static irqreturn_t rga2_irq_thread(int irq, void *data) { - struct rga_scheduler_t *rga_scheduler = data; + struct rga_scheduler_t *scheduler = data; struct rga_job *job; - job = rga_scheduler->running_job; + job = scheduler->running_job; if (!job) return IRQ_HANDLED; if (DEBUGGER_EN(INT_FLAG)) pr_info("irq INT[%x], STATS0[%x]\n", - rga_read(RGA2_INT, rga_scheduler), rga_read(RGA2_STATUS, - rga_scheduler)); + rga_read(RGA2_INT, scheduler), rga_read(RGA2_STATUS, + scheduler)); job->rga_command_base.osd_info.cur_flags0 = rga_read(RGA2_OSD_CUR_FLAGS0_OFFSET, - rga_scheduler); + scheduler); job->rga_command_base.osd_info.cur_flags1 = rga_read(RGA2_OSD_CUR_FLAGS1_OFFSET, - rga_scheduler); + scheduler); - rga_job_done(rga_scheduler, 0); + rga_job_done(scheduler, 0); return IRQ_HANDLED; } @@ -1085,23 +1085,23 @@ static const struct of_device_id rga2_dt_ids[] = { {}, }; -static void init_scheduler(struct rga_scheduler_t *rga_scheduler, +static void init_scheduler(struct rga_scheduler_t *scheduler, const char *name) { - spin_lock_init(&rga_scheduler->irq_lock); - INIT_LIST_HEAD(&rga_scheduler->todo_list); - init_waitqueue_head(&rga_scheduler->job_done_wq); + spin_lock_init(&scheduler->irq_lock); + INIT_LIST_HEAD(&scheduler->todo_list); + init_waitqueue_head(&scheduler->job_done_wq); if (!strcmp(name, "rga3_core0")) { - rga_scheduler->ops = &rga3_ops; + scheduler->ops = &rga3_ops; /* TODO: get by hw version */ - rga_scheduler->core = RGA3_SCHEDULER_CORE0; + scheduler->core = RGA3_SCHEDULER_CORE0; } else if (!strcmp(name, "rga3_core1")) { - rga_scheduler->ops = &rga3_ops; - rga_scheduler->core = RGA3_SCHEDULER_CORE1; + scheduler->ops = &rga3_ops; + scheduler->core = RGA3_SCHEDULER_CORE1; } else if (!strcmp(name, "rga2")) { - rga_scheduler->ops = &rga2_ops; - rga_scheduler->core = RGA2_SCHEDULER_CORE0; + scheduler->ops = &rga2_ops; + scheduler->core = RGA2_SCHEDULER_CORE0; } } @@ -1114,7 +1114,7 @@ static int rga_drv_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const struct rga_match_data_t *match_data; int i, irq; - struct rga_scheduler_t *rga_scheduler = NULL; + struct rga_scheduler_t *scheduler = NULL; if (!pdev->dev.of_node) return -EINVAL; @@ -1131,19 +1131,19 @@ static int rga_drv_probe(struct platform_device *pdev) return -EINVAL; } - rga_scheduler = + scheduler = devm_kzalloc(&pdev->dev, sizeof(struct rga_scheduler_t), GFP_KERNEL); - if (rga_scheduler == NULL) { + if (scheduler == NULL) { pr_err("failed to allocate scheduler. dev name = %s\n", dev_driver_string(dev)); return -ENOMEM; } - init_scheduler(rga_scheduler, + init_scheduler(scheduler, dev_driver_string(dev)); - rga_scheduler->dev = &pdev->dev; + scheduler->dev = &pdev->dev; /* map the registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1152,9 +1152,9 @@ static int rga_drv_probe(struct platform_device *pdev) return -ENXIO; } - rga_scheduler->rga_base = + scheduler->rga_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!rga_scheduler->rga_base) { + if (!scheduler->rga_base) { pr_err("ioremap failed\n"); ret = -ENOENT; return ret; @@ -1171,7 +1171,7 @@ static int rga_drv_probe(struct platform_device *pdev) return irq; } - rga_scheduler->irq = irq; + scheduler->irq = irq; pr_info("%s, irq = %d, match scheduler\n", match_data->irqs[0].name, irq); @@ -1179,7 +1179,7 @@ static int rga_drv_probe(struct platform_device *pdev) match_data->irqs[0].irq_hdl, match_data->irqs[0].irq_thread, IRQF_SHARED, dev_driver_string(dev), - rga_scheduler); + scheduler); if (ret < 0) { pr_err("request irq name: %s failed: %d\n", match_data->irqs[0].name, ret); @@ -1193,12 +1193,12 @@ static int rga_drv_probe(struct platform_device *pdev) if (IS_ERR(clk)) pr_err("failed to get %s\n", match_data->clks[i]); - rga_scheduler->clks[i] = clk; + scheduler->clks[i] = clk; } - rga_scheduler->num_clks = match_data->num_clks; + scheduler->num_clks = match_data->num_clks; #endif - platform_set_drvdata(pdev, rga_scheduler); + platform_set_drvdata(pdev, scheduler); device_init_wakeup(dev, true); @@ -1206,16 +1206,16 @@ static int rga_drv_probe(struct platform_device *pdev) #ifndef CONFIG_ROCKCHIP_FPGA pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(rga_scheduler->dev); + ret = pm_runtime_get_sync(scheduler->dev); if (ret < 0) { pr_err("failed to get pm runtime, ret = %d\n", ret); goto failed; } - for (i = 0; i < rga_scheduler->num_clks; i++) { - if (!IS_ERR(rga_scheduler->clks[i])) { - ret = clk_prepare_enable(rga_scheduler->clks[i]); + for (i = 0; i < scheduler->num_clks; i++) { + if (!IS_ERR(scheduler->clks[i])) { + ret = clk_prepare_enable(scheduler->clks[i]); if (ret < 0) { pr_err("failed to enable clk\n"); goto failed; @@ -1224,28 +1224,28 @@ static int rga_drv_probe(struct platform_device *pdev) } #endif //CONFIG_ROCKCHIP_FPGA - rga_scheduler->ops->get_version(rga_scheduler); + scheduler->ops->get_version(scheduler); pr_info("%s driver loaded successfully ver:%s\n", - dev_driver_string(dev), rga_scheduler->version.str); + dev_driver_string(dev), scheduler->version.str); /* TODO: get by hw version, Currently only supports judgment 1106. */ - if (rga_scheduler->core == RGA3_SCHEDULER_CORE0 || - rga_scheduler->core == RGA3_SCHEDULER_CORE1) { - rga_scheduler->data = &rga3_data; - } else if (rga_scheduler->core == RGA2_SCHEDULER_CORE0) { - if (!strcmp(rga_scheduler->version.str, "3.3.87975")) - rga_scheduler->data = &rga2e_1106_data; + if (scheduler->core == RGA3_SCHEDULER_CORE0 || + scheduler->core == RGA3_SCHEDULER_CORE1) { + scheduler->data = &rga3_data; + } else if (scheduler->core == RGA2_SCHEDULER_CORE0) { + if (!strcmp(scheduler->version.str, "3.3.87975")) + scheduler->data = &rga2e_1106_data; else - rga_scheduler->data = &rga2e_data; + scheduler->data = &rga2e_data; } - data->rga_scheduler[data->num_of_scheduler] = rga_scheduler; + data->scheduler[data->num_of_scheduler] = scheduler; data->num_of_scheduler++; - for (i = rga_scheduler->num_clks - 1; i >= 0; i--) - if (!IS_ERR(rga_scheduler->clks[i])) - clk_disable_unprepare(rga_scheduler->clks[i]); + for (i = scheduler->num_clks - 1; i >= 0; i--) + if (!IS_ERR(scheduler->clks[i])) + clk_disable_unprepare(scheduler->clks[i]); pm_runtime_put_sync(&pdev->dev); diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index eaeb5ab57f64..cb2ab6dc1bc2 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -50,12 +50,12 @@ struct rga_scheduler_t *rga_job_get_scheduler(int core) int i; for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { - if (core == rga_drvdata->rga_scheduler[i]->core) { - scheduler = rga_drvdata->rga_scheduler[i]; + if (core == rga_drvdata->scheduler[i]->core) { + scheduler = rga_drvdata->scheduler[i]; if (DEBUGGER_EN(MSG)) pr_info("job choose core: %d\n", - rga_drvdata->rga_scheduler[i]->core); + rga_drvdata->scheduler[i]->core); break; } } @@ -242,112 +242,6 @@ static struct rga_job *rga_job_alloc(struct rga_req *rga_command_base) return job; } -struct rga_internal_ctx_t * -rga_internal_ctx_lookup(struct rga_pending_ctx_manager *ctx_manager, uint32_t id) -{ - struct rga_internal_ctx_t *ctx = NULL; - - mutex_lock(&ctx_manager->lock); - - ctx = idr_find(&ctx_manager->ctx_id_idr, id); - - mutex_unlock(&ctx_manager->lock); - - return ctx; -} - -/* - * Called at driver close to release the internal ctx's id references. - */ -static int rga_internal_ctx_free_remove_idr_cb(int id, void *ptr, void *data) -{ - struct rga_internal_ctx_t *ctx = ptr; - - idr_remove(&rga_drvdata->pend_ctx_manager->ctx_id_idr, ctx->id); - if (ctx->cached_cmd != NULL) { - kfree(ctx->cached_cmd); - ctx->cached_cmd = NULL; - } - kfree(ctx); - - return 0; -} - -static int rga_internal_ctx_free_remove_idr(struct rga_internal_ctx_t *ctx) -{ - struct rga_pending_ctx_manager *ctx_manager; - struct rga_req *cached_cmd; - unsigned long flags; - - ctx_manager = rga_drvdata->pend_ctx_manager; - - if (IS_ERR_OR_NULL(ctx)) { - pr_err("ctx already freed"); - return -EFAULT; - } - - mutex_lock(&ctx_manager->lock); - - ctx_manager->ctx_count--; - idr_remove(&ctx_manager->ctx_id_idr, ctx->id); - - mutex_unlock(&ctx_manager->lock); - - spin_lock_irqsave(&ctx->lock, flags); - - cached_cmd = ctx->cached_cmd; - - spin_unlock_irqrestore(&ctx->lock, flags); - - if (cached_cmd != NULL) - kfree(cached_cmd); - - kfree(ctx); - - return 0; -} - -static int rga_internal_ctx_signal(struct rga_scheduler_t *scheduler, struct rga_job *job) -{ - struct rga_pending_ctx_manager *ctx_manager; - struct rga_internal_ctx_t *ctx; - int finished_job_count; - unsigned long flags; - - ctx_manager = rga_drvdata->pend_ctx_manager; - - ctx = rga_internal_ctx_lookup(ctx_manager, job->ctx_id); - if (IS_ERR_OR_NULL(ctx)) { - pr_err("can not find internal ctx from id[%d]", job->ctx_id); - return -EINVAL; - } - - spin_lock_irqsave(&ctx->lock, flags); - - finished_job_count = ++ctx->finished_job_count; - - spin_unlock_irqrestore(&ctx->lock, flags); - - if (finished_job_count >= ctx->cmd_num) { - rga_dma_fence_signal(ctx->out_fence); - - job->flags |= RGA_JOB_DONE; - - if (job->flags & RGA_JOB_ASYNC) - rga_job_cleanup(job); - - wake_up(&scheduler->job_done_wq); - - spin_lock_irqsave(&ctx->lock, flags); - - ctx->is_running = false; - - spin_unlock_irqrestore(&ctx->lock, flags); - } - - return 0; -} - static void rga_job_dump_info(struct rga_job *job) { pr_info("job: priority = %d, core = %d\n", @@ -403,42 +297,42 @@ failed: return ret; } -static void rga_job_next(struct rga_scheduler_t *rga_scheduler) +static void rga_job_next(struct rga_scheduler_t *scheduler) { struct rga_job *job = NULL; unsigned long flags; next_job: - spin_lock_irqsave(&rga_scheduler->irq_lock, flags); + spin_lock_irqsave(&scheduler->irq_lock, flags); - if (rga_scheduler->running_job || - list_empty(&rga_scheduler->todo_list)) { - spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); + if (scheduler->running_job || + list_empty(&scheduler->todo_list)) { + spin_unlock_irqrestore(&scheduler->irq_lock, flags); return; } - job = list_first_entry(&rga_scheduler->todo_list, struct rga_job, head); + job = list_first_entry(&scheduler->todo_list, struct rga_job, head); list_del_init(&job->head); - rga_scheduler->job_count--; + scheduler->job_count--; - rga_scheduler->running_job = job; + scheduler->running_job = job; - spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); + spin_unlock_irqrestore(&scheduler->irq_lock, flags); - job->ret = rga_job_run(job, rga_scheduler); + job->ret = rga_job_run(job, scheduler); /* If some error before hw run */ if (job->ret < 0) { pr_err("some error on rga_job_run before hw start, %s(%d)\n", __func__, __LINE__); - spin_lock_irqsave(&rga_scheduler->irq_lock, flags); + spin_lock_irqsave(&scheduler->irq_lock, flags); - rga_scheduler->running_job = NULL; + scheduler->running_job = NULL; - spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); + spin_unlock_irqrestore(&scheduler->irq_lock, flags); if (job->flags & RGA_JOB_USE_HANDLE) rga_mm_put_handle_info(job); @@ -446,7 +340,7 @@ next_job: rga_dma_put_info(job); if (job->use_batch_mode) { - rga_internal_ctx_signal(rga_scheduler, job); + rga_internal_ctx_signal(scheduler, job); } else { rga_dma_fence_signal(job->out_fence); @@ -455,14 +349,14 @@ next_job: if (job->flags & RGA_JOB_ASYNC) rga_job_cleanup(job); - wake_up(&rga_scheduler->job_done_wq); + wake_up(&scheduler->job_done_wq); } goto next_job; } } -static void rga_job_finish_and_next(struct rga_scheduler_t *rga_scheduler, +static void rga_job_finish_and_next(struct rga_scheduler_t *scheduler, struct rga_job *job, int ret) { ktime_t now; @@ -478,7 +372,7 @@ static void rga_job_finish_and_next(struct rga_scheduler_t *rga_scheduler, if (job->core == RGA2_SCHEDULER_CORE0) rga2_dma_flush_cache_for_virtual_address(&job->vir_page_table, - rga_scheduler); + scheduler); if (job->flags & RGA_JOB_USE_HANDLE) rga_mm_put_handle_info(job); @@ -486,7 +380,7 @@ static void rga_job_finish_and_next(struct rga_scheduler_t *rga_scheduler, rga_dma_put_info(job); if (job->use_batch_mode) - rga_internal_ctx_signal(rga_scheduler, job); + rga_internal_ctx_signal(scheduler, job); else { rga_dma_fence_signal(job->out_fence); @@ -495,30 +389,30 @@ static void rga_job_finish_and_next(struct rga_scheduler_t *rga_scheduler, if (job->flags & RGA_JOB_ASYNC) rga_job_cleanup(job); - wake_up(&rga_scheduler->job_done_wq); + wake_up(&scheduler->job_done_wq); } - rga_job_next(rga_scheduler); + rga_job_next(scheduler); - rga_power_disable(rga_scheduler); + rga_power_disable(scheduler); } -void rga_job_done(struct rga_scheduler_t *rga_scheduler, int ret) +void rga_job_done(struct rga_scheduler_t *scheduler, int ret) { struct rga_job *job; unsigned long flags; ktime_t now = ktime_get(); - spin_lock_irqsave(&rga_scheduler->irq_lock, flags); + spin_lock_irqsave(&scheduler->irq_lock, flags); - job = rga_scheduler->running_job; - rga_scheduler->running_job = NULL; + job = scheduler->running_job; + scheduler->running_job = NULL; - rga_scheduler->timer.busy_time += ktime_us_delta(now, job->hw_recoder_time); + scheduler->timer.busy_time += ktime_us_delta(now, job->hw_recoder_time); - spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); + spin_unlock_irqrestore(&scheduler->irq_lock, flags); - rga_job_finish_and_next(rga_scheduler, job, ret); + rga_job_finish_and_next(scheduler, job, ret); } static void rga_job_timeout_clean(struct rga_scheduler_t *scheduler) @@ -571,7 +465,7 @@ static struct rga_scheduler_t *rga_job_schedule(struct rga_job *job) return NULL; } } else { - job->core = rga_drvdata->rga_scheduler[0]->core; + job->core = rga_drvdata->scheduler[0]->core; } scheduler = rga_job_get_scheduler(job->core); @@ -619,18 +513,17 @@ static struct rga_scheduler_t *rga_job_schedule(struct rga_job *job) } static void rga_running_job_abort(struct rga_job *job, - struct rga_scheduler_t *rga_scheduler) + struct rga_scheduler_t *scheduler) { unsigned long flags; - spin_lock_irqsave(&rga_scheduler->irq_lock, flags); + spin_lock_irqsave(&scheduler->irq_lock, flags); /* invalid job */ - if (job == rga_scheduler->running_job) { - rga_scheduler->running_job = NULL; - } + if (job == scheduler->running_job) + scheduler->running_job = NULL; - spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); + spin_unlock_irqrestore(&scheduler->irq_lock, flags); rga_job_cleanup(job); } @@ -640,20 +533,20 @@ static void rga_invalid_job_abort(struct rga_job *job) rga_job_cleanup(job); } -static inline int rga_job_wait(struct rga_scheduler_t *rga_scheduler, +static inline int rga_job_wait(struct rga_scheduler_t *scheduler, struct rga_job *job) { int left_time; ktime_t now; int ret; - left_time = wait_event_interruptible_timeout(rga_scheduler->job_done_wq, + left_time = wait_event_interruptible_timeout(scheduler->job_done_wq, job->flags & RGA_JOB_DONE, RGA_SYNC_TIMEOUT_DELAY); switch (left_time) { case 0: pr_err("%s timeout", __func__); - rga_scheduler->ops->soft_reset(rga_scheduler); + scheduler->ops->soft_reset(scheduler); ret = -EBUSY; break; case -ERESTARTSYS: @@ -673,235 +566,6 @@ static inline int rga_job_wait(struct rga_scheduler_t *rga_scheduler, return ret; } -uint32_t rga_internal_ctx_alloc_to_get_idr_id(uint32_t flags) -{ - struct rga_pending_ctx_manager *ctx_manager; - struct rga_internal_ctx_t *ctx; - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (ctx == NULL) { - pr_err("can not kzalloc for rga_pending_ctx_manager\n"); - return -ENOMEM; - } - - ctx_manager = rga_drvdata->pend_ctx_manager; - if (ctx_manager == NULL) { - pr_err("rga_pending_ctx_manager is null!\n"); - kfree(ctx); - return -EFAULT; - } - - spin_lock_init(&ctx->lock); - - /* - * Get the user-visible handle using idr. Preload and perform - * allocation under our spinlock. - */ - - mutex_lock(&ctx_manager->lock); - - idr_preload(GFP_KERNEL); - ctx->id = idr_alloc(&ctx_manager->ctx_id_idr, ctx, 1, 0, GFP_KERNEL); - idr_preload_end(); - - ctx_manager->ctx_count++; - - kref_init(&ctx->refcount); - ctx->pid = current->pid; - ctx->flags = flags; - - mutex_unlock(&ctx_manager->lock); - - if (ctx->id < 0) - pr_err("[pid: %d]alloc ctx_id failed", ctx->pid); - - return (uint32_t)ctx->id; -} - -int rga_job_config_by_user_ctx(struct rga_user_ctx_t *user_ctx) -{ - struct rga_pending_ctx_manager *ctx_manager; - struct rga_internal_ctx_t *ctx; - struct rga_req *cached_cmd; - int ret = 0; - bool first_config = false; - unsigned long flags; - - ctx_manager = rga_drvdata->pend_ctx_manager; - - ctx = rga_internal_ctx_lookup(ctx_manager, user_ctx->id); - if (IS_ERR_OR_NULL(ctx)) { - pr_err("can not find internal ctx from id[%d]", user_ctx->id); - return -EINVAL; - } - - spin_lock_irqsave(&ctx->lock, flags); - - cached_cmd = ctx->cached_cmd; - - spin_unlock_irqrestore(&ctx->lock, flags); - - if (cached_cmd == NULL) { - cached_cmd = kmalloc_array(user_ctx->cmd_num, sizeof(struct rga_req), GFP_KERNEL); - if (cached_cmd == NULL) { - pr_err("cmd_cached list alloc error!\n"); - return -ENOMEM; - } - - first_config = true; - } - - if (unlikely(copy_from_user(cached_cmd, u64_to_user_ptr(user_ctx->cmd_ptr), - sizeof(struct rga_req) * user_ctx->cmd_num))) { - pr_err("rga_user_ctx cmd list copy_from_user failed\n"); - if (first_config) - kfree(cached_cmd); - return -EFAULT; - } - - spin_lock_irqsave(&ctx->lock, flags); - - ctx->sync_mode = user_ctx->sync_mode; - ctx->cmd_num = user_ctx->cmd_num; - ctx->cached_cmd = cached_cmd; - ctx->mpi_config_flags = user_ctx->mpi_config_flags; - - spin_unlock_irqrestore(&ctx->lock, flags); - - return ret; -} - -int rga_job_commit_by_user_ctx(struct rga_user_ctx_t *user_ctx) -{ - struct rga_pending_ctx_manager *ctx_manager; - struct rga_internal_ctx_t *ctx; - struct rga_req *cached_cmd; - int i; - int ret = 0; - unsigned long flags; - - ctx_manager = rga_drvdata->pend_ctx_manager; - - ctx = rga_internal_ctx_lookup(ctx_manager, user_ctx->id); - if (IS_ERR_OR_NULL(ctx)) { - pr_err("can not find internal ctx from id[%d]", user_ctx->id); - return -EINVAL; - } - - spin_lock_irqsave(&ctx->lock, flags); - - if (ctx->is_running) { - pr_err("can not re-config when ctx is running"); - spin_unlock_irqrestore(&ctx->lock, flags); - return -EFAULT; - } - - /* Reset */ - ctx->finished_job_count = 0; - - cached_cmd = ctx->cached_cmd; - if (cached_cmd == NULL) { - pr_err("can not find cached cmd from id[%d]", user_ctx->id); - spin_unlock_irqrestore(&ctx->lock, flags); - return -EINVAL; - } - - ctx->use_batch_mode = true; - ctx->is_running = true; - - spin_unlock_irqrestore(&ctx->lock, flags); - - for (i = 0; i < ctx->cmd_num; i++) { - ret = rga_job_commit(&(cached_cmd[i]), ctx); - if (ret < 0) { - pr_err("rga_job_commit failed\n"); - return -EFAULT; - } - } - - user_ctx->out_fence_fd = ctx->out_fence_fd; - - return ret; -} - -void rga_internel_ctx_kref_release(struct kref *ref) -{ - struct rga_internal_ctx_t *ctx; - struct rga_scheduler_t *scheduler = NULL; - struct rga_job *job_pos, *job_q, *job; - int i; - bool need_reset = false; - unsigned long flags; - ktime_t now = ktime_get(); - - ctx = container_of(ref, struct rga_internal_ctx_t, refcount); - - spin_lock_irqsave(&ctx->lock, flags); - - if (!ctx->is_running || ctx->finished_job_count >= ctx->cmd_num) { - spin_unlock_irqrestore(&ctx->lock, flags); - goto free_ctx; - } - - spin_unlock_irqrestore(&ctx->lock, flags); - - for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { - scheduler = rga_drvdata->rga_scheduler[i]; - - spin_lock_irqsave(&scheduler->irq_lock, flags); - - list_for_each_entry_safe(job_pos, job_q, &scheduler->todo_list, head) { - if (ctx->id == job_pos->ctx_id) { - job = job_pos; - list_del_init(&job_pos->head); - - scheduler->job_count--; - } - } - - if (scheduler->running_job) { - job = scheduler->running_job; - - if (job->ctx_id == ctx->id) { - scheduler->running_job = NULL; - scheduler->timer.busy_time += ktime_us_delta(now, job->hw_recoder_time); - need_reset = true; - } - } - - spin_unlock_irqrestore(&scheduler->irq_lock, flags); - - if (need_reset) { - pr_info("reset core[%d] by user cancel", scheduler->core); - scheduler->ops->soft_reset(scheduler); - - rga_job_finish_and_next(scheduler, job, 0); - } - } - -free_ctx: - rga_internal_ctx_free_remove_idr(ctx); -} - -int rga_job_cancel_by_user_ctx(uint32_t ctx_id) -{ - struct rga_pending_ctx_manager *ctx_manager; - struct rga_internal_ctx_t *ctx; - int ret = 0; - - ctx_manager = rga_drvdata->pend_ctx_manager; - - ctx = rga_internal_ctx_lookup(ctx_manager, ctx_id); - if (IS_ERR_OR_NULL(ctx)) { - pr_err("can not find internal ctx from id[%d]", ctx_id); - return -EINVAL; - } - - kref_put(&ctx->refcount, rga_internel_ctx_kref_release); - - return ret; -} - static int rga_job_alloc_release_fence(struct dma_fence **release_fence, spinlock_t *lock) { struct dma_fence *fence; @@ -1152,6 +816,341 @@ running_job_abort: return ret; } +struct rga_internal_ctx_t * +rga_internal_ctx_lookup(struct rga_pending_ctx_manager *ctx_manager, uint32_t id) +{ + struct rga_internal_ctx_t *ctx = NULL; + + mutex_lock(&ctx_manager->lock); + + ctx = idr_find(&ctx_manager->ctx_id_idr, id); + + mutex_unlock(&ctx_manager->lock); + + return ctx; +} + +/* + * Called at driver close to release the internal ctx's id references. + */ +static int rga_internal_ctx_free_remove_idr_cb(int id, void *ptr, void *data) +{ + struct rga_internal_ctx_t *ctx = ptr; + + idr_remove(&rga_drvdata->pend_ctx_manager->ctx_id_idr, ctx->id); + if (ctx->cached_cmd != NULL) { + kfree(ctx->cached_cmd); + ctx->cached_cmd = NULL; + } + kfree(ctx); + + return 0; +} + +static int rga_internal_ctx_free_remove_idr(struct rga_internal_ctx_t *ctx) +{ + struct rga_pending_ctx_manager *ctx_manager; + struct rga_req *cached_cmd; + unsigned long flags; + + ctx_manager = rga_drvdata->pend_ctx_manager; + + if (IS_ERR_OR_NULL(ctx)) { + pr_err("ctx already freed"); + return -EFAULT; + } + + mutex_lock(&ctx_manager->lock); + + ctx_manager->ctx_count--; + idr_remove(&ctx_manager->ctx_id_idr, ctx->id); + + mutex_unlock(&ctx_manager->lock); + + spin_lock_irqsave(&ctx->lock, flags); + + cached_cmd = ctx->cached_cmd; + + spin_unlock_irqrestore(&ctx->lock, flags); + + if (cached_cmd != NULL) + kfree(cached_cmd); + + kfree(ctx); + + return 0; +} + +int rga_internal_ctx_signal(struct rga_scheduler_t *scheduler, struct rga_job *job) +{ + struct rga_pending_ctx_manager *ctx_manager; + struct rga_internal_ctx_t *ctx; + int finished_job_count; + unsigned long flags; + + ctx_manager = rga_drvdata->pend_ctx_manager; + + ctx = rga_internal_ctx_lookup(ctx_manager, job->ctx_id); + if (IS_ERR_OR_NULL(ctx)) { + pr_err("can not find internal ctx from id[%d]", job->ctx_id); + return -EINVAL; + } + + spin_lock_irqsave(&ctx->lock, flags); + + finished_job_count = ++ctx->finished_job_count; + + spin_unlock_irqrestore(&ctx->lock, flags); + + if (finished_job_count >= ctx->cmd_num) { + rga_dma_fence_signal(ctx->out_fence); + + job->flags |= RGA_JOB_DONE; + + if (job->flags & RGA_JOB_ASYNC) + rga_job_cleanup(job); + + wake_up(&scheduler->job_done_wq); + + spin_lock_irqsave(&ctx->lock, flags); + + ctx->is_running = false; + + spin_unlock_irqrestore(&ctx->lock, flags); + } + + return 0; +} + +uint32_t rga_internal_ctx_alloc_to_get_idr_id(uint32_t flags) +{ + struct rga_pending_ctx_manager *ctx_manager; + struct rga_internal_ctx_t *ctx; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (ctx == NULL) { + pr_err("can not kzalloc for rga_pending_ctx_manager\n"); + return -ENOMEM; + } + + ctx_manager = rga_drvdata->pend_ctx_manager; + if (ctx_manager == NULL) { + pr_err("rga_pending_ctx_manager is null!\n"); + kfree(ctx); + return -EFAULT; + } + + spin_lock_init(&ctx->lock); + + /* + * Get the user-visible handle using idr. Preload and perform + * allocation under our spinlock. + */ + + mutex_lock(&ctx_manager->lock); + + idr_preload(GFP_KERNEL); + ctx->id = idr_alloc(&ctx_manager->ctx_id_idr, ctx, 1, 0, GFP_KERNEL); + idr_preload_end(); + + ctx_manager->ctx_count++; + + kref_init(&ctx->refcount); + ctx->pid = current->pid; + ctx->flags = flags; + + mutex_unlock(&ctx_manager->lock); + + if (ctx->id < 0) + pr_err("[pid: %d]alloc ctx_id failed", ctx->pid); + + return (uint32_t)ctx->id; +} + +int rga_internal_ctx_config_by_user_ctx(struct rga_user_ctx_t *user_ctx) +{ + struct rga_pending_ctx_manager *ctx_manager; + struct rga_internal_ctx_t *ctx; + struct rga_req *cached_cmd; + int ret = 0; + bool first_config = false; + unsigned long flags; + + ctx_manager = rga_drvdata->pend_ctx_manager; + + ctx = rga_internal_ctx_lookup(ctx_manager, user_ctx->id); + if (IS_ERR_OR_NULL(ctx)) { + pr_err("can not find internal ctx from id[%d]", user_ctx->id); + return -EINVAL; + } + + spin_lock_irqsave(&ctx->lock, flags); + + cached_cmd = ctx->cached_cmd; + + spin_unlock_irqrestore(&ctx->lock, flags); + + if (cached_cmd == NULL) { + cached_cmd = kmalloc_array(user_ctx->cmd_num, sizeof(struct rga_req), GFP_KERNEL); + if (cached_cmd == NULL) { + pr_err("cmd_cached list alloc error!\n"); + return -ENOMEM; + } + + first_config = true; + } + + if (unlikely(copy_from_user(cached_cmd, u64_to_user_ptr(user_ctx->cmd_ptr), + sizeof(struct rga_req) * user_ctx->cmd_num))) { + pr_err("rga_user_ctx cmd list copy_from_user failed\n"); + if (first_config) + kfree(cached_cmd); + return -EFAULT; + } + + spin_lock_irqsave(&ctx->lock, flags); + + ctx->sync_mode = user_ctx->sync_mode; + ctx->cmd_num = user_ctx->cmd_num; + ctx->cached_cmd = cached_cmd; + ctx->mpi_config_flags = user_ctx->mpi_config_flags; + + spin_unlock_irqrestore(&ctx->lock, flags); + + return ret; +} + +int rga_internal_ctx_commit_by_user_ctx(struct rga_user_ctx_t *user_ctx) +{ + struct rga_pending_ctx_manager *ctx_manager; + struct rga_internal_ctx_t *ctx; + struct rga_req *cached_cmd; + int i; + int ret = 0; + unsigned long flags; + + ctx_manager = rga_drvdata->pend_ctx_manager; + + ctx = rga_internal_ctx_lookup(ctx_manager, user_ctx->id); + if (IS_ERR_OR_NULL(ctx)) { + pr_err("can not find internal ctx from id[%d]", user_ctx->id); + return -EINVAL; + } + + spin_lock_irqsave(&ctx->lock, flags); + + if (ctx->is_running) { + pr_err("can not re-config when ctx is running"); + spin_unlock_irqrestore(&ctx->lock, flags); + return -EFAULT; + } + + /* Reset */ + ctx->finished_job_count = 0; + + cached_cmd = ctx->cached_cmd; + if (cached_cmd == NULL) { + pr_err("can not find cached cmd from id[%d]", user_ctx->id); + spin_unlock_irqrestore(&ctx->lock, flags); + return -EINVAL; + } + + ctx->use_batch_mode = true; + ctx->is_running = true; + + spin_unlock_irqrestore(&ctx->lock, flags); + + for (i = 0; i < ctx->cmd_num; i++) { + ret = rga_job_commit(&(cached_cmd[i]), ctx); + if (ret < 0) { + pr_err("rga_job_commit failed\n"); + return -EFAULT; + } + } + + user_ctx->out_fence_fd = ctx->out_fence_fd; + + return ret; +} + +void rga_internal_ctx_kref_release(struct kref *ref) +{ + struct rga_internal_ctx_t *ctx; + struct rga_scheduler_t *scheduler = NULL; + struct rga_job *job_pos, *job_q, *job; + int i; + bool need_reset = false; + unsigned long flags; + ktime_t now = ktime_get(); + + ctx = container_of(ref, struct rga_internal_ctx_t, refcount); + + spin_lock_irqsave(&ctx->lock, flags); + + if (!ctx->is_running || ctx->finished_job_count >= ctx->cmd_num) { + spin_unlock_irqrestore(&ctx->lock, flags); + goto free_ctx; + } + + spin_unlock_irqrestore(&ctx->lock, flags); + + for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { + scheduler = rga_drvdata->scheduler[i]; + + spin_lock_irqsave(&scheduler->irq_lock, flags); + + list_for_each_entry_safe(job_pos, job_q, &scheduler->todo_list, head) { + if (ctx->id == job_pos->ctx_id) { + job = job_pos; + list_del_init(&job_pos->head); + + scheduler->job_count--; + } + } + + if (scheduler->running_job) { + job = scheduler->running_job; + + if (job->ctx_id == ctx->id) { + scheduler->running_job = NULL; + scheduler->timer.busy_time += ktime_us_delta(now, job->hw_recoder_time); + need_reset = true; + } + } + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + + if (need_reset) { + pr_info("reset core[%d] by user cancel", scheduler->core); + scheduler->ops->soft_reset(scheduler); + + rga_job_finish_and_next(scheduler, job, 0); + } + } + +free_ctx: + rga_internal_ctx_free_remove_idr(ctx); +} + +int rga_internal_ctx_cancel_by_user_ctx(uint32_t ctx_id) +{ + struct rga_pending_ctx_manager *ctx_manager; + struct rga_internal_ctx_t *ctx; + int ret = 0; + + ctx_manager = rga_drvdata->pend_ctx_manager; + + ctx = rga_internal_ctx_lookup(ctx_manager, ctx_id); + if (IS_ERR_OR_NULL(ctx)) { + pr_err("can not find internal ctx from id[%d]", ctx_id); + return -EINVAL; + } + + kref_put(&ctx->refcount, rga_internal_ctx_kref_release); + + return ret; +} + int rga_ctx_manager_init(struct rga_pending_ctx_manager **ctx_manager_session) { struct rga_pending_ctx_manager *ctx_manager = NULL; diff --git a/drivers/video/rockchip/rga3/rga_mm.c b/drivers/video/rockchip/rga3/rga_mm.c index 801c711991e8..e9528f1d88ee 100644 --- a/drivers/video/rockchip/rga3/rga_mm.c +++ b/drivers/video/rockchip/rga3/rga_mm.c @@ -346,7 +346,7 @@ static int rga_mm_map_dma_buffer(struct rga_external_buffer *external_buffer, for (i = 0; i < internal_buffer->dma_buffer_size; i++) { /* If the physical address is greater than 4G, there is no need to map RGA2. */ - if ((rga_drvdata->rga_scheduler[i]->core == RGA2_SCHEDULER_CORE0) && + if ((rga_drvdata->scheduler[i]->core == RGA2_SCHEDULER_CORE0) && (~internal_buffer->mm_flag & RGA_MEM_UNDER_4G) && i != 0) continue; @@ -355,22 +355,22 @@ static int rga_mm_map_dma_buffer(struct rga_external_buffer *external_buffer, ret = rga_dma_map_fd((int)external_buffer->memory, &internal_buffer->dma_buffer[i], DMA_BIDIRECTIONAL, - rga_drvdata->rga_scheduler[i]->dev); + rga_drvdata->scheduler[i]->dev); else if (external_buffer->type == RGA_DMA_BUFFER_PTR) ret = rga_dma_map_buf((struct dma_buf *) u64_to_user_ptr(external_buffer->memory), &internal_buffer->dma_buffer[i], DMA_BIDIRECTIONAL, - rga_drvdata->rga_scheduler[i]->dev); + rga_drvdata->scheduler[i]->dev); else ret = -EFAULT; if (ret < 0) { pr_err("%s core[%d] map dma buffer error!\n", - __func__, rga_drvdata->rga_scheduler[0]->core); + __func__, rga_drvdata->scheduler[0]->core); goto FREE_RGA_DMA_BUF; } - internal_buffer->dma_buffer[i].core = rga_drvdata->rga_scheduler[i]->core; + internal_buffer->dma_buffer[i].core = rga_drvdata->scheduler[i]->core; /* At first, check whether the physical address. */ if (i == 0) { @@ -407,11 +407,11 @@ static void rga_mm_unmap_virt_addr(struct rga_internal_buffer *internal_buffer) WARN_ON(internal_buffer->dma_buffer == NULL || internal_buffer->virt_addr == NULL); for (i = 0; i < internal_buffer->dma_buffer_size; i++) - if (rga_drvdata->rga_scheduler[i]->core == RGA3_SCHEDULER_CORE0 || - rga_drvdata->rga_scheduler[i]->core == RGA3_SCHEDULER_CORE1) + if (rga_drvdata->scheduler[i]->core == RGA3_SCHEDULER_CORE0 || + rga_drvdata->scheduler[i]->core == RGA3_SCHEDULER_CORE1) rga_iommu_unmap_virt_addr(&internal_buffer->dma_buffer[i]); else if (internal_buffer->dma_buffer[i].core != 0) - dma_unmap_sg(rga_drvdata->rga_scheduler[i]->dev, + dma_unmap_sg(rga_drvdata->scheduler[i]->dev, internal_buffer->dma_buffer[i].sgt->sgl, internal_buffer->dma_buffer[i].sgt->orig_nents, DMA_BIDIRECTIONAL); @@ -463,7 +463,7 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer, for (i = 0; i < internal_buffer->dma_buffer_size; i++) { /* If the physical address is greater than 4G, there is no need to map RGA2. */ - if ((rga_drvdata->rga_scheduler[i]->core == RGA2_SCHEDULER_CORE0) && + if ((rga_drvdata->scheduler[i]->core == RGA2_SCHEDULER_CORE0) && (~internal_buffer->mm_flag & RGA_MEM_UNDER_4G) && i != 0) continue; @@ -472,7 +472,7 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer, &internal_buffer->dma_buffer[i]); if (ret < 0) { pr_err("%s core[%d] alloc sgt error!\n", __func__, - rga_drvdata->rga_scheduler[0]->core); + rga_drvdata->scheduler[0]->core); goto free_sgt_and_dma_buffer; } @@ -482,47 +482,47 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer, } for (i = 0; i < internal_buffer->dma_buffer_size; i++) { - if ((rga_drvdata->rga_scheduler[i]->core == RGA2_SCHEDULER_CORE0) && + if ((rga_drvdata->scheduler[i]->core == RGA2_SCHEDULER_CORE0) && (~internal_buffer->mm_flag & RGA_MEM_UNDER_4G)) continue; - if (rga_drvdata->rga_scheduler[i]->core == RGA3_SCHEDULER_CORE0 || - rga_drvdata->rga_scheduler[i]->core == RGA3_SCHEDULER_CORE1) { + if (rga_drvdata->scheduler[i]->core == RGA3_SCHEDULER_CORE0 || + rga_drvdata->scheduler[i]->core == RGA3_SCHEDULER_CORE1) { ret = rga_iommu_map_virt_addr(&internal_buffer->memory_parm, &internal_buffer->dma_buffer[i], - rga_drvdata->rga_scheduler[i]->dev, + rga_drvdata->scheduler[i]->dev, internal_buffer->current_mm); if (ret < 0) { pr_err("%s core[%d] iommu_map virtual address error!\n", - __func__, rga_drvdata->rga_scheduler[i]->core); + __func__, rga_drvdata->scheduler[i]->core); goto unmap_virt_addr; } } else { - ret = dma_map_sg(rga_drvdata->rga_scheduler[i]->dev, + ret = dma_map_sg(rga_drvdata->scheduler[i]->dev, internal_buffer->dma_buffer[i].sgt->sgl, internal_buffer->dma_buffer[i].sgt->orig_nents, DMA_BIDIRECTIONAL); if (ret == 0) { pr_err("%s core[%d] dma_map_sgt error! va = 0x%lx, nents = %d\n", - __func__, rga_drvdata->rga_scheduler[i]->core, + __func__, rga_drvdata->scheduler[i]->core, (unsigned long)internal_buffer->virt_addr->addr, internal_buffer->dma_buffer[i].sgt->orig_nents); goto unmap_virt_addr; } } - internal_buffer->dma_buffer[i].core = rga_drvdata->rga_scheduler[i]->core; + internal_buffer->dma_buffer[i].core = rga_drvdata->scheduler[i]->core; } return 0; unmap_virt_addr: for (i = 0; i < internal_buffer->dma_buffer_size; i++) - if (rga_drvdata->rga_scheduler[i]->core == RGA3_SCHEDULER_CORE0 || - rga_drvdata->rga_scheduler[i]->core == RGA3_SCHEDULER_CORE1) + if (rga_drvdata->scheduler[i]->core == RGA3_SCHEDULER_CORE0 || + rga_drvdata->scheduler[i]->core == RGA3_SCHEDULER_CORE1) rga_iommu_unmap_virt_addr(&internal_buffer->dma_buffer[i]); else if (internal_buffer->dma_buffer[i].core != 0) - dma_unmap_sg(rga_drvdata->rga_scheduler[i]->dev, + dma_unmap_sg(rga_drvdata->scheduler[i]->dev, internal_buffer->dma_buffer[i].sgt->sgl, internal_buffer->dma_buffer[i].sgt->orig_nents, DMA_BIDIRECTIONAL); diff --git a/drivers/video/rockchip/rga3/rga_policy.c b/drivers/video/rockchip/rga3/rga_policy.c index 6922dcb4c0fd..0fab697747b4 100644 --- a/drivers/video/rockchip/rga3/rga_policy.c +++ b/drivers/video/rockchip/rga3/rga_policy.c @@ -188,8 +188,8 @@ int rga_job_assign(struct rga_job *job) /* function */ for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { - data = rga_drvdata->rga_scheduler[i]->data; - scheduler = rga_drvdata->rga_scheduler[i]; + data = rga_drvdata->scheduler[i]->data; + scheduler = rga_drvdata->scheduler[i]; if (DEBUGGER_EN(MSG)) pr_info("start policy on core = %d", scheduler->core); @@ -276,7 +276,7 @@ int rga_job_assign(struct rga_job *job) skip_functional_policy: for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { - scheduler = rga_drvdata->rga_scheduler[i]; + scheduler = rga_drvdata->scheduler[i]; if (optional_cores & scheduler->core) { spin_lock_irqsave(&scheduler->irq_lock, flags);