Skip to content

Commit d8163a3

Browse files
Sing-Han Chengregkh
authored andcommitted
phy: tegra: xusb: Add Tegra234 support
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 <[email protected]> Co-developed-by: Wayne Chang <[email protected]> Signed-off-by: Wayne Chang <[email protected]> Signed-off-by: Jon Hunter <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 71d9e89 commit d8163a3

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
lines changed

drivers/phy/tegra/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_132_SOC) += xusb-tegra124.o
77
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_210_SOC) += xusb-tegra210.o
88
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_186_SOC) += xusb-tegra186.o
99
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_194_SOC) += xusb-tegra186.o
10+
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_234_SOC) += xusb-tegra186.o
1011
obj-$(CONFIG_PHY_TEGRA194_P2U) += phy-tegra194-p2u.o

drivers/phy/tegra/xusb-tegra186.c

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@
8989
#define USB2_TRK_START_TIMER(x) (((x) & 0x7f) << 12)
9090
#define USB2_TRK_DONE_RESET_TIMER(x) (((x) & 0x7f) << 19)
9191
#define USB2_PD_TRK BIT(26)
92+
#define USB2_TRK_COMPLETED BIT(31)
93+
94+
#define XUSB_PADCTL_USB2_BIAS_PAD_CTL2 0x28c
95+
#define USB2_TRK_HW_MODE BIT(0)
96+
#define CYA_TRK_CODE_UPDATE_ON_IDLE BIT(31)
9297

9398
#define XUSB_PADCTL_HSIC_PADX_CTL0(x) (0x300 + (x) * 0x20)
9499
#define HSIC_PD_TX_DATA0 BIT(1)
@@ -609,9 +614,31 @@ static void tegra186_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl)
609614
value &= ~USB2_PD_TRK;
610615
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
611616

612-
udelay(100);
617+
if (padctl->soc->poll_trk_completed) {
618+
err = padctl_readl_poll(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1,
619+
USB2_TRK_COMPLETED, USB2_TRK_COMPLETED, 100);
620+
if (err) {
621+
/* The failure with polling on trk complete will not
622+
* cause the failure of powering on the bias pad.
623+
*/
624+
dev_warn(dev, "failed to poll USB2 trk completed: %d\n", err);
625+
}
613626

614-
clk_disable_unprepare(priv->usb2_trk_clk);
627+
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
628+
value |= USB2_TRK_COMPLETED;
629+
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
630+
} else {
631+
udelay(100);
632+
}
633+
634+
if (padctl->soc->trk_hw_mode) {
635+
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL2);
636+
value |= USB2_TRK_HW_MODE;
637+
value &= ~CYA_TRK_CODE_UPDATE_ON_IDLE;
638+
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL2);
639+
} else {
640+
clk_disable_unprepare(priv->usb2_trk_clk);
641+
}
615642

616643
mutex_unlock(&padctl->lock);
617644
}
@@ -637,6 +664,13 @@ static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl)
637664
value |= USB2_PD_TRK;
638665
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
639666

667+
if (padctl->soc->trk_hw_mode) {
668+
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL2);
669+
value &= ~USB2_TRK_HW_MODE;
670+
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL2);
671+
clk_disable_unprepare(priv->usb2_trk_clk);
672+
}
673+
640674
mutex_unlock(&padctl->lock);
641675
}
642676

@@ -1559,7 +1593,8 @@ const struct tegra_xusb_padctl_soc tegra186_xusb_padctl_soc = {
15591593
EXPORT_SYMBOL_GPL(tegra186_xusb_padctl_soc);
15601594
#endif
15611595

1562-
#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC)
1596+
#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
1597+
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
15631598
static const char * const tegra194_xusb_padctl_supply_names[] = {
15641599
"avdd-usb",
15651600
"vclamp-usb",
@@ -1615,8 +1650,31 @@ const struct tegra_xusb_padctl_soc tegra194_xusb_padctl_soc = {
16151650
.supply_names = tegra194_xusb_padctl_supply_names,
16161651
.num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names),
16171652
.supports_gen2 = true,
1653+
.poll_trk_completed = true,
16181654
};
16191655
EXPORT_SYMBOL_GPL(tegra194_xusb_padctl_soc);
1656+
1657+
const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc = {
1658+
.num_pads = ARRAY_SIZE(tegra194_pads),
1659+
.pads = tegra194_pads,
1660+
.ports = {
1661+
.usb2 = {
1662+
.ops = &tegra186_usb2_port_ops,
1663+
.count = 4,
1664+
},
1665+
.usb3 = {
1666+
.ops = &tegra186_usb3_port_ops,
1667+
.count = 4,
1668+
},
1669+
},
1670+
.ops = &tegra186_xusb_padctl_ops,
1671+
.supply_names = tegra194_xusb_padctl_supply_names,
1672+
.num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names),
1673+
.supports_gen2 = true,
1674+
.poll_trk_completed = true,
1675+
.trk_hw_mode = true,
1676+
};
1677+
EXPORT_SYMBOL_GPL(tegra234_xusb_padctl_soc);
16201678
#endif
16211679

16221680
MODULE_AUTHOR("JC Kuo <[email protected]>");

drivers/phy/tegra/xusb.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ static const struct of_device_id tegra_xusb_padctl_of_match[] = {
7171
.compatible = "nvidia,tegra194-xusb-padctl",
7272
.data = &tegra194_xusb_padctl_soc,
7373
},
74+
#endif
75+
#if defined(CONFIG_ARCH_TEGRA_234_SOC)
76+
{
77+
.compatible = "nvidia,tegra234-xusb-padctl",
78+
.data = &tegra234_xusb_padctl_soc,
79+
},
7480
#endif
7581
{ }
7682
};

drivers/phy/tegra/xusb.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define __PHY_TEGRA_XUSB_H
99

1010
#include <linux/io.h>
11+
#include <linux/iopoll.h>
1112
#include <linux/mutex.h>
1213
#include <linux/workqueue.h>
1314

@@ -431,6 +432,8 @@ struct tegra_xusb_padctl_soc {
431432
unsigned int num_supplies;
432433
bool supports_gen2;
433434
bool need_fake_usb3_port;
435+
bool poll_trk_completed;
436+
bool trk_hw_mode;
434437
};
435438

436439
struct tegra_xusb_padctl {
@@ -473,6 +476,23 @@ static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
473476
return value;
474477
}
475478

479+
static inline u32 padctl_readl_poll(struct tegra_xusb_padctl *padctl,
480+
unsigned long offset, u32 val, u32 mask,
481+
int us)
482+
{
483+
u32 regval;
484+
int err;
485+
486+
err = readl_poll_timeout(padctl->regs + offset, regval,
487+
(regval & mask) == val, 1, us);
488+
if (err) {
489+
dev_err(padctl->dev, "%08lx poll timeout > %08x\n", offset,
490+
regval);
491+
}
492+
493+
return err;
494+
}
495+
476496
struct tegra_xusb_lane *tegra_xusb_find_lane(struct tegra_xusb_padctl *padctl,
477497
const char *name,
478498
unsigned int index);
@@ -489,5 +509,8 @@ extern const struct tegra_xusb_padctl_soc tegra186_xusb_padctl_soc;
489509
#if defined(CONFIG_ARCH_TEGRA_194_SOC)
490510
extern const struct tegra_xusb_padctl_soc tegra194_xusb_padctl_soc;
491511
#endif
512+
#if defined(CONFIG_ARCH_TEGRA_234_SOC)
513+
extern const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc;
514+
#endif
492515

493516
#endif /* __PHY_TEGRA_XUSB_H */

0 commit comments

Comments
 (0)