mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user