linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/18] Tegra XUSB OTG support
@ 2019-12-06 10:50 Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 01/18] dt-bindings: phy: tegra-xusb: Add usb-role-switch Nagarjuna Kristam
                   ` (17 more replies)
  0 siblings, 18 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

This patch series adds OTG support on XUSB hardware used in Tegra210 and
Tegra186 SoCs.

This patchset is composed with :
 - dt bindings of XUSB Pad Controller
 - dt bindings for XUSB device Driver
 - Tegra PHY driver for usb-role-switch and usb-phy
 - Tegra XUSB host mode driver to support OTG mode
 - Tegra XUSB device mode driver to use usb-phy and multi device mode
 - dts for XUSB pad controller
 - dts for xudc

Tegra Pad controller driver register for role switch updates for
OTG/peripheral capable USB ports and adds usb-phy for that corresponding
USB ports.

Host and Device mode drivers gets usb-phy from USB2's phy and registers
notifier for role changes to perform corresponding role tasks.

Tests done:
 - device mode support using micro-B USB cable connection between ubuntu
   host and DUT on micro-B port
 - host mode support by connecting pen-drive to micro USB port on DUT
   using micro-B OTG cable.
 - toggling between these 2 modes by hot plugging corresponding cables.

DUT: Jetson-tx1, Jetson tx2.

Nagarjuna Kristam (18):
  dt-bindings: phy: tegra-xusb: Add usb-role-switch
  dt-bindings: usb: Add NVIDIA Tegra XUSB device mode controller binding
  phy: tegra: xusb: Add usb-role-switch support
  phy: tegra: xusb: Add usb-phy support
  phy: tegra: xusb: Add support to get companion USB 3 port
  phy: tegra: xusb: Add set_mode support for USB 2 phy on Tegra210
  phy: tegra: xusb: Add set_mode support for utmi phy on Tegra186
  usb: xhci-tegra: Add OTG support
  usb: gadget: tegra-xudc: Remove usb-role-switch support
  usb: gadget: tegra-xudc: Add usb-phy support
  usb: gadget: tegra-xudc: use phy_set_mode to set/unset device mode
  usb: gadget: tegra-xudc: support multiple device modes
  arm64: tegra: update OTG port entries for jetson-tx1
  arm64: tegra: update OTG port entries for jetson-tx2
  arm64: tegra: Add xudc node for Tegra210
  arm64: tegra: Enable xudc on Jetson TX1
  arm64: tegra: Add xudc node for Tegra186
  arm64: tegra: Enable xudc node on Jetson TX2

 .../bindings/phy/nvidia,tegra124-xusb-padctl.txt   |   4 +
 .../devicetree/bindings/usb/nvidia,tegra-xudc.yaml | 204 +++++++++++++++
 arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts |  23 +-
 arch/arm64/boot/dts/nvidia/tegra186.dtsi           |  19 ++
 arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi     |  34 ++-
 arch/arm64/boot/dts/nvidia/tegra210.dtsi           |  19 ++
 drivers/phy/tegra/Kconfig                          |   1 +
 drivers/phy/tegra/xusb-tegra186.c                  | 109 ++++++--
 drivers/phy/tegra/xusb-tegra210.c                  | 126 ++++++++--
 drivers/phy/tegra/xusb.c                           | 132 ++++++++++
 drivers/phy/tegra/xusb.h                           |   5 +
 drivers/usb/gadget/udc/tegra-xudc.c                | 277 ++++++++++++++-------
 drivers/usb/host/xhci-tegra.c                      | 226 ++++++++++++++++-
 include/linux/phy/tegra/xusb.h                     |   2 +
 14 files changed, 1042 insertions(+), 139 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml

-- 
2.7.4


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 01/18] dt-bindings: phy: tegra-xusb: Add usb-role-switch
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 14:49   ` Thierry Reding
  2019-12-06 10:50 ` [PATCH 02/18] dt-bindings: usb: Add NVIDIA Tegra XUSB device mode controller binding Nagarjuna Kristam
                   ` (16 subsequent siblings)
  17 siblings, 1 reply; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Add usb-role-switch property for Tegra210 and Tegra186 platforms. This
entry is used by XUSB pad controller driver to register for role changes
for OTG/Peripheral capable USB 2 ports.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
index 9fb682e..0f19ed6 100644
--- a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
+++ b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
@@ -179,6 +179,10 @@ Optional properties:
   is internal. In the absence of this property the port is considered to be
   external.
 - vbus-supply: phandle to a regulator supplying the VBUS voltage.
+- usb-role-switch: boolean property to indicate use of USB Role Switch.
+  This property is MUST for OTG,Peripheral capable USB 2 ports. Connector
+  should be added as subnode, see connector.txt. vbus-gpio in connector is
+  Mandatory.
 
 ULPI ports:
 -----------
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 02/18] dt-bindings: usb: Add NVIDIA Tegra XUSB device mode controller binding
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 01/18] dt-bindings: phy: tegra-xusb: Add usb-role-switch Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-13 18:45   ` Rob Herring
  2019-12-06 10:50 ` [PATCH 03/18] phy: tegra: xusb: Add usb-role-switch support Nagarjuna Kristam
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Add device-tree binding documentation for the XUSB device mode controller
present on Tegra210 and Tegra186 SoC. This controller supports the USB 3.0
specification.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 .../devicetree/bindings/usb/nvidia,tegra-xudc.yaml | 204 +++++++++++++++++++++
 1 file changed, 204 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml

diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml b/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
new file mode 100644
index 0000000..b23c451
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
@@ -0,0 +1,204 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/nvidia,tegra-xudc.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Device tree binding for NVIDIA Tegra XUSB device mode controller (XUDC)
+
+description:
+  The Tegra XUDC controller supports both USB 2.0 HighSpeed/FullSpeed and
+  USB 3.0 SuperSpeed protocols.
+
+maintainers:
+  - Nagarjuna Kristam <nkristam@nvidia.com>
+  - JC Kuo <jckuo@nvidia.com>
+  - Thierry Reding <treding@nvidia.com>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+        - const: nvidia,tegra210-xudc # For Tegra210
+      - items:
+        - const: nvidia,tegra186-xudc # For Tegra186
+
+  interrupts:
+    maxItems: 1
+    description: Must contain the XUSB device interrupt.
+
+  power-domains:
+    maxItems: 2
+    description:
+      A list of PM domain specifiers that reference each power-domain
+      used by the XUSB device mode controller. This list must comprise of a
+      specifier for the XUSBA and XUSBB power-domains.
+      See ../power/power_domain.txt and ../arm/tegra/nvidia,tegra20-pmc.txt
+      for details.
+
+  power-domains-names:
+    maxItems: 2
+    description:
+       A list of names that represent each of the specifiers in
+       the 'power-domains' property.
+    items:
+      - const: ss
+      - const: dev
+
+  nvidia,xusb-padctl:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description:
+      phandle to the XUSB pad controller that is used to configure the USB pads
+      used by the XUDC controller.
+
+  phys:
+    minItems: 1
+    description:
+      Must contain an entry for each entry in phy-names.
+      See ../phy/phy-bindings.txt for details.
+
+  phy-names:
+    minItems: 1
+    items:
+      - const: usb2-0
+      - const: usb2-1
+      - const: usb2-2
+      - const: usb2-3
+      - const: usb3-0
+      - const: usb3-1
+      - const: usb3-2
+      - const: usb3-3
+
+  avddio-usb-supply:
+    description: PCIe/USB3 analog logic power supply. Must supply 1.05 V.
+
+  hvdd-usb-supply:
+    description: USB controller power supply. Must supply 3.3 V.
+
+required:
+  - compatible
+  - power-domains
+  - power-domain-names
+  - nvidia,xusb-padctl
+  - phys
+  - phy-names
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          items:
+            const: nvidia,tegra210-xudc
+
+    then:
+      properties:
+        reg:
+          maxItems: 3
+          items:
+          - description: XUSB device controller registers
+          - description: XUSB device PCI Config registers
+          - description: XUSB device registers.
+        reg-names:
+          maxItems: 3
+          items:
+            - const: base
+            - const: fpci
+            - const: ipfs
+        clocks:
+          description:
+            Must contain an entry for all clocks used. See ../clock/clock-bindings.txt
+            for details.
+          maxItems: 5
+          items:
+            - description: Clock to enable core XUSB dev clock.
+            - description: Clock to enable XUSB super speed clock.
+            - description: Clock to enable XUSB super speed dev clock.
+            - description: Clock to enable XUSB high speed dev clock.
+            - description: Clock to enable XUSB full speed dev clock.
+        clock-names:
+          items:
+           - const: dev
+           - const: ss
+           - const: ss_src
+           - const: hs_src
+           - const: fs_src
+      required:
+        - reg
+        - reg-names
+        - clocks
+        - clock-names
+        - avddio-usb-supply
+        - hvdd-usb-supply
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: nvidia,tegra186-xudc
+
+    then:
+      properties:
+        reg:
+          maxItems: 2
+          items:
+          - description: XUSB device controller registers
+          - description: XUSB device PCI Config registers
+        reg-names:
+          maxItems: 2
+          items:
+            - const: base
+            - const: fpci
+        clocks:
+          description:
+            Must contain an entry for all clocks used. See ../clock/clock-bindings.txt
+            for details.
+          maxItems: 4
+          items:
+            - description: Clock to enable core XUSB dev clock.
+            - description: Clock to enable XUSB super speed clock.
+            - description: Clock to enable XUSB super speed dev clock.
+            - description: Clock to enable XUSB full speed dev clock.
+        clock-names:
+          items:
+           - const: dev
+           - const: ss
+           - const: ss_src
+           - const: fs_src
+      required:
+        - reg
+        - reg-names
+        - clocks
+        - clock-names
+
+examples:
+  - |
+    #include <dt-bindings/clock/tegra210-car.h>
+    #include <dt-bindings/gpio/tegra-gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    usb@700d0000 {
+        compatible = "nvidia,tegra210-xudc";
+        reg = <0x0 0x700d0000 0x0 0x8000>,
+              <0x0 0x700d8000 0x0 0x1000>,
+              <0x0 0x700d9000 0x0 0x1000>;
+        reg-names = "base", "fpci", "ipfs";
+
+        interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+
+        clocks = <&tegra_car TEGRA210_CLK_XUSB_DEV>,
+                 <&tegra_car TEGRA210_CLK_XUSB_SS>,
+                 <&tegra_car TEGRA210_CLK_XUSB_SSP_SRC>,
+                 <&tegra_car TEGRA210_CLK_XUSB_HS_SRC>,
+                 <&tegra_car TEGRA210_CLK_XUSB_FS_SRC>;
+        clock-names = "dev", "ss", "ss_src", "hs_src", "fs_src";
+
+        power-domains = <&pd_xusbdev>, <&pd_xusbss>;
+        power-domain-names = "dev", "ss";
+
+        nvidia,xusb-padctl = <&padctl>;
+
+        phys = <&micro_b>;
+        phy-names = "usb2-0";
+
+        avddio-usb-supply = <&vdd_pex_1v05>;
+        hvdd-usb-supply = <&vdd_3v3_sys>;
+    };
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 03/18] phy: tegra: xusb: Add usb-role-switch support
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 01/18] dt-bindings: phy: tegra-xusb: Add usb-role-switch Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 02/18] dt-bindings: usb: Add NVIDIA Tegra XUSB device mode controller binding Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 14:54   ` Thierry Reding
  2019-12-06 10:50 ` [PATCH 04/18] phy: tegra: xusb: Add usb-phy support Nagarjuna Kristam
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

If usb-role-switch property is present in USB 2 port, register
usb-role-switch to receive usb role changes.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/phy/tegra/Kconfig |  1 +
 drivers/phy/tegra/xusb.c  | 40 ++++++++++++++++++++++++++++++++++++++++
 drivers/phy/tegra/xusb.h  |  3 +++
 3 files changed, 44 insertions(+)

diff --git a/drivers/phy/tegra/Kconfig b/drivers/phy/tegra/Kconfig
index f9817c3..df07c4d 100644
--- a/drivers/phy/tegra/Kconfig
+++ b/drivers/phy/tegra/Kconfig
@@ -2,6 +2,7 @@
 config PHY_TEGRA_XUSB
 	tristate "NVIDIA Tegra XUSB pad controller driver"
 	depends on ARCH_TEGRA
+	select USB_CONN_GPIO
 	help
 	  Choose this option if you have an NVIDIA Tegra SoC.
 
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index f98ec39..da60a63 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -523,6 +523,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
 	port->dev.type = &tegra_xusb_port_type;
 	port->dev.of_node = of_node_get(np);
 	port->dev.parent = padctl->dev;
+	port->dev.driver = padctl->dev->driver;
 
 	err = dev_set_name(&port->dev, "%s-%u", name, index);
 	if (err < 0)
@@ -532,6 +533,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
 	if (err < 0)
 		goto unregister;
 
+	dev_set_drvdata(&port->dev, port);
 	return 0;
 
 unregister:
@@ -541,6 +543,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
 
 static void tegra_xusb_port_unregister(struct tegra_xusb_port *port)
 {
+	usb_role_switch_unregister(port->usb_role_sw);
 	device_unregister(&port->dev);
 }
 
@@ -551,11 +554,39 @@ static const char *const modes[] = {
 	[USB_DR_MODE_OTG] = "otg",
 };
 
+static int tegra_xusb_role_sw_set(struct device *dev, enum usb_role role)
+{
+	dev_dbg(dev, "%s calling notifier for role is %d\n", __func__, role);
+
+	return 0;
+}
+
+static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
+{
+	int err = 0;
+	struct usb_role_switch_desc role_sx_desc = {
+					.set = tegra_xusb_role_sw_set,
+					.fwnode = dev_fwnode(&port->dev),
+						   };
+
+	port->usb_role_sw = usb_role_switch_register(&port->dev,
+						&role_sx_desc);
+	if (IS_ERR(port->usb_role_sw)) {
+		err = PTR_ERR(port->usb_role_sw);
+		if (err != EPROBE_DEFER)
+			dev_err(&port->dev, "Failed to register USB role SW: %d",
+				err);
+	}
+
+	return err;
+}
+
 static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
 {
 	struct tegra_xusb_port *port = &usb2->base;
 	struct device_node *np = port->dev.of_node;
 	const char *mode;
+	int err;
 
 	usb2->internal = of_property_read_bool(np, "nvidia,internal");
 
@@ -572,6 +603,15 @@ static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
 		usb2->mode = USB_DR_MODE_HOST;
 	}
 
+	if (of_property_read_bool(np, "usb-role-switch")) {
+		/* populate connector entry */
+		of_platform_populate(np, NULL, NULL, &port->dev);
+
+		err = tegra_xusb_setup_usb_role_switch(port);
+		if (err < 0)
+			return err;
+	}
+
 	usb2->supply = devm_regulator_get(&port->dev, "vbus");
 	return PTR_ERR_OR_ZERO(usb2->supply);
 }
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
index da94fcc..9f27899 100644
--- a/drivers/phy/tegra/xusb.h
+++ b/drivers/phy/tegra/xusb.h
@@ -12,6 +12,7 @@
 #include <linux/workqueue.h>
 
 #include <linux/usb/otg.h>
+#include <linux/usb/role.h>
 
 /* legacy entry points for backwards-compatibility */
 int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
