Re: [PATCH 4/5] phy: tegra: xusb: Add support for power supplies

2019-01-28 Thread jckuo

Thanks Thierry.

Reviewed-by: JC Kuo 

On 1/28/19 4:00 PM, Thierry Reding wrote:

On Mon, Jan 28, 2019 at 03:22:09PM +0800, jckuo wrote:

Hi Thierry,

I think any non-zero return value of
regulator_bulk_enable()/devm_regulator_bulk_get() means error.

Thanks,

JC

Theoretically I think only regulator_bulk_enable() could return a
positive value, but even so it never will in practice because all of the
regulator_enable() (see _regulator_enable()) calls will only ever return
negative error codes.

I can change this and resend if you have strong concerns about this
possibly missing legitimate error cases.

Thierry


On 1/25/19 7:25 PM, Thierry Reding wrote:

From: Thierry Reding 

Support enabling various supplies needed to provide power to the PLLs
and logic used to drive the USB, PCI and SATA pads.

Signed-off-by: Thierry Reding 
---
   drivers/phy/tegra/xusb.c | 34 +-
   drivers/phy/tegra/xusb.h |  5 +
   2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index 57a2d08ef6da..e510629f4f1c 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -864,6 +864,7 @@ static int tegra_xusb_padctl_probe(struct platform_device 
*pdev)
struct tegra_xusb_padctl *padctl;
const struct of_device_id *match;
struct resource *res;
+   unsigned int i;
int err;
/* for backwards compatibility with old device trees */
@@ -901,14 +902,38 @@ static int tegra_xusb_padctl_probe(struct platform_device 
*pdev)
goto remove;
}
+   padctl->supplies = devm_kcalloc(>dev, padctl->soc->num_supplies,
+   sizeof(*padctl->supplies), GFP_KERNEL);
+   if (!padctl->supplies) {
+   err = -ENOMEM;
+   goto remove;
+   }
+
+   for (i = 0; i < padctl->soc->num_supplies; i++)
+   padctl->supplies[i].supply = padctl->soc->supply_names[i];
+
+   err = devm_regulator_bulk_get(>dev, padctl->soc->num_supplies,
+ padctl->supplies);
+   if (err < 0) {
+   dev_err(>dev, "failed to get regulators: %d\n", err);
+   goto remove;
+   }
+
err = reset_control_deassert(padctl->rst);
if (err < 0)
goto remove;
+   err = regulator_bulk_enable(padctl->soc->num_supplies,
+   padctl->supplies);
+   if (err < 0) {
+   dev_err(>dev, "failed to enable supplies: %d\n", err);
+   goto reset;
+   }
+
err = tegra_xusb_setup_pads(padctl);
if (err < 0) {
dev_err(>dev, "failed to setup pads: %d\n", err);
-   goto reset;
+   goto power_down;
}
err = tegra_xusb_setup_ports(padctl);
@@ -921,6 +946,8 @@ static int tegra_xusb_padctl_probe(struct platform_device 
*pdev)
   remove_pads:
tegra_xusb_remove_pads(padctl);
+power_down:
+   regulator_bulk_disable(padctl->soc->num_supplies, padctl->supplies);
   reset:
reset_control_assert(padctl->rst);
   remove:
@@ -936,6 +963,11 @@ static int tegra_xusb_padctl_remove(struct platform_device 
*pdev)
tegra_xusb_remove_ports(padctl);
tegra_xusb_remove_pads(padctl);
+   err = regulator_bulk_disable(padctl->soc->num_supplies,
+padctl->supplies);
+   if (err < 0)
+   dev_err(>dev, "failed to disable supplies: %d\n", err);
+
err = reset_control_assert(padctl->rst);
if (err < 0)
dev_err(>dev, "failed to assert reset: %d\n", err);
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
index bb60fc09c752..5d5d22f6cb41 100644
--- a/drivers/phy/tegra/xusb.h
+++ b/drivers/phy/tegra/xusb.h
@@ -370,6 +370,9 @@ struct tegra_xusb_padctl_soc {
} ports;
const struct tegra_xusb_padctl_ops *ops;
+
+   const char * const *supply_names;
+   unsigned int num_supplies;
   };
   struct tegra_xusb_padctl {
@@ -393,6 +396,8 @@ struct tegra_xusb_padctl {
unsigned int enable;
struct clk *clk;
+
+   struct regulator_bulk_data *supplies;
   };
   static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value,


Re: [PATCH 4/6] arm64: tegra: Add XUSB and pad controller on Tegra186

2019-01-27 Thread jckuo

Reviewed-by: JC Kuo 

On 1/25/19 7:30 PM, Thierry Reding wrote:

From: Thierry Reding 

Adds the XUSB pad and XUSB controllers on Tegra186.

Signed-off-by: Thierry Reding 
---
  arch/arm64/boot/dts/nvidia/tegra186.dtsi | 135 +++
  1 file changed, 135 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index 22815db4a3ed..09d3b0d60e41 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -338,6 +338,141 @@
status = "disabled";
};
  
