Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <singhanc@nvidia.com>
Co-developed-by: Wayne Chang <waynec@nvidia.com>
Signed-off-by: Wayne Chang <waynec@nvidia.com>
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://lore.kernel.org/r/20230111110450.24617-6-jonathanh@nvidia.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Sing-Han Chen and committed by
Vinod Koul
5c7f94f8 e5f91244

+91 -3
+1
drivers/phy/tegra/Makefile
··· 7 7 phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_210_SOC) += xusb-tegra210.o 8 8 phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_186_SOC) += xusb-tegra186.o 9 9 phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_194_SOC) += xusb-tegra186.o 10 + phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_234_SOC) += xusb-tegra186.o 10 11 obj-$(CONFIG_PHY_TEGRA194_P2U) += phy-tegra194-p2u.o
+61 -3
drivers/phy/tegra/xusb-tegra186.c
··· 89 89 #define USB2_TRK_START_TIMER(x) (((x) & 0x7f) << 12) 90 90 #define USB2_TRK_DONE_RESET_TIMER(x) (((x) & 0x7f) << 19) 91 91 #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) 92 97 93 98 #define XUSB_PADCTL_HSIC_PADX_CTL0(x) (0x300 + (x) * 0x20) 94 99 #define HSIC_PD_TX_DATA0 BIT(1) ··· 614 609 value &= ~USB2_PD_TRK; 615 610 padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); 616 611 617 - udelay(100); 612 + if (padctl->soc->poll_trk_completed) { 613 + err = padctl_readl_poll(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1, 614 + USB2_TRK_COMPLETED, USB2_TRK_COMPLETED, 100); 615 + if (err) { 616 + /* The failure with polling on trk complete will not 617 + * cause the failure of powering on the bias pad. 618 + */ 619 + dev_warn(dev, "failed to poll USB2 trk completed: %d\n", err); 620 + } 618 621 619 - clk_disable_unprepare(priv->usb2_trk_clk); 622 + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); 623 + value |= USB2_TRK_COMPLETED; 624 + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); 625 + } else { 626 + udelay(100); 627 + } 628 + 629 + if (padctl->soc->trk_hw_mode) { 630 + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL2); 631 + value |= USB2_TRK_HW_MODE; 632 + value &= ~CYA_TRK_CODE_UPDATE_ON_IDLE; 633 + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL2); 634 + } else { 635 + clk_disable_unprepare(priv->usb2_trk_clk); 636 + } 620 637 621 638 mutex_unlock(&padctl->lock); 622 639 } ··· 663 636 value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); 664 637 value |= USB2_PD_TRK; 665 638 padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); 639 + 640 + if (padctl->soc->trk_hw_mode) { 641 + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL2); 642 + value &= ~USB2_TRK_HW_MODE; 643 + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL2); 644 + clk_disable_unprepare(priv->usb2_trk_clk); 645 + } 666 646 667 647 mutex_unlock(&padctl->lock); 668 648 } ··· 1593 1559 EXPORT_SYMBOL_GPL(tegra186_xusb_padctl_soc); 1594 1560 #endif 1595 1561 1596 - #if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) 1562 + #if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \ 1563 + IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) 1597 1564 static const char * const tegra194_xusb_padctl_supply_names[] = { 1598 1565 "avdd-usb", 1599 1566 "vclamp-usb", ··· 1650 1615 .supply_names = tegra194_xusb_padctl_supply_names, 1651 1616 .num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names), 1652 1617 .supports_gen2 = true, 1618 + .poll_trk_completed = true, 1653 1619 }; 1654 1620 EXPORT_SYMBOL_GPL(tegra194_xusb_padctl_soc); 1621 + 1622 + const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc = { 1623 + .num_pads = ARRAY_SIZE(tegra194_pads), 1624 + .pads = tegra194_pads, 1625 + .ports = { 1626 + .usb2 = { 1627 + .ops = &tegra186_usb2_port_ops, 1628 + .count = 4, 1629 + }, 1630 + .usb3 = { 1631 + .ops = &tegra186_usb3_port_ops, 1632 + .count = 4, 1633 + }, 1634 + }, 1635 + .ops = &tegra186_xusb_padctl_ops, 1636 + .supply_names = tegra194_xusb_padctl_supply_names, 1637 + .num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names), 1638 + .supports_gen2 = true, 1639 + .poll_trk_completed = true, 1640 + .trk_hw_mode = true, 1641 + }; 1642 + EXPORT_SYMBOL_GPL(tegra234_xusb_padctl_soc); 1655 1643 #endif 1656 1644 1657 1645 MODULE_AUTHOR("JC Kuo <jckuo@nvidia.com>");
+6
drivers/phy/tegra/xusb.c
··· 72 72 .data = &tegra194_xusb_padctl_soc, 73 73 }, 74 74 #endif 75 + #if defined(CONFIG_ARCH_TEGRA_234_SOC) 76 + { 77 + .compatible = "nvidia,tegra234-xusb-padctl", 78 + .data = &tegra234_xusb_padctl_soc, 79 + }, 80 + #endif 75 81 { } 76 82 }; 77 83 MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match);
+23
drivers/phy/tegra/xusb.h
··· 8 8 #define __PHY_TEGRA_XUSB_H 9 9 10 10 #include <linux/io.h> 11 + #include <linux/iopoll.h> 11 12 #include <linux/mutex.h> 12 13 #include <linux/workqueue.h> 13 14 ··· 432 431 unsigned int num_supplies; 433 432 bool supports_gen2; 434 433 bool need_fake_usb3_port; 434 + bool poll_trk_completed; 435 + bool trk_hw_mode; 435 436 }; 436 437 437 438 struct tegra_xusb_padctl { ··· 476 473 return value; 477 474 } 478 475 476 + static inline u32 padctl_readl_poll(struct tegra_xusb_padctl *padctl, 477 + unsigned long offset, u32 val, u32 mask, 478 + int us) 479 + { 480 + u32 regval; 481 + int err; 482 + 483 + err = readl_poll_timeout(padctl->regs + offset, regval, 484 + (regval & mask) == val, 1, us); 485 + if (err) { 486 + dev_err(padctl->dev, "%08lx poll timeout > %08x\n", offset, 487 + regval); 488 + } 489 + 490 + return err; 491 + } 492 + 479 493 struct tegra_xusb_lane *tegra_xusb_find_lane(struct tegra_xusb_padctl *padctl, 480 494 const char *name, 481 495 unsigned int index); ··· 508 488 #endif 509 489 #if defined(CONFIG_ARCH_TEGRA_194_SOC) 510 490 extern const struct tegra_xusb_padctl_soc tegra194_xusb_padctl_soc; 491 + #endif 492 + #if defined(CONFIG_ARCH_TEGRA_234_SOC) 493 + extern const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc; 511 494 #endif 512 495 513 496 #endif /* __PHY_TEGRA_XUSB_H */