lkml.org 
[lkml]   [2022]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    SubjectRe: [PATCH v3 11/13] phy: tegra: xusb: Add Tegra234 support
    From


    On 14/11/2022 12:40, Wayne Chang wrote:
    > From: Sing-Han Chen <singhanc@nvidia.com>
    >
    > Add support for the XUSB pad controller found on Tegra234 SoCs. It is
    > mostly similar to the same IP found on Tegra194, because most of
    > the Tegra234 XUSB PADCTL registers definition and programming sequence
    > are the same as Tegra194, Tegra234 XUSB PADCTL can share the same
    > driver with Tegra186 and Tegra194 XUSB PADCTL.
    >
    > Introduce a new feature, USB2 HW tracking, for Tegra234.
    > The feature is to enable HW periodical PAD tracking which measure
    > and capture the electric parameters of USB2.0 PAD.
    >
    > Signed-off-by: Sing-Han Chen <singhanc@nvidia.com>
    > Co-developed-by: Wayne Chang <waynec@nvidia.com>
    > Signed-off-by: Wayne Chang <waynec@nvidia.com>
    > ---
    > V2 -> V3:nothing has changed
    > V1 -> V2:remove atomic and the helper in padctl_readl_poll func.
    > drivers/phy/tegra/Makefile | 1 +
    > drivers/phy/tegra/xusb-tegra186.c | 64 +++++++++++++++++++++++++++++--
    > drivers/phy/tegra/xusb.c | 6 +++
    > drivers/phy/tegra/xusb.h | 22 +++++++++++
    > 4 files changed, 90 insertions(+), 3 deletions(-)
    >
    > diff --git a/drivers/phy/tegra/Makefile b/drivers/phy/tegra/Makefile
    > index 89b84067cb4c..eeeea72de117 100644
    > --- a/drivers/phy/tegra/Makefile
    > +++ b/drivers/phy/tegra/Makefile
    > @@ -7,4 +7,5 @@ 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
    > phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_194_SOC) += xusb-tegra186.o
    > +phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_234_SOC) += xusb-tegra186.o
    > obj-$(CONFIG_PHY_TEGRA194_P2U) += phy-tegra194-p2u.o
    > diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
    > index f121b4ffbbfd..5ae3cea19c84 100644
    > --- a/drivers/phy/tegra/xusb-tegra186.c
    > +++ b/drivers/phy/tegra/xusb-tegra186.c
    > @@ -89,6 +89,11 @@
    > #define USB2_TRK_START_TIMER(x) (((x) & 0x7f) << 12)
    > #define USB2_TRK_DONE_RESET_TIMER(x) (((x) & 0x7f) << 19)
    > #define USB2_PD_TRK BIT(26)
    > +#define USB2_TRK_COMPLETED BIT(31)
    > +
    > +#define XUSB_PADCTL_USB2_BIAS_PAD_CTL2 0x28c
    > +#define USB2_TRK_HW_MODE BIT(0)
    > +#define CYA_TRK_CODE_UPDATE_ON_IDLE BIT(31)
    >
    > #define XUSB_PADCTL_HSIC_PADX_CTL0(x) (0x300 + (x) * 0x20)
    > #define HSIC_PD_TX_DATA0 BIT(1)
    > @@ -609,9 +614,31 @@ static void tegra186_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl)
    > value &= ~USB2_PD_TRK;
    > padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
    >
    > - udelay(100);
    > + if (padctl->soc->poll_trk_completed) {
    > + err = padctl_readl_poll(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1,
    > + USB2_TRK_COMPLETED, USB2_TRK_COMPLETED, 100);
    > + if (err) {
    > + /* The failure with polling on trk complete will not
    > + * cause the failure of powering on the bias pad.
    > + */
    > + dev_warn(dev, "failed to poll USB2 trk completed: %d\n", err);
    > + }
    >
    > - clk_disable_unprepare(priv->usb2_trk_clk);
    > + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
    > + value |= USB2_TRK_COMPLETED;
    > + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
    > + } else {
    > + udelay(100);
    > + }
    > +
    > + if (padctl->soc->trk_hw_mode) {
    > + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL2);
    > + value |= USB2_TRK_HW_MODE;
    > + value &= ~CYA_TRK_CODE_UPDATE_ON_IDLE;
    > + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL2);
    > + } else {
    > + clk_disable_unprepare(priv->usb2_trk_clk);
    > + }
    >
    > mutex_unlock(&padctl->lock);
    > }
    > @@ -637,6 +664,13 @@ static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl)
    > value |= USB2_PD_TRK;
    > padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
    >
    > + if (padctl->soc->trk_hw_mode) {
    > + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL2);
    > + value &= ~USB2_TRK_HW_MODE;
    > + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL2);
    > + clk_disable_unprepare(priv->usb2_trk_clk);
    > + }
    > +
    > mutex_unlock(&padctl->lock);
    > }
    >
    > @@ -1560,7 +1594,8 @@ const struct tegra_xusb_padctl_soc tegra186_xusb_padctl_soc = {
    > EXPORT_SYMBOL_GPL(tegra186_xusb_padctl_soc);
    > #endif
    >
    > -#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC)
    > +#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
    > + IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
    > static const char * const tegra194_xusb_padctl_supply_names[] = {
    > "avdd-usb",
    > "vclamp-usb",
    > @@ -1616,8 +1651,31 @@ const struct tegra_xusb_padctl_soc tegra194_xusb_padctl_soc = {
    > .supply_names = tegra194_xusb_padctl_supply_names,
    > .num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names),
    > .supports_gen2 = true,
    > + .poll_trk_completed = true,
    > };
    > EXPORT_SYMBOL_GPL(tegra194_xusb_padctl_soc);
    > +
    > +const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc = {
    > + .num_pads = ARRAY_SIZE(tegra194_pads),
    > + .pads = tegra194_pads,
    > + .ports = {
    > + .usb2 = {
    > + .ops = &tegra186_usb2_port_ops,
    > + .count = 4,
    > + },
    > + .usb3 = {
    > + .ops = &tegra186_usb3_port_ops,
    > + .count = 4,
    > + },
    > + },
    > + .ops = &tegra186_xusb_padctl_ops,
    > + .supply_names = tegra194_xusb_padctl_supply_names,
    > + .num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names),
    > + .supports_gen2 = true,
    > + .poll_trk_completed = true,
    > + .trk_hw_mode = true,
    > +};
    > +EXPORT_SYMBOL_GPL(tegra234_xusb_padctl_soc);
    > #endif
    >
    > MODULE_AUTHOR("JC Kuo <jckuo@nvidia.com>");
    > diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
    > index dce45fbbd699..c2f160628552 100644
    > --- a/drivers/phy/tegra/xusb.c
    > +++ b/drivers/phy/tegra/xusb.c
    > @@ -71,6 +71,12 @@ static const struct of_device_id tegra_xusb_padctl_of_match[] = {
    > .compatible = "nvidia,tegra194-xusb-padctl",
    > .data = &tegra194_xusb_padctl_soc,
    > },
    > +#endif
    > +#if defined(CONFIG_ARCH_TEGRA_234_SOC)
    > + {
    > + .compatible = "nvidia,tegra234-xusb-padctl",
    > + .data = &tegra234_xusb_padctl_soc,
    > + },
    > #endif
    > { }
    > };
    > diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
    > index 8cfbbdbd6e0c..a21826c730d7 100644
    > --- a/drivers/phy/tegra/xusb.h
    > +++ b/drivers/phy/tegra/xusb.h
    > @@ -8,6 +8,7 @@
    > #define __PHY_TEGRA_XUSB_H
    >
    > #include <linux/io.h>
    > +#include <linux/iopoll.h>
    > #include <linux/mutex.h>
    > #include <linux/workqueue.h>
    >
    > @@ -433,6 +434,8 @@ struct tegra_xusb_padctl_soc {
    > unsigned int num_supplies;
    > bool supports_gen2;
    > bool need_fake_usb3_port;
    > + bool poll_trk_completed;
    > + bool trk_hw_mode;
    > };
    >
    > struct tegra_xusb_padctl {
    > @@ -475,6 +478,22 @@ static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
    > return value;
    > }
    >
    > +static inline u32 padctl_readl_poll(struct tegra_xusb_padctl *padctl,
    > + unsigned long offset, u32 val, u32 mask, int us)
    > +{
    > + u32 regval;
    > + int err;
    > +
    > + err = readl_poll_timeout(padctl->regs + offset, regval,
    > + (regval & mask) == val, 1, us);
    > + if (err) {
    > + dev_err(padctl->dev, "%08lx poll timeout > %08x\n", offset,
    > + regval);
    > + }
    > +
    > + return err;
    > +}
    > +
    > struct tegra_xusb_lane *tegra_xusb_find_lane(struct tegra_xusb_padctl *padctl,
    > const char *name,
    > unsigned int index);
    > @@ -491,5 +510,8 @@ extern const struct tegra_xusb_padctl_soc tegra186_xusb_padctl_soc;
    > #if defined(CONFIG_ARCH_TEGRA_194_SOC)
    > extern const struct tegra_xusb_padctl_soc tegra194_xusb_padctl_soc;
    > #endif
    > +#if defined(CONFIG_ARCH_TEGRA_234_SOC)
    > +extern const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc;
    > +#endif
    >
    > #endif /* __PHY_TEGRA_XUSB_H */


    Reviewed-by: Jon Hunter <jonathanh@nvidia.com>

    Thanks
    Jon
    --
    nvpublic

    \
     
     \ /
      Last update: 2022-11-15 13:24    [W:4.287 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site