+	padctl: padctl@352 {

+   compatible = "nvidia,tegra186-xusb-padctl";
+   reg = <0x0 0x0352 0x0 0x1000>,
+ <0x0 0x0354 0x0 0x1000>;
+   reg-names = "padctl", "ao";
+
+   resets = < TEGRA186_RESET_XUSB_PADCTL>;
+   reset-names = "padctl";
+
+   status = "disabled";
+
+   pads {
+   usb2 {
+   clocks = < TEGRA186_CLK_USB2_TRK>;
+   clock-names = "trk";
+   status = "disabled";
+
+   lanes {
+   usb2-0 {
+   status = "disabled";
+   #phy-cells = <0>;
+   };
+
+   usb2-1 {
+   status = "disabled";
+   #phy-cells = <0>;
+   };
+
+   usb2-2 {
+   status = "disabled";
+   #phy-cells = <0>;
+   };
+   };
+   };
+
+   hsic {
+   clocks = < TEGRA186_CLK_HSIC_TRK>;
+   clock-names = "trk";
+   status = "disabled";
+
+   lanes {
+   hsic-0 {
+   status = "disabled";
+   #phy-cells = <0>;
+   };
+   };
+   };
+
+   usb3 {
+   status = "disabled";
+
+   lanes {
+   usb3-0 {
+   status = "disabled";
+   #phy-cells = <0>;
+   };
+
+   usb3-1 {
+   status = "disabled";
+   #phy-cells = <0>;
+   };
+
+   usb3-2 {
+   status = "disabled";
+   #phy-cells = <0>;
+   };
+   };
+   };
+   };
+
+   ports {
+   usb2-0 {
+   status = "disabled";
+   };
+
+   usb2-1 {
+   status = "disabled";
+   };
+
+   usb2-2 {
+   status = "disabled";
+   };
+
+   hsic-0 {
+   status = "disabled";
+   };
+
+   usb3-0 {
+   status = "disabled";
+   };
+
+   usb3-1 {
+   status = "disabled";
+   };
+
+   usb3-2 {
+   status = "disabled";
+   };
+   };
+   };
+
+   usb@353 {
+   compatible = "nvidia,tegra186-xusb";
+   reg = <0x0 0x0353 0x0 0x8000>,
+ <0x0 0x03538000 0x0 0x1000>;
+   reg-names = "hcd", "fpci";
+
+   interrupts = ,
+,
+;
+
+   clocks = < TEGRA186_CLK_XUSB_HOST>,
+< TEGRA186_CLK_XUSB_FALCON>,
+< TEGRA186_CLK_XUSB_SS>,
+< TEGRA186_CLK_XUSB_CORE_SS>,
+< TEGRA186_CLK_CLK_M>,
+< TEGRA186_CLK_XUSB_FS>,
+< TEGRA186_CLK_PLLU>,
+< TEGRA186_CLK_CLK_M>,
+

Re: [PATCH 3/6] usb: host: xhci-tegra: Add Tegra186 XUSB support

2019-01-27 Thread jckuo

Reviewed-by: JC Kuo 

On 1/25/19 7:30 PM, Thierry Reding wrote:

From: JC Kuo 

This commit adds Tegra186 XUSB host mode controller support. This is
very similar to the existing support for Tegra124 and Tegra210, except
that the number of ports and PHYs differs and the IPFS wrapper being
gone.

Signed-off-by: JC Kuo 
Signed-off-by: Thierry Reding 
---
  drivers/usb/host/xhci-tegra.c | 25 +
  1 file changed, 25 insertions(+)

diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 49e033f953a2..9a07ea0f9c97 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -1423,9 +1423,34 @@ static const struct tegra_xusb_soc tegra210_soc = {
  };
  MODULE_FIRMWARE("nvidia/tegra210/xusb.bin");
  
+static const char * const tegra186_supply_names[] = {

+};
+
+static const struct tegra_xusb_phy_type tegra186_phy_types[] = {
+   { .name = "usb3", .num = 3, },
+   { .name = "usb2", .num = 3, },
+   { .name = "hsic", .num = 1, },
+};
+
+static const struct tegra_xusb_soc tegra186_soc = {
+   .firmware = "nvidia/tegra186/xusb.bin",
+   .supply_names = tegra186_supply_names,
+   .num_supplies = ARRAY_SIZE(tegra186_supply_names),
+   .phy_types = tegra186_phy_types,
+   .num_types = ARRAY_SIZE(tegra186_phy_types),
+   .ports = {
+   .usb3 = { .offset = 0, .count = 3, },
+   .usb2 = { .offset = 3, .count = 3, },
+   .hsic = { .offset = 6, .count = 1, },
+   },
+   .scale_ss_clock = false,
+   .has_ipfs = false,
+};
+
  static const struct of_device_id tegra_xusb_of_match[] = {
{ .compatible = "nvidia,tegra124-xusb", .data = _soc },
{ .compatible = "nvidia,tegra210-xusb", .data = _soc },
+   { .compatible = "nvidia,tegra186-xusb", .data = _soc },
{ },
  };
  MODULE_DEVICE_TABLE(of, tegra_xusb_of_match);


Re: [PATCH 2/6] usb: host: xhci-tegra: Selectively program IPFS

2019-01-27 Thread jckuo

Reviewed-by: JC Kuo 

On 1/25/19 7:30 PM, Thierry Reding wrote:

From: JC Kuo 

Starting with Tegra186, the XUSB controller no longer has the IPFS
wrapper. This commit adds a "has_ipfs" field to struct tegra_xusb_soc
that can be used to declare the existence of the IPFS wrapper.

For the existing chips (i.e. Tegra124 and Tegra210), the new field is
set to true. A future patch adding support for Tegra186 will set it to
false.

Signed-off-by: JC Kuo 
Signed-off-by: Thierry Reding 
---
  drivers/usb/host/xhci-tegra.c | 43 +--
  1 file changed, 26 insertions(+), 17 deletions(-)

diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 938ff06c0349..49e033f953a2 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -161,6 +161,7 @@ struct tegra_xusb_soc {
} ports;
  
  	bool scale_ss_clock;

+   bool has_ipfs;
  };
  
  struct tegra_xusb {

@@ -637,16 +638,18 @@ static irqreturn_t tegra_xusb_mbox_thread(int irq, void 
*data)
return IRQ_HANDLED;
  }
  
