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

Commit 66e55b63 authored by Deepak Katragadda's avatar Deepak Katragadda
Browse files

clk: msm: gdsc: Check the GDS_HW_CTRL register to determine if GDSC is ON



When a gdsc is enabled, check the GDSCs hw_ctrl register status
to determine if the GDSC is on. Just relying on the GDSC status
bit might lead to issues wherein the GDSC status bit might be
set but the GDSC hw_ctrl is still waiting on an ACK; leading to
NOC errors.

Change-Id: Idcdefa57a7cf0eda10e0501385aa8d7e8689f90f
Signed-off-by: default avatarDeepak Katragadda <dkatraga@codeaurora.org>
parent 69ac846d
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@
	gdsc_mmagic_video: qcom,gdsc@8c119c {
		compatible = "qcom,gdsc";
		regulator-name = "gdsc_mmagic_video";
		reg = <0x8c119c 0x4>;
		reg = <0x8c119c 0x4>,
		      <0x8c120c 0x4>;
		reg-names = "base", "hw_ctrl_addr";
		qcom,no-status-check-on-disable;
		status = "disabled";
	};
@@ -30,7 +32,9 @@
	gdsc_mmagic_mdss: qcom,gdsc@8c247c {
		compatible = "qcom,gdsc";
		regulator-name = "gdsc_mmagic_mdss";
		reg = <0x8c247c 0x4>;
		reg = <0x8c247c 0x4>,
		      <0x8c2480 0x4>;
		reg-names = "base", "hw_ctrl_addr";
		qcom,no-status-check-on-disable;
		status = "disabled";
	};
@@ -38,7 +42,9 @@
	gdsc_mmagic_camss: qcom,gdsc@8c3c4c {
		compatible = "qcom,gdsc";
		regulator-name = "gdsc_mmagic_camss";
		reg = <0x8c3c4c 0x4>;
		reg = <0x8c3c4c 0x4>,
		      <0x8c3c50 0x4>;
		reg-names = "base", "hw_ctrl_addr";
		qcom,no-status-check-on-disable;
		status = "disabled";
	};
@@ -151,7 +157,9 @@
	gdsc_gpu: qcom,gdsc@8c4034 {
		compatible = "qcom,gdsc";
		regulator-name = "gdsc_gpu";
		reg = <0x8c4034 0x4>;
		reg = <0x8c4034 0x4>,
		      <0x8c4038 0x4>;
		reg-names = "base", "hw_ctrl_addr";
		qcom,no-status-check-on-disable;
		status = "disabled";
	};
@@ -192,7 +200,10 @@
	gdsc_aggre0_noc: qcom,gdsc@381004 {
		compatible = "qcom,gdsc";
		regulator-name = "gdsc_aggre0_noc";
		reg = <0x381004 0x4>;
		reg = <0x381004 0x4>,
		      <0x381028 0x4>;
		reg-names = "base", "hw_ctrl_addr";
		qcom,no-status-check-on-disable;
		status = "disabled";
	};
};
+28 −5
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ struct gdsc {
	int			root_clk_idx;
	bool			no_status_check_on_disable;
	void __iomem		*domain_addr;
	void __iomem		*hw_ctrl_addr;
};

static int gdsc_is_enabled(struct regulator_dev *rdev)
@@ -117,7 +118,7 @@ static int gdsc_is_enabled(struct regulator_dev *rdev)
static int gdsc_enable(struct regulator_dev *rdev)
{
	struct gdsc *sc = rdev_get_drvdata(rdev);
	uint32_t regval;
	uint32_t regval, hw_ctrl_regval;
	int i, ret;

	if (sc->root_en || sc->force_root_en)
@@ -144,6 +145,13 @@ static int gdsc_enable(struct regulator_dev *rdev)
		regval &= ~SW_COLLAPSE_MASK;
		writel_relaxed(regval, sc->gdscr);

		/* Wait for 8 XO cycles before polling the status bit. */
		mb();
		udelay(1);

		if (sc->hw_ctrl_addr)
			ret = poll_gdsc_status(sc->hw_ctrl_addr, ENABLED);
		else
			ret = poll_gdsc_status(sc->gdscr, ENABLED);

		if (ret) {
@@ -151,8 +159,10 @@ static int gdsc_enable(struct regulator_dev *rdev)
				sc->rdesc.name, regval);
			udelay(TIMEOUT_US);
			regval = readl_relaxed(sc->gdscr);
			dev_err(&rdev->dev, "%s final state: 0x%x (%d us after timeout)\n",
				sc->rdesc.name, regval, TIMEOUT_US);
			hw_ctrl_regval = readl_relaxed(sc->hw_ctrl_addr);
			dev_err(&rdev->dev, "%s final state: 0x%x, GDS_HW_CTRL: 0x%x (%d us after timeout)\n",
					sc->rdesc.name, regval,
					hw_ctrl_regval, TIMEOUT_US);
			return ret;
		}
	} else {
@@ -231,6 +241,10 @@ static int gdsc_disable(struct regulator_dev *rdev)
			 */
			udelay(TIMEOUT_US);
		} else {
			if (sc->hw_ctrl_addr)
				ret = poll_gdsc_status(sc->hw_ctrl_addr,
								DISABLED);
			else
				ret = poll_gdsc_status(sc->gdscr, DISABLED);
			if (ret)
				dev_err(&rdev->dev, "%s disable timed out: 0x%x\n",
@@ -379,6 +393,15 @@ static int gdsc_probe(struct platform_device *pdev)
			return -ENOMEM;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
							"hw_ctrl_addr");
	if (res) {
		sc->hw_ctrl_addr = devm_ioremap(&pdev->dev, res->start,
							resource_size(res));
		if (sc->hw_ctrl_addr == NULL)
			return -ENOMEM;
	}

	sc->clock_count = of_property_count_strings(pdev->dev.of_node,
					    "clock-names");
	if (sc->clock_count == -EINVAL) {