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

Commit 82d4ec97 authored by Amit Nischal's avatar Amit Nischal Committed by Gerrit - the friendly Code Review server
Browse files

usb: Add support for reset controller framework



The current api which performs the clock reset is moved to use the reset
framework, so support the changes in USB driver for the same. The reset
framework requires to get reset handle and perform assert/deassert of the
resets.

Change-Id: Ifcde1c6af624294cbd1944eaa9b526dd6dcc51de
Signed-off-by: default avatarAmit Nischal <anischal@codeaurora.org>
parent c6855ffd
Loading
Loading
Loading
Loading
+21 −12
Original line number Diff line number Diff line
@@ -118,6 +118,10 @@ Required properties:
   USB3_PHY_POWER_DOWN_CONTROL,
   USB3_PHY_SW_RESET,
   USB3_PHY_START
- resets: reset specifier pair consists of phandle for the reset controller
  and reset lines used by this controller.
- reset-names: reset signal name strings sorted in the same order as the resets
  property.

Optional properties:
 - reg: Additional register set of address and length to control QMP PHY are:
@@ -126,7 +130,7 @@ Optional 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 "cfg_ahb_clk", "phy_reset" and "phy_phy_reset".
   property. "cfg_ahb_clk" is an optional clock.
 - qcom,vbus-valid-override: If present, indicates VBUS pin is not connected to
   the USB PHY and the controller must rely on external VBUS notification in
   order to manually relay the notification to the SSPHY.
@@ -150,13 +154,17 @@ Example:
		clocks = <&clock_gcc clk_gcc_usb3_phy_aux_clk>,
			 <&clock_gcc clk_gcc_usb3_phy_pipe_clk>,
			 <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>,
			 <&clock_gcc clk_gcc_usb3_phy_reset>,
			 <&clock_gcc clk_gcc_usb3phy_phy_reset>,
			 <&clock_gcc clk_ln_bb_clk1>,
			 <&clock_gcc clk_gcc_usb3_clkref_clk>;

		clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk", "phy_reset",
			      "phy_phy_reset", "ref_clk_src", "ref_clk";
		clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk",
			      "ref_clk_src", "ref_clk";

		resets = <&clock_gcc GCC_USB3_PHY_BCR>,
			<&clock_gcc GCC_USB3PHY_PHY_BCR>;
		reset-names = "phy_reset",
				"phy_phy_reset";

	};

QUSB2 High-Speed PHY
@@ -173,11 +181,11 @@ Required properties:
 - 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
 - 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 clock is "phy_reset".
 - phy_type: Should be one of "ulpi" or "utmi". ChipIdea core uses "ulpi" mode.
 - resets: reset specifier pair consists of phandle for the reset controller
   and reset lines used by this controller.
 - reset-names: reset signal name strings sorted in the same order as the resets
   property.

Optional properties:
 - reg-names: Additional registers corresponding with the following:
@@ -218,7 +226,8 @@ Example:

		clocks = <&clock_rpm clk_ln_bb_clk>,
			 <&clock_gcc clk_gcc_rx2_usb1_clkref_clk>,
			 <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>,
			 <&clock_gcc clk_gcc_qusb2_phy_reset>;
		clock-names = "ref_clk_src", "ref_clk", "cfg_ahb_clk", "phy_reset";
			 <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>;
		clock-names = "ref_clk_src", "ref_clk", "cfg_ahb_clk";
		resets = <&clock_gcc GCC_QUSB2PHY_PRIM_BCR>;
		reset-names = "phy_reset";
	};
+7 −0
Original line number Diff line number Diff line
@@ -15,6 +15,10 @@ Required properties :
 - clock-names: Names of the clocks in 1-1 correspondence with the "clocks"
   property. Required clocks are "xo", "iface_clk", "core_clk", "sleep_clk"
   and "utmi_clk".
- resets: reset specifier pair consists of phandle for the reset provider
  and reset lines used by this controller.
- reset-names: reset signal name strings sorted in the same order as the resets
  property.