-static void tegra_xusb_ipfs_config(struct tegra_xusb *tegra,

-  struct resource *regs)
+static void tegra_xusb_config(struct tegra_xusb *tegra,
+ struct resource *regs)
  {
u32 value;
  
-	value = ipfs_readl(tegra, IPFS_XUSB_HOST_CONFIGURATION_0);

-   value |= IPFS_EN_FPCI;
-   ipfs_writel(tegra, value, IPFS_XUSB_HOST_CONFIGURATION_0);
+   if (tegra->soc->has_ipfs) {
+   value = ipfs_readl(tegra, IPFS_XUSB_HOST_CONFIGURATION_0);
+   value |= IPFS_EN_FPCI;
+   ipfs_writel(tegra, value, IPFS_XUSB_HOST_CONFIGURATION_0);
  
-	usleep_range(10, 20);

+   usleep_range(10, 20);
+   }
  
  	/* Program BAR0 space */

value = fpci_readl(tegra, XUSB_CFG_4);
@@ -661,13 +664,15 @@ static void tegra_xusb_ipfs_config(struct tegra_xusb 
*tegra,
value |= XUSB_IO_SPACE_EN | XUSB_MEM_SPACE_EN | XUSB_BUS_MASTER_EN;
fpci_writel(tegra, value, XUSB_CFG_1);
  
-	/* Enable interrupt assertion */

-   value = ipfs_readl(tegra, IPFS_XUSB_HOST_INTR_MASK_0);
-   value |= IPFS_IP_INT_MASK;
-   ipfs_writel(tegra, value, IPFS_XUSB_HOST_INTR_MASK_0);
+   if (tegra->soc->has_ipfs) {
+   /* Enable interrupt assertion */
+   value = ipfs_readl(tegra, IPFS_XUSB_HOST_INTR_MASK_0);
+   value |= IPFS_IP_INT_MASK;
+   ipfs_writel(tegra, value, IPFS_XUSB_HOST_INTR_MASK_0);
  
-	/* Set hysteresis */

-   ipfs_writel(tegra, 0x80, IPFS_XUSB_HOST_CLKGATE_HYSTERESIS_0);
+   /* Set hysteresis */
+   ipfs_writel(tegra, 0x80, IPFS_XUSB_HOST_CLKGATE_HYSTERESIS_0);
+   }
  }
  
  static int tegra_xusb_clk_enable(struct tegra_xusb *tegra)

@@ -1015,10 +1020,12 @@ static int tegra_xusb_probe(struct platform_device 
*pdev)
if (IS_ERR(tegra->fpci_base))
return PTR_ERR(tegra->fpci_base);
  
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);

