summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/venus/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/qcom/venus/core.c')
-rw-r--r--drivers/media/platform/qcom/venus/core.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 203c6538044f..6103aaf43987 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -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,29 @@ 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);
- ret |= hfi_create(core, &venus_core_ops);
+ while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0]))
+ usleep_range(1000, 1500);
+
+ hfi_reinit(core);
pm_runtime_get_sync(core->dev);
ret |= venus_boot(core);
-
ret |= hfi_core_resume(core, true);
enable_irq(core->irq);
@@ -224,15 +225,9 @@ static int venus_probe(struct platform_device *pdev)
ret = dma_set_mask_and_coherent(dev, core->res->dma_mask);
if (ret)
- return ret;
+ goto err_core_put;
- if (!dev->dma_parms) {
- dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms),
- GFP_KERNEL);
- if (!dev->dma_parms)
- return -ENOMEM;
- }
- dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+ dma_set_max_seg_size(dev, UINT_MAX);
INIT_LIST_HEAD(&core->instances);
mutex_init(&core->lock);
@@ -242,11 +237,11 @@ static int venus_probe(struct platform_device *pdev)
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
"venus", core);
if (ret)
- return ret;
+ goto err_core_put;
ret = hfi_create(core, &venus_core_ops);
if (ret)
- return ret;
+ goto err_core_put;
pm_runtime_enable(dev);
@@ -287,8 +282,12 @@ static int venus_probe(struct platform_device *pdev)
goto err_core_deinit;
ret = pm_runtime_put_sync(dev);
- if (ret)
+ if (ret) {
+ pm_runtime_get_noresume(dev);
goto err_dev_unregister;
+ }
+
+ venus_dbgfs_init(core);
return 0;
@@ -299,9 +298,13 @@ err_core_deinit:
err_venus_shutdown:
venus_shutdown(core);
err_runtime_disable:
+ pm_runtime_put_noidle(dev);
pm_runtime_set_suspended(dev);
pm_runtime_disable(dev);
hfi_destroy(core);
+err_core_put:
+ if (core->pm_ops->core_put)
+ core->pm_ops->core_put(dev);
return ret;
}
@@ -337,6 +340,7 @@ static int venus_remove(struct platform_device *pdev)
v4l2_device_unregister(&core->v4l2_dev);
mutex_destroy(&core->pm_lock);
mutex_destroy(&core->lock);
+ venus_dbgfs_deinit(core);
return ret;
}
@@ -520,6 +524,7 @@ static const struct venus_resources sdm845_res_v2 = {
.vcodec_clks_num = 2,
.vcodec_pmdomains = { "venus", "vcodec0", "vcodec1" },
.vcodec_pmdomains_num = 3,
+ .opp_pmdomain = (const char *[]) { "cx", NULL },
.vcodec_num = 2,
.max_load = 3110400, /* 4096x2160@90 */
.hfi_version = HFI_VERSION_4XX,
@@ -527,6 +532,10 @@ static const struct venus_resources sdm845_res_v2 = {
.vmem_size = 0,
.vmem_addr = 0,
.dma_mask = 0xe0000000 - 1,
+ .cp_start = 0,
+ .cp_size = 0x70800000,
+ .cp_nonpixel_start = 0x1000000,
+ .cp_nonpixel_size = 0x24800000,
.fwname = "qcom/venus-5.2/venus.mdt",
};
@@ -565,6 +574,7 @@ static const struct venus_resources sc7180_res = {
.vcodec_clks_num = 2,
.vcodec_pmdomains = { "venus", "vcodec0" },
.vcodec_pmdomains_num = 2,
+ .opp_pmdomain = (const char *[]) { "cx", NULL },
.vcodec_num = 1,
.hfi_version = HFI_VERSION_4XX,
.vmem_id = VIDC_RESOURCE_NONE,