This adds suspend (power collapse) function with slightly
different order of calls comparing with Venus 3xx.
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@xxxxxxxxxx>
---
drivers/media/platform/qcom/venus/hfi_venus.c | 52 +++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c
b/drivers/media/platform/qcom/venus/hfi_venus.c
index 53546174aab8..f61d34bf61b4 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -1443,6 +1443,55 @@ static int venus_suspend_1xx(struct venus_core *core)
return 0;
}
+static int venus_suspend_4xx(struct venus_core *core)
+{
+ struct venus_hfi_device *hdev = to_hfi_priv(core);
+ struct device *dev = core->dev;
+ u32 val;
+ int ret;
+
+ if (!hdev->power_enabled || hdev->suspended)
+ return 0;
+
+ mutex_lock(&hdev->lock);
+ ret = venus_is_valid_state(hdev);
+ mutex_unlock(&hdev->lock);
+
+ if (!ret) {
+ dev_err(dev, "bad state, cannot suspend\n");
+ return -EINVAL;
+ }
+
+ ret = venus_prepare_power_collapse(hdev, false);
+ if (ret) {
+ dev_err(dev, "prepare for power collapse fail (%d)\n", ret);
+ return ret;
+ }
+
+ ret = readl_poll_timeout(core->base + CPU_CS_SCIACMDARG0, val,
+ val & CPU_CS_SCIACMDARG0_PC_READY,
+ POLL_INTERVAL_US, 100000);
+ if (ret) {
+ dev_err(dev, "Polling power collapse ready timed out\n");
+ return ret;
+ }
+
+ mutex_lock(&hdev->lock);
+
+ ret = venus_power_off(hdev);
+ if (ret) {
+ dev_err(dev, "venus_power_off (%d)\n", ret);
+ mutex_unlock(&hdev->lock);
+ return ret;
+ }
+
+ hdev->suspended = true;
+
+ mutex_unlock(&hdev->lock);
+
+ return 0;
+}
+
static int venus_suspend_3xx(struct venus_core *core)
{
struct venus_hfi_device *hdev = to_hfi_priv(core);
@@ -1507,6 +1556,9 @@ static int venus_suspend(struct venus_core *core)
if (core->res->hfi_version == HFI_VERSION_3XX)
return venus_suspend_3xx(core);
+ if (core->res->hfi_version == HFI_VERSION_4XX)
+ return venus_suspend_4xx(core);
+
return venus_suspend_1xx(core);
}