-   tegra->ipfs_base = devm_ioremap_resource(>dev, res);
-   if (IS_ERR(tegra->ipfs_base))
-   return PTR_ERR(tegra->ipfs_base);
+   if (tegra->soc->has_ipfs) {
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+   tegra->ipfs_base = devm_ioremap_resource(>dev, res);
+   if (IS_ERR(tegra->ipfs_base))
+   return PTR_ERR(tegra->ipfs_base);
+   }
  
  	tegra->xhci_irq = platform_get_irq(pdev, 0);

if (tegra->xhci_irq < 0)
@@ -1208,7 +1215,7 @@ static int tegra_xusb_probe(struct platform_device *pdev)
goto disable_rpm;
}
  
-	tegra_xusb_ipfs_config(tegra, regs);

+   tegra_xusb_config(tegra, regs);
  
  	err = tegra_xusb_load_firmware(tegra);

if (err < 0) {
@@ -1380,6 +1387,7 @@ static const struct tegra_xusb_soc tegra124_soc = {
.usb3 = { .offset = 0, .count = 2, },
},
.scale_ss_clock = true,
+   .has_ipfs = true,
  };
  MODULE_FIRMWARE("nvidia/tegra124/xusb.bin");
  
@@ -1411,6 +1419,7 @@ static const struct tegra_xusb_soc tegra210_soc = {

.usb3 = { .offset = 0, .count = 4, },
},
.scale_ss_clock = false,
+   .has_ipfs = true,
  };
  MODULE_FIRMWARE("nvidia/tegra210/xusb.bin");
  


Re: [PATCH 1/6] dt-bindings: usb: xhci-tegra: Add Tegra186 support

2019-01-27 Thread jckuo

Reviewed-by: JC Kuo 

On 1/25/19 7:30 PM, Thierry Reding wrote:

From: Thierry Reding 

Extend the bindings to cover the set of features found in Tegra186.

Signed-off-by: Thierry Reding 
---
  .../devicetree/bindings/usb/nvidia,tegra124-xusb.txt  | 4 
  1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra124-xusb.txt 
b/Documentation/devicetree/bindings/usb/nvidia,tegra124-xusb.txt
index 4156c3e181c5..5bfcc0b4d6b9 100644
--- a/Documentation/devicetree/bindings/usb/nvidia,tegra124-xusb.txt
+++ b/Documentation/devicetree/bindings/usb/nvidia,tegra124-xusb.txt
@@ -10,6 +10,7 @@ Required properties:
- Tegra124: "nvidia,tegra124-xusb"
- Tegra132: "nvidia,tegra132-xusb", "nvidia,tegra124-xusb"
- Tegra210: "nvidia,tegra210-xusb"
+  - Tegra186: "nvidia,tegra186-xusb"
  - reg: Must contain the base and length of the xHCI host registers, XUSB FPCI
