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

Commit 3f107147 authored by Mayank Rana's avatar Mayank Rana
Browse files

usb: phy: qusb: Fix QUSB PHY sequence based on clk source



CLK_REF_SEL (BIT:7) of QUSB2PHY_PLL_TEST register selects clock source
with QUSB PHY as differential clock or single ended clock. Based on
this it is required to use QUSB PHY initialization sequence. This
change updates QUSB PHY initialization by using recommonded sequence.

As ref_clk and ref_clk_src only required when using differential clock
source with QUSB PHY. Make those clocks as optional here.

Change-Id: Ic9a4d8c843b5d4318197f170a6d480954ae47ca9
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent f9c4d6a5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ Required properties:
 - 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. Required clocks are "ref_clk_src", "cfg_ahb_clk" and "phy_reset".
   property. Required clocks are "cfg_ahb_clk" and "phy_reset".
 - phy_type: Should be one of "ulpi" or "utmi". ChipIdea core uses "ulpi" mode.

Optional properties:
+0 −1
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@
					0x79 0x0c
					0x21 0x10
					0x14 0x9c
					0x80 0x04
					0x9f 0x1c
					0x00 0x18>;
		phy_type = "utmi";
+4 −12
Original line number Diff line number Diff line
@@ -2017,18 +2017,14 @@
					0x79 0x0C
					0x21 0x10
					0x14 0x9C
					0x80 0x04
					0x9F 0x1C
					0x00 0x18>;
		phy_type= "utmi";

		clocks = <&clock_gcc clk_ln_bb_clk>,
			 <&clock_gcc clk_gcc_rx1_usb2_clkref_clk>,
			 <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>,
		clocks = <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>,
			 <&clock_gcc clk_gcc_qusb2phy_prim_reset>;

		clock-names = "ref_clk_src", "ref_clk", "cfg_ahb_clk",
			      "phy_reset";
		clock-names = "cfg_ahb_clk", "phy_reset";
	};

	qusb_phy1: qusb@7412000 {
@@ -2055,19 +2051,15 @@
					0x79 0x0C
					0x21 0x10
					0x14 0x9C
					0x80 0x04
					0x9F 0x1C
					0x00 0x18>;
		phy_type = "utmi";
		qcom,hold-reset;

		clocks = <&clock_gcc clk_ln_bb_clk>,
			 <&clock_gcc clk_gcc_rx2_usb2_clkref_clk>,
			 <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>,
		clocks = <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>,
			 <&clock_gcc clk_gcc_qusb2phy_sec_reset>;

		clock-names = "ref_clk_src", "ref_clk", "cfg_ahb_clk",
			      "phy_reset";
		clock-names = "cfg_ahb_clk", "phy_reset";
	};

	ssphy: ssphy@7410000 {
+32 −22
Original line number Diff line number Diff line
@@ -529,6 +529,7 @@ static int qusb_phy_init(struct usb_phy *phy)
{
	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
	int ret, reset_val = 0;
	bool is_se_clk = true;

	dev_dbg(phy->dev, "%s\n", __func__);

@@ -622,33 +623,50 @@ static int qusb_phy_init(struct usb_phy *phy)
				qphy->base + QUSB2PHY_PORT_TUNE2);
	}

	/* ensure above writes are completed before re-enabling PHY */
	wmb();

	/* Enable the PHY */
	writel_relaxed(CLAMP_N_EN | FREEZIO_N,
		qphy->base + QUSB2PHY_PORT_POWERDOWN);

	/* Ensure above write is completed before turning ON ref clk */
	wmb();

	/* Require to get phy pll lock successfully */
	usleep_range(150, 160);

	if (qphy->tcsr_phy_clk_scheme_sel) {
		ret = readl_relaxed(qphy->tcsr_phy_clk_scheme_sel);
		if (ret & PHY_CLK_SCHEME_SEL) {
			pr_debug("%s:select single-ended clk src\n",
				__func__);
			reset_val |= CLK_REF_SEL;
			is_se_clk = true;
		} else {
			pr_debug("%s:select differential clk src\n",
				__func__);
			reset_val &= ~CLK_REF_SEL;
			is_se_clk = false;
		}

		writel_relaxed(reset_val, qphy->base + QUSB2PHY_PLL_TEST);
	}

	/* ensure above writes are completed before re-enabling PHY */
	wmb();
	if (!is_se_clk)
		reset_val &= ~CLK_REF_SEL;
	else
		reset_val |= CLK_REF_SEL;

	/* Enable the PHY */
	writel_relaxed(CLAMP_N_EN | FREEZIO_N,
		qphy->base + QUSB2PHY_PORT_POWERDOWN);
	/* Turn on phy ref_clk if DIFF_CLK else select SE_CLK */
	if (!is_se_clk && qphy->ref_clk_base)
		writel_relaxed((readl_relaxed(qphy->ref_clk_base) |
					QUSB2PHY_REFCLK_ENABLE),
					qphy->ref_clk_base);
	else
		writel_relaxed(reset_val, qphy->base + QUSB2PHY_PLL_TEST);

	/* Ensure above write is completed before turning ON ref clk */
	/* Make sure that above write is completed to get PLL source clock */
	wmb();

	/* Require to get phy pll lock successfully */
	usleep_range(150, 160);
	/* Required to get PHY PLL lock successfully */
	usleep_range(100, 110);

	if (!(readb_relaxed(qphy->base + QUSB2PHY_PLL_STATUS) &
					QUSB2PHY_PLL_LOCK)) {
@@ -657,15 +675,6 @@ static int qusb_phy_init(struct usb_phy *phy)
		WARN_ON(1);
	}

	/* Turn on phy ref_clk */
	if (qphy->ref_clk_base) {
		writel_relaxed((readl_relaxed(qphy->ref_clk_base) |
					QUSB2PHY_REFCLK_ENABLE),
					qphy->ref_clk_base);
		/* Make sure that above write is completed to get ref clk ON */
		wmb();
	}

	return 0;
}

@@ -917,7 +926,8 @@ static int qusb_phy_probe(struct platform_device *pdev)

	qphy->ref_clk_src = devm_clk_get(dev, "ref_clk_src");
	if (IS_ERR(qphy->ref_clk_src))
		return PTR_ERR(qphy->ref_clk_src);
		dev_dbg(dev, "clk get failed for ref_clk_src\n");

	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");