summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
diff options
context:
space:
mode:
authorRobert Foss <robert.foss@linaro.org>2021-03-16 18:19:21 +0100
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2021-03-22 12:30:14 +0100
commit2f6f8af672038b34d71e16ce9b30c59cc987db2b (patch)
treed142ee5e5879165a1b45944139c697a0bfb195c1 /drivers/media/platform/qcom/camss/camss-vfe-4-7.c
parentmedia: camss: Add support for CSIPHY hardware version Titan 170 (diff)
downloadlinux-2f6f8af672038b34d71e16ce9b30c59cc987db2b.tar.xz
linux-2f6f8af672038b34d71e16ce9b30c59cc987db2b.zip
media: camss: Refactor VFE power domain toggling
For Titan ISPs clocks fail to re-enable during vfe_get() after any vfe has been halted and its corresponding power domain power has been detached. Since all of the clocks depend on all of the PDs, per VFE PD detaching is no option for Gen2 HW. In order to not have regressions on for Gen1 HW, refactor the power domain management into hardware version specific code paths. Signed-off-by: Robert Foss <robert.foss@linaro.org> Reviewed-by: Andrey Konovalov <andrey.konovalov@linaro.org> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/platform/qcom/camss/camss-vfe-4-7.c')
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-4-7.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
index f5ba09a93016..a59635217758 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
@@ -8,6 +8,7 @@
* Copyright (C) 2015-2018 Linaro Ltd.
*/
+#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
@@ -1104,6 +1105,42 @@ static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
}
+/*
+ * vfe_pm_domain_off - Disable power domains specific to this VFE.
+ * @vfe: VFE Device
+ */
+static void vfe_pm_domain_off(struct vfe_device *vfe)
+{
+ struct camss *camss;
+
+ if (!vfe)
+ return;
+
+ camss = vfe->camss;
+
+ device_link_del(camss->genpd_link[vfe->id]);
+}
+
+/*
+ * vfe_pm_domain_on - Enable power domains specific to this VFE.
+ * @vfe: VFE Device
+ */
+static int vfe_pm_domain_on(struct vfe_device *vfe)
+{
+ struct camss *camss = vfe->camss;
+ enum vfe_line_id id = vfe->id;
+
+ camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
+
+ if (!camss->genpd_link[id]) {
+ dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static void vfe_violation_read(struct vfe_device *vfe)
{
u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
@@ -1162,6 +1199,8 @@ const struct vfe_hw_ops vfe_ops_4_7 = {
.hw_version_read = vfe_hw_version_read,
.isr_read = vfe_isr_read,
.isr = vfe_isr,
+ .pm_domain_off = vfe_pm_domain_off,
+ .pm_domain_on = vfe_pm_domain_on,
.reg_update_clear = vfe_reg_update_clear,
.reg_update = vfe_reg_update,
.subdev_init = vfe_subdev_init,