registers and XUSB IPFS registers.
  - reg-names: Must contain the following entries:
@@ -59,6 +60,8 @@ For Tegra210:
  - avdd-pll-uerefe-supply: PLLE reference PLL power supply. Must supply 1.05 V.
  - dvdd-pex-pll-supply: PCIe/USB3 PLL power supply. Must supply 1.05 V.
  - hvdd-pex-pll-e-supply: High-voltage PLLE power supply. Must supply 1.8 V.
+
+For Tegra210 and Tegra186:
  - power-domains: A list of PM domain specifiers that reference each 
power-domain
used by the xHCI controller. This list must comprise of a specifier for the
XUSBA and XUSBC power-domains. See ../power/power_domain.txt and
@@ -78,6 +81,7 @@ Optional properties:
- Tegra132: usb2-0, usb2-1, usb2-2, hsic-0, hsic-1, usb3-0, usb3-1
- Tegra210: usb2-0, usb2-1, usb2-2, usb2-3, hsic-0, usb3-0, usb3-1, usb3-2,
usb3-3
+  - Tegra186: usb2-0, usb2-1, usb2-2, hsic-0, usb3-0, usb3-1, usb3-2
  
  Example:

  


Re: [PATCH 5/5] phy: tegra: xusb: Add Tegra186 support

2019-01-27 Thread jckuo

Reviewed-by: JC Kuo 

On 1/25/19 7:25 PM, Thierry Reding wrote:

From: JC Kuo 

Add support for the XUSB pad controller found on Tegra186 SoCs. It is
mostly similar to the same IP found on earlier chips, but the number of
pads exposed differs, as do the programming sequences.

Note that the DVDD_PEX, DVDD_PEX_PLL, HVDD_PEX and HVDD_PEX_PLL power
supplies of the XUSB pad controller require strict power sequencing and
are therefore controlled by the PMIC on Tegra186.

Signed-off-by: JC Kuo 
Signed-off-by: Thierry Reding 
---
  MAINTAINERS   |   5 +
  drivers/phy/tegra/Makefile|   1 +
  drivers/phy/tegra/xusb-tegra186.c | 908 ++
  drivers/phy/tegra/xusb.c  |   6 +
  drivers/phy/tegra/xusb.h  |  27 +
  5 files changed, 947 insertions(+)
  create mode 100644 drivers/phy/tegra/xusb-tegra186.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ddcdc29dfe1f..754f7e757361 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15099,6 +15099,11 @@ M: Laxman Dewangan 
  S:Supported
  F:drivers/spi/spi-tegra*
  
+TEGRA XUSB PADCTL DRIVER

+M: JC Kuo 
+S: Supported
+F: drivers/phy/tegra/xusb*
+
  TEHUTI ETHERNET DRIVER
  M:Andy Gospodarek 
  L:net...@vger.kernel.org
diff --git a/drivers/phy/tegra/Makefile b/drivers/phy/tegra/Makefile
index 898589238fd9..a93cd9a499b2 100644
--- a/drivers/phy/tegra/Makefile
+++ b/drivers/phy/tegra/Makefile
@@ -4,3 +4,4 @@ phy-tegra-xusb-y += xusb.o
  phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_124_SOC) += xusb-tegra124.o
  phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_132_SOC) += xusb-tegra124.o
  phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_210_SOC) += xusb-tegra210.o
+phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_186_SOC) += xusb-tegra186.o
diff --git a/drivers/phy/tegra/xusb-tegra186.c 
b/drivers/phy/tegra/xusb-tegra186.c
new file mode 100644
index ..0dbcaddade90
--- /dev/null
+++ b/drivers/phy/tegra/xusb-tegra186.c
@@ -0,0 +1,908 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "xusb.h"
+
+/* FUSE USB_CALIB registers */
+#define HS_CURR_LEVEL_PADX_SHIFT(x)((x) ? (11 + (x - 1) * 6) : 0)
+#define HS_CURR_LEVEL_PAD_MASK 0x3f
+#define HS_TERM_RANGE_ADJ_SHIFT7
+#define HS_TERM_RANGE_ADJ_MASK 0xf
+#define HS_SQUELCH_SHIFT   29
+#define HS_SQUELCH_MASK0x7
+
+#define RPD_CTRL_SHIFT 0
+#define RPD_CTRL_MASK  0x1f
+
+/* XUSB PADCTL registers */
+#define XUSB_PADCTL_USB2_PAD_MUX   0x4
+#define  USB2_PORT_SHIFT(x)((x) * 2)
+#define  USB2_PORT_MASK0x3
+#define   PORT_XUSB1
+#define  HSIC_PORT_SHIFT(x)((x) + 20)
+#define  HSIC_PORT_MASK0x1
+#define   PORT_HSIC0
+
+#define XUSB_PADCTL_USB2_PORT_CAP  0x8
+#define XUSB_PADCTL_SS_PORT_CAP0xc
+#define  PORTX_CAP_SHIFT(x)((x) * 4)
+#define  PORT_CAP_MASK 0x3
+#define   PORT_CAP_DISABLED0x0
+#define   PORT_CAP_HOST0x1
+#define   PORT_CAP_DEVICE  0x2
+#define   PORT_CAP_OTG 0x3
+
+#define XUSB_PADCTL_ELPG_PROGRAM   0x20
+#define  USB2_PORT_WAKE_INTERRUPT_ENABLE(x)(1 << (x))
+#define  USB2_PORT_WAKEUP_EVENT(x) (   1 << ((x) + 7))
+#define  SS_PORT_WAKE_INTERRUPT_ENABLE(x)  (1 << ((x) + 14))
+#define  SS_PORT_WAKEUP_EVENT(x)   (1 << ((x) + 21))
+#define  USB2_HSIC_PORT_WAKE_INTERRUPT_ENABLE(x)   (1 << ((x) + 28))
+#define  USB2_HSIC_PORT_WAKEUP_EVENT(x)(1 << ((x) + 
30))
+#define  ALL_WAKE_EVENTS   \
+   (USB2_PORT_WAKEUP_EVENT(0) | USB2_PORT_WAKEUP_EVENT(1) |\
+   USB2_PORT_WAKEUP_EVENT(2) | SS_PORT_WAKEUP_EVENT(0) |   \
+   SS_PORT_WAKEUP_EVENT(1) | SS_PORT_WAKEUP_EVENT(2) | \
+   USB2_HSIC_PORT_WAKEUP_EVENT(0))
+
+#define XUSB_PADCTL_ELPG_PROGRAM_1 0x24
+#define  SSPX_ELPG_CLAMP_EN(x) (1 << (0 + (x) * 3))
+#define  SSPX_ELPG_CLAMP_EN_EARLY(x)   (1 << (1 + (x) * 3))
+#define  SSPX_ELPG_VCORE_DOWN(x)   (1 << (2 + (x) * 3))
+
+#define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x)  (0x88 + (x) * 0x40)
+#define  HS_CURR_LEVEL(x) 

Re: [PATCH 4/5] phy: tegra: xusb: Add support for power supplies

2019-01-27 Thread jckuo

Hi Thierry,

I think any non-zero return value of 
regulator_bulk_enable()/devm_regulator_bulk_get() means error.


Thanks,

JC

On 1/25/19 7:25 PM, Thierry Reding wrote:

From: Thierry Reding 

Support enabling various supplies needed to provide power to the PLLs
and logic used to drive the USB, PCI and SATA pads.

Signed-off-by: Thierry Reding 
---
  drivers/phy/tegra/xusb.c | 34 +-
  drivers/phy/tegra/xusb.h |  5 +
  2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index 57a2d08ef6da..e510629f4f1c 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -864,6 +864,7 @@ static int tegra_xusb_padctl_probe(struct platform_device 
*pdev)
struct tegra_xusb_padctl *padctl;
const struct of_device_id *match;
struct resource *res;
+   unsigned int i;
int err;
  
  	/* for backwards compatibility with old device trees */

@@ -901,14 +902,38 @@ static int tegra_xusb_padctl_probe(struct platform_device 
*pdev)
goto remove;
}
  
