u32 state;
u32 job_id;
u32 val;
+ s32 info;
u8 cpu;
} g2d_stamp_list[G2D_MAX_STAMP_SIZE];
while (1) {
stamp = &g2d_stamp_list[i];
- seq_printf(s, "[%d] %u:%u@%u (0x%x) %06llu\n", i++,
+ seq_printf(s, "[%4d] %u:%2u@%u (0x%2x) %6d %06llu\n", i++,
stamp->cpu, stamp->job_id, stamp->val, stamp->state,
- ktime_to_us(stamp->time));
+ stamp->info, ktime_to_us(stamp->time));
i &= (G2D_MAX_STAMP_SIZE - 1);
i, regs[i].offset, regs[i].value);
}
-void g2d_stamp_task(struct g2d_task *task, u32 val)
+void g2d_stamp_task(struct g2d_task *task, u32 val, s32 info)
{
int ptr = atomic_inc_return(&p_stamp) & (G2D_MAX_STAMP_SIZE - 1);
struct g2d_stamp *stamp = &g2d_stamp_list[ptr];
stamp->time = ktime_get();
stamp->val = val;
stamp->cpu = smp_processor_id();
+ stamp->info = info;
/* when error status, dump the task */
if ((stamp->val == G2D_STAMP_STATE_TIMEOUT_HW) ||
if (stamp->val == G2D_STAMP_STATE_DONE) {
if (g2d_debug == 1) {
- pr_info("Job #%x took %06llu to H/W process\n",
- task->job_id, ktime_us_delta(task->ktime_end, task->ktime_begin));
+ pr_info("Job #%x took %06d to H/W process\n",
+ task->job_id, info);
} else if (g2d_debug == 2) {
g2d_dump_task(task);
}
};
enum g2d_stamp_id {
- G2D_STAMP_STATE_ALLOC,
+ G2D_STAMP_STATE_RUNTIME_PM,
+ G2D_STAMP_STATE_TASK_RESOURCE,
G2D_STAMP_STATE_BEGIN,
- G2D_STAMP_STATE_PM_RESUME,
G2D_STAMP_STATE_PUSH,
+ G2D_STAMP_STATE_INT,
G2D_STAMP_STATE_DONE,
- G2D_STAMP_STATE_PM_SUSPEND,
- G2D_STAMP_STATE_FREE,
G2D_STAMP_STATE_TIMEOUT_FENCE,
G2D_STAMP_STATE_TIMEOUT_HW,
G2D_STAMP_STATE_ERR_INT,
G2D_STAMP_STATE_MMUFAULT,
- G2D_STAMP_STATE_SHUTDOWN_S,
- G2D_STAMP_STATE_SHUTDOWN_E,
- G2D_STAMP_STATE_SUSPEND_S,
- G2D_STAMP_STATE_SUSPEND_E,
- G2D_STAMP_STATE_RESUME_S,
- G2D_STAMP_STATE_RESUME_E,
+ G2D_STAMP_STATE_SHUTDOWN,
+ G2D_STAMP_STATE_SUSPEND,
+ G2D_STAMP_STATE_RESUME,
G2D_STAMP_STATE_HWFCBUF,
};
void g2d_init_debug(struct g2d_device *dev);
void g2d_destroy_debug(struct g2d_device *dev);
-void g2d_stamp_task(struct g2d_task *task, u32 val);
+void g2d_stamp_task(struct g2d_task *task, u32 val, s32 info);
void g2d_dump_task(struct g2d_task *task);
#endif /* __EXYNOS_G2D_HELPER_H_ */
unsigned long flags;
u32 job_state;
- /* TODO: Dump of internal state of G2D */
+ spin_lock_irqsave(&g2d_dev->lock_task, flags);
- dev_err(g2d_dev->dev, "%s: Time is up: %d msec for job %d\n",
- __func__, G2D_HW_TIMEOUT_MSEC, task->job_id);
+ job_state = g2d_hw_get_job_state(g2d_dev, task->job_id);
- spin_lock_irqsave(&g2d_dev->lock_task, flags);
+ g2d_stamp_task(task, G2D_STAMP_STATE_TIMEOUT_HW, job_state);
+
+ dev_err(g2d_dev->dev, "%s: Time is up: %d msec for job %u %lu %u\n",
+ __func__, G2D_HW_TIMEOUT_MSEC,
+ task->job_id, task->state, job_state);
if (!is_task_state_active(task))
/*
*/
goto out;
- job_state = g2d_hw_get_job_state(g2d_dev, task->job_id);
if (job_state == G2D_JOB_STATE_DONE)
/*
* The task timed out is not currently running in H/W.
/* Time out is not caused by this task */
goto out;
- g2d_stamp_task(task, G2D_STAMP_STATE_TIMEOUT_HW);
-
mark_task_state_killed(task);
g2d_hw_kill_task(g2d_dev, task->job_id);
{
g2d_hw_push_task(g2d_dev, task);
- g2d_stamp_task(task, G2D_STAMP_STATE_PUSH);
+ task->ktime_end = ktime_get();
+
+ /* record the time between user request and H/W push */
+ g2d_stamp_task(task, G2D_STAMP_STATE_PUSH,
+ (int)ktime_us_delta(task->ktime_end, task->ktime_begin));
+
+ task->ktime_begin = ktime_get();
if (IS_HWFC(task->flags))
hwfc_set_valid_buffer(task->job_id, task->job_id);
spin_lock(&g2d_dev->lock_task);
intflags = g2d_hw_finished_job_ids(g2d_dev);
+
+ g2d_stamp_task(NULL, G2D_STAMP_STATE_INT, intflags);
+
if (intflags != 0) {
for (id = 0; id < G2D_MAX_JOBS; id++) {
if ((intflags & (1 << id)) == 0)
struct g2d_task *task =
g2d_get_active_task_from_id(g2d_dev, job_id);
- if (job_id < 0) {
+ if (job_id < 0)
dev_err(g2d_dev->dev, "No task is running in HW\n");
- } else if (task == NULL) {
+ else if (task == NULL)
dev_err(g2d_dev->dev,
"%s: Current job %d in HW is not active\n",
__func__, job_id);
- } else {
+ else
dev_err(g2d_dev->dev,
"%s: Error occurred during running job %d\n",
__func__, job_id);
- g2d_stamp_task(task, G2D_STAMP_STATE_ERR_INT);
- }
+ g2d_stamp_task(task, G2D_STAMP_STATE_ERR_INT, errstatus);
g2d_flush_all_tasks(g2d_dev);
task = g2d_get_active_task_from_id(g2d_dev, job_id);
spin_unlock_irqrestore(&g2d_dev->lock_task, flags);
- g2d_stamp_task(task, G2D_STAMP_STATE_MMUFAULT);
+ g2d_stamp_task(task, G2D_STAMP_STATE_MMUFAULT, 0);
return 0;
}
break;
}
- g2d_stamp_task(task, G2D_STAMP_STATE_BEGIN);
+ g2d_stamp_task(task, G2D_STAMP_STATE_BEGIN, task->priority);
g2d_start_task(task);
{
struct g2d_device *g2d_dev = platform_get_drvdata(pdev);
- g2d_stamp_task(NULL, G2D_STAMP_STATE_SHUTDOWN_S);
+ g2d_stamp_task(NULL, G2D_STAMP_STATE_SHUTDOWN, 0);
g2d_prepare_suspend(g2d_dev);
wait_event(g2d_dev->freeze_wait, list_empty(&g2d_dev->tasks_active));
if (test_and_set_bit(G2D_DEVICE_STATE_IOVMM_DISABLED, &g2d_dev->state))
iovmm_deactivate(g2d_dev->dev);
- g2d_stamp_task(NULL, G2D_STAMP_STATE_SHUTDOWN_E);
+ g2d_stamp_task(NULL, G2D_STAMP_STATE_SHUTDOWN, 1);
}
static int g2d_remove(struct platform_device *pdev)
#ifdef CONFIG_PM
static int g2d_runtime_resume(struct device *dev)
{
- g2d_stamp_task(NULL, G2D_STAMP_STATE_PM_RESUME);
+ g2d_stamp_task(NULL, G2D_STAMP_STATE_RUNTIME_PM, 0);
return 0;
}
struct g2d_device *g2d_dev = dev_get_drvdata(dev);
clk_unprepare(g2d_dev->clock);
- g2d_stamp_task(NULL, G2D_STAMP_STATE_PM_SUSPEND);
+ g2d_stamp_task(NULL, G2D_STAMP_STATE_RUNTIME_PM, 1);
return 0;
}
unsigned long flags;
char name[32];
int i;
+ s32 afbc = 0;
for (i = 0; i < task->num_source; i++) {
fence = task->source[i].fence;
if (fence)
dma_fence_remove_callback(fence, &task->target.fence_cb);
- g2d_stamp_task(task, G2D_STAMP_STATE_TIMEOUT_FENCE);
+ /* check compressed buffer because crashed buffer makes recovery */
+ for (i = 0; i < task->num_source; i++) {
+ if (IS_AFBC(
+ task->source[i].commands[G2DSFR_IMG_COLORMODE].value))
+ afbc |= 1 << i;
+ }
+
+ if (IS_AFBC(task->target.commands[G2DSFR_IMG_COLORMODE].value))
+ afbc |= 1 << G2D_MAX_IMAGES;
+
+ g2d_stamp_task(task, G2D_STAMP_STATE_TIMEOUT_FENCE, afbc);
g2d_queuework_task(&task->starter);
};
{
list_del_init(&task->node);
- g2d_stamp_task(task, G2D_STAMP_STATE_DONE);
+ task->ktime_end = ktime_get();
+
+ g2d_stamp_task(task, G2D_STAMP_STATE_DONE,
+ (int)ktime_us_delta(task->ktime_end, task->ktime_begin));
del_timer(&task->timer);
success = false;
}
- task->ktime_end = ktime_get();
-
g2d_finish_task(g2d_dev, task, success);
}
list_move_tail(&task->node, &g2d_dev->tasks_active);
change_task_state_active(task);
- task->ktime_begin = ktime_get();
-
setup_timer(&task->timer,
g2d_hw_timeout_handler, (unsigned long)task);
set_bit(G2D_DEVICE_STATE_SUSPEND, &g2d_dev->state);
spin_unlock_irq(&g2d_dev->lock_task);
- g2d_stamp_task(NULL, G2D_STAMP_STATE_SUSPEND_S);
+ g2d_stamp_task(NULL, G2D_STAMP_STATE_SUSPEND, 0);
wait_event(g2d_dev->freeze_wait, list_empty(&g2d_dev->tasks_active));
- g2d_stamp_task(NULL, G2D_STAMP_STATE_SUSPEND_E);
+ g2d_stamp_task(NULL, G2D_STAMP_STATE_SUSPEND, 1);
}
void g2d_suspend_finish(struct g2d_device *g2d_dev)
spin_lock_irq(&g2d_dev->lock_task);
- g2d_stamp_task(NULL, G2D_STAMP_STATE_RESUME_S);
+ g2d_stamp_task(NULL, G2D_STAMP_STATE_RESUME, 0);
clear_bit(G2D_DEVICE_STATE_SUSPEND, &g2d_dev->state);
while (!list_empty(&g2d_dev->tasks_prepared)) {
}
spin_unlock_irq(&g2d_dev->lock_task);
- g2d_stamp_task(NULL, G2D_STAMP_STATE_RESUME_E);
+ g2d_stamp_task(NULL, G2D_STAMP_STATE_RESUME, 1);
}
static void g2d_schedule_task(struct g2d_task *task)
mod_timer(&task->timer,
jiffies + msecs_to_jiffies(G2D_FENCE_TIMEOUT_MSEC));
+ task->ktime_begin = ktime_get();
+
kref_put(&task->starter, g2d_queuework_task);
}
g2d_init_commands(task);
- g2d_stamp_task(task, G2D_STAMP_STATE_ALLOC);
+ g2d_stamp_task(task, G2D_STAMP_STATE_TASK_RESOURCE, 0);
spin_unlock_irqrestore(&g2d_dev->lock_task, flags);
list_add(&task->node, &g2d_dev->tasks_free);
}
- g2d_stamp_task(task, G2D_STAMP_STATE_FREE);
+ g2d_stamp_task(task, G2D_STAMP_STATE_TASK_RESOURCE, 1);
spin_unlock_irqrestore(&g2d_dev->lock_task, flags);
}
ptask = ptask->next;
}
+ g2d_stamp_task(task, G2D_STAMP_STATE_HWFCBUF, idx);
+
task->job_id = idx;
spin_unlock_irqrestore(&task->g2d_dev->lock_task, flags);
data->num_buffers = 1;
data->buffer[0].dmabuf.offset = 0;
data->buffer[0].length = ctx->hwfc_info->bufs[idx]->size;
-
- g2d_stamp_task(task, G2D_STAMP_STATE_HWFCBUF);
}
if (target->buffer_type == G2D_BUFTYPE_EMPTY) {