Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5df14030 authored by Sreesudhan Ramakrish Ramkumar's avatar Sreesudhan Ramakrish Ramkumar Committed by Peter Liu
Browse files

msm: camera: isp: Enable regulator to turn on clocks in ISPIF.



ISPIF enables VFE clocks to perform a hardware reset. VFE clocks
needs VFE regulators to be enabled to turn on clocks. This change
enables the regulators before the clocks are enabled and disables
regulators after clocks are disabled.

Change-Id: I8a65f8238cfbdaac64184e697e3f7e2a5665d4e9
Signed-off-by: default avatarSreesudhan Ramakrish Ramkumar <srramku@codeaurora.org>
parent fd854d74
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -11,7 +11,10 @@ Required properties:
- interrupts : should contain the ispif interrupt.
- interrupt-names : should specify relevant names to each interrupts
  property defined.
- vdd-supply: phandle to GDSC regulator.
- camss-vdd-supply: phandle to GDSC regulator.
- mmagic-vdd-supply: phandle to mmagic regulator.
- vfe0-vdd-supply: phandle to vfe0 regulator.
- vfe1-vdd-supply: phandle to vfe1 regulator.
- clocks: list of phandles to the clock controller device and coresponding
  clock names.
- clock-names: name of the clocks required for the device used by the consumer.
@@ -37,7 +40,10 @@ Example:
	reg-names = "ispif";
	interrupts = <0 55 0>;
	interrupt-names = "ispif";
	vdd-supply = <&gdsc_camss_top>;
	camss-vdd-supply = <&gdsc_camss_top>;
	mmagic-vdd-supply = <&gdsc_mmagic_camss>;
	vfe0-vdd-supply = <&gdsc_vfe0>;
	vfe1-vdd-supply = <&gdsc_vfe1>;
	clocks = <&clock_mmss clk_camss_ispif_ahb_clk>,
		<&clock_mmss clk_csi0_clk_src>,
		<&clock_mmss clk_camss_csi0_clk>,
+4 −1
Original line number Diff line number Diff line
@@ -208,7 +208,10 @@
		interrupts = <0 309 0>;
		interrupt-names = "ispif";
		qcom,num-isps = <0x2>;
		vdd-supply = <&gdsc_camss_top>;
		camss-vdd-supply = <&gdsc_camss_top>;
		mmagic-vdd-supply = <&gdsc_mmagic_camss>;
		vfe0-vdd-supply = <&gdsc_vfe0>;
		vfe1-vdd-supply = <&gdsc_vfe1>;
		clocks = <&clock_mmss clk_camss_ispif_ahb_clk>,
			<&clock_mmss clk_csi0_clk_src>,
			<&clock_mmss clk_camss_csi0_clk>,
