media: camss: Do vfe_get/vfe_put for csid on sm8250
authorBryan O'Donoghue <bryan.odonoghue@linaro.org>
Wed, 22 Dec 2021 00:37:50 +0000 (01:37 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Sun, 23 Jan 2022 20:18:41 +0000 (21:18 +0100)
The sm8250 CAMSS CSID depends on the VFE it is attached to being powered on
and clocked prior to taking the CSID out of reset.

It is possible to open just the CSID subdev from libcamera and attempt to
bring the CSID block up.

If we do not first bring up the VFE the CSID will fail to come out of
reset.

Tested-by: Julian Grahsl <jgrahsl@snap.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/platform/qcom/camss/camss-csid.c
drivers/media/platform/qcom/camss/camss-vfe.c
drivers/media/platform/qcom/camss/camss-vfe.h

index 9ef6fbbeeddf30779560ce053504940254a4cd8e..e6835b92695b62fbe108e489e9a0b90266e5d923 100644 (file)
@@ -156,10 +156,18 @@ static int csid_set_clock_rates(struct csid_device *csid)
 static int csid_set_power(struct v4l2_subdev *sd, int on)
 {
        struct csid_device *csid = v4l2_get_subdevdata(sd);
-       struct device *dev = csid->camss->dev;
+       struct camss *camss = csid->camss;
+       struct device *dev = camss->dev;
+       struct vfe_device *vfe = &camss->vfe[csid->id];
        int ret;
 
        if (on) {
+               if (camss->version == CAMSS_8250) {
+                       ret = vfe_get(vfe);
+                       if (ret < 0)
+                               return ret;
+               }
+
                ret = pm_runtime_resume_and_get(dev);
                if (ret < 0)
                        return ret;
@@ -204,6 +212,8 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
                camss_disable_clocks(csid->nclocks, csid->clock);
                ret = csid->vdda ? regulator_disable(csid->vdda) : 0;
                pm_runtime_put_sync(dev);
+               if (camss->version == CAMSS_8250)
+                       vfe_put(vfe);
        }
 
        return ret;
index 5b5fe620914d05cabac9990550a98e809e7e24dc..703ea39f126281ab4a530ddad01a60fbc756d3e8 100644 (file)
@@ -575,7 +575,7 @@ static int vfe_check_clock_rates(struct vfe_device *vfe)
  *
  * Return 0 on success or a negative error code otherwise
  */
-static int vfe_get(struct vfe_device *vfe)
+int vfe_get(struct vfe_device *vfe)
 {
        int ret;
 
@@ -637,7 +637,7 @@ error_pm_domain:
  * vfe_put - Power down VFE module
  * @vfe: VFE Device
  */
-static void vfe_put(struct vfe_device *vfe)
+void vfe_put(struct vfe_device *vfe)
 {
        mutex_lock(&vfe->power_lock);
 
index 6500474a749e7b148e31afb653e155752e2e2e5f..0eba04eb9b77c0341c3bac61679008b8f9f6e3e0 100644 (file)
@@ -203,4 +203,7 @@ extern const struct vfe_hw_ops vfe_ops_4_8;
 extern const struct vfe_hw_ops vfe_ops_170;
 extern const struct vfe_hw_ops vfe_ops_480;
 
+int vfe_get(struct vfe_device *vfe);
+void vfe_put(struct vfe_device *vfe);
+
 #endif /* QC_MSM_CAMSS_VFE_H */