@@ -266,6 +267,8 @@ struct tegra_xusb_port {
 	struct list_head list;
 	struct device dev;
 
+	struct usb_role_switch *usb_role_sw;
+
 	const struct tegra_xusb_port_ops *ops;
 };
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 04/18] phy: tegra: xusb: Add usb-phy support
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (2 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 03/18] phy: tegra: xusb: Add usb-role-switch support Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 05/18] phy: tegra: xusb: Add support to get companion USB 3 port Nagarjuna Kristam
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

For USB 2 ports that has usb-role-switch enabled, add usb-phy for
corresponding USB 2 phy. USB role changes from role switch are then
updated to corresponding host and device mode drivers via usb-phy notifier
block.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/phy/tegra/xusb.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/phy/tegra/xusb.h |  2 ++
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index da60a63..4c86c99 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -543,7 +543,11 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
 
 static void tegra_xusb_port_unregister(struct tegra_xusb_port *port)
 {
-	usb_role_switch_unregister(port->usb_role_sw);
+	if (port->usb_role_sw) {
+		cancel_work_sync(&port->usb_phy_work);
+		usb_role_switch_unregister(port->usb_role_sw);
+		usb_remove_phy(&port->usb_phy);
+	}
 	device_unregister(&port->dev);
 }
 
@@ -554,16 +558,59 @@ static const char *const modes[] = {
 	[USB_DR_MODE_OTG] = "otg",
 };
 
+static void tegra_xusb_usb_phy_work(struct work_struct *work)
+{
+	struct tegra_xusb_port *port = container_of(work,
+				struct tegra_xusb_port, usb_phy_work);
+	enum usb_role role = usb_role_switch_get_role(port->usb_role_sw);
+
+	dev_dbg(&port->dev, "%s calling notifier for role %d\n", __func__,
+		role);
+
+	atomic_notifier_call_chain(&port->usb_phy.notifier, role,
+				   &port->usb_phy);
+}
+
 static int tegra_xusb_role_sw_set(struct device *dev, enum usb_role role)
 {
+	struct tegra_xusb_port *port = dev_get_drvdata(dev);
+
 	dev_dbg(dev, "%s calling notifier for role is %d\n", __func__, role);
 
+	schedule_work(&port->usb_phy_work);
+
+	return 0;
+}
+
+static int tegra_xusb_set_peripheral(struct usb_otg *otg,
+					struct usb_gadget *gadget)
+{
+	struct tegra_xusb_port *port = container_of(otg->usb_phy,
+					struct tegra_xusb_port, usb_phy);
+
+	if (gadget != NULL)
+		schedule_work(&port->usb_phy_work);
+
+	return 0;
+}
+
+static int tegra_xusb_set_host(struct usb_otg *otg, struct usb_bus *host)
+{
+	struct tegra_xusb_port *port = container_of(otg->usb_phy,
+					struct tegra_xusb_port, usb_phy);
+
+	if (host != NULL)
+		schedule_work(&port->usb_phy_work);
+
 	return 0;
 }
 
+
 static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
 {
 	int err = 0;
+	struct tegra_xusb_lane *lane = tegra_xusb_find_lane(port->padctl,
+							"usb2", port->index);
 	struct usb_role_switch_desc role_sx_desc = {
 					.set = tegra_xusb_role_sw_set,
 					.fwnode = dev_fwnode(&port->dev),
@@ -576,6 +623,30 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
 		if (err != EPROBE_DEFER)
 			dev_err(&port->dev, "Failed to register USB role SW: %d",
 				err);
+		return err;
+	}
+
+	INIT_WORK(&port->usb_phy_work, tegra_xusb_usb_phy_work);
+
+	port->usb_phy.otg = devm_kzalloc(&port->dev,
+					 sizeof(struct usb_otg), GFP_KERNEL);
+	if (!port->usb_phy.otg)
+		return -ENOMEM;
+
+	/*
+	 * Assign phy dev to usb-phy dev. Host/device drivers can use phy
+	 * reference to retrieve usb-phy details.
+	 */
+	port->usb_phy.dev = &lane->pad->lanes[port->index]->dev;
+	port->usb_phy.dev->driver = port->padctl->dev->driver;
+	port->usb_phy.otg->usb_phy = &port->usb_phy;
+	port->usb_phy.otg->set_peripheral = tegra_xusb_set_peripheral;
+	port->usb_phy.otg->set_host = tegra_xusb_set_host;
+
+	err = usb_add_phy_dev(&port->usb_phy);
+	if (err < 0) {
+		dev_err(&port->dev, "Failed to add usbphy: %d\n", err);
+		return err;
 	}
 
 	return err;
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
index 9f27899..2345657 100644
--- a/drivers/phy/tegra/xusb.h
+++ b/drivers/phy/tegra/xusb.h
@@ -268,6 +268,8 @@ struct tegra_xusb_port {
 	struct device dev;
 
 	struct usb_role_switch *usb_role_sw;
+	struct work_struct usb_phy_work;
+	struct usb_phy usb_phy;
 
 	const struct tegra_xusb_port_ops *ops;
 };
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 05/18] phy: tegra: xusb: Add support to get companion USB 3 port
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (3 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 04/18] phy: tegra: xusb: Add usb-phy support Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 14:57   ` Thierry Reding
  2019-12-06 10:50 ` [PATCH 06/18] phy: tegra: xusb: Add set_mode support for USB 2 phy on Tegra210 Nagarjuna Kristam
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Tegra XUSB host, device mode driver requires the USB 3 companion port
number for corresponding USB 2 port. Add API to retrieve the same.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/phy/tegra/xusb.c       | 21 +++++++++++++++++++++
 include/linux/phy/tegra/xusb.h |  2 ++
 2 files changed, 23 insertions(+)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index 4c86c99..2e73cf8 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -1254,6 +1254,27 @@ int tegra_phy_xusb_utmi_port_reset(struct phy *phy)
 }
 EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_port_reset);
 
+int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
+				    unsigned int port)
+{
+	struct tegra_xusb_usb2_port *usb2 = tegra_xusb_find_usb2_port(padctl,
+								      port);
+	struct tegra_xusb_usb3_port *usb3;
+	int i;
+
+	if (!usb2)
+		return -EINVAL;
+
+	for (i = 0; i < padctl->soc->ports.usb3.count; i++) {
+		usb3 = tegra_xusb_find_usb3_port(padctl, i);
+		if (usb3 && usb3->port == usb2->base.index)
+			return usb3->base.index;
+	}
+
+	return -1;
+}
+EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get_usb3_companion);
+
 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
 MODULE_DESCRIPTION("Tegra XUSB Pad Controller driver");
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h
index 1235865..71d9569 100644
--- a/include/linux/phy/tegra/xusb.h
+++ b/include/linux/phy/tegra/xusb.h
@@ -21,4 +21,6 @@ int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
 int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl,
 					bool val);
 int tegra_phy_xusb_utmi_port_reset(struct phy *phy);
+int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
+					 unsigned int port);
 #endif /* PHY_TEGRA_XUSB_H */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 06/18] phy: tegra: xusb: Add set_mode support for USB 2 phy on Tegra210
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (4 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 05/18] phy: tegra: xusb: Add support to get companion USB 3 port Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 07/18] phy: tegra: xusb: Add set_mode support for utmi phy on Tegra186 Nagarjuna Kristam
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Add support for set_mode on USB 2 phy. This allow XUSB host/device mode
drivers to configure the hardware to corresponding modes.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/phy/tegra/xusb-tegra210.c | 126 ++++++++++++++++++++++++++++++--------
 1 file changed, 99 insertions(+), 27 deletions(-)

diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c
index 394913b..6610b1d7 100644
--- a/drivers/phy/tegra/xusb-tegra210.c
+++ b/drivers/phy/tegra/xusb-tegra210.c
@@ -236,6 +236,7 @@
 #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT 18
 #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK 0xf
 #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING 8
+#define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_GROUNDED 0
 
 struct tegra210_xusb_fuse_calibration {
 	u32 hs_curr_level[4];
@@ -935,6 +936,98 @@ static int tegra210_usb2_phy_exit(struct phy *phy)
 	return tegra210_xusb_padctl_disable(lane->pad->padctl);
 }
 
+static int tegra210_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
+					      bool status)
+{
+	u32 value;
+
+	dev_dbg(padctl->dev, "%s vbus override\n", status ? "set" : "clear");
+
+	value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID);
+
+	if (status) {
+		value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
+		value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK <<
+			   XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT);
+		value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING <<
+			 XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT;
+	} else {
+		value &= ~XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
+	}
+
+	padctl_writel(padctl, value, XUSB_PADCTL_USB2_VBUS_ID);
+
+	return 0;
+}
+
+static int tegra210_xusb_padctl_id_override(struct tegra_xusb_padctl *padctl,
+					    bool status)
+{
+	u32 value;
+
+	dev_dbg(padctl->dev, "%s id override\n", status ? "set" : "clear");
+
+	value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID);
+
+	if (status) {
+		if (value & XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON) {
+			value &= ~XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
+			padctl_writel(padctl, value, XUSB_PADCTL_USB2_VBUS_ID);
+			usleep_range(1000, 2000);
+
+			value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID);
+		}
+
+		value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK <<
+			   XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT);
+		value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_GROUNDED <<
+			 XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT;
+	} else {
+		value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK <<
+			   XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT);
+		value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING <<
+			 XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT;
+	}
+
+	padctl_writel(padctl, value, XUSB_PADCTL_USB2_VBUS_ID);
+
+	return 0;
+}
+
+static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode,
+				      int submode)
+{
+	struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
+	struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+	struct tegra_xusb_usb2_port *port = tegra_xusb_find_usb2_port(padctl,
+								lane->index);
+	int err = 0;
+
+	mutex_lock(&padctl->lock);
+
+	dev_dbg(&port->base.dev, "%s: mode %d", __func__, mode);
+
+	if (mode == PHY_MODE_USB_OTG) {
+		if (submode == USB_ROLE_HOST) {
+			tegra210_xusb_padctl_id_override(padctl, true);
+
+			err = regulator_enable(port->supply);
+		} else if (submode == USB_ROLE_DEVICE) {
+			tegra210_xusb_padctl_vbus_override(padctl, true);
+		} else if (submode == USB_ROLE_NONE) {
+			if (regulator_is_enabled(port->supply))
+				regulator_disable(port->supply);
+
+			tegra210_xusb_padctl_id_override(padctl, false);
+			tegra210_xusb_padctl_vbus_override(padctl, false);
+		}
+	}
+
+	mutex_unlock(&padctl->lock);
+
+	return err;
+}
+
 static int tegra210_usb2_phy_power_on(struct phy *phy)
 {
 	struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
@@ -1048,9 +1141,11 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
 	padctl_writel(padctl, value,
 		      XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index));
 
-	err = regulator_enable(port->supply);
-	if (err)
-		return err;
+	if (port->supply && port->mode == USB_DR_MODE_HOST) {
+		err = regulator_enable(port->supply);
+		if (err)
+			return err;
+	}
 
 	mutex_lock(&padctl->lock);
 
@@ -1164,6 +1259,7 @@ static const struct phy_ops tegra210_usb2_phy_ops = {
 	.exit = tegra210_usb2_phy_exit,
 	.power_on = tegra210_usb2_phy_power_on,
 	.power_off = tegra210_usb2_phy_power_off,
+	.set_mode = tegra210_usb2_phy_set_mode,
 	.owner = THIS_MODULE,
 };
 
@@ -2023,30 +2119,6 @@ static const struct tegra_xusb_port_ops tegra210_usb3_port_ops = {
 	.map = tegra210_usb3_port_map,
 };
 
-static int tegra210_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
-					      bool status)
-{
-	u32 value;
-
-	dev_dbg(padctl->dev, "%s vbus override\n", status ? "set" : "clear");
-
-	value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID);
-
-	if (status) {
-		value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
-		value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK <<
-			   XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT);
-		value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING <<
-			 XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT;
-	} else {
-		value &= ~XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
-	}
-
-	padctl_writel(padctl, value, XUSB_PADCTL_USB2_VBUS_ID);
-
-	return 0;
-}
-
 static int tegra210_utmi_port_reset(struct phy *phy)
 {
 	struct tegra_xusb_padctl *padctl;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 07/18] phy: tegra: xusb: Add set_mode support for utmi phy on Tegra186
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (5 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 06/18] phy: tegra: xusb: Add set_mode support for USB 2 phy on Tegra210 Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 08/18] usb: xhci-tegra: Add OTG support Nagarjuna Kristam
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Add support for set_mode on utmi phy. This allow XUSB host/device mode
drivers to configure the hardware to corresponding modes.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/phy/tegra/xusb-tegra186.c | 109 ++++++++++++++++++++++++++++++--------
 1 file changed, 87 insertions(+), 22 deletions(-)

diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
index 84c2739..9a45160 100644
--- a/drivers/phy/tegra/xusb-tegra186.c
+++ b/drivers/phy/tegra/xusb-tegra186.c
@@ -301,6 +301,92 @@ static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
 	tegra186_utmi_bias_pad_power_off(padctl);
 }
 
+static int tegra186_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
+					       bool status)
+{
+	u32 value;
+
+	dev_dbg(padctl->dev, "%s vbus override\n", status ? "set" : "clear");
+
+	value = padctl_readl(padctl, USB2_VBUS_ID);
+
+	if (status) {
+		value |= VBUS_OVERRIDE;
+		value &= ~ID_OVERRIDE(~0);
+		value |= ID_OVERRIDE_FLOATING;
+	} else {
+		value &= ~VBUS_OVERRIDE;
+	}
+
+	padctl_writel(padctl, value, USB2_VBUS_ID);
+
+	return 0;
+}
+
+static int tegra186_xusb_padctl_id_override(struct tegra_xusb_padctl *padctl,
+					    bool status)
+{
+	u32 value;
+
+	dev_dbg(padctl->dev, "%s id override\n", status ? "set" : "clear");
+
+	value = padctl_readl(padctl, USB2_VBUS_ID);
+
+	if (status) {
+		if (value & VBUS_OVERRIDE) {
+			value &= ~VBUS_OVERRIDE;
+			padctl_writel(padctl, value, USB2_VBUS_ID);
+			usleep_range(1000, 2000);
+
+			value = padctl_readl(padctl, USB2_VBUS_ID);
+		}
+
+		value &= ~ID_OVERRIDE(~0);
+		value |= ID_OVERRIDE_GROUNDED;
+	} else {
+		value &= ~ID_OVERRIDE(~0);
+		value |= ID_OVERRIDE_FLOATING;
+	}
+
+	padctl_writel(padctl, value, USB2_VBUS_ID);
+
+	return 0;
+}
+
+static int tegra186_utmi_phy_set_mode(struct phy *phy, enum phy_mode mode,
+				      int submode)
+{
+	struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
+	struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+	struct tegra_xusb_usb2_port *port = tegra_xusb_find_usb2_port(padctl,
+								lane->index);
+	int err = 0;
+
+	mutex_lock(&padctl->lock);
+
+	dev_dbg(&port->base.dev, "%s: mode %d", __func__, mode);
+
+	if (mode == PHY_MODE_USB_OTG) {
+		if (submode == USB_ROLE_HOST) {
+			tegra186_xusb_padctl_id_override(padctl, true);
+
+			err = regulator_enable(port->supply);
+		} else if (submode == USB_ROLE_DEVICE) {
+			tegra186_xusb_padctl_vbus_override(padctl, true);
+		} else if (submode == USB_ROLE_NONE) {
+			if (regulator_is_enabled(port->supply))
+				regulator_disable(port->supply);
+
+			tegra186_xusb_padctl_id_override(padctl, false);
+			tegra186_xusb_padctl_vbus_override(padctl, false);
+		}
+	}
+
+	mutex_unlock(&padctl->lock);
+
+	return err;
+}
+
 static int tegra186_utmi_phy_power_on(struct phy *phy)
 {
 	struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
@@ -439,6 +525,7 @@ static const struct phy_ops utmi_phy_ops = {
 	.exit = tegra186_utmi_phy_exit,
 	.power_on = tegra186_utmi_phy_power_on,
 	.power_off = tegra186_utmi_phy_power_off,
+	.set_mode = tegra186_utmi_phy_set_mode,
 	.owner = THIS_MODULE,
 };
 
@@ -857,28 +944,6 @@ static void tegra186_xusb_padctl_remove(struct tegra_xusb_padctl *padctl)
 {
 }
 
-static int tegra186_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
-					       bool status)
-{
-	u32 value;
-
-	dev_dbg(padctl->dev, "%s vbus override\n", status ? "set" : "clear");
-
-	value = padctl_readl(padctl, USB2_VBUS_ID);
-
-	if (status) {
-		value |= VBUS_OVERRIDE;
-		value &= ~ID_OVERRIDE(~0);
-		value |= ID_OVERRIDE_FLOATING;
-	} else {
-		value &= ~VBUS_OVERRIDE;
-	}
-
-	padctl_writel(padctl, value, USB2_VBUS_ID);
-
-	return 0;
-}
-
 static const struct tegra_xusb_padctl_ops tegra186_xusb_padctl_ops = {
 	.probe = tegra186_xusb_padctl_probe,
 	.remove = tegra186_xusb_padctl_remove,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 08/18] usb: xhci-tegra: Add OTG support
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (6 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 07/18] phy: tegra: xusb: Add set_mode support for utmi phy on Tegra186 Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 09/18] usb: gadget: tegra-xudc: Remove usb-role-switch support Nagarjuna Kristam
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Get usb-phy's for availbale USB 2 phys. Register id notifiers for available
usb-phy's to receive role change notifications. Perform PP for the received
role change usb ports.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/usb/host/xhci-tegra.c | 226 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 225 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index bf90654..4b6db83 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -23,6 +23,9 @@
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 #include <linux/slab.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/role.h>
 #include <soc/tegra/pmc.h>
 
 #include "xhci.h"
