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

Commit 0834d2ac authored by Devdutt Patnaik's avatar Devdutt Patnaik
Browse files

usb: phy: qusb: Update ref_clk and ref_clk_src clock usage



GCC_QUSB_REF_CLK_EN register controls the enable/disable of the
DIFF/CML clock to the QUSB2 PHY. When using SE/CMOS clock, control
of the DIFF clk is not needed. ref_clk is optional clock but driver
is not marking ref_clk as NULL if it fails to get reference of this
clock. Hence query or update this clock reference only if devicetree
qusb2phy node is having reference to this clock.

ref_clk_src is mandatory to provide SE/CMOS or DIFF/CML based
reference clock. Hence make ref_clk_src as mandatory clock.

Also use qusb_phy_enable_clocks() API within qusb_phy_remove() API
for disabling QUSB2 PHY related clocks.

Change-Id: I697e5c718285449268d5bb32deff5d18acf0cc2a
Signed-off-by: default avatarDevdutt Patnaik <dpatnaik@codeaurora.org>
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 0a176741
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -149,6 +149,10 @@ Required properties:
	"vdd" : vdd supply for digital circuit operation
	"vdda18" : 1.8v high-voltage analog supply
	"vdda33" : 3.3v high-voltage analog supply
 - clocks: a list of phandles to the PHY clocks. Use as per
   Documentation/devicetree/bindings/clock/clock-bindings.txt
 - clock-names: Names of the clocks in 1-1 correspondence with the "clocks"
   property. "ref_clk_src" is a mandatory clock.
 - qcom,vdd-voltage-level: This property must be a list of three integer
   values (no, min, max) where each value represents either a voltage in
   microvolts or a value corresponding to voltage corner
@@ -164,16 +168,10 @@ Optional properties:
   via the QSCRATCH interface.
   "emu_phy_base" : phy base address used for programming emulation target phy.
   "ref_clk_addr" : ref_clk bcr address used for on/off ref_clk before reset.
   "tcsr_phy_clk_scheme_sel": address used to determine QUSB PHY clk source.
   "tcsr_phy_level_shift_keeper": address used to clamp QUSB PHY level shifter.
   "efuse_addr": EFUSE address to read and update analog tune parameter.
 - reg-names: Should be "qscratch_base". The qscratch register bank
   allows us to manipulate QUSB PHY bits eg. to enable D+ pull-up using s/w
   control in device mode. The reg-names property is required if the
   reg property is specified.
 - tcsr_clamp_dig_n" : To enable/disable digital clamp to the phy. When
   de-asserted, it will prevent random leakage from qusb2 phy resulting from
   out of sequence turn on/off of 1p8, 3p3 and DVDD regulators.
 - clocks: a list of phandles to the PHY clocks. Use as per
   Documentation/devicetree/bindings/clock/clock-bindings.txt
 - clock-names: Names of the clocks in 1-1 correspondence with the "clocks"
   property. "cfg_ahb_clk" and "ref_clk" are optional clocks.
 - qcom,qusb-phy-init-seq: QUSB PHY initialization sequence with value,reg pair.
 - qcom,qusb-phy-host-init-seq: QUSB PHY initialization sequence for host mode
   with value,reg pair.
+31 −17
Original line number Diff line number Diff line
@@ -158,15 +158,23 @@ static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)

	if (!qphy->clocks_enabled && on) {
		clk_prepare_enable(qphy->ref_clk_src);
		if (qphy->ref_clk)
			clk_prepare_enable(qphy->ref_clk);

		if (qphy->cfg_ahb_clk)
			clk_prepare_enable(qphy->cfg_ahb_clk);

		qphy->clocks_enabled = true;
	}

	if (qphy->clocks_enabled && !on) {
		if (qphy->cfg_ahb_clk)
			clk_disable_unprepare(qphy->cfg_ahb_clk);

		if (qphy->ref_clk)
			clk_disable_unprepare(qphy->ref_clk);

		clk_disable_unprepare(qphy->ref_clk_src);
		clk_disable_unprepare(qphy->cfg_ahb_clk);
		qphy->clocks_enabled = false;
	}

@@ -835,15 +843,28 @@ static int qusb_phy_probe(struct platform_device *pdev)
		}
	}

	/* ref_clk_src is needed irrespective of SE_CLK or DIFF_CLK usage */
	qphy->ref_clk_src = devm_clk_get(dev, "ref_clk_src");
	if (IS_ERR(qphy->ref_clk_src))
	if (IS_ERR(qphy->ref_clk_src)) {
		dev_dbg(dev, "clk get failed for ref_clk_src\n");
		ret = PTR_ERR(qphy->ref_clk_src);
		return ret;
	}

	/* ref_clk is needed only for DIFF_CLK case, hence make it optional. */
	if (of_property_match_string(pdev->dev.of_node,
				"clock-names", "ref_clk") >= 0) {
		qphy->ref_clk = devm_clk_get(dev, "ref_clk");
	if (IS_ERR(qphy->ref_clk))
		dev_dbg(dev, "clk get failed for ref_clk\n");
	else
		if (IS_ERR(qphy->ref_clk)) {
			ret = PTR_ERR(qphy->ref_clk);
			if (ret != -EPROBE_DEFER)
				dev_dbg(dev,
					"clk get failed for ref_clk\n");
			return ret;
		}

		clk_set_rate(qphy->ref_clk, 19200000);
	}

	if (of_property_match_string(pdev->dev.of_node,
				"clock-names", "cfg_ahb_clk") >= 0) {
@@ -1024,14 +1045,7 @@ static int qusb_phy_remove(struct platform_device *pdev)
	struct qusb_phy *qphy = platform_get_drvdata(pdev);

	usb_remove_phy(&qphy->phy);

	if (qphy->clocks_enabled) {
		clk_disable_unprepare(qphy->cfg_ahb_clk);
		clk_disable_unprepare(qphy->ref_clk);
		clk_disable_unprepare(qphy->ref_clk_src);
		qphy->clocks_enabled = false;
	}

	qusb_phy_enable_clocks(qphy, false);
	qusb_phy_enable_power(qphy, false, true);

	return 0;