diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index 99d725a79f99..14558ada644a 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -51,14 +51,15 @@ #include #include #include +#include #include "rga.h" #include "rga_debugger.h" #define RGA_CORE_REG_OFFSET 0x10000 -/* sample interval: 100ms */ -#define RGA_LOAD_INTERVAL 100000 +/* sample interval: 1000ms */ +#define RGA_LOAD_INTERVAL 1000000000 #if ((defined(CONFIG_RK_IOMMU) || defined(CONFIG_ROCKCHIP_IOMMU)) \ && defined(CONFIG_ION_ROCKCHIP)) @@ -246,6 +247,7 @@ struct rga_job { struct dma_fence *in_fence; spinlock_t fence_lock; ktime_t timestamp; + ktime_t running_time; unsigned int flags; int job_id; int priority; @@ -262,6 +264,11 @@ struct rga_backend_ops { void (*soft_reset)(struct rga_scheduler_t *scheduler); }; +struct rga_timer { + u32 busy_time; + u32 busy_time_record; +}; + struct rga_scheduler_t { struct device *dev; void __iomem *rga_base; @@ -281,7 +288,8 @@ struct rga_scheduler_t { int irq; struct rga_version_t version; int core; - unsigned int core_offset; + + struct rga_timer timer; }; struct rga_drvdata_t { diff --git a/drivers/video/rockchip/rga3/rga2_reg_info.c b/drivers/video/rockchip/rga3/rga2_reg_info.c index b8fb4cce6c47..ccca25b655d9 100644 --- a/drivers/video/rockchip/rga3/rga2_reg_info.c +++ b/drivers/video/rockchip/rga3/rga2_reg_info.c @@ -2487,13 +2487,16 @@ int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) rga_write(rga_read(RGA2_INT, scheduler) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8), RGA2_INT, scheduler); - if (RGA_DEBUG_MSG) { + if (RGA_DEBUG_TIME) { pr_err("sys_ctrl = %x, int = %x, set cmd use time = %lld\n", rga_read(RGA2_SYS_CTRL, scheduler), rga_read(RGA2_INT, scheduler), - ktime_to_us(ktime_sub(now, job->timestamp))); + ktime_to_us(ktime_sub(now, job->running_time))); } + job->timestamp = now; + job->running_time = now; + rga_write(1, RGA2_CMD_CTRL, scheduler); #if CONFIG_ROCKCHIP_RGA_DEBUGGER diff --git a/drivers/video/rockchip/rga3/rga3_reg_info.c b/drivers/video/rockchip/rga3/rga3_reg_info.c index 17d7aaccae07..a8b3ef97baa2 100644 --- a/drivers/video/rockchip/rga3/rga3_reg_info.c +++ b/drivers/video/rockchip/rga3/rga3_reg_info.c @@ -2084,12 +2084,17 @@ int rga3_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) rga_read(RGA3_INT_EN, scheduler), rga_read(RGA3_INT_RAW, scheduler)); - pr_err("status0 = %x, status1 = %x, set cmd use time = %lld\n", + pr_err("status0 = %x, status1 = %x\n", rga_read(RGA3_STATUS0, scheduler), - rga_read(RGA3_STATUS1, scheduler), - ktime_to_us(ktime_sub(now, job->timestamp))); + rga_read(RGA3_STATUS1, scheduler)); } + if (RGA_DEBUG_TIME) + pr_err("set cmd use time = %lld\n", ktime_to_us(ktime_sub(now, job->running_time))); + + job->timestamp = now; + job->running_time = now; + rga_write(1, RGA3_SYS_CTRL, scheduler); #if CONFIG_ROCKCHIP_RGA_DEBUGGER diff --git a/drivers/video/rockchip/rga3/rga_debugger.c b/drivers/video/rockchip/rga3/rga_debugger.c index 5fea529a8c20..23bb4362fa0e 100644 --- a/drivers/video/rockchip/rga3/rga_debugger.c +++ b/drivers/video/rockchip/rga3/rga_debugger.c @@ -138,8 +138,31 @@ static int rga_version_show(struct seq_file *m, void *data) static int rga_load_show(struct seq_file *m, void *data) { - seq_printf(m, "%s: v%s\n", DRIVER_DESC, DRIVER_VERSION); + struct rga_scheduler_t *rga_scheduler = NULL; + unsigned long flags; + int i; + int load; + u32 busy_time_total; + seq_printf(m, "num of scheduler = %d\n", rga_drvdata->num_of_scheduler); + seq_printf(m, "================= load ==================\n"); + + for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { + rga_scheduler = rga_drvdata->rga_scheduler[i]; + + seq_printf(m, "scheduler[%d]: %s\n", + i, dev_driver_string(rga_scheduler->dev)); + + spin_lock_irqsave(&rga_scheduler->irq_lock, flags); + + busy_time_total = rga_scheduler->timer.busy_time_record; + + spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); + + load = (busy_time_total * 100000 / RGA_LOAD_INTERVAL); + seq_printf(m, "load = %d", load); + seq_printf(m, "-----------------------------------\n"); + } return 0; } @@ -154,8 +177,8 @@ static int rga_scheduler_show(struct seq_file *m, void *data) for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { rga_scheduler = rga_drvdata->rga_scheduler[i]; - seq_printf(m, "scheduler[%d]: core = %d\n", - i, rga_scheduler->core); + seq_printf(m, "scheduler[%d]: %s\n", + i, dev_driver_string(rga_scheduler->dev)); seq_printf(m, "-----------------------------------\n"); seq_printf(m, "pd_ref = %d\n", rga_scheduler->pd_refcount); } @@ -535,4 +558,4 @@ void rga_cmd_print_debug_info(struct rga_req *req) pr_info("yuv2rgb mode is %x\n", req->yuv2rgb_mode); pr_info("set core = %d, priority = %d, in_fence_fd = %d\n", req->core, req->priority, req->in_fence_fd); -} \ No newline at end of file +} diff --git a/drivers/video/rockchip/rga3/rga_drv.c b/drivers/video/rockchip/rga3/rga_drv.c index e62c488f220f..32f4bd7133bd 100644 --- a/drivers/video/rockchip/rga3/rga_drv.c +++ b/drivers/video/rockchip/rga3/rga_drv.c @@ -23,6 +23,10 @@ struct rga2_mmu_info_t rga2_mmu_info; struct rga_drvdata_t *rga_drvdata; +/* set hrtimer */ +static struct hrtimer timer; +static ktime_t kt; + static const struct rga_backend_ops rga3_ops = { .get_version = rga3_get_version, .set_reg = rga3_set_reg, @@ -71,6 +75,51 @@ int rga_kernel_commit(struct rga_req *cmd) } EXPORT_SYMBOL_GPL(rga_kernel_commit); +static enum hrtimer_restart hrtimer_handler(struct hrtimer *timer) +{ + struct rga_drvdata_t *rga = rga_drvdata; + struct rga_scheduler_t *scheduler = NULL; + struct rga_job *job = NULL; + unsigned long flags; + int i; + + ktime_t now = ktime_get(); + + for (i = 0; i < rga->num_of_scheduler; i++) { + scheduler = rga->rga_scheduler[i]; + + spin_lock_irqsave(&scheduler->irq_lock, flags); + + /* if timer action on job running */ + job = scheduler->running_job; + if (job) { + scheduler->timer.busy_time += ktime_us_delta(now, job->timestamp); + job->timestamp = now; + } + + scheduler->timer.busy_time_record = scheduler->timer.busy_time; + scheduler->timer.busy_time = 0; + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + } + + hrtimer_forward_now(timer, kt); + return HRTIMER_RESTART; +} + +static void rga_init_timer(void) +{ + kt = ktime_set(0, RGA_LOAD_INTERVAL); + hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_start(&timer, kt, HRTIMER_MODE_REL); + timer.function = hrtimer_handler; +} + +static void rga_cancel_timer(void) +{ + hrtimer_cancel(&timer); +} + #ifndef CONFIG_ROCKCHIP_FPGA int rga_power_enable(struct rga_scheduler_t *rga_scheduler) { @@ -901,6 +950,8 @@ static int __init rga_init(void) return ret; } + rga_init_timer(); + rga_drvdata->fence_ctx = rga_fence_context_alloc(); if (IS_ERR(rga_drvdata->fence_ctx)) { pr_err("failed to allocate fence context for RGA\n"); @@ -941,6 +992,8 @@ static void __exit rga_exit(void) rga_fence_context_free(rga_drvdata->fence_ctx); + rga_cancel_timer(); + platform_driver_unregister(&rga3_core0_driver); platform_driver_unregister(&rga3_core1_driver); platform_driver_unregister(&rga2_driver); diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index 5efefc8007d5..a4cfbc1a485c 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -89,6 +89,7 @@ static struct rga_job *rga_job_alloc(struct rga_req *rga_command_base) INIT_LIST_HEAD(&job->head); job->timestamp = ktime_get(); + job->running_time = ktime_get(); job->rga_command_base = *rga_command_base; @@ -267,23 +268,25 @@ void rga_job_done(struct rga_scheduler_t *rga_scheduler, int ret) struct rga_job *job; unsigned long flags; - ktime_t now; + ktime_t now = ktime_get(); spin_lock_irqsave(&rga_scheduler->irq_lock, flags); job = rga_scheduler->running_job; rga_scheduler->running_job = NULL; + rga_scheduler->timer.busy_time += ktime_us_delta(now, job->timestamp); + spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags); job->flags |= RGA_JOB_DONE; job->ret = ret; - now = ktime_get(); - if (RGA_DEBUG_TIME) pr_err("%s use time = %lld\n", __func__, - ktime_to_us(ktime_sub(now, job->timestamp))); + ktime_us_delta(now, job->running_time)); + + job->running_time = now; if (job->core == RGA2_SCHEDULER_CORE0) rga2_dma_flush_cache_for_virtual_address(&job->vir_page_table, @@ -446,7 +449,7 @@ static inline int rga_job_wait(struct rga_scheduler_t *rga_scheduler, if (RGA_DEBUG_TIME) pr_err("%s use time = %lld\n", __func__, - ktime_to_us(ktime_sub(now, job->timestamp))); + ktime_to_us(ktime_sub(now, job->running_time))); return ret; }