+	padctl->supplies = devm_kcalloc(>dev, padctl->soc->num_supplies,

+   sizeof(*padctl->supplies), GFP_KERNEL);
+   if (!padctl->supplies) {
+   err = -ENOMEM;
+   goto remove;
+   }
+
+   for (i = 0; i < padctl->soc->num_supplies; i++)
+   padctl->supplies[i].supply = padctl->soc->supply_names[i];
+
+   err = devm_regulator_bulk_get(>dev, padctl->soc->num_supplies,
+ padctl->supplies);
+   if (err < 0) {
+   dev_err(>dev, "failed to get regulators: %d\n", err);
+   goto remove;
+   }
+
err = reset_control_deassert(padctl->rst);
if (err < 0)
goto remove;
  
+	err = regulator_bulk_enable(padctl->soc->num_supplies,

+   padctl->supplies);
+   if (err < 0) {
+   dev_err(>dev, "failed to enable supplies: %d\n", err);
+   goto reset;
+   }
+
err = tegra_xusb_setup_pads(padctl);
if (err < 0) {
dev_err(>dev, "failed to setup pads: %d\n", err);
-   goto reset;
+   goto power_down;
}
  
  	err = tegra_xusb_setup_ports(padctl);

@@ -921,6 +946,8 @@ static int tegra_xusb_padctl_probe(struct platform_device 
*pdev)
  
  remove_pads:

tegra_xusb_remove_pads(padctl);
+power_down:
+   regulator_bulk_disable(padctl->soc->num_supplies, padctl->supplies);
  reset:
reset_control_assert(padctl->rst);
  remove:
@@ -936,6 +963,11 @@ static int tegra_xusb_padctl_remove(struct platform_device 
*pdev)
tegra_xusb_remove_ports(padctl);
tegra_xusb_remove_pads(padctl);
  
+	err = regulator_bulk_disable(padctl->soc->num_supplies,

+padctl->supplies);
+   if (err < 0)
+   dev_err(>dev, "failed to disable supplies: %d\n", err);
+
err = reset_control_assert(padctl->rst);
if (err < 0)
dev_err(>dev, "failed to assert reset: %d\n", err);
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
index bb60fc09c752..5d5d22f6cb41 100644
--- a/drivers/phy/tegra/xusb.h
+++ b/drivers/phy/tegra/xusb.h
@@ -370,6 +370,9 @@ struct tegra_xusb_padctl_soc {
} ports;
  
  	const struct tegra_xusb_padctl_ops *ops;

+
+   const char * const *supply_names;
+   unsigned int num_supplies;
  };
  
  struct tegra_xusb_padctl {

@@ -393,6 +396,8 @@ struct tegra_xusb_padctl {
unsigned int enable;
  
  	struct clk *clk;

+
+   struct regulator_bulk_data *supplies;
  };
  
  static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value,


Re: [PATCH 3/5] phy: tegra: xusb: Parse dual-role mode property

2019-01-27 Thread jckuo

Reviewed-by: JC Kuo 

On 1/25/19 7:25 PM, Thierry Reding wrote:

From: Thierry Reding 

The device tree bindings document the "mode" property of "ports"
subnodes, but the driver was not parsing the property. In preparation
for adding role switching, parse the property at probe time.

Based on work by JC Kuo .

Signed-off-by: Thierry Reding 
---
  drivers/phy/tegra/xusb.c | 21 +
  drivers/phy/tegra/xusb.h |  3 +++
  2 files changed, 24 insertions(+)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index e3bc60cfe6a1..57a2d08ef6da 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -546,13 +546,34 @@ static void tegra_xusb_port_unregister(struct 
tegra_xusb_port *port)
device_unregister(>dev);
  }
  