+154 −0
Original line number Diff line number Diff line
@@ -95,6 +95,143 @@ static struct msm_cam_clk_info ispif_8626_reset_clk_info[] = {
static struct msm_cam_clk_info ispif_ahb_clk_info[ISPIF_CLK_INFO_MAX];
static struct msm_cam_clk_info ispif_clk_info[ISPIF_CLK_INFO_MAX];

static int msm_ispif_set_regulator(struct ispif_device *ispif_dev,
	uint8_t enable)
{
	int rc = 0;

	if (enable) {
		if (!ispif_dev->fs_vfe0) {
			ispif_dev->fs_vfe0 = regulator_get(
				&ispif_dev->pdev->dev, "vfe0-vdd");
			if (IS_ERR(ispif_dev->fs_vfe0)) {
				pr_err("%s: Regulator vfe0 get failed %ld\n",
					__func__,
					PTR_ERR(ispif_dev->fs_vfe0));
				rc = -ENODEV;
				goto vfe0_reg_get_failed;
			}
		}

		if (!ispif_dev->fs_vfe1) {
			ispif_dev->fs_vfe1 = regulator_get(
				&ispif_dev->pdev->dev, "vfe1-vdd");
			if (IS_ERR(ispif_dev->fs_vfe1)) {
				pr_err("%s: Regulator vfe1 get failed %ld\n",
					__func__,
					PTR_ERR(ispif_dev->fs_vfe1));
				rc = -ENODEV;
				goto vfe1_reg_get_failed;
			}
		}

		if (!ispif_dev->fs_camss) {
			ispif_dev->fs_camss = regulator_get(
				&ispif_dev->pdev->dev,
				"camss-vdd");
			if (IS_ERR(ispif_dev->fs_camss)) {
				pr_err("%s: Regulator camss get failed %ld\n",
					__func__,
					PTR_ERR(ispif_dev->fs_camss));
				rc = -ENODEV;
				goto camss_reg_get_failed;
			}
		}

		if (!ispif_dev->fs_mmagic_camss) {
			ispif_dev->fs_mmagic_camss = regulator_get(
				&ispif_dev->pdev->dev,
				"mmagic-vdd");
			if (IS_ERR(ispif_dev->fs_mmagic_camss)) {
				pr_err("%s: Regulator mmagic get failed %ld\n",
					__func__,
					PTR_ERR(ispif_dev->fs_mmagic_camss));
				rc = -ENODEV;
				goto mmagic_reg_get_failed;
			}
		}

		if (ispif_dev->fs_mmagic_camss) {
			rc = regulator_enable(ispif_dev->fs_mmagic_camss);
			if (rc) {
				pr_err("%s: Regulator enable mmagic failed\n",
					__func__);
				goto fs_mmagic_en_failed;
			}
		}

		if (ispif_dev->fs_camss) {
			rc = regulator_enable(ispif_dev->fs_camss);
			if (rc) {
				pr_err("%s: Regulator enable camss failed\n",
					__func__);
				goto fs_camss_en_failed;
			}
		}

		if (ispif_dev->fs_vfe0) {
			rc = regulator_enable(ispif_dev->fs_vfe0);
			if (rc) {
				pr_err("%s: Regulator enable for vfe0 failed\n",
					__func__);
				goto fs_vfe0_en_failed;
			}
		}

		if (ispif_dev->fs_vfe1) {
			rc = regulator_enable(ispif_dev->fs_vfe1);
			if (rc) {
				pr_err("%s: Regulator enable for vfe0 failed\n",
					__func__);
				goto fs_vfe1_en_failed;
			}
		}
	} else {
		if (ispif_dev->fs_vfe0) {
			regulator_disable(ispif_dev->fs_vfe0);
			regulator_put(ispif_dev->fs_vfe0);
			ispif_dev->fs_vfe0 = NULL;
		}

		if (ispif_dev->fs_vfe1) {
			regulator_disable(ispif_dev->fs_vfe1);
			regulator_put(ispif_dev->fs_vfe1);
			ispif_dev->fs_vfe1 = NULL;
		}
		if (ispif_dev->fs_camss) {
			regulator_disable(ispif_dev->fs_camss);
			regulator_put(ispif_dev->fs_camss);
			ispif_dev->fs_camss = NULL;
		}
		if (ispif_dev->fs_mmagic_camss) {
			regulator_disable(ispif_dev->fs_mmagic_camss);
			regulator_put(ispif_dev->fs_mmagic_camss);
			ispif_dev->fs_mmagic_camss = NULL;
		}
	}
	return rc;
fs_vfe1_en_failed:
	regulator_disable(ispif_dev->fs_vfe0);
fs_vfe0_en_failed:
	regulator_disable(ispif_dev->fs_camss);
fs_camss_en_failed:
	regulator_disable(ispif_dev->fs_mmagic_camss);
fs_mmagic_en_failed:
	regulator_put(ispif_dev->fs_mmagic_camss);
	ispif_dev->fs_mmagic_camss = NULL;
mmagic_reg_get_failed:
	regulator_put(ispif_dev->fs_camss);
	ispif_dev->fs_camss = NULL;
camss_reg_get_failed:
	regulator_put(ispif_dev->fs_vfe1);
	ispif_dev->fs_vfe1 = NULL;
vfe1_reg_get_failed:
	regulator_put(ispif_dev->fs_vfe0);
	ispif_dev->fs_vfe0 = NULL;
vfe0_reg_get_failed:
	return rc;
}

static int msm_ispif_reset_hw(struct ispif_device *ispif)
{
	int rc = 0;
@@ -108,6 +245,12 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif)
		pr_err("%s: msm_isp_get_clk_info() failed", __func__);
			return -EFAULT;
	}
	/* Turn ON regulators before enabling the clocks*/
	rc = msm_ispif_set_regulator(ispif, 1);
	if (rc < 0) {
		pr_err("%s: ispif enable regulator failed", __func__);
			return -EFAULT;
	}

	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_clk_info, ispif->clk,
@@ -156,6 +299,8 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif)
				pr_err("%s: VFE0 reset wait timeout\n",
					 __func__);
		}
		/* Turn OFF regulators */
		rc = msm_ispif_set_regulator(ispif, 0);
		return -ETIMEDOUT;
	}

@@ -171,6 +316,8 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif)
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
			/* Turn OFF regulators */
			rc = msm_ispif_set_regulator(ispif, 0);
			return -ETIMEDOUT;
		}
	}
@@ -195,6 +342,13 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif)
		}
	}

	/* Turn OFF regulators after enabling the clocks*/
	rc = msm_ispif_set_regulator(ispif, 0);
	if (rc < 0) {
		pr_err("%s: ispif disable regulator failed", __func__);
			return -EFAULT;
	}

	return rc;
}

+4 −0
Original line number Diff line number Diff line
@@ -70,5 +70,9 @@ struct ispif_device {
	uint32_t ispif_rdi0_debug;
	uint32_t ispif_rdi1_debug;
	uint32_t ispif_rdi2_debug;
	struct regulator *fs_vfe0;
	struct regulator *fs_vfe1;
	struct regulator *fs_mmagic_camss;
	struct regulator *fs_camss;
};
#endif