video: rockchip: rga3: code optimization

1. rename rga_scheduler to scheduler
2. sort rga_internal_ctx_* func

Signed-off-by: Li Huang <putin.li@rock-chips.com>
Change-Id: I1a5fd7f1b8b400728ac00c55b684d401ad269dc1
This commit is contained in:
Li Huang
2022-03-31 14:21:25 +08:00
committed by Tao Huang
parent 0a1063e4ac
commit 2be1c5ce62
8 changed files with 527 additions and 527 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);