mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
video: rockchip: rga3: fix hardware state has been cleared after timeout
Change-Id: I15607f0af364bbb5947aba19024f0d582148016f Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com>
This commit is contained in:
@@ -3120,23 +3120,35 @@ static int rga2_read_status(struct rga_job *job, struct rga_scheduler_t *schedul
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga2_irq(struct rga_scheduler_t *scheduler)
|
||||
static void rga2_clear_intr(struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
struct rga_job *job = scheduler->running_job;
|
||||
|
||||
/*clear INTR */
|
||||
rga_write(rga_read(RGA2_INT, scheduler) |
|
||||
(m_RGA2_INT_ERROR_CLEAR_MASK |
|
||||
m_RGA2_INT_ALL_CMD_DONE_INT_CLEAR | m_RGA2_INT_NOW_CMD_DONE_INT_CLEAR |
|
||||
m_RGA2_INT_LINE_RD_CLEAR | m_RGA2_INT_LINE_WR_CLEAR),
|
||||
RGA2_INT, scheduler);
|
||||
}
|
||||
|
||||
static int rga2_irq(struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
struct rga_job *job = scheduler->running_job;
|
||||
|
||||
/* The hardware interrupt top-half don't need to lock the scheduler. */
|
||||
if (job == NULL)
|
||||
return IRQ_HANDLED;
|
||||
if (job == NULL) {
|
||||
rga2_clear_intr(scheduler);
|
||||
rga_err("core[%d], invalid job, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n",
|
||||
scheduler->core, rga_read(RGA2_INT, scheduler),
|
||||
rga_read(RGA2_STATUS2, scheduler), rga_read(RGA2_STATUS1, scheduler),
|
||||
rga_read(RGA2_WORK_CNT, scheduler), rga_read(RGA2_WORK_CNT, scheduler));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) {
|
||||
rga2_clear_intr(scheduler);
|
||||
|
||||
if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state))
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
scheduler->ops->read_status(job, scheduler);
|
||||
|
||||
@@ -3158,6 +3170,8 @@ static int rga2_irq(struct rga_scheduler_t *scheduler)
|
||||
scheduler->ops->soft_reset(scheduler);
|
||||
}
|
||||
|
||||
rga2_clear_intr(scheduler);
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
|
||||
@@ -263,27 +263,29 @@ static int rga_job_timeout_query_state(struct rga_job *job, int orig_ret)
|
||||
{
|
||||
struct rga_scheduler_t *scheduler = job->scheduler;
|
||||
|
||||
if (scheduler->ops->read_status) {
|
||||
scheduler->ops->read_status(job, scheduler);
|
||||
rga_job_err(job, "core[%d]: INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n",
|
||||
scheduler->core,
|
||||
job->intr_status, job->hw_status, job->cmd_status,
|
||||
job->work_cycle, job->work_cycle);
|
||||
}
|
||||
|
||||
if (test_bit(RGA_JOB_STATE_DONE, &job->state) &&
|
||||
test_bit(RGA_JOB_STATE_FINISH, &job->state)) {
|
||||
return orig_ret;
|
||||
} else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) &&
|
||||
test_bit(RGA_JOB_STATE_FINISH, &job->state)) {
|
||||
rga_job_err(job, "job hardware has finished, but the software has timeout!\n");
|
||||
|
||||
return -EBUSY;
|
||||
} else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) &&
|
||||
!test_bit(RGA_JOB_STATE_FINISH, &job->state)) {
|
||||
rga_job_err(job, "job hardware has timeout.\n");
|
||||
|
||||
if (scheduler->ops->read_status)
|
||||
scheduler->ops->read_status(job, scheduler);
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
rga_job_err(job, "timeout core[%d]: INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n",
|
||||
scheduler->core,
|
||||
job->intr_status, job->hw_status, job->cmd_status,
|
||||
job->work_cycle, job->work_cycle);
|
||||
|
||||
return orig_ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user