@@ -170,6 +173,7 @@ struct tegra_xusb_soc {
 
 	bool scale_ss_clock;
 	bool has_ipfs;
+	bool otg_reset_sspi;
 };
 
 struct tegra_xusb {
@@ -212,6 +216,14 @@ struct tegra_xusb {
 	struct phy **phys;
 	unsigned int num_phys;
 
+	struct usb_phy **usbphy;
+	unsigned int num_usb_phys;
+	int otg_usb2_port;
+	int otg_usb3_port;
+	bool host_mode;
+	struct notifier_block id_nb;
+	struct work_struct id_work;
+
 	/* Firmware loading related */
 	struct {
 		size_t size;
@@ -966,6 +978,206 @@ static int tegra_xusb_powerdomain_init(struct device *dev,
 	return 0;
 }
 
+static void tegra_xhci_set_port_power(struct tegra_xusb *tegra, bool main,
+						 bool set)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(tegra->hcd);
+	struct usb_hcd *hcd = main ?  xhci->main_hcd : xhci->shared_hcd;
+	int wait = (!main && !set) ? 1000 : 10;
+	u16 typeReq = set ? SetPortFeature : ClearPortFeature;
+	u16 wIndex = main ? tegra->otg_usb2_port + 1 : tegra->otg_usb3_port + 1;
+	u32 status;
+	u32 stat_power = main ? USB_PORT_STAT_POWER : USB_SS_PORT_STAT_POWER;
+	u32 status_val = set ? stat_power : 0;
+
+	dev_dbg(tegra->dev, "%s:%s %s PP\n", __func__, set ? "set" : "clear",
+							main ? "HS" : "SS");
+
+	tegra_xhci_hc_driver.hub_control(hcd, typeReq, USB_PORT_FEAT_POWER,
+					 wIndex, NULL, 0);
+
+	do {
+		tegra_xhci_hc_driver.hub_control(hcd, GetPortStatus, 0, wIndex,
+					(char *) &status, sizeof(status));
+		if (status_val == (status & stat_power))
+			break;
+
+		if (!main && !set)
+			usleep_range(600, 700);
+		else
+			usleep_range(10, 20);
+	} while (--wait > 0);
+
+	if (status_val != (status & stat_power))
+		dev_info(tegra->dev, "failed to %s %s PP %d\n",
+						set ? "set" : "clear",
+						main ? "HS" : "SS", status);
+}
+
+static struct phy *tegra_xusb_get_phy(struct tegra_xusb *tegra, char *name,
+								int port)
+{
+	int i, phy_count = 0;
+
+	for (i = 0; i < tegra->soc->num_types; i++) {
+		if (!strncmp(tegra->soc->phy_types[i].name, "usb2",
+							    strlen(name)))
+			return tegra->phys[phy_count+port];
+
+		phy_count += tegra->soc->phy_types[i].num;
+	}
+
+	return NULL;
+}
+
+static void tegra_xhci_id_work(struct work_struct *work)
+{
+	struct tegra_xusb *tegra = container_of(work, struct tegra_xusb,
+						id_work);
+	struct xhci_hcd *xhci = hcd_to_xhci(tegra->hcd);
+	struct tegra_xusb_mbox_msg msg;
+	struct phy *phy = tegra_xusb_get_phy(tegra, "usb2",
+						    tegra->otg_usb2_port);
+	u32 status;
+	int ret;
+
+	dev_dbg(tegra->dev, "host mode %s\n", tegra->host_mode ? "on" : "off");
+
+	mutex_lock(&tegra->lock);
+
+	if (tegra->host_mode)
+		phy_set_mode_ext(phy, PHY_MODE_USB_OTG, USB_ROLE_HOST);
+	else
+		phy_set_mode_ext(phy, PHY_MODE_USB_OTG, USB_ROLE_NONE);
+
+	mutex_unlock(&tegra->lock);
+
+	if (tegra->host_mode) {
+		/* switch to host mode */
+		if (tegra->otg_usb3_port >= 0) {
+			if (tegra->soc->otg_reset_sspi) {
+				/* set PP=0 */
+				tegra_xhci_hc_driver.hub_control(
+					xhci->shared_hcd, GetPortStatus,
+					0, tegra->otg_usb3_port+1,
+					(char *) &status, sizeof(status));
+				if (status & USB_SS_PORT_STAT_POWER)
+					tegra_xhci_set_port_power(tegra, false,
+								  false);
+
+				/* reset OTG port SSPI */
+				msg.cmd = MBOX_CMD_RESET_SSPI;
+				msg.data = tegra->otg_usb3_port+1;
+
+				ret = tegra_xusb_mbox_send(tegra, &msg);
+				if (ret < 0) {
+					dev_info(tegra->dev,
+						"failed to RESET_SSPI %d\n",
+						ret);
+				}
+			}
+
+			tegra_xhci_set_port_power(tegra, false, true);
+		}
+
+		tegra_xhci_set_port_power(tegra, true, true);
+
+	} else {
+		if (tegra->otg_usb3_port >= 0)
+			tegra_xhci_set_port_power(tegra, false, false);
+
+		tegra_xhci_set_port_power(tegra, true, false);
+	}
+}
+
+static int tegra_xusb_get_usb2_port(struct tegra_xusb *tegra,
+					      struct usb_phy *usbphy)
+{
+	int i;
+
+	for (i = 0; i < tegra->num_usb_phys; i++) {
+		if (tegra->usbphy[i] && usbphy == tegra->usbphy[i])
+			return i;
+	}
+
+	return -1;
+}
+
+static int tegra_xhci_id_notify(struct notifier_block *nb,
+					 unsigned long action, void *data)
+{
+	struct tegra_xusb *tegra = container_of(nb, struct tegra_xusb,
+						    id_nb);
+	struct usb_phy *usbphy = (struct usb_phy *)data;
+
+	dev_dbg(tegra->dev, "%s: action is %ld", __func__, action);
+
+	if ((tegra->host_mode && action == USB_ROLE_HOST) ||
+		(!tegra->host_mode && action != USB_ROLE_HOST)) {
+		dev_dbg(tegra->dev, "Same role(%d) received. Ignore",
+							tegra->host_mode);
+		return NOTIFY_OK;
+	}
+
+	tegra->otg_usb2_port = tegra_xusb_get_usb2_port(tegra, usbphy);
+	tegra->otg_usb3_port = tegra_xusb_padctl_get_usb3_companion(
+							tegra->padctl,
+							tegra->otg_usb2_port);
+
+	tegra->host_mode = (action == USB_ROLE_HOST) ? true : false;
+
+	schedule_work(&tegra->id_work);
+
+	return NOTIFY_OK;
+}
+
+static int tegra_xusb_init_usb_phy(struct tegra_xusb *tegra)
+{
+	int i;
+
+	tegra->usbphy = devm_kcalloc(tegra->dev, tegra->num_usb_phys,
+				   sizeof(*tegra->usbphy), GFP_KERNEL);
+	if (!tegra->usbphy)
+		return -ENOMEM;
+
+	INIT_WORK(&tegra->id_work, tegra_xhci_id_work);
+	tegra->id_nb.notifier_call = tegra_xhci_id_notify;
+
+	for (i = 0; i < tegra->num_usb_phys; i++) {
+		struct phy *phy = tegra_xusb_get_phy(tegra, "usb2", i);
+
+		if (!phy)
+			continue;
+
+		tegra->usbphy[i] = devm_usb_get_phy_by_node(tegra->dev,
+							phy->dev.of_node,
+							&tegra->id_nb);
+		if (!IS_ERR(tegra->usbphy[i])) {
+			dev_dbg(tegra->dev, "usbphy-%d registered", i);
+			otg_set_host(tegra->usbphy[i]->otg, &tegra->hcd->self);
+		} else {
+			/*
+			 * usb-phy is optional, continue if its not available.
+			 */
+			tegra->usbphy[i] = NULL;
+		}
+	}
+
+	return 0;
+}
+
+static void tegra_xusb_deinit_usb_phy(struct tegra_xusb *tegra)
+{
+	int i;
+
+	cancel_work_sync(&tegra->id_work);
+
+	for (i = 0; i < tegra->num_usb_phys; i++)
+		if (tegra->usbphy[i])
+			otg_set_host(tegra->usbphy[i]->otg, NULL);
+}
+
+
 static int tegra_xusb_probe(struct platform_device *pdev)
 {
 	struct tegra_xusb_mbox_msg msg;
@@ -1136,8 +1348,11 @@ static int tegra_xusb_probe(struct platform_device *pdev)
 		goto put_powerdomains;
 	}
 
-	for (i = 0; i < tegra->soc->num_types; i++)
+	for (i = 0; i < tegra->soc->num_types; i++) {
+		if (!strncmp(tegra->soc->phy_types[i].name, "usb2", 4))
+			tegra->num_usb_phys = tegra->soc->phy_types[i].num;
 		tegra->num_phys += tegra->soc->phy_types[i].num;
+	}
 
 	tegra->phys = devm_kcalloc(&pdev->dev, tegra->num_phys,
 				   sizeof(*tegra->phys), GFP_KERNEL);
@@ -1268,6 +1483,12 @@ static int tegra_xusb_probe(struct platform_device *pdev)
 		goto remove_usb3;
 	}
 
+	err = tegra_xusb_init_usb_phy(tegra);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to Init usb-phy: %d\n", err);
+		goto remove_usb3;
+	}
+
 	return 0;
 
 remove_usb3:
@@ -1301,6 +1522,8 @@ static int tegra_xusb_remove(struct platform_device *pdev)
 	struct tegra_xusb *tegra = platform_get_drvdata(pdev);
 	struct xhci_hcd *xhci = hcd_to_xhci(tegra->hcd);
 
+	tegra_xusb_deinit_usb_phy(tegra);
+
 	usb_remove_hcd(xhci->shared_hcd);
 	usb_put_hcd(xhci->shared_hcd);
 	xhci->shared_hcd = NULL;
@@ -1421,6 +1644,7 @@ static const struct tegra_xusb_soc tegra210_soc = {
 	},
 	.scale_ss_clock = false,
 	.has_ipfs = true,
+	.otg_reset_sspi = true,
 	.mbox = {
 		.cmd = 0xe4,
 		.data_in = 0xe8,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 09/18] usb: gadget: tegra-xudc: Remove usb-role-switch support
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (7 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 08/18] usb: xhci-tegra: Add OTG support Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 10/18] usb: gadget: tegra-xudc: Add usb-phy support Nagarjuna Kristam
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Padctl driver will act as a central driver to receive USB role changes via
usb-role-switch. This is updated to corresponding host, device drivers.
Hence remove usb-role-switch from XUDC driver.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/usb/gadget/udc/tegra-xudc.c | 65 ++++++++++---------------------------
 1 file changed, 17 insertions(+), 48 deletions(-)

diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
index 634c2c1..6ddb974 100644
--- a/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/drivers/usb/gadget/udc/tegra-xudc.c
@@ -477,8 +477,8 @@ struct tegra_xudc {
 
 	struct clk_bulk_data *clks;
 
-	enum usb_role device_mode;
-	struct usb_role_switch *usb_role_sw;
+	enum usb_role role;
+	bool device_mode;
 	struct work_struct usb_role_sw_work;
 
 	struct phy *usb3_phy;
@@ -596,6 +596,8 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
 {
 	int err;
 
+	if (xudc->device_mode)
+		return;
 	pm_runtime_get_sync(xudc->dev);
 
 	err = phy_power_on(xudc->utmi_phy);
@@ -610,7 +612,8 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
 
 	tegra_xusb_padctl_set_vbus_override(xudc->padctl, true);
 
-	xudc->device_mode = USB_ROLE_DEVICE;
+	xudc->device_mode = true;
+
 }
 
 static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
@@ -619,6 +622,9 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
 	u32 pls, val;
 	int err;
 
+	if (!xudc->device_mode)
+		return;
+
 	dev_dbg(xudc->dev, "device mode off\n");
 
 	connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS);
@@ -643,7 +649,7 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
 		xudc_writel(xudc, val, PORTSC);
 	}
 
-	xudc->device_mode = USB_ROLE_NONE;
+	xudc->device_mode = false;
 
 	/* Wait for disconnect event. */
 	if (connected)
@@ -668,31 +674,13 @@ static void tegra_xudc_usb_role_sw_work(struct work_struct *work)
 	struct tegra_xudc *xudc = container_of(work, struct tegra_xudc,
 					       usb_role_sw_work);
 
-	if (!xudc->usb_role_sw ||
-		usb_role_switch_get_role(xudc->usb_role_sw) == USB_ROLE_DEVICE)
+	if (xudc->role == USB_ROLE_DEVICE)
 		tegra_xudc_device_mode_on(xudc);
 	else
 		tegra_xudc_device_mode_off(xudc);
 
 }
 
