mirror of
https://github.com/torvalds/linux.git
synced 2024-12-21 10:31:54 +00:00
media: venus: Rework recovery mechanism
After power domains and clock restructuring the recovery for sdm845 and v4 did not work properly. Fix that by reworking the recovery function and the sequence. Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> Reviewed-by: Fritz Koenig <frkoenig@chromium.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
parent
10865c9898
commit
43e221e485
@ -6,6 +6,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/interconnect.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
@ -40,13 +41,7 @@ static void venus_event_notify(struct venus_core *core, u32 event)
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
disable_irq_nosync(core->irq);
|
||||
|
||||
/*
|
||||
* Delay recovery to ensure venus has completed any pending cache
|
||||
* operations. Without this sleep, we see device reset when firmware is
|
||||
* unloaded after a system error.
|
||||
*/
|
||||
schedule_delayed_work(&core->work, msecs_to_jiffies(100));
|
||||
schedule_delayed_work(&core->work, msecs_to_jiffies(10));
|
||||
}
|
||||
|
||||
static const struct hfi_core_ops venus_core_ops = {
|
||||
@ -59,23 +54,30 @@ static void venus_sys_error_handler(struct work_struct *work)
|
||||
container_of(work, struct venus_core, work.work);
|
||||
int ret = 0;
|
||||
|
||||
dev_warn(core->dev, "system error has occurred, starting recovery!\n");
|
||||
|
||||
pm_runtime_get_sync(core->dev);
|
||||
|
||||
hfi_core_deinit(core, true);
|
||||
hfi_destroy(core);
|
||||
|
||||
dev_warn(core->dev, "system error has occurred, starting recovery!\n");
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
|
||||
while (pm_runtime_active(core->dev_dec) || pm_runtime_active(core->dev_enc))
|
||||
msleep(10);
|
||||
|
||||
venus_shutdown(core);
|
||||
|
||||
pm_runtime_put_sync(core->dev);
|
||||
|
||||
while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0]))
|
||||
usleep_range(1000, 1500);
|
||||
|
||||
hfi_destroy(core);
|
||||
ret |= hfi_create(core, &venus_core_ops);
|
||||
|
||||
pm_runtime_get_sync(core->dev);
|
||||
|
||||
ret |= venus_boot(core);
|
||||
|
||||
ret |= hfi_core_resume(core, true);
|
||||
|
||||
enable_irq(core->irq);
|
||||
|
@ -986,13 +986,6 @@ static void venus_process_msg_sys_error(struct venus_hfi_device *hdev,
|
||||
|
||||
venus_set_state(hdev, VENUS_STATE_DEINIT);
|
||||
|
||||
/*
|
||||
* Once SYS_ERROR received from HW, it is safe to halt the AXI.
|
||||
* With SYS_ERROR, Venus FW may have crashed and HW might be
|
||||
* active and causing unnecessary transactions. Hence it is
|
||||
* safe to stop all AXI transactions from venus subsystem.
|
||||
*/
|
||||
venus_halt_axi(hdev);
|
||||
venus_sfr_print(hdev);
|
||||
}
|
||||
|
||||
@ -1009,10 +1002,6 @@ static irqreturn_t venus_isr_thread(struct venus_core *core)
|
||||
res = hdev->core->res;
|
||||
pkt = hdev->pkt_buf;
|
||||
|
||||
if (hdev->irq_status & WRAPPER_INTR_STATUS_A2HWD_MASK) {
|
||||
venus_sfr_print(hdev);
|
||||
hfi_process_watchdog_timeout(core);
|
||||
}
|
||||
|
||||
while (!venus_iface_msgq_read(hdev, pkt)) {
|
||||
msg_ret = hfi_process_msg_packet(core, pkt);
|
||||
|
Loading…
Reference in New Issue
Block a user