* [PATCH v2 0/2] usb: tegra: power down UTMI pad
@ 2022-08-16 8:23 Jim Lin
2022-08-16 8:23 ` [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops Jim Lin
2022-08-16 8:23 ` [PATCH v2 2/2] usb: gadget: tegra: Reduce pad power Jim Lin
0 siblings, 2 replies; 8+ messages in thread
From: Jim Lin @ 2022-08-16 8:23 UTC (permalink / raw)
To: jckuo, thierry.reding, jonathanh
Cc: vkoul, balbi, gregkh, jilin, bhsieh, linux-phy, linux-tegra,
linux-kernel, linux-usb
1. Make functions to be generic and public for tegra host/gadget driver
to power on/down UTMI pad
2. For tegra gadget driver to power down pad after disconnected
--
v2: update copyright year
drivers/usb/gadget/udc/tegra-xudc.c
include/linux/phy/tegra/xusb.h
Jim Lin (2):
phy: tegra: xusb: add utmi pad power on/down ops
usb: gadget: tegra: Reduce pad power
drivers/phy/tegra/xusb-tegra186.c | 19 ++++++++++++-------
drivers/phy/tegra/xusb.c | 22 +++++++++++++++++++++-
drivers/phy/tegra/xusb.h | 4 +++-
drivers/usb/gadget/udc/tegra-xudc.c | 6 +++++-
include/linux/phy/tegra/xusb.h | 4 +++-
5 files changed, 44 insertions(+), 11 deletions(-)
--
2.17.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops
2022-08-16 8:23 [PATCH v2 0/2] usb: tegra: power down UTMI pad Jim Lin
@ 2022-08-16 8:23 ` Jim Lin
2022-09-04 14:45 ` Vinod Koul
2022-08-16 8:23 ` [PATCH v2 2/2] usb: gadget: tegra: Reduce pad power Jim Lin
1 sibling, 1 reply; 8+ messages in thread
From: Jim Lin @ 2022-08-16 8:23 UTC (permalink / raw)
To: jckuo, thierry.reding, jonathanh
Cc: vkoul, balbi, gregkh, jilin, bhsieh, linux-phy, linux-tegra,
linux-kernel, linux-usb
Add utmi_pad_power_on/down ops for each SOC instead of exporting
tegra_phy_xusb_utmi_pad_power_on/down directly for Tegra186 chip.
Signed-off-by: BH Hsieh <bhsieh@nvidia.com>
Signed-off-by: Jim Lin <jilin@nvidia.com>
---
v2: update copyright year
drivers/phy/tegra/xusb-tegra186.c | 19 ++++++++++++-------
drivers/phy/tegra/xusb.c | 22 +++++++++++++++++++++-
drivers/phy/tegra/xusb.h | 4 +++-
include/linux/phy/tegra/xusb.h | 4 +++-
4 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
index ae3915ed9fef..5abdf81aa143 100644
--- a/drivers/phy/tegra/xusb-tegra186.c
+++ b/drivers/phy/tegra/xusb-tegra186.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2016-2022, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/delay.h>
@@ -638,7 +638,7 @@ static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl)
mutex_unlock(&padctl->lock);
}
-static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
+static void tegra186_utmi_pad_power_on(struct phy *phy)
{
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
@@ -656,6 +656,8 @@ static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
return;
}
+ dev_dbg(dev, "power on UTMI pad %u\n", index);
+
tegra186_utmi_bias_pad_power_on(padctl);
udelay(2);
@@ -669,7 +671,7 @@ static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
}
-static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
+static void tegra186_utmi_pad_power_down(struct phy *phy)
{
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
@@ -679,6 +681,8 @@ static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
if (!phy)
return;
+ dev_dbg(padctl->dev, "power down UTMI pad %u\n", index);
+
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
value |= USB2_OTG_PD;
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
@@ -849,15 +853,14 @@ static int tegra186_utmi_phy_power_on(struct phy *phy)
value |= RPD_CTRL(priv->calib.rpd_ctrl);
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
- /* TODO: pad power saving */
- tegra_phy_xusb_utmi_pad_power_on(phy);
+ tegra186_utmi_pad_power_on(phy);
+
return 0;
}
static int tegra186_utmi_phy_power_off(struct phy *phy)
{
- /* TODO: pad power saving */
- tegra_phy_xusb_utmi_pad_power_down(phy);
+ tegra186_utmi_pad_power_down(phy);
return 0;
}
@@ -1486,6 +1489,8 @@ static const struct tegra_xusb_padctl_ops tegra186_xusb_padctl_ops = {
.suspend_noirq = tegra186_xusb_padctl_suspend_noirq,
.resume_noirq = tegra186_xusb_padctl_resume_noirq,
.vbus_override = tegra186_xusb_padctl_vbus_override,
+ .utmi_pad_power_on = tegra186_utmi_pad_power_on,
+ .utmi_pad_power_down = tegra186_utmi_pad_power_down,
};
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC)
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index 963de5913e50..49873718d54a 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/delay.h>
@@ -1458,6 +1458,26 @@ int tegra_phy_xusb_utmi_port_reset(struct phy *phy)
}
EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_port_reset);
+void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
+{
+ struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
+ struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+
+ if (padctl->soc->ops->utmi_pad_power_on)
+ padctl->soc->ops->utmi_pad_power_on(phy);
+}
+EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_power_on);
+
+void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
+{
+ struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
+ struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+
+ if (padctl->soc->ops->utmi_pad_power_down)
+ padctl->soc->ops->utmi_pad_power_down(phy);
+}
+EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_power_down);
+
int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
unsigned int port)
{
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
index 034f7a2c28d6..8cfbbdbd6e0c 100644
--- a/drivers/phy/tegra/xusb.h
+++ b/drivers/phy/tegra/xusb.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2015, Google Inc.
*/
@@ -412,6 +412,8 @@ struct tegra_xusb_padctl_ops {
unsigned int index, bool enable);
int (*vbus_override)(struct tegra_xusb_padctl *padctl, bool set);
int (*utmi_port_reset)(struct phy *phy);
+ void (*utmi_pad_power_on)(struct phy *phy);
+ void (*utmi_pad_power_down)(struct phy *phy);
};
struct tegra_xusb_padctl_soc {
diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h
index 3a35e74cdc61..70998e6dd6fd 100644
--- a/include/linux/phy/tegra/xusb.h
+++ b/include/linux/phy/tegra/xusb.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2016-2022, NVIDIA CORPORATION. All rights reserved.
*/
#ifndef PHY_TEGRA_XUSB_H
@@ -21,6 +21,8 @@ int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
unsigned int port, bool enable);
int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl,
bool val);
+void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy);
+void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy);
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);
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] usb: gadget: tegra: Reduce pad power
2022-08-16 8:23 [PATCH v2 0/2] usb: tegra: power down UTMI pad Jim Lin
2022-08-16 8:23 ` [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops Jim Lin
@ 2022-08-16 8:23 ` Jim Lin
1 sibling, 0 replies; 8+ messages in thread
From: Jim Lin @ 2022-08-16 8:23 UTC (permalink / raw)
To: jckuo, thierry.reding, jonathanh
Cc: vkoul, balbi, gregkh, jilin, bhsieh, linux-phy, linux-tegra,
linux-kernel, linux-usb
Program USB2 UTMI pad PD controls during port connect/disconnect.
Power down pad after disconnected to save power.
Signed-off-by: Jim Lin <jilin@nvidia.com>
---
v2: update copyright year
drivers/usb/gadget/udc/tegra-xudc.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
index 43f1b0d461c1..e59f19be6327 100644
--- a/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/drivers/usb/gadget/udc/tegra-xudc.c
@@ -2,7 +2,7 @@
/*
* NVIDIA Tegra XUSB device mode controller
*
- * Copyright (c) 2013-2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2013-2022, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2015, Google Inc.
*/
@@ -703,6 +703,8 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
pm_runtime_get_sync(xudc->dev);
+ tegra_phy_xusb_utmi_pad_power_on(xudc->curr_utmi_phy);
+
err = phy_power_on(xudc->curr_utmi_phy);
if (err < 0)
dev_err(xudc->dev, "UTMI power on failed: %d\n", err);
@@ -757,6 +759,8 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
/* Make sure interrupt handler has completed before powergating. */
synchronize_irq(xudc->irq);
+ tegra_phy_xusb_utmi_pad_power_down(xudc->curr_utmi_phy);
+
err = phy_power_off(xudc->curr_utmi_phy);
if (err < 0)
dev_err(xudc->dev, "UTMI PHY power off failed: %d\n", err);
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops
2022-08-16 8:23 ` [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops Jim Lin
@ 2022-09-04 14:45 ` Vinod Koul
2022-09-06 2:43 ` JC Kuo
0 siblings, 1 reply; 8+ messages in thread
From: Vinod Koul @ 2022-09-04 14:45 UTC (permalink / raw)
To: Jim Lin
Cc: jckuo, thierry.reding, jonathanh, balbi, gregkh, bhsieh,
linux-phy, linux-tegra, linux-kernel, linux-usb
On 16-08-22, 16:23, Jim Lin wrote:
> Add utmi_pad_power_on/down ops for each SOC instead of exporting
> tegra_phy_xusb_utmi_pad_power_on/down directly for Tegra186 chip.
Can you please help me understand why do we need to utmi power_on/down
exported and cant be handled thry phy-ops..
>
> Signed-off-by: BH Hsieh <bhsieh@nvidia.com>
> Signed-off-by: Jim Lin <jilin@nvidia.com>
> ---
> v2: update copyright year
>
> drivers/phy/tegra/xusb-tegra186.c | 19 ++++++++++++-------
> drivers/phy/tegra/xusb.c | 22 +++++++++++++++++++++-
> drivers/phy/tegra/xusb.h | 4 +++-
> include/linux/phy/tegra/xusb.h | 4 +++-
> 4 files changed, 39 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
> index ae3915ed9fef..5abdf81aa143 100644
> --- a/drivers/phy/tegra/xusb-tegra186.c
> +++ b/drivers/phy/tegra/xusb-tegra186.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0
> /*
> - * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved.
> + * Copyright (c) 2016-2022, NVIDIA CORPORATION. All rights reserved.
> */
>
> #include <linux/delay.h>
> @@ -638,7 +638,7 @@ static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl)
> mutex_unlock(&padctl->lock);
> }
>
> -static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
> +static void tegra186_utmi_pad_power_on(struct phy *phy)
> {
> struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
> struct tegra_xusb_padctl *padctl = lane->pad->padctl;
> @@ -656,6 +656,8 @@ static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
> return;
> }
>
> + dev_dbg(dev, "power on UTMI pad %u\n", index);
> +
> tegra186_utmi_bias_pad_power_on(padctl);
>
> udelay(2);
> @@ -669,7 +671,7 @@ static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
> padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
> }
>
> -static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
> +static void tegra186_utmi_pad_power_down(struct phy *phy)
> {
> struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
> struct tegra_xusb_padctl *padctl = lane->pad->padctl;
> @@ -679,6 +681,8 @@ static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
> if (!phy)
> return;
>
> + dev_dbg(padctl->dev, "power down UTMI pad %u\n", index);
> +
> value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
> value |= USB2_OTG_PD;
> padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
> @@ -849,15 +853,14 @@ static int tegra186_utmi_phy_power_on(struct phy *phy)
> value |= RPD_CTRL(priv->calib.rpd_ctrl);
> padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
>
> - /* TODO: pad power saving */
> - tegra_phy_xusb_utmi_pad_power_on(phy);
> + tegra186_utmi_pad_power_on(phy);
> +
> return 0;
> }
>
> static int tegra186_utmi_phy_power_off(struct phy *phy)
> {
> - /* TODO: pad power saving */
> - tegra_phy_xusb_utmi_pad_power_down(phy);
> + tegra186_utmi_pad_power_down(phy);
>
> return 0;
> }
> @@ -1486,6 +1489,8 @@ static const struct tegra_xusb_padctl_ops tegra186_xusb_padctl_ops = {
> .suspend_noirq = tegra186_xusb_padctl_suspend_noirq,
> .resume_noirq = tegra186_xusb_padctl_resume_noirq,
> .vbus_override = tegra186_xusb_padctl_vbus_override,
> + .utmi_pad_power_on = tegra186_utmi_pad_power_on,
> + .utmi_pad_power_down = tegra186_utmi_pad_power_down,
> };
>
> #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC)
> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
> index 963de5913e50..49873718d54a 100644
> --- a/drivers/phy/tegra/xusb.c
> +++ b/drivers/phy/tegra/xusb.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /*
> - * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
> + * Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved.
> */
>
> #include <linux/delay.h>
> @@ -1458,6 +1458,26 @@ int tegra_phy_xusb_utmi_port_reset(struct phy *phy)
> }
> EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_port_reset);
>
> +void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
> +{
> + struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
> + struct tegra_xusb_padctl *padctl = lane->pad->padctl;
> +
> + if (padctl->soc->ops->utmi_pad_power_on)
> + padctl->soc->ops->utmi_pad_power_on(phy);
> +}
> +EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_power_on);
> +
> +void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
> +{
> + struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
> + struct tegra_xusb_padctl *padctl = lane->pad->padctl;
> +
> + if (padctl->soc->ops->utmi_pad_power_down)
> + padctl->soc->ops->utmi_pad_power_down(phy);
> +}
> +EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_power_down);
> +
> int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
> unsigned int port)
> {
> diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
> index 034f7a2c28d6..8cfbbdbd6e0c 100644
> --- a/drivers/phy/tegra/xusb.h
> +++ b/drivers/phy/tegra/xusb.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> /*
> - * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
> + * Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved.
> * Copyright (c) 2015, Google Inc.
> */
>
> @@ -412,6 +412,8 @@ struct tegra_xusb_padctl_ops {
> unsigned int index, bool enable);
> int (*vbus_override)(struct tegra_xusb_padctl *padctl, bool set);
> int (*utmi_port_reset)(struct phy *phy);
> + void (*utmi_pad_power_on)(struct phy *phy);
> + void (*utmi_pad_power_down)(struct phy *phy);
> };
>
> struct tegra_xusb_padctl_soc {
> diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h
> index 3a35e74cdc61..70998e6dd6fd 100644
> --- a/include/linux/phy/tegra/xusb.h
> +++ b/include/linux/phy/tegra/xusb.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> /*
> - * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved.
> + * Copyright (c) 2016-2022, NVIDIA CORPORATION. All rights reserved.
> */
>
> #ifndef PHY_TEGRA_XUSB_H
> @@ -21,6 +21,8 @@ int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
> unsigned int port, bool enable);
> int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl,
> bool val);
> +void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy);
> +void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy);
> 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);
> --
> 2.17.1
--
~Vinod
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops
2022-09-04 14:45 ` Vinod Koul
@ 2022-09-06 2:43 ` JC Kuo
2022-09-13 14:34 ` Vinod Koul
0 siblings, 1 reply; 8+ messages in thread
From: JC Kuo @ 2022-09-06 2:43 UTC (permalink / raw)
To: Vinod Koul, Jim Lin
Cc: thierry.reding, jonathanh, balbi, gregkh, bhsieh, linux-phy,
linux-tegra, linux-kernel, linux-usb
Hi Vinod,
Before the device or host is being attached, we can keep most of the
transceivers powered down (PD=1/PD_DR=1) to minimize power consumption. At this
stage, in .phy_power_on(), we enable only the single-ended receiver (PD_ZI=0)
for detecting connection. Upon detecting device's or host's connection, host or
controller driver will invoke tegra_phy_xusb_utmi_pad_power_on() to power on all
of the transceivers (PD=0/PD_DR=0) to equip full link functionality.
Thanks,
JC
On 9/4/22 22:45, Vinod Koul wrote:
> On 16-08-22, 16:23, Jim Lin wrote:
>> Add utmi_pad_power_on/down ops for each SOC instead of exporting
>> tegra_phy_xusb_utmi_pad_power_on/down directly for Tegra186 chip.
>
> Can you please help me understand why do we need to utmi power_on/down
> exported and cant be handled thry phy-ops..
>
>>
>> Signed-off-by: BH Hsieh <bhsieh@nvidia.com>
>> Signed-off-by: Jim Lin <jilin@nvidia.com>
>> ---
>> v2: update copyright year
>>
>> drivers/phy/tegra/xusb-tegra186.c | 19 ++++++++++++-------
>> drivers/phy/tegra/xusb.c | 22 +++++++++++++++++++++-
>> drivers/phy/tegra/xusb.h | 4 +++-
>> include/linux/phy/tegra/xusb.h | 4 +++-
>> 4 files changed, 39 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
>> index ae3915ed9fef..5abdf81aa143 100644
>> --- a/drivers/phy/tegra/xusb-tegra186.c
>> +++ b/drivers/phy/tegra/xusb-tegra186.c
>> @@ -1,6 +1,6 @@
>> // SPDX-License-Identifier: GPL-2.0
>> /*
>> - * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved.
>> + * Copyright (c) 2016-2022, NVIDIA CORPORATION. All rights reserved.
>> */
>>
>> #include <linux/delay.h>
>> @@ -638,7 +638,7 @@ static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl)
>> mutex_unlock(&padctl->lock);
>> }
>>
>> -static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
>> +static void tegra186_utmi_pad_power_on(struct phy *phy)
>> {
>> struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
>> struct tegra_xusb_padctl *padctl = lane->pad->padctl;
>> @@ -656,6 +656,8 @@ static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
>> return;
>> }
>>
>> + dev_dbg(dev, "power on UTMI pad %u\n", index);
>> +
>> tegra186_utmi_bias_pad_power_on(padctl);
>>
>> udelay(2);
>> @@ -669,7 +671,7 @@ static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
>> padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
>> }
>>
>> -static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
>> +static void tegra186_utmi_pad_power_down(struct phy *phy)
>> {
>> struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
>> struct tegra_xusb_padctl *padctl = lane->pad->padctl;
>> @@ -679,6 +681,8 @@ static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
>> if (!phy)
>> return;
>>
>> + dev_dbg(padctl->dev, "power down UTMI pad %u\n", index);
>> +
>> value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
>> value |= USB2_OTG_PD;
>> padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
>> @@ -849,15 +853,14 @@ static int tegra186_utmi_phy_power_on(struct phy *phy)
>> value |= RPD_CTRL(priv->calib.rpd_ctrl);
>> padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
>>
>> - /* TODO: pad power saving */
>> - tegra_phy_xusb_utmi_pad_power_on(phy);
>> + tegra186_utmi_pad_power_on(phy);
>> +
>> return 0;
>> }
>>
>> static int tegra186_utmi_phy_power_off(struct phy *phy)
>> {
>> - /* TODO: pad power saving */
>> - tegra_phy_xusb_utmi_pad_power_down(phy);
>> + tegra186_utmi_pad_power_down(phy);
>>
>> return 0;
>> }
>> @@ -1486,6 +1489,8 @@ static const struct tegra_xusb_padctl_ops tegra186_xusb_padctl_ops = {
>> .suspend_noirq = tegra186_xusb_padctl_suspend_noirq,
>> .resume_noirq = tegra186_xusb_padctl_resume_noirq,
>> .vbus_override = tegra186_xusb_padctl_vbus_override,
>> + .utmi_pad_power_on = tegra186_utmi_pad_power_on,
>> + .utmi_pad_power_down = tegra186_utmi_pad_power_down,
>> };
>>
>> #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC)
>> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
>> index 963de5913e50..49873718d54a 100644
>> --- a/drivers/phy/tegra/xusb.c
>> +++ b/drivers/phy/tegra/xusb.c
>> @@ -1,6 +1,6 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /*
>> - * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
>> + * Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved.
>> */
>>
>> #include <linux/delay.h>
>> @@ -1458,6 +1458,26 @@ int tegra_phy_xusb_utmi_port_reset(struct phy *phy)
>> }
>> EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_port_reset);
>>
>> +void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
>> +{
>> + struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
>> + struct tegra_xusb_padctl *padctl = lane->pad->padctl;
>> +
>> + if (padctl->soc->ops->utmi_pad_power_on)
>> + padctl->soc->ops->utmi_pad_power_on(phy);
>> +}
>> +EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_power_on);
>> +
>> +void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
>> +{
>> + struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
>> + struct tegra_xusb_padctl *padctl = lane->pad->padctl;
>> +
>> + if (padctl->soc->ops->utmi_pad_power_down)
>> + padctl->soc->ops->utmi_pad_power_down(phy);
>> +}
>> +EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_power_down);
>> +
>> int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
>> unsigned int port)
>> {
>> diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
>> index 034f7a2c28d6..8cfbbdbd6e0c 100644
>> --- a/drivers/phy/tegra/xusb.h
>> +++ b/drivers/phy/tegra/xusb.h
>> @@ -1,6 +1,6 @@
>> /* SPDX-License-Identifier: GPL-2.0-only */
>> /*
>> - * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
>> + * Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved.
>> * Copyright (c) 2015, Google Inc.
>> */
>>
>> @@ -412,6 +412,8 @@ struct tegra_xusb_padctl_ops {
>> unsigned int index, bool enable);
>> int (*vbus_override)(struct tegra_xusb_padctl *padctl, bool set);
>> int (*utmi_port_reset)(struct phy *phy);
>> + void (*utmi_pad_power_on)(struct phy *phy);
>> + void (*utmi_pad_power_down)(struct phy *phy);
>> };
>>
>> struct tegra_xusb_padctl_soc {
>> diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h
>> index 3a35e74cdc61..70998e6dd6fd 100644
>> --- a/include/linux/phy/tegra/xusb.h
>> +++ b/include/linux/phy/tegra/xusb.h
>> @@ -1,6 +1,6 @@
>> /* SPDX-License-Identifier: GPL-2.0-only */
>> /*
>> - * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved.
>> + * Copyright (c) 2016-2022, NVIDIA CORPORATION. All rights reserved.
>> */
>>
>> #ifndef PHY_TEGRA_XUSB_H
>> @@ -21,6 +21,8 @@ int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
>> unsigned int port, bool enable);
>> int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl,
>> bool val);
>> +void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy);
>> +void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy);
>> 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);
>> --
>> 2.17.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops
2022-09-06 2:43 ` JC Kuo
@ 2022-09-13 14:34 ` Vinod Koul
2022-09-14 2:59 ` JC Kuo
0 siblings, 1 reply; 8+ messages in thread
From: Vinod Koul @ 2022-09-13 14:34 UTC (permalink / raw)
To: JC Kuo
Cc: Jim Lin, thierry.reding, jonathanh, balbi, gregkh, bhsieh,
linux-phy, linux-tegra, linux-kernel, linux-usb
On 06-09-22, 10:43, JC Kuo wrote:
> Hi Vinod,
Please _do_ _not_ _top_ _post_
> Before the device or host is being attached, we can keep most of the
> transceivers powered down (PD=1/PD_DR=1) to minimize power consumption. At this
> stage, in .phy_power_on(), we enable only the single-ended receiver (PD_ZI=0)
> for detecting connection. Upon detecting device's or host's connection, host or
> controller driver will invoke tegra_phy_xusb_utmi_pad_power_on() to power on all
> of the transceivers (PD=0/PD_DR=0) to equip full link functionality.
Thanks for this explanation... It helps!
Just a suggestion, can this be moved into phy_init() you have detected
connection in phy_power_on(), the transceiver can be enabled in
phy_int... Would that work?
--
~Vinod
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops
2022-09-13 14:34 ` Vinod Koul
@ 2022-09-14 2:59 ` JC Kuo
2022-09-20 6:33 ` Vinod Koul
0 siblings, 1 reply; 8+ messages in thread
From: JC Kuo @ 2022-09-14 2:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Jim Lin, thierry.reding, jonathanh, balbi, gregkh, bhsieh,
linux-phy, linux-tegra, linux-kernel, linux-usb
On 9/13/22 22:34, Vinod Koul wrote:
> On 06-09-22, 10:43, JC Kuo wrote:
>> Hi Vinod,
>
> Please _do_ _not_ _top_ _post_
>
>> Before the device or host is being attached, we can keep most of the
>> transceivers powered down (PD=1/PD_DR=1) to minimize power consumption. At this
>> stage, in .phy_power_on(), we enable only the single-ended receiver (PD_ZI=0)
>> for detecting connection. Upon detecting device's or host's connection, host or
>> controller driver will invoke tegra_phy_xusb_utmi_pad_power_on() to power on all
>> of the transceivers (PD=0/PD_DR=0) to equip full link functionality.
>
> Thanks for this explanation... It helps!
>
> Just a suggestion, can this be moved into phy_init() you have detected
> connection in phy_power_on(), the transceiver can be enabled in
> phy_int... Would that work?
> That would work, too. However, because Tegra USB has separate phys for USB3 SS
and USB2, I'd like to keep the USB2 phy operations as they are now, so that USB
host and device controller drivers do not have to distinguish the phy type and
invoke different phy stubs. Furthermore, PD_ZI=0 does really power on the USB2
phy, partially.
For example:
1. in .probe(),
for_each_usb_phy {
phy_init(phy);
}
for_each_usb3_phy {
phy_power_on(phy);
};
2. upon detecting connection,
phy_power_on(the_target_usb2_phy);
Thanks,
JC
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops
2022-09-14 2:59 ` JC Kuo
@ 2022-09-20 6:33 ` Vinod Koul
0 siblings, 0 replies; 8+ messages in thread
From: Vinod Koul @ 2022-09-20 6:33 UTC (permalink / raw)
To: JC Kuo
Cc: Jim Lin, thierry.reding, jonathanh, balbi, gregkh, bhsieh,
linux-phy, linux-tegra, linux-kernel, linux-usb
On 14-09-22, 10:59, JC Kuo wrote:
> On 9/13/22 22:34, Vinod Koul wrote:
> > On 06-09-22, 10:43, JC Kuo wrote:
> > Thanks for this explanation... It helps!
> >
> > Just a suggestion, can this be moved into phy_init() you have detected
> > connection in phy_power_on(), the transceiver can be enabled in
> > phy_int... Would that work?
> > That would work, too. However, because Tegra USB has separate phys for USB3 SS
> and USB2, I'd like to keep the USB2 phy operations as they are now, so that USB
> host and device controller drivers do not have to distinguish the phy type and
> invoke different phy stubs. Furthermore, PD_ZI=0 does really power on the USB2
> phy, partially.
>
> For example:
> 1. in .probe(),
> for_each_usb_phy {
> phy_init(phy);
> }
>
> for_each_usb3_phy {
> phy_power_on(phy);
> };
>
> 2. upon detecting connection,
>
> phy_power_on(the_target_usb2_phy);
It should be always phy_init() in probe and once detection
phy_power_on()
that should be generic flow for all...
--
~Vinod
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-09-20 6:36 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-16 8:23 [PATCH v2 0/2] usb: tegra: power down UTMI pad Jim Lin
2022-08-16 8:23 ` [PATCH v2 1/2] phy: tegra: xusb: add utmi pad power on/down ops Jim Lin
2022-09-04 14:45 ` Vinod Koul
2022-09-06 2:43 ` JC Kuo
2022-09-13 14:34 ` Vinod Koul
2022-09-14 2:59 ` JC Kuo
2022-09-20 6:33 ` Vinod Koul
2022-08-16 8:23 ` [PATCH v2 2/2] usb: gadget: tegra: Reduce pad power Jim Lin
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).