-static int tegra_xudc_usb_role_sw_set(struct device *dev, enum usb_role role)
-{
-	struct tegra_xudc *xudc = dev_get_drvdata(dev);
-	unsigned long flags;
-
-	dev_dbg(dev, "%s role is %d\n", __func__, role);
-
-	spin_lock_irqsave(&xudc->lock, flags);
-
-	if (!xudc->suspended)
-		schedule_work(&xudc->usb_role_sw_work);
-
-	spin_unlock_irqrestore(&xudc->lock, flags);
-
-	return 0;
-}
-
 static void tegra_xudc_plc_reset_work(struct work_struct *work)
 {
 	struct delayed_work *dwork = to_delayed_work(work);
@@ -729,8 +717,7 @@ static void tegra_xudc_port_reset_war_work(struct work_struct *work)
 
 	spin_lock_irqsave(&xudc->lock, flags);
 
-	if ((xudc->device_mode == USB_ROLE_DEVICE)
-			      && xudc->wait_for_sec_prc) {
+	if (xudc->device_mode && xudc->wait_for_sec_prc) {
 		pls = (xudc_readl(xudc, PORTSC) & PORTSC_PLS_MASK) >>
 			PORTSC_PLS_SHIFT;
 		dev_dbg(xudc->dev, "pls = %x\n", pls);
@@ -3457,7 +3444,6 @@ static int tegra_xudc_probe(struct platform_device *pdev)
 {
 	struct tegra_xudc *xudc;
 	struct resource *res;
-	struct usb_role_switch_desc role_sx_desc = { 0 };
 	unsigned int i;
 	int err;
 
@@ -3587,23 +3573,10 @@ static int tegra_xudc_probe(struct platform_device *pdev)
 	INIT_DELAYED_WORK(&xudc->port_reset_war_work,
 				tegra_xudc_port_reset_war_work);
 
-	if (of_property_read_bool(xudc->dev->of_node, "usb-role-switch")) {
-		role_sx_desc.set = tegra_xudc_usb_role_sw_set;
-		role_sx_desc.fwnode = dev_fwnode(xudc->dev);
-
-		xudc->usb_role_sw = usb_role_switch_register(xudc->dev,
-							&role_sx_desc);
-		if (IS_ERR(xudc->usb_role_sw)) {
-			err = PTR_ERR(xudc->usb_role_sw);
-			dev_err(xudc->dev, "Failed to register USB role SW: %d",
-					   err);
-			goto free_eps;
-		}
-	} else {
-		/* Set the mode as device mode and this keeps phy always ON */
-		dev_info(xudc->dev, "Set usb role to device mode always");
-		schedule_work(&xudc->usb_role_sw_work);
-	}
+	/* Set the mode as device mode and this keeps phy always ON */
+	dev_info(xudc->dev, "Set usb role to device mode always");
+	xudc->role = USB_ROLE_DEVICE;
+	schedule_work(&xudc->usb_role_sw_work);
 
 	pm_runtime_enable(&pdev->dev);
 
@@ -3643,11 +3616,7 @@ static int tegra_xudc_remove(struct platform_device *pdev)
 	pm_runtime_get_sync(xudc->dev);
 
 	cancel_delayed_work(&xudc->plc_reset_work);
-
-	if (xudc->usb_role_sw) {
-		usb_role_switch_unregister(xudc->usb_role_sw);
-		cancel_work_sync(&xudc->usb_role_sw_work);
-	}
+	cancel_work_sync(&xudc->usb_role_sw_work);
 
 	usb_del_gadget_udc(&xudc->gadget);
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 10/18] usb: gadget: tegra-xudc: Add usb-phy support
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (8 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 09/18] usb: gadget: tegra-xudc: Remove usb-role-switch support Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 11/18] usb: gadget: tegra-xudc: use phy_set_mode to set/unset device mode Nagarjuna Kristam
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

usb-phy is used to get notified on the USB role changes. Get usb-phy from
the utmi phy.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/usb/gadget/udc/tegra-xudc.c | 39 +++++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
index 6ddb974..0f27d57 100644
--- a/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/drivers/usb/gadget/udc/tegra-xudc.c
@@ -26,7 +26,9 @@
 #include <linux/reset.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
 #include <linux/usb/role.h>
+#include <linux/usb/phy.h>
 #include <linux/workqueue.h>
 
 /* XUSB_DEV registers */
@@ -488,6 +490,9 @@ struct tegra_xudc {
 	bool suspended;
 	bool powergated;
 
+	struct usb_phy *usbphy;
+	struct notifier_block vbus_nb;
+
 	struct completion disconnect_complete;
 
 	bool selfpowered;
@@ -678,7 +683,22 @@ static void tegra_xudc_usb_role_sw_work(struct work_struct *work)
 		tegra_xudc_device_mode_on(xudc);
 	else
 		tegra_xudc_device_mode_off(xudc);
+}
+
+static int tegra_xudc_vbus_notifier(struct notifier_block *nb,
+					 unsigned long action, void *data)
+{
+	struct tegra_xudc *xudc = container_of(nb, struct tegra_xudc,
+					       vbus_nb);
+
+	dev_dbg(xudc->dev, "%s action is %ld\n", __func__, action);
+
+	xudc->role = (enum usb_role)action;
 
+	if (!xudc->suspended)
+		schedule_work(&xudc->usb_role_sw_work);
+
+	return NOTIFY_OK;
 }
 
 static void tegra_xudc_plc_reset_work(struct work_struct *work)
@@ -1949,6 +1969,9 @@ static int tegra_xudc_gadget_start(struct usb_gadget *gadget,
 		xudc_writel(xudc, val, CTRL);
 	}
 
+	if (xudc->usbphy)
+		otg_set_peripheral(xudc->usbphy->otg, gadget);
+
 	xudc->driver = driver;
 unlock:
 	dev_dbg(xudc->dev, "%s: ret value is %d", __func__, ret);
@@ -1969,6 +1992,9 @@ static int tegra_xudc_gadget_stop(struct usb_gadget *gadget)
 
 	spin_lock_irqsave(&xudc->lock, flags);
 
+	if (xudc->usbphy)
+		otg_set_peripheral(xudc->usbphy->otg, NULL);
+
 	val = xudc_readl(xudc, CTRL);
 	val &= ~(CTRL_IE | CTRL_ENABLE);
 	xudc_writel(xudc, val, CTRL);
@@ -3573,10 +3599,15 @@ static int tegra_xudc_probe(struct platform_device *pdev)
 	INIT_DELAYED_WORK(&xudc->port_reset_war_work,
 				tegra_xudc_port_reset_war_work);
 
-	/* Set the mode as device mode and this keeps phy always ON */
-	dev_info(xudc->dev, "Set usb role to device mode always");
-	xudc->role = USB_ROLE_DEVICE;
-	schedule_work(&xudc->usb_role_sw_work);
+	xudc->vbus_nb.notifier_call = tegra_xudc_vbus_notifier;
+	xudc->usbphy = devm_usb_get_phy_by_node(xudc->dev,
+						xudc->utmi_phy->dev.of_node,
+						&xudc->vbus_nb);
+	if (IS_ERR(xudc->usbphy)) {
+		err = PTR_ERR(xudc->usbphy);
+		dev_err(xudc->dev, "failed to get usbphy phy: %d\n", err);
+		goto free_eps;
+	}
 
 	pm_runtime_enable(&pdev->dev);
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 11/18] usb: gadget: tegra-xudc: use phy_set_mode to set/unset device mode
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (9 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 10/18] usb: gadget: tegra-xudc: Add usb-phy support Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 12/18] usb: gadget: tegra-xudc: support multiple device modes Nagarjuna Kristam
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

When device mode is set/uset, vbus override activity is done via
exported functions from padctl driver. Use phy_set_mode instead.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/usb/gadget/udc/tegra-xudc.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
index 0f27d57..283c320 100644
--- a/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/drivers/usb/gadget/udc/tegra-xudc.c
@@ -615,7 +615,7 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
 
 	dev_dbg(xudc->dev, "device mode on\n");
 
-	tegra_xusb_padctl_set_vbus_override(xudc->padctl, true);
+	phy_set_mode_ext(xudc->utmi_phy, PHY_MODE_USB_OTG, USB_ROLE_DEVICE);
 
 	xudc->device_mode = true;
 
@@ -636,7 +636,7 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
 
 	reinit_completion(&xudc->disconnect_complete);
 
-	tegra_xusb_padctl_set_vbus_override(xudc->padctl, false);
+	phy_set_mode_ext(xudc->utmi_phy, PHY_MODE_USB_OTG, USB_ROLE_NONE);
 
 	pls = (xudc_readl(xudc, PORTSC) & PORTSC_PLS_MASK) >>
 		PORTSC_PLS_SHIFT;
@@ -716,9 +716,11 @@ static void tegra_xudc_plc_reset_work(struct work_struct *work)
 
 		if (pls == PORTSC_PLS_INACTIVE) {
 			dev_info(xudc->dev, "PLS = Inactive. Toggle VBUS\n");
-			tegra_xusb_padctl_set_vbus_override(xudc->padctl,
-							      false);
-			tegra_xusb_padctl_set_vbus_override(xudc->padctl, true);
+			phy_set_mode_ext(xudc->utmi_phy, PHY_MODE_USB_OTG,
+					 USB_ROLE_NONE);
+			phy_set_mode_ext(xudc->utmi_phy, PHY_MODE_USB_OTG,
+					 USB_ROLE_DEVICE);
+
 			xudc->wait_csc = false;
 		}
 	}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 12/18] usb: gadget: tegra-xudc: support multiple device modes
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (10 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 11/18] usb: gadget: tegra-xudc: use phy_set_mode to set/unset device mode Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 13/18] arm64: tegra: update OTG port entries for jetson-tx1 Nagarjuna Kristam
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

This change supports limited multiple device modes by:
- At most 4 ports contains OTG/Device capability.
- One port run as device mode at a time.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 drivers/usb/gadget/udc/tegra-xudc.c | 229 ++++++++++++++++++++++++++----------
 1 file changed, 167 insertions(+), 62 deletions(-)

diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
index 283c320..a17d896 100644
--- a/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/drivers/usb/gadget/udc/tegra-xudc.c
@@ -483,14 +483,15 @@ struct tegra_xudc {
 	bool device_mode;
 	struct work_struct usb_role_sw_work;
 
-	struct phy *usb3_phy;
-	struct phy *utmi_phy;
+	struct phy **usb3_phy;
+	struct phy **utmi_phy;
 
 	struct tegra_xudc_save_regs saved_regs;
 	bool suspended;
 	bool powergated;
 
-	struct usb_phy *usbphy;
+	struct usb_phy **usbphy;
+	int current_phy_index;
 	struct notifier_block vbus_nb;
 
 	struct completion disconnect_complete;
@@ -522,6 +523,7 @@ struct tegra_xudc_soc {
 	unsigned int num_supplies;
 	const char * const *clock_names;
 	unsigned int num_clks;
+	unsigned int num_phys;
 	bool u1_enable;
 	bool u2_enable;
 	bool lpm_enable;
@@ -605,17 +607,18 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
 		return;
 	pm_runtime_get_sync(xudc->dev);
 
-	err = phy_power_on(xudc->utmi_phy);
+	err = phy_power_on(xudc->utmi_phy[xudc->current_phy_index]);
 	if (err < 0)
 		dev_err(xudc->dev, "utmi power on failed %d\n", err);
 
-	err = phy_power_on(xudc->usb3_phy);
+	err = phy_power_on(xudc->usb3_phy[xudc->current_phy_index]);
 	if (err < 0)
 		dev_err(xudc->dev, "usb3 phy power on failed %d\n", err);
 
 	dev_dbg(xudc->dev, "device mode on\n");
 
-	phy_set_mode_ext(xudc->utmi_phy, PHY_MODE_USB_OTG, USB_ROLE_DEVICE);
+	phy_set_mode_ext(xudc->utmi_phy[xudc->current_phy_index],
+			 PHY_MODE_USB_OTG, USB_ROLE_DEVICE);
 
 	xudc->device_mode = true;
 
@@ -636,7 +639,8 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
 
 	reinit_completion(&xudc->disconnect_complete);
 
-	phy_set_mode_ext(xudc->utmi_phy, PHY_MODE_USB_OTG, USB_ROLE_NONE);
+	phy_set_mode_ext(xudc->utmi_phy[xudc->current_phy_index],
+			 PHY_MODE_USB_OTG, USB_ROLE_NONE);
 
 	pls = (xudc_readl(xudc, PORTSC) & PORTSC_PLS_MASK) >>
 		PORTSC_PLS_SHIFT;
@@ -663,11 +667,11 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
 	/* Make sure interrupt handler has completed before powergating. */
 	synchronize_irq(xudc->irq);
 
-	err = phy_power_off(xudc->utmi_phy);
+	err = phy_power_off(xudc->utmi_phy[xudc->current_phy_index]);
 	if (err < 0)
 		dev_err(xudc->dev, "utmi_phy power off failed %d\n", err);
 
-	err = phy_power_off(xudc->usb3_phy);
+	err = phy_power_off(xudc->usb3_phy[xudc->current_phy_index]);
 	if (err < 0)
 		dev_err(xudc->dev, "usb3_phy power off failed %d\n", err);
 
@@ -685,17 +689,43 @@ static void tegra_xudc_usb_role_sw_work(struct work_struct *work)
 		tegra_xudc_device_mode_off(xudc);
 }
 
-static int tegra_xudc_vbus_notifier(struct notifier_block *nb,
+static int tegra_xudc_get_phy_index(struct tegra_xudc *xudc,
+					      struct usb_phy *usbphy)
+{
+	int i;
+
+	for (i = 0; i < xudc->soc->num_phys; i++) {
+		if (xudc->usbphy[i] && usbphy == xudc->usbphy[i])
+			return i;
+	}
+
+	dev_info(xudc->dev, "phy index could not be found for shared usb-phy");
+	return -1;
+}
+
+static int tegra_xudc_vbus_notify(struct notifier_block *nb,
 					 unsigned long action, void *data)
 {
 	struct tegra_xudc *xudc = container_of(nb, struct tegra_xudc,
 					       vbus_nb);
+	struct usb_phy *usbphy = (struct usb_phy *)data;
 
 	dev_dbg(xudc->dev, "%s action is %ld\n", __func__, action);
 
+	if ((xudc->device_mode && action == USB_ROLE_DEVICE) ||
+	    (!xudc->device_mode && action != USB_ROLE_DEVICE)) {
+		dev_info(xudc->dev, "Same role(%d) received. Ignore",
+			 xudc->device_mode);
+		return NOTIFY_OK;
+	}
+
 	xudc->role = (enum usb_role)action;
 
-	if (!xudc->suspended)
+	xudc->current_phy_index = tegra_xudc_get_phy_index(xudc, usbphy);
+	dev_dbg(xudc->dev, "%s current phy index is %d\n", __func__,
+		xudc->current_phy_index);
+
+	if (!xudc->suspended && xudc->current_phy_index != -1)
 		schedule_work(&xudc->usb_role_sw_work);
 
 	return NOTIFY_OK;
@@ -716,10 +746,12 @@ static void tegra_xudc_plc_reset_work(struct work_struct *work)
 
 		if (pls == PORTSC_PLS_INACTIVE) {
 			dev_info(xudc->dev, "PLS = Inactive. Toggle VBUS\n");
-			phy_set_mode_ext(xudc->utmi_phy, PHY_MODE_USB_OTG,
-					 USB_ROLE_NONE);
-			phy_set_mode_ext(xudc->utmi_phy, PHY_MODE_USB_OTG,
-					 USB_ROLE_DEVICE);
+			phy_set_mode_ext(
+					xudc->utmi_phy[xudc->current_phy_index],
+					PHY_MODE_USB_OTG, USB_ROLE_NONE);
+			phy_set_mode_ext(
+					xudc->utmi_phy[xudc->current_phy_index],
+					PHY_MODE_USB_OTG, USB_ROLE_DEVICE);
 
 			xudc->wait_csc = false;
 		}
@@ -747,7 +779,8 @@ static void tegra_xudc_port_reset_war_work(struct work_struct *work)
 		if (pls == PORTSC_PLS_DISABLED) {
 			dev_dbg(xudc->dev, "toggle vbus\n");
 			/* PRC doesn't complete in 100ms, toggle the vbus */
-			ret = tegra_phy_xusb_utmi_port_reset(xudc->utmi_phy);
+			ret = tegra_phy_xusb_utmi_port_reset(
+				xudc->utmi_phy[xudc->current_phy_index]);
 			if (ret == 1)
 				xudc->wait_for_sec_prc = 0;
 		}
@@ -1935,7 +1968,7 @@ static int tegra_xudc_gadget_start(struct usb_gadget *gadget,
 	struct tegra_xudc *xudc = to_xudc(gadget);
 	unsigned long flags;
 	u32 val;
-	int ret;
+	int ret, i;
 
 	if (!driver)
 		return -EINVAL;
@@ -1971,8 +2004,9 @@ static int tegra_xudc_gadget_start(struct usb_gadget *gadget,
 		xudc_writel(xudc, val, CTRL);
 	}
 
-	if (xudc->usbphy)
-		otg_set_peripheral(xudc->usbphy->otg, gadget);
+	for (i = 0; i < xudc->soc->num_phys; i++)
+		if (xudc->usbphy[i])
+			otg_set_peripheral(xudc->usbphy[i]->otg, gadget);
 
 	xudc->driver = driver;
 unlock:
@@ -1989,13 +2023,15 @@ static int tegra_xudc_gadget_stop(struct usb_gadget *gadget)
 	struct tegra_xudc *xudc = to_xudc(gadget);
 	unsigned long flags;
 	u32 val;
+	int i;
 
 	pm_runtime_get_sync(xudc->dev);
 
 	spin_lock_irqsave(&xudc->lock, flags);
 
-	if (xudc->usbphy)
-		otg_set_peripheral(xudc->usbphy->otg, NULL);
+	for (i = 0; i < xudc->soc->num_phys; i++)
+		if (xudc->usbphy[i])
+			otg_set_peripheral(xudc->usbphy[i]->otg, NULL);
 
 	val = xudc_readl(xudc, CTRL);
 	val &= ~(CTRL_IE | CTRL_ENABLE);
@@ -3329,33 +3365,117 @@ static void tegra_xudc_device_params_init(struct tegra_xudc *xudc)
 	xudc_writel(xudc, val, CFG_DEV_SSPI_XFER);
 }
 
-static int tegra_xudc_phy_init(struct tegra_xudc *xudc)
+static int tegra_xudc_phy_get(struct tegra_xudc *xudc)
 {
-	int err;
+	int err = 0, i, usb3;
 
-	err = phy_init(xudc->utmi_phy);
-	if (err < 0) {
-		dev_err(xudc->dev, "utmi phy init failed: %d\n", err);
-		return err;
-	}
+	xudc->utmi_phy = devm_kcalloc(xudc->dev, xudc->soc->num_phys,
+					   sizeof(*xudc->utmi_phy), GFP_KERNEL);
+	if (!xudc->utmi_phy)
+		return -ENOMEM;
 
-	err = phy_init(xudc->usb3_phy);
-	if (err < 0) {
-		dev_err(xudc->dev, "usb3 phy init failed: %d\n", err);
-		goto exit_utmi_phy;
+	xudc->usb3_phy = devm_kcalloc(xudc->dev, xudc->soc->num_phys,
+					   sizeof(*xudc->usb3_phy), GFP_KERNEL);
+	if (!xudc->usb3_phy)
+		return -ENOMEM;
+
+	xudc->usbphy = devm_kcalloc(xudc->dev, xudc->soc->num_phys,
+					   sizeof(*xudc->usbphy), GFP_KERNEL);
+	if (!xudc->usbphy)
+		return -ENOMEM;
+
+	xudc->vbus_nb.notifier_call = tegra_xudc_vbus_notify;
+
+	for (i = 0; i < xudc->soc->num_phys; i++) {
+		char phy_name[] = "usb.-.";
+
+		/* Get USB2 phy */
+		snprintf(phy_name, sizeof(phy_name), "usb2-%d", i);
+		xudc->utmi_phy[i] = devm_phy_optional_get(xudc->dev, phy_name);
+		if (IS_ERR(xudc->utmi_phy[i])) {
+			err = PTR_ERR(xudc->utmi_phy[i]);
+			if (err != -EPROBE_DEFER)
+				dev_err(xudc->dev, "failed to get usb2-%d phy: %d\n",
+					i, err);
+
+			goto clean_up;
+		} else if (xudc->utmi_phy[i]) {
+			/* Get usb-phy, if utmi phy is available */
+			xudc->usbphy[i] = devm_usb_get_phy_by_node(xudc->dev,
+						xudc->utmi_phy[i]->dev.of_node,
+						&xudc->vbus_nb);
+			if (IS_ERR(xudc->usbphy[i])) {
+				dev_err(xudc->dev, "failed to get usbphy-%d: %d\n",
+					i, err);
+				goto clean_up;
+			}
+		} else if (!xudc->utmi_phy[i]) {
+			/* if utmi phy is not available, ignore USB3 phy get */
+			continue;
+		}
+
+		/* Get USB3 phy */
+		usb3 = tegra_xusb_padctl_get_usb3_companion(xudc->padctl, i);
+		if (usb3 < 0)
+			continue;
+
+		snprintf(phy_name, sizeof(phy_name), "usb3-%d", usb3);
+		xudc->usb3_phy[i] = devm_phy_optional_get(xudc->dev, phy_name);
+		if (IS_ERR(xudc->usb3_phy[i])) {
+			err = PTR_ERR(xudc->usb3_phy[i]);
+			if (err != -EPROBE_DEFER)
+				dev_err(xudc->dev, "failed to get usb3-%d phy: %d\n",
+					usb3, err);
+
+			goto clean_up;
+		} else if (xudc->usb3_phy[i])
+			dev_dbg(xudc->dev, "usb3_phy-%d registered", usb3);
 	}
 
-	return 0;
+	return err;
+
+clean_up:
+	for (i = 0; i < xudc->soc->num_phys; i++) {
+		xudc->usb3_phy[i] = NULL;
+		xudc->utmi_phy[i] = NULL;
+		xudc->usbphy[i] = NULL;
+	}
 
-exit_utmi_phy:
-	phy_exit(xudc->utmi_phy);
 	return err;
 }
 
 static void tegra_xudc_phy_exit(struct tegra_xudc *xudc)
 {
-	phy_exit(xudc->usb3_phy);
-	phy_exit(xudc->utmi_phy);
+	int i;
+
+	for (i = 0; i < xudc->soc->num_phys; i++) {
+		phy_exit(xudc->usb3_phy[i]);
+		phy_exit(xudc->utmi_phy[i]);
+	}
+}
+
+static int tegra_xudc_phy_init(struct tegra_xudc *xudc)
+{
+	int err, i;
+
+	for (i = 0; i < xudc->soc->num_phys; i++) {
+		err = phy_init(xudc->utmi_phy[i]);
+		if (err < 0) {
+			dev_err(xudc->dev, "utmi phy init failed: %d\n", err);
+			goto exit_phy;
+		}
+
+		err = phy_init(xudc->usb3_phy[i]);
+		if (err < 0) {
+			dev_err(xudc->dev, "usb3 phy init failed: %d\n", err);
+			goto exit_phy;
+		}
+	}
+	return 0;
+
+exit_phy:
+	tegra_xudc_phy_exit(xudc);
+	return err;
 }
 
 static const char * const tegra210_xudc_supply_names[] = {
@@ -3383,6 +3503,7 @@ static struct tegra_xudc_soc tegra210_xudc_soc_data = {
 	.num_supplies = ARRAY_SIZE(tegra210_xudc_supply_names),
 	.clock_names = tegra210_xudc_clock_names,
 	.num_clks = ARRAY_SIZE(tegra210_xudc_clock_names),
+	.num_phys = 4,
 	.u1_enable = false,
 	.u2_enable = true,
 	.lpm_enable = false,
@@ -3395,6 +3516,7 @@ static struct tegra_xudc_soc tegra210_xudc_soc_data = {
 static struct tegra_xudc_soc tegra186_xudc_soc_data = {
 	.clock_names = tegra186_xudc_clock_names,
 	.num_clks = ARRAY_SIZE(tegra186_xudc_clock_names),
+	.num_phys = 4,
 	.u1_enable = true,
 	.u2_enable = true,
 	.lpm_enable = false,
@@ -3560,19 +3682,9 @@ static int tegra_xudc_probe(struct platform_device *pdev)
 		goto put_padctl;
 	}
 
-	xudc->usb3_phy = devm_phy_optional_get(&pdev->dev, "usb3");
-	if (IS_ERR(xudc->usb3_phy)) {
-		err = PTR_ERR(xudc->usb3_phy);
-		dev_err(xudc->dev, "failed to get usb3 phy: %d\n", err);
-		goto disable_regulator;
-	}
-
-	xudc->utmi_phy = devm_phy_optional_get(&pdev->dev, "usb2");
-	if (IS_ERR(xudc->utmi_phy)) {
-		err = PTR_ERR(xudc->utmi_phy);
-		dev_err(xudc->dev, "failed to get usb2 phy: %d\n", err);
-		goto disable_regulator;
-	}
+	err = tegra_xudc_phy_get(xudc);
+		if (err)
+			goto disable_regulator;
 
 	err = tegra_xudc_powerdomain_init(xudc);
 	if (err)
@@ -3601,16 +3713,6 @@ static int tegra_xudc_probe(struct platform_device *pdev)
 	INIT_DELAYED_WORK(&xudc->port_reset_war_work,
 				tegra_xudc_port_reset_war_work);
 
-	xudc->vbus_nb.notifier_call = tegra_xudc_vbus_notifier;
-	xudc->usbphy = devm_usb_get_phy_by_node(xudc->dev,
-						xudc->utmi_phy->dev.of_node,
-						&xudc->vbus_nb);
-	if (IS_ERR(xudc->usbphy)) {
-		err = PTR_ERR(xudc->usbphy);
-		dev_err(xudc->dev, "failed to get usbphy phy: %d\n", err);
-		goto free_eps;
-	}
-
 	pm_runtime_enable(&pdev->dev);
 
 	xudc->gadget.ops = &tegra_xudc_gadget_ops;
@@ -3645,6 +3747,7 @@ static int tegra_xudc_probe(struct platform_device *pdev)
 static int tegra_xudc_remove(struct platform_device *pdev)
 {
 	struct tegra_xudc *xudc = platform_get_drvdata(pdev);
+	int i;
 
 	pm_runtime_get_sync(xudc->dev);
 
@@ -3660,8 +3763,10 @@ static int tegra_xudc_remove(struct platform_device *pdev)
 
 	regulator_bulk_disable(xudc->soc->num_supplies, xudc->supplies);
 
-	phy_power_off(xudc->utmi_phy);
-	phy_power_off(xudc->usb3_phy);
+	for (i = 0; i < xudc->soc->num_phys; i++) {
+		phy_power_off(xudc->utmi_phy[i]);
+		phy_power_off(xudc->usb3_phy[i]);
+	}
 
 	tegra_xudc_phy_exit(xudc);
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 13/18] arm64: tegra: update OTG port entries for jetson-tx1
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (11 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 12/18] usb: gadget: tegra-xudc: support multiple device modes Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 14/18] arm64: tegra: update OTG port entries for jetson-tx2 Nagarjuna Kristam
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Populate OTG vbus regulator. Add usb-role-switch entry to USB 2-0 port
and corresponding connector details.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
index b009507..18c0610 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
@@ -1336,7 +1336,6 @@
 		       <&{/padctl@7009f000/pads/pcie/lanes/pcie-5}>;
 		phy-names = "usb2-0", "usb2-1", "usb2-2", "usb2-3", "usb3-0",
 			    "usb3-1";
-
 		dvddio-pex-supply = <&vdd_pex_1v05>;
 		hvddio-pex-supply = <&vdd_1v8>;
 		avdd-usb-supply = <&vdd_3v3_sys>;
@@ -1440,7 +1439,19 @@
 		ports {
 			usb2-0 {
 				status = "okay";
+				vbus-supply = <&vdd_usb_vbus_otg>;
 				mode = "otg";
+
+				usb-role-switch;
+				connector {
+					compatible = "usb-b-connector",
+						     "gpio-usb-b-connector";
+					label = "micro-USB";
+					type = "micro";
+					vbus-gpio = <&gpio TEGRA_GPIO(Z, 0)
+						     GPIO_ACTIVE_LOW>;
+					id-gpio = <&pmic 0 0>;
+				};
 			};
 
 			usb2-1 {
@@ -1606,6 +1617,17 @@
 			vin-supply = <&vdd_5v0_sys>;
 		};
 
+		vdd_usb_vbus_otg: regulator@11 {
+			compatible = "regulator-fixed";
+			reg = <9>;
+			regulator-name = "USB_VBUS_EN0";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio TEGRA_GPIO(CC, 4) GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+			vin-supply = <&vdd_5v0_sys>;
+		};
+
 		vdd_hdmi: regulator@10 {
 			compatible = "regulator-fixed";
 			reg = <10>;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 14/18] arm64: tegra: update OTG port entries for jetson-tx2
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (12 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 13/18] arm64: tegra: update OTG port entries for jetson-tx1 Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 15/18] arm64: tegra: Add xudc node for Tegra210 Nagarjuna Kristam
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Add usb-role-switch entry to OTG usb port and add corresponding connector
details.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
index f1de4ff..a1dcdb9 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
@@ -174,8 +174,20 @@
 			usb2-0 {
 				status = "okay";
 				mode = "otg";
-
 				vbus-supply = <&vdd_usb0>;
+
+				usb-role-switch;
+				connector {
+					compatible = "usb-b-connector",
+						     "gpio-usb-b-connector";
+					label = "micro-USB";
+					type = "micro";
+					vbus-gpio = <&gpio
+						     TEGRA186_MAIN_GPIO(X, 7)
+						     GPIO_ACTIVE_LOW>;
+					id-gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
+				};
+
 			};
 
 			usb2-1 {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 15/18] arm64: tegra: Add xudc node for Tegra210
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (13 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 14/18] arm64: tegra: update OTG port entries for jetson-tx2 Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 16/18] arm64: tegra: Enable xudc on Jetson TX1 Nagarjuna Kristam
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Tegra210 has one XUSB device mode controller, which can be operated
HS and SS modes. Add DT entry for XUSB device mode controller.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 48c6325..023f4c3 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1207,6 +1207,25 @@
 		status = "disabled";
 	};
 
+	usb@700d0000 {
+		compatible = "nvidia,tegra210-xudc";
+		reg = <0x0 0x700d0000 0x0 0x8000>,
+		      <0x0 0x700d8000 0x0 0x1000>,
+		      <0x0 0x700d9000 0x0 0x1000>;
+		reg-names = "base", "fpci", "ipfs";
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA210_CLK_XUSB_DEV>,
+			 <&tegra_car TEGRA210_CLK_XUSB_SS>,
+			 <&tegra_car TEGRA210_CLK_XUSB_SSP_SRC>,
+			 <&tegra_car TEGRA210_CLK_XUSB_HS_SRC>,
+			 <&tegra_car TEGRA210_CLK_XUSB_FS_SRC>;
+		clock-names = "dev", "ss", "ss_src", "hs_src", "fs_src";
+		power-domains = <&pd_xusbdev>, <&pd_xusbss>;
+		power-domain-names = "dev", "ss";
+		nvidia,xusb-padctl = <&padctl>;
+		status = "disabled";
+	};
+
 	mipi: mipi@700e3000 {
 		compatible = "nvidia,tegra210-mipi";
 		reg = <0x0 0x700e3000 0x0 0x100>;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 16/18] arm64: tegra: Enable xudc on Jetson TX1
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (14 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 15/18] arm64: tegra: Add xudc node for Tegra210 Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 17/18] arm64: tegra: Add xudc node for Tegra186 Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 18/18] arm64: tegra: Enable xudc node on Jetson TX2 Nagarjuna Kristam
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Enable XUSB device mode driver for USB 2-0 slot on Jetson TX1.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
index 18c0610..49a2a82 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
@@ -1361,7 +1361,7 @@
 				status = "okay";
 
 				lanes {
-					usb2-0 {
+					micro_b: usb2-0 {
 						nvidia,function = "xusb";
 						status = "okay";
 					};
@@ -1494,6 +1494,14 @@
 		vmmc-supply = <&vdd_3v3_sd>;
 	};
 
+	usb@700d0000 {
+		status = "okay";
+		phys = <&micro_b>;
+		phy-names = "usb2-0";
+		avddio-usb-supply = <&vdd_3v3_sys>;
+		hvdd-usb-supply = <&vdd_1v8>;
+	};
+
 	regulators {
 		compatible = "simple-bus";
 		#address-cells = <1>;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 17/18] arm64: tegra: Add xudc node for Tegra186
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (15 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 16/18] arm64: tegra: Enable xudc on Jetson TX1 Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  2019-12-06 10:50 ` [PATCH 18/18] arm64: tegra: Enable xudc node on Jetson TX2 Nagarjuna Kristam
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Tegra186 has one XUSB device mode controller, which can be operated
HS and SS modes. Add DT entry for XUSB device mode controller.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index 7893d78..6da9d09 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -554,6 +554,25 @@
 		#size-cells = <0>;
 	};
 
+	usb@3550000 {
+		compatible = "nvidia,tegra186-xudc";
+		reg = <0x0 0x03550000 0x0 0x8000>,
+		      <0x0 0x03558000 0x0 0x1000>;
+		reg-names = "base", "fpci";
+		interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&bpmp TEGRA186_CLK_XUSB_CORE_DEV>,
+			 <&bpmp TEGRA186_CLK_XUSB_SS>,
+			 <&bpmp TEGRA186_CLK_XUSB_CORE_SS>,
+			 <&bpmp TEGRA186_CLK_XUSB_FS>;
+		clock-names = "dev", "ss", "ss_src", "fs_src";
+		iommus = <&smmu TEGRA186_SID_XUSB_DEV>;
+		power-domains = <&bpmp TEGRA186_POWER_DOMAIN_XUSBB>,
+				<&bpmp TEGRA186_POWER_DOMAIN_XUSBA>;
+		power-domain-names = "dev", "ss";
+		nvidia,xusb-padctl = <&padctl>;
+		status = "disabled";
+	};
+
 	fuse@3820000 {
 		compatible = "nvidia,tegra186-efuse";
 		reg = <0x0 0x03820000 0x0 0x10000>;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 18/18] arm64: tegra: Enable xudc node on Jetson TX2
  2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
                   ` (16 preceding siblings ...)
  2019-12-06 10:50 ` [PATCH 17/18] arm64: tegra: Add xudc node for Tegra186 Nagarjuna Kristam
@ 2019-12-06 10:50 ` Nagarjuna Kristam
  17 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-06 10:50 UTC (permalink / raw)
  To: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, robh+dt, kishon
  Cc: devicetree, linux-tegra, linux-usb, linux-kernel, Nagarjuna Kristam

Enable XUSB device mode driver for USB 2-0 slot on Jetson TX2.

Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
index a1dcdb9..d7628f5 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
@@ -131,7 +131,7 @@
 				status = "okay";
 
 				lanes {
-					usb2-0 {
+					micro_b: usb2-0 {
 						nvidia,function = "xusb";
 						status = "okay";
 					};
@@ -213,6 +213,13 @@
 		phy-names = "usb2-0", "usb2-1", "usb3-0";
 	};
 
+	usb@3550000 {
+		status = "okay";
+
+		phys = <&micro_b>;
+		phy-names = "usb2-0";
+	};
+
 	i2c@c250000 {
 		/* carrier board ID EEPROM */
 		eeprom@57 {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH 01/18] dt-bindings: phy: tegra-xusb: Add usb-role-switch
  2019-12-06 10:50 ` [PATCH 01/18] dt-bindings: phy: tegra-xusb: Add usb-role-switch Nagarjuna Kristam
@ 2019-12-06 14:49   ` Thierry Reding
  2019-12-09  4:45     ` Nagarjuna Kristam
  0 siblings, 1 reply; 27+ messages in thread
From: Thierry Reding @ 2019-12-06 14:49 UTC (permalink / raw)
  To: Nagarjuna Kristam
  Cc: balbi, gregkh, jonathanh, mark.rutland, robh+dt, kishon,
	devicetree, linux-tegra, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2269 bytes --]

On Fri, Dec 06, 2019 at 04:20:04PM +0530, Nagarjuna Kristam wrote:
> Add usb-role-switch property for Tegra210 and Tegra186 platforms. This
> entry is used by XUSB pad controller driver to register for role changes
> for OTG/Peripheral capable USB 2 ports.
> 
> Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
> ---
>  Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
> index 9fb682e..0f19ed6 100644
> --- a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
> +++ b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
> @@ -179,6 +179,10 @@ Optional properties:
>    is internal. In the absence of this property the port is considered to be
>    external.
>  - vbus-supply: phandle to a regulator supplying the VBUS voltage.
> +- usb-role-switch: boolean property to indicate use of USB Role Switch.

That first sentence here seems a bit useless and vague. It doesn't
really convey anything other than the name already does. Perhaps
something like:

	Boolean property to indicate that the port support OTG. If
	present, the port supports switching between USB host and
	peripheral roles.

> +  This property is MUST for OTG,Peripheral capable USB 2 ports. Connector

If this is mandatory, why not add it to the list of required properties?
I guess since it's only mandatory for ports that support OTG, perhaps we
could add a section "Required properties for OTG capable ports:" or
something like that? Then you can also omit the second sentence in the
description.

> +  should be added as subnode, see connector.txt. vbus-gpio in connector is

There's no file called "connector.txt". Are you referring to

	Documentation/devicetree/bindings/connector/usb-connector.txt

? Also, that file calls the property "vbus-gpios" and lists it as
optional. What would happen if we don't specify it? Doesn't that just
mean that we can't support role detection?

> +  Mandatory.

"mandatory"

Thierry

>  
>  ULPI ports:
>  -----------
> -- 
> 2.7.4
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 03/18] phy: tegra: xusb: Add usb-role-switch support
  2019-12-06 10:50 ` [PATCH 03/18] phy: tegra: xusb: Add usb-role-switch support Nagarjuna Kristam
@ 2019-12-06 14:54   ` Thierry Reding
  2019-12-10  3:52     ` Nagarjuna Kristam
  0 siblings, 1 reply; 27+ messages in thread
From: Thierry Reding @ 2019-12-06 14:54 UTC (permalink / raw)
  To: Nagarjuna Kristam
  Cc: balbi, gregkh, jonathanh, mark.rutland, robh+dt, kishon,
	devicetree, linux-tegra, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4611 bytes --]

On Fri, Dec 06, 2019 at 04:20:06PM +0530, Nagarjuna Kristam wrote:
> If usb-role-switch property is present in USB 2 port, register
> usb-role-switch to receive usb role changes.
> 
> Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
> ---
>  drivers/phy/tegra/Kconfig |  1 +
>  drivers/phy/tegra/xusb.c  | 40 ++++++++++++++++++++++++++++++++++++++++
>  drivers/phy/tegra/xusb.h  |  3 +++
>  3 files changed, 44 insertions(+)
> 
> diff --git a/drivers/phy/tegra/Kconfig b/drivers/phy/tegra/Kconfig
> index f9817c3..df07c4d 100644
> --- a/drivers/phy/tegra/Kconfig
> +++ b/drivers/phy/tegra/Kconfig
> @@ -2,6 +2,7 @@
>  config PHY_TEGRA_XUSB
>  	tristate "NVIDIA Tegra XUSB pad controller driver"
>  	depends on ARCH_TEGRA
> +	select USB_CONN_GPIO
>  	help
>  	  Choose this option if you have an NVIDIA Tegra SoC.
>  
> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
> index f98ec39..da60a63 100644
> --- a/drivers/phy/tegra/xusb.c
> +++ b/drivers/phy/tegra/xusb.c
> @@ -523,6 +523,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
>  	port->dev.type = &tegra_xusb_port_type;
>  	port->dev.of_node = of_node_get(np);
>  	port->dev.parent = padctl->dev;
> +	port->dev.driver = padctl->dev->driver;
>  
>  	err = dev_set_name(&port->dev, "%s-%u", name, index);
>  	if (err < 0)
> @@ -532,6 +533,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
>  	if (err < 0)
>  		goto unregister;
>  
> +	dev_set_drvdata(&port->dev, port);

You never seem to use dev_get_drvdata() to get at this. Also, you can
get at it via container_of(), so this is only marginally useful to begin
with.

>  	return 0;
>  
>  unregister:
> @@ -541,6 +543,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
>  
>  static void tegra_xusb_port_unregister(struct tegra_xusb_port *port)
>  {
> +	usb_role_switch_unregister(port->usb_role_sw);
>  	device_unregister(&port->dev);
>  }
>  
> @@ -551,11 +554,39 @@ static const char *const modes[] = {
>  	[USB_DR_MODE_OTG] = "otg",
>  };
>  
> +static int tegra_xusb_role_sw_set(struct device *dev, enum usb_role role)
> +{
> +	dev_dbg(dev, "%s calling notifier for role is %d\n", __func__, role);
> +
> +	return 0;
> +}
> +
> +static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
> +{
> +	int err = 0;
> +	struct usb_role_switch_desc role_sx_desc = {
> +					.set = tegra_xusb_role_sw_set,
> +					.fwnode = dev_fwnode(&port->dev),
> +						   };
> +
> +	port->usb_role_sw = usb_role_switch_register(&port->dev,
> +						&role_sx_desc);
> +	if (IS_ERR(port->usb_role_sw)) {
> +		err = PTR_ERR(port->usb_role_sw);
> +		if (err != EPROBE_DEFER)
> +			dev_err(&port->dev, "Failed to register USB role SW: %d",
> +				err);
> +	}
> +
> +	return err;
> +}
> +
>  static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
>  {
>  	struct tegra_xusb_port *port = &usb2->base;
>  	struct device_node *np = port->dev.of_node;
>  	const char *mode;
> +	int err;
>  
>  	usb2->internal = of_property_read_bool(np, "nvidia,internal");
>  
> @@ -572,6 +603,15 @@ static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
>  		usb2->mode = USB_DR_MODE_HOST;
>  	}
>  
> +	if (of_property_read_bool(np, "usb-role-switch")) {
> +		/* populate connector entry */
> +		of_platform_populate(np, NULL, NULL, &port->dev);

I think we want to clean this up on failure, don't we? Otherwise we
might end up trying to register the same platform device multiple times.
Also, do we want to depopulate when the port is removed again?

Have you tried unloading and loading the driver to see if that works?

Thierry

> +
> +		err = tegra_xusb_setup_usb_role_switch(port);
> +		if (err < 0)
> +			return err;
> +	}
> +
>  	usb2->supply = devm_regulator_get(&port->dev, "vbus");
>  	return PTR_ERR_OR_ZERO(usb2->supply);
>  }
> diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
> index da94fcc..9f27899 100644
> --- a/drivers/phy/tegra/xusb.h
> +++ b/drivers/phy/tegra/xusb.h
> @@ -12,6 +12,7 @@
>  #include <linux/workqueue.h>
>  
>  #include <linux/usb/otg.h>
> +#include <linux/usb/role.h>
>  
>  /* legacy entry points for backwards-compatibility */
>  int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
> @@ -266,6 +267,8 @@ struct tegra_xusb_port {
>  	struct list_head list;
>  	struct device dev;
>  
> +	struct usb_role_switch *usb_role_sw;
> +
>  	const struct tegra_xusb_port_ops *ops;
>  };
>  
> -- 
> 2.7.4
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 05/18] phy: tegra: xusb: Add support to get companion USB 3 port
  2019-12-06 10:50 ` [PATCH 05/18] phy: tegra: xusb: Add support to get companion USB 3 port Nagarjuna Kristam
@ 2019-12-06 14:57   ` Thierry Reding
  2019-12-09  6:27     ` Nagarjuna Kristam
  0 siblings, 1 reply; 27+ messages in thread
From: Thierry Reding @ 2019-12-06 14:57 UTC (permalink / raw)
  To: Nagarjuna Kristam
  Cc: balbi, gregkh, jonathanh, mark.rutland, robh+dt, kishon,
	devicetree, linux-tegra, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2363 bytes --]

On Fri, Dec 06, 2019 at 04:20:08PM +0530, Nagarjuna Kristam wrote:
> Tegra XUSB host, device mode driver requires the USB 3 companion port
> number for corresponding USB 2 port. Add API to retrieve the same.
> 
> Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
> ---
>  drivers/phy/tegra/xusb.c       | 21 +++++++++++++++++++++
>  include/linux/phy/tegra/xusb.h |  2 ++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
> index 4c86c99..2e73cf8 100644
> --- a/drivers/phy/tegra/xusb.c
> +++ b/drivers/phy/tegra/xusb.c
> @@ -1254,6 +1254,27 @@ int tegra_phy_xusb_utmi_port_reset(struct phy *phy)
>  }
>  EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_port_reset);
>  
> +int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
> +				    unsigned int port)
> +{
> +	struct tegra_xusb_usb2_port *usb2 = tegra_xusb_find_usb2_port(padctl,
> +								      port);
> +	struct tegra_xusb_usb3_port *usb3;
> +	int i;
> +
> +	if (!usb2)
> +		return -EINVAL;
> +
> +	for (i = 0; i < padctl->soc->ports.usb3.count; i++) {
> +		usb3 = tegra_xusb_find_usb3_port(padctl, i);
> +		if (usb3 && usb3->port == usb2->base.index)
> +			return usb3->base.index;
> +	}
> +
> +	return -1;

Since you return -EINVAL above, callers will have to interpret negative
return values as standard errors, which would make this EPERM. That does
not really make sense. Perhaps something like -ENODEV would be more
appropriate in this case?

Thierry

> +}
> +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get_usb3_companion);
> +
>  MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
>  MODULE_DESCRIPTION("Tegra XUSB Pad Controller driver");
>  MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h
> index 1235865..71d9569 100644
> --- a/include/linux/phy/tegra/xusb.h
> +++ b/include/linux/phy/tegra/xusb.h
> @@ -21,4 +21,6 @@ int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
>  int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl,
>  					bool val);
>  int tegra_phy_xusb_utmi_port_reset(struct phy *phy);
> +int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
> +					 unsigned int port);
>  #endif /* PHY_TEGRA_XUSB_H */
> -- 
> 2.7.4
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 01/18] dt-bindings: phy: tegra-xusb: Add usb-role-switch
  2019-12-06 14:49   ` Thierry Reding
@ 2019-12-09  4:45     ` Nagarjuna Kristam
  0 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-09  4:45 UTC (permalink / raw)
  To: Thierry Reding
  Cc: balbi, gregkh, jonathanh, mark.rutland, robh+dt, kishon,
	devicetree, linux-tegra, linux-usb, linux-kernel



> On 06-12-2019 20:19, Thierry Reding wrote:
> 
> On Fri, Dec 06, 2019 at 04:20:04PM +0530, Nagarjuna Kristam wrote:
>> Add usb-role-switch property for Tegra210 and Tegra186 platforms. This
>> entry is used by XUSB pad controller driver to register for role changes
>> for OTG/Peripheral capable USB 2 ports.
>>
>> Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
>> ---
>>  Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
>> index 9fb682e..0f19ed6 100644
>> --- a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
>> +++ b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
>> @@ -179,6 +179,10 @@ Optional properties:
>>    is internal. In the absence of this property the port is considered to be
>>    external.
>>  - vbus-supply: phandle to a regulator supplying the VBUS voltage.
>> +- usb-role-switch: boolean property to indicate use of USB Role Switch.
> That first sentence here seems a bit useless and vague. It doesn't
> really convey anything other than the name already does. Perhaps
> something like:
> 
> 	Boolean property to indicate that the port support OTG. If
> 	present, the port supports switching between USB host and
> 	peripheral roles.
> 
Will update this accordingly.

>> +  This property is MUST for OTG,Peripheral capable USB 2 ports. Connector
> If this is mandatory, why not add it to the list of required properties?
> I guess since it's only mandatory for ports that support OTG, perhaps we
> could add a section "Required properties for OTG capable ports:" or
> something like that? Then you can also omit the second sentence in the
> description.
> 
Will add section "Required properties for OTG/Peripheral capable ports:" under ports
and add usb-role-switch there.

>> +  should be added as subnode, see connector.txt. vbus-gpio in connector is
> There's no file called "connector.txt". Are you referring to
> 
> 	Documentation/devicetree/bindings/connector/usb-connector.txt
> 
> ? Also, that file calls the property "vbus-gpios" and lists it as
> optional. What would happen if we don't specify it? Doesn't that just
> mean that we can't support role detection?
> 
After going through other bindings found usb/usb-conn-gpio.txt is the one that should
be referred. Will update accordingly. All details on gpios are documented clearly
in usb/usb-conn-gpio.txt.

>> +  Mandatory.
> "mandatory"
> 
> Thierry
> 
>>  
Will update.

Thanks,
Nagarjuna
>>  ULPI ports:
>>  -----------
>> -- 
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 05/18] phy: tegra: xusb: Add support to get companion USB 3 port
  2019-12-06 14:57   ` Thierry Reding
@ 2019-12-09  6:27     ` Nagarjuna Kristam
  0 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-09  6:27 UTC (permalink / raw)
  To: Thierry Reding
  Cc: balbi, gregkh, jonathanh, mark.rutland, robh+dt, kishon,
	devicetree, linux-tegra, linux-usb, linux-kernel



On 06-12-2019 20:27, Thierry Reding wrote:
> On Fri, Dec 06, 2019 at 04:20:08PM +0530, Nagarjuna Kristam wrote:
>> Tegra XUSB host, device mode driver requires the USB 3 companion port
>> number for corresponding USB 2 port. Add API to retrieve the same.
>>
>> Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
>> ---
>>  drivers/phy/tegra/xusb.c       | 21 +++++++++++++++++++++
>>  include/linux/phy/tegra/xusb.h |  2 ++
>>  2 files changed, 23 insertions(+)
>>
>> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
>> index 4c86c99..2e73cf8 100644
>> --- a/drivers/phy/tegra/xusb.c
>> +++ b/drivers/phy/tegra/xusb.c
>> @@ -1254,6 +1254,27 @@ int tegra_phy_xusb_utmi_port_reset(struct phy *phy)
>>  }
>>  EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_port_reset);
>>  
>> +int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
>> +				    unsigned int port)
>> +{
>> +	struct tegra_xusb_usb2_port *usb2 = tegra_xusb_find_usb2_port(padctl,
>> +								      port);
>> +	struct tegra_xusb_usb3_port *usb3;
>> +	int i;
>> +
>> +	if (!usb2)
>> +		return -EINVAL;
>> +
>> +	for (i = 0; i < padctl->soc->ports.usb3.count; i++) {
>> +		usb3 = tegra_xusb_find_usb3_port(padctl, i);
>> +		if (usb3 && usb3->port == usb2->base.index)
>> +			return usb3->base.index;
>> +	}
>> +
>> +	return -1;
> Since you return -EINVAL above, callers will have to interpret negative
> return values as standard errors, which would make this EPERM. That does
> not really make sense. Perhaps something like -ENODEV would be more
> appropriate in this case?
> 
> Thierry
> 
Yes, making -ENODEV instead of -1 makes it inline with generic error codes.
Will update accordingly.

-Nagarjuna
>> +}
>> +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get_usb3_companion);
>> +
>>  MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
>>  MODULE_DESCRIPTION("Tegra XUSB Pad Controller driver");
>>  MODULE_LICENSE("GPL v2");
>> diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h
>> index 1235865..71d9569 100644
>> --- a/include/linux/phy/tegra/xusb.h
>> +++ b/include/linux/phy/tegra/xusb.h
>> @@ -21,4 +21,6 @@ int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
>>  int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl,
>>  					bool val);
>>  int tegra_phy_xusb_utmi_port_reset(struct phy *phy);
>> +int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
>> +					 unsigned int port);
>>  #endif /* PHY_TEGRA_XUSB_H */
>> -- 
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 03/18] phy: tegra: xusb: Add usb-role-switch support
  2019-12-06 14:54   ` Thierry Reding
@ 2019-12-10  3:52     ` Nagarjuna Kristam
  0 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-10  3:52 UTC (permalink / raw)
  To: Thierry Reding
  Cc: balbi, gregkh, jonathanh, mark.rutland, robh+dt, kishon,
	devicetree, linux-tegra, linux-usb, linux-kernel



On 06-12-2019 20:24, Thierry Reding wrote:
> On Fri, Dec 06, 2019 at 04:20:06PM +0530, Nagarjuna Kristam wrote:
>> If usb-role-switch property is present in USB 2 port, register
>> usb-role-switch to receive usb role changes.
>>
>> Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
>> ---
>>  drivers/phy/tegra/Kconfig |  1 +
>>  drivers/phy/tegra/xusb.c  | 40 ++++++++++++++++++++++++++++++++++++++++
>>  drivers/phy/tegra/xusb.h  |  3 +++
>>  3 files changed, 44 insertions(+)
>>
>> diff --git a/drivers/phy/tegra/Kconfig b/drivers/phy/tegra/Kconfig
>> index f9817c3..df07c4d 100644
>> --- a/drivers/phy/tegra/Kconfig
>> +++ b/drivers/phy/tegra/Kconfig
>> @@ -2,6 +2,7 @@
>>  config PHY_TEGRA_XUSB
>>  	tristate "NVIDIA Tegra XUSB pad controller driver"
>>  	depends on ARCH_TEGRA
>> +	select USB_CONN_GPIO
>>  	help
>>  	  Choose this option if you have an NVIDIA Tegra SoC.
>>  
>> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
>> index f98ec39..da60a63 100644
>> --- a/drivers/phy/tegra/xusb.c
>> +++ b/drivers/phy/tegra/xusb.c
>> @@ -523,6 +523,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
>>  	port->dev.type = &tegra_xusb_port_type;
>>  	port->dev.of_node = of_node_get(np);
>>  	port->dev.parent = padctl->dev;
>> +	port->dev.driver = padctl->dev->driver;
>>  
>>  	err = dev_set_name(&port->dev, "%s-%u", name, index);
>>  	if (err < 0)
>> @@ -532,6 +533,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
>>  	if (err < 0)
>>  		goto unregister;
>>  
>> +	dev_set_drvdata(&port->dev, port);
> You never seem to use dev_get_drvdata() to get at this. Also, you can
> get at it via container_of(), so this is only marginally useful to begin
> with.
> 
Its actually used in API tegra_xusb_role_sw_set, but thats in patch 0004.
Will move this line to 0004 patch to align with the usage.

>>  	return 0;
>>  
>>  unregister:
>> @@ -541,6 +543,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
>>  
>>  static void tegra_xusb_port_unregister(struct tegra_xusb_port *port)
>>  {
>> +	usb_role_switch_unregister(port->usb_role_sw);
>>  	device_unregister(&port->dev);
>>  }
>>  
>> @@ -551,11 +554,39 @@ static const char *const modes[] = {
>>  	[USB_DR_MODE_OTG] = "otg",
>>  };
>>  
>> +static int tegra_xusb_role_sw_set(struct device *dev, enum usb_role role)
>> +{
>> +	dev_dbg(dev, "%s calling notifier for role is %d\n", __func__, role);
>> +
>> +	return 0;
>> +}
>> +
>> +static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
>> +{
>> +	int err = 0;
>> +	struct usb_role_switch_desc role_sx_desc = {
>> +					.set = tegra_xusb_role_sw_set,
>> +					.fwnode = dev_fwnode(&port->dev),
>> +						   };
>> +
>> +	port->usb_role_sw = usb_role_switch_register(&port->dev,
>> +						&role_sx_desc);
>> +	if (IS_ERR(port->usb_role_sw)) {
>> +		err = PTR_ERR(port->usb_role_sw);
>> +		if (err != EPROBE_DEFER)
>> +			dev_err(&port->dev, "Failed to register USB role SW: %d",
>> +				err);
>> +	}
>> +
>> +	return err;
>> +}
>> +
>>  static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
>>  {
>>  	struct tegra_xusb_port *port = &usb2->base;
>>  	struct device_node *np = port->dev.of_node;
>>  	const char *mode;
>> +	int err;
>>  
>>  	usb2->internal = of_property_read_bool(np, "nvidia,internal");
>>  
>> @@ -572,6 +603,15 @@ static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
>>  		usb2->mode = USB_DR_MODE_HOST;
>>  	}
>>  
>> +	if (of_property_read_bool(np, "usb-role-switch")) {
>> +		/* populate connector entry */
>> +		of_platform_populate(np, NULL, NULL, &port->dev);
> I think we want to clean this up on failure, don't we? Otherwise we
> might end up trying to register the same platform device multiple times.
> Also, do we want to depopulate when the port is removed again?
> 
> Have you tried unloading and loading the driver to see if that works?
> 
> Thierry
> 
platform needs to be depopulate on error/remove and will add corresponding code.
padctl driver can be unloaded after unloading all dependent drivers. re-loading
caused failure of usb role switch due to missing depopulate. Will update changes
to consider the same.

Thanks,
Nagarjuna
>> +
>> +		err = tegra_xusb_setup_usb_role_switch(port);
>> +		if (err < 0)
>> +			return err;
>> +	}
>> +
>>  	usb2->supply = devm_regulator_get(&port->dev, "vbus");
>>  	return PTR_ERR_OR_ZERO(usb2->supply);
>>  }
>> diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
>> index da94fcc..9f27899 100644
>> --- a/drivers/phy/tegra/xusb.h
>> +++ b/drivers/phy/tegra/xusb.h
>> @@ -12,6 +12,7 @@
>>  #include <linux/workqueue.h>
>>  
>>  #include <linux/usb/otg.h>
>> +#include <linux/usb/role.h>
>>  
>>  /* legacy entry points for backwards-compatibility */
>>  int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
>> @@ -266,6 +267,8 @@ struct tegra_xusb_port {
>>  	struct list_head list;
>>  	struct device dev;
>>  
>> +	struct usb_role_switch *usb_role_sw;
>> +
>>  	const struct tegra_xusb_port_ops *ops;
>>  };
>>  
>> -- 
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 02/18] dt-bindings: usb: Add NVIDIA Tegra XUSB device mode controller binding
  2019-12-06 10:50 ` [PATCH 02/18] dt-bindings: usb: Add NVIDIA Tegra XUSB device mode controller binding Nagarjuna Kristam
@ 2019-12-13 18:45   ` Rob Herring
  2019-12-16  6:30     ` Nagarjuna Kristam
  0 siblings, 1 reply; 27+ messages in thread
From: Rob Herring @ 2019-12-13 18:45 UTC (permalink / raw)
  To: Nagarjuna Kristam
  Cc: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, kishon,
	devicetree, linux-tegra, linux-usb, linux-kernel

On Fri, Dec 06, 2019 at 04:20:05PM +0530, Nagarjuna Kristam wrote:
> Add device-tree binding documentation for the XUSB device mode controller
> present on Tegra210 and Tegra186 SoC. This controller supports the USB 3.0
> specification.
> 
> Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
> ---

Next time version your patches correctly and include version history 
here so I don't have to go look up why my R-by is missing.

>  .../devicetree/bindings/usb/nvidia,tegra-xudc.yaml | 204 +++++++++++++++++++++
>  1 file changed, 204 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml b/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
> new file mode 100644
> index 0000000..b23c451
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
> @@ -0,0 +1,204 @@
> +# SPDX-License-Identifier: GPL-2.0

Dual license new bindings please:

(GPL-2.0-only OR BSD-2-Clause)

> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/usb/nvidia,tegra-xudc.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Device tree binding for NVIDIA Tegra XUSB device mode controller (XUDC)
> +
> +description:
> +  The Tegra XUDC controller supports both USB 2.0 HighSpeed/FullSpeed and
> +  USB 3.0 SuperSpeed protocols.
> +
> +maintainers:
> +  - Nagarjuna Kristam <nkristam@nvidia.com>
> +  - JC Kuo <jckuo@nvidia.com>
> +  - Thierry Reding <treding@nvidia.com>
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +        - const: nvidia,tegra210-xudc # For Tegra210
> +      - items:
> +        - const: nvidia,tegra186-xudc # For Tegra186

Use 'enum' instead of oneOf+const.

> +
> +  interrupts:
> +    maxItems: 1
> +    description: Must contain the XUSB device interrupt.

Don't need a description for a single interrupt line.

> +
> +  power-domains:
> +    maxItems: 2
> +    description:
> +      A list of PM domain specifiers that reference each power-domain
> +      used by the XUSB device mode controller. This list must comprise of a
> +      specifier for the XUSBA and XUSBB power-domains.
> +      See ../power/power_domain.txt and ../arm/tegra/nvidia,tegra20-pmc.txt
> +      for details.

Just need:

items:
  - description: XUSBA power-domain
  - description: XUSBB power-domain

> +
> +  power-domains-names:
> +    maxItems: 2
> +    description:
> +       A list of names that represent each of the specifiers in
> +       the 'power-domains' property.

That's every 'power-domains-names'.

> +    items:
> +      - const: ss
> +      - const: dev

Okay, but those names don't match up with XUSBA and XUSBB. Names should 
be meaningful or local to the module, not the provider if that helps.

> +
> +  nvidia,xusb-padctl:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description:
> +      phandle to the XUSB pad controller that is used to configure the USB pads
> +      used by the XUDC controller.
> +
> +  phys:
> +    minItems: 1
> +    description:
> +      Must contain an entry for each entry in phy-names.
> +      See ../phy/phy-bindings.txt for details.
> +
> +  phy-names:
> +    minItems: 1
> +    items:
> +      - const: usb2-0
> +      - const: usb2-1
> +      - const: usb2-2
> +      - const: usb2-3
> +      - const: usb3-0
> +      - const: usb3-1
> +      - const: usb3-2
> +      - const: usb3-3
> +
> +  avddio-usb-supply:
> +    description: PCIe/USB3 analog logic power supply. Must supply 1.05 V.
> +
> +  hvdd-usb-supply:
> +    description: USB controller power supply. Must supply 3.3 V.
> +
> +required:
> +  - compatible
> +  - power-domains
> +  - power-domain-names
> +  - nvidia,xusb-padctl
> +  - phys
> +  - phy-names
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          items:
> +            const: nvidia,tegra210-xudc
> +
> +    then:
> +      properties:
> +        reg:
> +          maxItems: 3
> +          items:
> +          - description: XUSB device controller registers
> +          - description: XUSB device PCI Config registers
> +          - description: XUSB device registers.
> +        reg-names:
> +          maxItems: 3
> +          items:
> +            - const: base
> +            - const: fpci
> +            - const: ipfs

As these are a superset of tegra186, you can move this up and tegra186 
just needs to define 'maxItems: 2'.

> +        clocks:
> +          description:
> +            Must contain an entry for all clocks used. See ../clock/clock-bindings.txt
> +            for details.
> +          maxItems: 5
> +          items:
> +            - description: Clock to enable core XUSB dev clock.
> +            - description: Clock to enable XUSB super speed clock.
> +            - description: Clock to enable XUSB super speed dev clock.
> +            - description: Clock to enable XUSB high speed dev clock.
> +            - description: Clock to enable XUSB full speed dev clock.
> +        clock-names:
> +          items:
> +           - const: dev
> +           - const: ss
> +           - const: ss_src
> +           - const: hs_src
> +           - const: fs_src

I would re-order the last 2 entries so that you can do the same thing as 
I said for 'reg'.

> +      required:
> +        - reg
> +        - reg-names
> +        - clocks
> +        - clock-names

No need for these to be under the if. They are always required and 
don't have to be where defined by 'properties'.

> +        - avddio-usb-supply
> +        - hvdd-usb-supply
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: nvidia,tegra186-xudc
> +
> +    then:
> +      properties:
> +        reg:
> +          maxItems: 2
> +          items:
> +          - description: XUSB device controller registers
> +          - description: XUSB device PCI Config registers
> +        reg-names:
> +          maxItems: 2
> +          items:
> +            - const: base
> +            - const: fpci
> +        clocks:
> +          description:
> +            Must contain an entry for all clocks used. See ../clock/clock-bindings.txt
> +            for details.
> +          maxItems: 4
> +          items:
> +            - description: Clock to enable core XUSB dev clock.
> +            - description: Clock to enable XUSB super speed clock.
> +            - description: Clock to enable XUSB super speed dev clock.
> +            - description: Clock to enable XUSB full speed dev clock.
> +        clock-names:
> +          items:
> +           - const: dev
> +           - const: ss
> +           - const: ss_src
> +           - const: fs_src
> +      required:
> +        - reg
> +        - reg-names
> +        - clocks
> +        - clock-names
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/tegra210-car.h>
> +    #include <dt-bindings/gpio/tegra-gpio.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    usb@700d0000 {
> +        compatible = "nvidia,tegra210-xudc";
> +        reg = <0x0 0x700d0000 0x0 0x8000>,
> +              <0x0 0x700d8000 0x0 0x1000>,
> +              <0x0 0x700d9000 0x0 0x1000>;
> +        reg-names = "base", "fpci", "ipfs";
> +
> +        interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        clocks = <&tegra_car TEGRA210_CLK_XUSB_DEV>,
> +                 <&tegra_car TEGRA210_CLK_XUSB_SS>,
> +                 <&tegra_car TEGRA210_CLK_XUSB_SSP_SRC>,
> +                 <&tegra_car TEGRA210_CLK_XUSB_HS_SRC>,
> +                 <&tegra_car TEGRA210_CLK_XUSB_FS_SRC>;
> +        clock-names = "dev", "ss", "ss_src", "hs_src", "fs_src";
> +
> +        power-domains = <&pd_xusbdev>, <&pd_xusbss>;
> +        power-domain-names = "dev", "ss";
> +
> +        nvidia,xusb-padctl = <&padctl>;
> +
> +        phys = <&micro_b>;
> +        phy-names = "usb2-0";
> +
> +        avddio-usb-supply = <&vdd_pex_1v05>;
> +        hvdd-usb-supply = <&vdd_3v3_sys>;
> +    };
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 02/18] dt-bindings: usb: Add NVIDIA Tegra XUSB device mode controller binding
  2019-12-13 18:45   ` Rob Herring
@ 2019-12-16  6:30     ` Nagarjuna Kristam
  0 siblings, 0 replies; 27+ messages in thread
From: Nagarjuna Kristam @ 2019-12-16  6:30 UTC (permalink / raw)
  To: Rob Herring
  Cc: balbi, gregkh, thierry.reding, jonathanh, mark.rutland, kishon,
	devicetree, linux-tegra, linux-usb, linux-kernel

> 
> 
> On Fri, Dec 06, 2019 at 04:20:05PM +0530, Nagarjuna Kristam wrote:
>> Add device-tree binding documentation for the XUSB device mode controller
>> present on Tegra210 and Tegra186 SoC. This controller supports the USB 3.0
>> specification.
>>
>> Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
>> ---
> Next time version your patches correctly and include version history
> here so I don't have to go look up why my R-by is missing.
> 
Since this was a new series, i didnot add version history. But considering that this
was reviewed in different series, i will take a note to include the reviewed link
for quick reference.
>>  .../devicetree/bindings/usb/nvidia,tegra-xudc.yaml | 204 +++++++++++++++++++++
>>  1 file changed, 204 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml b/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
>> new file mode 100644
>> index 0000000..b23c451
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
>> @@ -0,0 +1,204 @@
>> +# SPDX-License-Identifier: GPL-2.0
> Dual license new bindings please:
> 
> (GPL-2.0-only OR BSD-2-Clause)
> 
Will update accordingly.
>> +%YAML 1.2
>> +---
>> +$id: "http://devicetree.org/schemas/usb/nvidia,tegra-xudc.yaml#"
>> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
>> +
>> +title: Device tree binding for NVIDIA Tegra XUSB device mode controller (XUDC)
>> +
>> +description:
>> +  The Tegra XUDC controller supports both USB 2.0 HighSpeed/FullSpeed and
>> +  USB 3.0 SuperSpeed protocols.
>> +
>> +maintainers:
>> +  - Nagarjuna Kristam <nkristam@nvidia.com>
>> +  - JC Kuo <jckuo@nvidia.com>
>> +  - Thierry Reding <treding@nvidia.com>
>> +
>> +properties:
>> +  compatible:
>> +    oneOf:
>> +      - items:
>> +        - const: nvidia,tegra210-xudc # For Tegra210
>> +      - items:
>> +        - const: nvidia,tegra186-xudc # For Tegra186
> Use 'enum' instead of oneOf+const.
> 
Will update
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +    description: Must contain the XUSB device interrupt.
> Don't need a description for a single interrupt line.
> 
Will remove
>> +
>> +  power-domains:
>> +    maxItems: 2
>> +    description:
>> +      A list of PM domain specifiers that reference each power-domain
>> +      used by the XUSB device mode controller. This list must comprise of a
>> +      specifier for the XUSBA and XUSBB power-domains.
>> +      See ../power/power_domain.txt and ../arm/tegra/nvidia,tegra20-pmc.txt
>> +      for details.
> Just need:
> 
> items:
>   - description: XUSBA power-domain
>   - description: XUSBB power-domain
> 
Will update including below coments to update as below
   - description: XUSBA(superSpeed) power-domain
   - description: XUSBB(device) power-domain
>> +
>> +  power-domains-names:
>> +    maxItems: 2
>> +    description:
>> +       A list of names that represent each of the specifiers in
>> +       the 'power-domains' property.
> That's every 'power-domains-names'.
> 
>> +    items:
>> +      - const: ss
>> +      - const: dev
> Okay, but those names don't match up with XUSBA and XUSBB. Names should
> be meaningful or local to the module, not the provider if that helps.
> 
>> +
>> +  nvidia,xusb-padctl:
>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>> +    description:
>> +      phandle to the XUSB pad controller that is used to configure the USB pads
>> +      used by the XUDC controller.
>> +
>> +  phys:
>> +    minItems: 1
>> +    description:
>> +      Must contain an entry for each entry in phy-names.
>> +      See ../phy/phy-bindings.txt for details.
>> +
>> +  phy-names:
>> +    minItems: 1
>> +    items:
>> +      - const: usb2-0
>> +      - const: usb2-1
>> +      - const: usb2-2
>> +      - const: usb2-3
>> +      - const: usb3-0
>> +      - const: usb3-1
>> +      - const: usb3-2
>> +      - const: usb3-3
>> +
>> +  avddio-usb-supply:
>> +    description: PCIe/USB3 analog logic power supply. Must supply 1.05 V.
>> +
>> +  hvdd-usb-supply:
>> +    description: USB controller power supply. Must supply 3.3 V.
>> +
>> +required:
>> +  - compatible
>> +  - power-domains
>> +  - power-domain-names
>> +  - nvidia,xusb-padctl
>> +  - phys
>> +  - phy-names
>> +
>> +allOf:
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          items:
>> +            const: nvidia,tegra210-xudc
>> +
>> +    then:
>> +      properties:
>> +        reg:
>> +          maxItems: 3
>> +          items:
>> +          - description: XUSB device controller registers
>> +          - description: XUSB device PCI Config registers
>> +          - description: XUSB device registers.
>> +        reg-names:
>> +          maxItems: 3
>> +          items:
>> +            - const: base
>> +            - const: fpci
>> +            - const: ipfs
> As these are a superset of tegra186, you can move this up and tegra186
> just needs to define 'maxItems: 2'.
> 
Will move Main definitions up and update these sections with minItems and maxItems
accordingly.
>> +        clocks:
>> +          description:
>> +            Must contain an entry for all clocks used. See ../clock/clock-bindings.txt
>> +            for details.
>> +          maxItems: 5
>> +          items:
>> +            - description: Clock to enable core XUSB dev clock.
>> +            - description: Clock to enable XUSB super speed clock.
>> +            - description: Clock to enable XUSB super speed dev clock.
>> +            - description: Clock to enable XUSB high speed dev clock.
>> +            - description: Clock to enable XUSB full speed dev clock.
>> +        clock-names:
>> +          items:
>> +           - const: dev
>> +           - const: ss
>> +           - const: ss_src
>> +           - const: hs_src
>> +           - const: fs_src
> I would re-order the last 2 entries so that you can do the same thing as
> I said for 'reg'.
> 
>> +      required:
>> +        - reg
>> +        - reg-names
>> +        - clocks
>> +        - clock-names
> No need for these to be under the if. They are always required and
> don't have to be where defined by 'properties'.
> 
Will move to main "required" section.
>> +        - avddio-usb-supply
>> +        - hvdd-usb-supply
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: nvidia,tegra186-xudc
>> +
>> +    then:
>> +      properties:
>> +        reg:
>> +          maxItems: 2
>> +          items:
>> +          - description: XUSB device controller registers
>> +          - description: XUSB device PCI Config registers
>> +        reg-names:
>> +          maxItems: 2
>> +          items:
>> +            - const: base
>> +            - const: fpci
>> +        clocks:
>> +          description:
>> +            Must contain an entry for all clocks used. See ../clock/clock-bindings.txt
>> +            for details.
>> +          maxItems: 4
>> +          items:
>> +            - description: Clock to enable core XUSB dev clock.
>> +            - description: Clock to enable XUSB super speed clock.
>> +            - description: Clock to enable XUSB super speed dev clock.
>> +            - description: Clock to enable XUSB full speed dev clock.
>> +        clock-names:
>> +          items:
>> +           - const: dev
>> +           - const: ss
>> +           - const: ss_src
>> +           - const: fs_src
>> +      required:
>> +        - reg
>> +        - reg-names
>> +        - clocks
>> +        - clock-names
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/tegra210-car.h>
>> +    #include <dt-bindings/gpio/tegra-gpio.h>
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +
>> +    usb@700d0000 {
>> +        compatible = "nvidia,tegra210-xudc";
>> +        reg = <0x0 0x700d0000 0x0 0x8000>,
>> +              <0x0 0x700d8000 0x0 0x1000>,
>> +              <0x0 0x700d9000 0x0 0x1000>;
>> +        reg-names = "base", "fpci", "ipfs";
>> +
>> +        interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
>> +
>> +        clocks = <&tegra_car TEGRA210_CLK_XUSB_DEV>,
>> +                 <&tegra_car TEGRA210_CLK_XUSB_SS>,
>> +                 <&tegra_car TEGRA210_CLK_XUSB_SSP_SRC>,
>> +                 <&tegra_car TEGRA210_CLK_XUSB_HS_SRC>,
>> +                 <&tegra_car TEGRA210_CLK_XUSB_FS_SRC>;
>> +        clock-names = "dev", "ss", "ss_src", "hs_src", "fs_src";
>> +
>> +        power-domains = <&pd_xusbdev>, <&pd_xusbss>;
>> +        power-domain-names = "dev", "ss";
>> +
>> +        nvidia,xusb-padctl = <&padctl>;
>> +
>> +        phys = <&micro_b>;
>> +        phy-names = "usb2-0";
>> +
>> +        avddio-usb-supply = <&vdd_pex_1v05>;
>> +        hvdd-usb-supply = <&vdd_3v3_sys>;
>> +    };
>> --
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2019-12-16  6:28 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-06 10:50 [PATCH 00/18] Tegra XUSB OTG support Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 01/18] dt-bindings: phy: tegra-xusb: Add usb-role-switch Nagarjuna Kristam
2019-12-06 14:49   ` Thierry Reding
2019-12-09  4:45     ` Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 02/18] dt-bindings: usb: Add NVIDIA Tegra XUSB device mode controller binding Nagarjuna Kristam
2019-12-13 18:45   ` Rob Herring
2019-12-16  6:30     ` Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 03/18] phy: tegra: xusb: Add usb-role-switch support Nagarjuna Kristam
2019-12-06 14:54   ` Thierry Reding
2019-12-10  3:52     ` Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 04/18] phy: tegra: xusb: Add usb-phy support Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 05/18] phy: tegra: xusb: Add support to get companion USB 3 port Nagarjuna Kristam
2019-12-06 14:57   ` Thierry Reding
2019-12-09  6:27     ` Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 06/18] phy: tegra: xusb: Add set_mode support for USB 2 phy on Tegra210 Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 07/18] phy: tegra: xusb: Add set_mode support for utmi phy on Tegra186 Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 08/18] usb: xhci-tegra: Add OTG support Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 09/18] usb: gadget: tegra-xudc: Remove usb-role-switch support Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 10/18] usb: gadget: tegra-xudc: Add usb-phy support Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 11/18] usb: gadget: tegra-xudc: use phy_set_mode to set/unset device mode Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 12/18] usb: gadget: tegra-xudc: support multiple device modes Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 13/18] arm64: tegra: update OTG port entries for jetson-tx1 Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 14/18] arm64: tegra: update OTG port entries for jetson-tx2 Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 15/18] arm64: tegra: Add xudc node for Tegra210 Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 16/18] arm64: tegra: Enable xudc on Jetson TX1 Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 17/18] arm64: tegra: Add xudc node for Tegra186 Nagarjuna Kristam
2019-12-06 10:50 ` [PATCH 18/18] arm64: tegra: Enable xudc node on Jetson TX2 Nagarjuna Kristam

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).