Optional properties :
- reg: Additional registers
@@ -99,6 +103,9 @@ Example MSM USB3.0 controller device node :
		clock-names = "core_clk", "iface_clk", "bus_aggr_clk",
				"utmi_clk", "sleep_clk", "cfg_ahb_clk", "xo";

		resets = <&clock_gcc GCC_USB_30_BCR>;
		reset-names = "core_reset";

		dwc3@f9200000 {
			compatible = "synopsys,dwc3";
			reg = <0xf9200000 0xfc000>;
+18 −9
Original line number Diff line number Diff line
@@ -1934,6 +1934,9 @@
		clock-names = "core_clk", "iface_clk", "bus_aggr_clk", "utmi_clk",
				"sleep_clk", "xo", "cfg_ahb_clk";

		resets = <&clock_gcc USB_30_BCR>;
		reset-names = "core_reset";

		dwc3@6a00000 {
			compatible = "snps,dwc3";
			reg = <0x06a00000 0xc8d0>;
@@ -2039,6 +2042,8 @@
			 <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>;
		clock-names = "core_clk", "iface_clk", "utmi_clk", "sleep_clk",
				"xo", "cfg_ahb_clk";
		resets = <&clock_gcc USB_20_BCR>;
		reset-names = "core_reset";

		dwc3@7600000 {
			compatible = "snps,dwc3";
@@ -2088,10 +2093,11 @@
		qcom,major-rev = <1>;

		clocks = <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>,
			 <&clock_gcc clk_gcc_qusb2phy_prim_reset>,
			 <&clock_gcc clk_ln_bb_clk>;
		clock-names = "cfg_ahb_clk", "ref_clk_src";

		clock-names = "cfg_ahb_clk", "phy_reset", "ref_clk_src";
		resets = <&clock_gcc QUSB2PHY_PRIM_BCR>;
		reset-names = "phy_reset";
	};

	qusb_phy1: qusb@7412000 {
@@ -2124,10 +2130,11 @@
		qcom,hold-reset;

		clocks = <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>,
			 <&clock_gcc clk_gcc_qusb2phy_sec_reset>,
			<&clock_gcc clk_ln_bb_clk>;
		clock-names = "cfg_ahb_clk", "ref_clk_src";

		clock-names = "cfg_ahb_clk", "phy_reset", "ref_clk_src";
		resets = <&clock_gcc QUSB2PHY_SEC_BCR>;
		reset-names = "phy_reset";
	};

	ssphy: ssphy@7410000 {
@@ -2209,13 +2216,15 @@
		clocks = <&clock_gcc clk_gcc_usb3_phy_aux_clk>,
			 <&clock_gcc clk_gcc_usb3_phy_pipe_clk>,
			 <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>,
			 <&clock_gcc clk_gcc_usb3_phy_reset>,
			 <&clock_gcc clk_gcc_usb3phy_phy_reset>,
			 <&clock_gcc clk_ln_bb_clk>,
			 <&clock_gcc clk_gcc_usb3_clkref_clk>;

		clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk", "phy_reset",
			      "phy_phy_reset", "ref_clk_src", "ref_clk";
		clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk",
				"ref_clk_src", "ref_clk";

		resets = <&clock_gcc USB3_PHY_BCR>,
			 <&clock_gcc USB3PHY_PHY_BCR>;
		reset-names = "phy_reset", "phy_phy_reset";
	};

	usb_nop_phy: usb_nop_phy {
+14 −7
Original line number Diff line number Diff line
@@ -1804,6 +1804,10 @@
				"utmi_clk", "sleep_clk", "xo";

		qcom,core-clk-rate = <120000000>;

		resets = <&clock_gcc USB_30_BCR>;
		reset-names = "core_reset";

		dwc3@a800000 {
			compatible = "snps,dwc3";
			reg = <0x0a800000 0xcd00>;
@@ -1870,10 +1874,11 @@
		phy_type= "utmi";

		clocks = <&clock_gcc clk_ln_bb_clk1>,
			 <&clock_gcc clk_gcc_rx1_usb2_clkref_clk>,
			 <&clock_gcc clk_gcc_qusb2phy_prim_reset>;
			 <&clock_gcc clk_gcc_rx1_usb2_clkref_clk>;
		clock-names = "ref_clk_src", "ref_clk";

		clock-names = "ref_clk_src", "ref_clk", "phy_reset";
		resets = <&clock_gcc QUSB2PHY_PRIM_BCR>;
		reset-names = "phy_reset";
	};

	ssphy: ssphy@c010000 {
@@ -2021,13 +2026,15 @@

		clocks = <&clock_gcc clk_gcc_usb3_phy_aux_clk>,
			 <&clock_gcc clk_gcc_usb3_phy_pipe_clk>,
			 <&clock_gcc clk_gcc_usb3_phy_reset>,
			 <&clock_gcc clk_gcc_usb3phy_phy_reset>,
			 <&clock_gcc clk_ln_bb_clk1>,
			 <&clock_gcc clk_gcc_usb3_clkref_clk>;

		clock-names = "aux_clk", "pipe_clk", "phy_reset",
			      "phy_phy_reset", "ref_clk_src", "ref_clk";
		clock-names = "aux_clk", "pipe_clk", "ref_clk_src",
				"ref_clk";

		resets = <&clock_gcc USB3_PHY_BCR>,
			 <&clock_gcc USB3PHY_PHY_BCR>;
		reset-names = "phy_reset", "phy_phy_reset";
	};

	usb_audio_qmi_dev {
+26 −8
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include <linux/msm-bus.h>
#include <linux/irq.h>
#include <linux/extcon.h>
#include <linux/reset.h>

#include "power.h"
#include "core.h"
@@ -159,6 +160,7 @@ struct dwc3_msm {
	struct clk		*utmi_clk_src;
	struct clk		*bus_aggr_clk;
	struct clk		*cfg_ahb_clk;
	struct reset_control	*core_reset;
	struct regulator	*dwc3_gdsc;

	struct usb_phy		*hs_phy, *ss_phy;
@@ -1517,19 +1519,19 @@ static int dwc3_msm_link_clk_reset(struct dwc3_msm *mdwc, bool assert)
		clk_disable_unprepare(mdwc->sleep_clk);
		clk_disable_unprepare(mdwc->core_clk);
		clk_disable_unprepare(mdwc->iface_clk);
		ret = clk_reset(mdwc->core_clk, CLK_RESET_ASSERT);
		ret = reset_control_assert(mdwc->core_reset);
		if (ret)
			dev_err(mdwc->dev, "dwc3 core_clk assert failed\n");
			dev_err(mdwc->dev, "dwc3 core_reset assert failed\n");
	} else {
		dev_dbg(mdwc->dev, "block_reset DEASSERT\n");
		ret = clk_reset(mdwc->core_clk, CLK_RESET_DEASSERT);
		ret = reset_control_deassert(mdwc->core_reset);
		if (ret)
			dev_err(mdwc->dev, "dwc3 core_reset deassert failed\n");
		ndelay(200);
		clk_prepare_enable(mdwc->iface_clk);
		clk_prepare_enable(mdwc->core_clk);
		clk_prepare_enable(mdwc->sleep_clk);
		clk_prepare_enable(mdwc->utmi_clk);
		if (ret)
			dev_err(mdwc->dev, "dwc3 core_clk deassert failed\n");
		enable_irq(mdwc->pwr_event_irq);
	}

@@ -2041,11 +2043,16 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc)
	if (mdwc->lpm_flags & MDWC3_POWER_COLLAPSE) {
		dev_dbg(mdwc->dev, "%s: exit power collapse\n", __func__);
		dwc3_msm_config_gdsc(mdwc, 1);

		clk_reset(mdwc->core_clk, CLK_RESET_ASSERT);
		ret = reset_control_assert(mdwc->core_reset);
		if (ret)
			dev_err(mdwc->dev, "%s:core_reset assert failed\n",
					__func__);
		/* HW requires a short delay for reset to take place properly */
		usleep_range(1000, 1200);
		clk_reset(mdwc->core_clk, CLK_RESET_DEASSERT);
		ret = reset_control_deassert(mdwc->core_reset);
		if (ret)
			dev_err(mdwc->dev, "%s:core_reset deassert failed\n",
					__func__);
		clk_prepare_enable(mdwc->sleep_clk);
	}

@@ -2366,6 +2373,17 @@ static int dwc3_msm_get_clk_gdsc(struct dwc3_msm *mdwc)
		mdwc->core_clk_rate = clk_round_rate(mdwc->core_clk, LONG_MAX);
	}

	mdwc->core_reset = devm_reset_control_get(mdwc->dev, "core_reset");
	if (IS_ERR(mdwc->core_reset)) {
		dev_err(mdwc->dev, "failed to get core_reset\n");
		return PTR_ERR(mdwc->core_reset);
	}

	/*
	 * Get Max supported clk frequency for USB Core CLK and request
	 * to set the same.
	 */
	mdwc->core_clk_rate = clk_round_rate(mdwc->core_clk, LONG_MAX);
	if (IS_ERR_VALUE(mdwc->core_clk_rate)) {
		dev_err(mdwc->dev, "fail to get core clk max freq.\n");
	} else {
Loading