+static const char *const modes[] = {

+   [USB_DR_MODE_UNKNOWN] = "",
+   [USB_DR_MODE_HOST] = "host",
+   [USB_DR_MODE_PERIPHERAL] = "peripheral",
+   [USB_DR_MODE_OTG] = "otg",
+};
+
  static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
  {
struct tegra_xusb_port *port = >base;
struct device_node *np = port->dev.of_node;
+   const char *mode;
  
  	usb2->internal = of_property_read_bool(np, "nvidia,internal");
  
+	if (!of_property_read_string(np, "mode", )) {

+   int err = match_string(modes, ARRAY_SIZE(modes), mode);
+   if (err < 0) {
+   dev_err(>dev, "invalid value %s for \"mode\"\n",
+   mode);
+   usb2->mode = USB_DR_MODE_UNKNOWN;
+   } else {
+   usb2->mode = err;
+   }
+   } else {
+   usb2->mode = USB_DR_MODE_HOST;
+   }
+
usb2->supply = devm_regulator_get(>dev, "vbus");
return PTR_ERR_OR_ZERO(usb2->supply);
  }
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
index b49dbc36efa3..bb60fc09c752 100644
--- a/drivers/phy/tegra/xusb.h
+++ b/drivers/phy/tegra/xusb.h
@@ -19,6 +19,8 @@
  #include 
  #include 
  
+#include 

+
  /* legacy entry points for backwards-compatibility */
  int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
  int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev);
@@ -271,6 +273,7 @@ struct tegra_xusb_usb2_port {
struct tegra_xusb_port base;
  
  	struct regulator *supply;

+   enum usb_dr_mode mode;
bool internal;
  };
  


Re: [PATCH 2/5] phy: tegra: xusb: Skip single function lane programming

2019-01-27 Thread jckuo

Reviewed-by: JC Kuo 

On 1/25/19 7:25 PM, Thierry Reding wrote:

From: JC Kuo 

Tegra186 USB2 pads and USB3 pads do not have hardware mux for changing
the pad function. For such "lanes", we can skip the lane mux register
programming.

Signed-off-by: JC Kuo 
Signed-off-by: Thierry Reding 
---
  drivers/phy/tegra/xusb.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index 5b3b8863363e..e3bc60cfe6a1 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -1,5 +1,5 @@
  /*
- * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION.  All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms and conditions of the GNU General Public License,
@@ -313,6 +313,10 @@ static void tegra_xusb_lane_program(struct tegra_xusb_lane 
*lane)
const struct tegra_xusb_lane_soc *soc = lane->soc;
u32 value;
  
+	/* skip single function lanes */

+   if (soc->num_funcs < 2)
+   return;
+
/* choose function */
value = padctl_readl(padctl, soc->offset);
value &= ~(soc->mask << soc->shift);


Re: [PATCH 1/5] dt-bindings: phy: tegra: Add Tegra186 support

2019-01-27 Thread jckuo

Reviewed-by: JC Kuo 

On 1/25/19 7:25 PM, Thierry Reding wrote:

From: Thierry Reding 

Extend the bindings to cover the set of features found in Tegra186. Note
that, technically, there are four more supplies connected to the XUSB
pad controller (DVDD_PEX, DVDD_PEX_PLL, HVDD_PEX and HVDD_PEX_PLL), but
the power sequencing requirements of Tegra186 require these to be under
the control of the PMIC.

Signed-off-by: Thierry Reding 
---
  .../bindings/phy/nvidia,tegra124-xusb-padctl.txt | 9 +
  1 file changed, 9 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt 
b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
index 3742c152c467..daedb15f322e 100644
--- a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
+++ b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt
@@ -36,11 +36,20 @@ Required properties:
- Tegra124: "nvidia,tegra124-xusb-padctl"
- Tegra132: "nvidia,tegra132-xusb-padctl", "nvidia,tegra124-xusb-padctl"
- Tegra210: "nvidia,tegra210-xusb-padctl"
+  - Tegra186: "nvidia,tegra186-xusb-padctl"
  - reg: Physical base address and length of the controller's registers.
  - resets: Must contain an entry for each entry in reset-names.
  - reset-names: Must include the following entries:
- "padctl"
  
+For Tegra186:

+- avdd-pll-erefeut-supply: UPHY brick and reference clock as well as UTMI PHY
+  power supply. Must supply 1.8 V.
+- avdd-usb-supply: USB I/Os, VBUS, ID, REXT, D+/D- power supply. Must supply
+  3.3 V.
+- vclamp-usb-supply: Bias rail for USB pad. Must supply 1.8 V.
+- vddio-hsic-supply: HSIC PHY power supply. Must supply 1.2 V.
+
  
  Pad nodes:

  ==