drivers/phy/tegra/xusb-tegra210.c

Source file repositories/reference/linux-study-clean/drivers/phy/tegra/xusb-tegra210.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/tegra/xusb-tegra210.c
Extension
.c
Size
102571 bytes
Lines
3300
Domain
Driver Families
Bucket
drivers/phy
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tegra210_xusb_fuse_calibration {
	u32 hs_curr_level[4];
	u32 hs_term_range_adj;
	u32 rpd_ctrl;
};

struct tegra210_xusb_padctl_context {
	u32 usb2_pad_mux;
	u32 usb2_port_cap;
	u32 ss_port_map;
	u32 usb3_pad_mux;
};

struct tegra210_xusb_padctl {
	struct tegra_xusb_padctl base;
	struct regmap *regmap;

	struct tegra210_xusb_fuse_calibration fuse;
	struct tegra210_xusb_padctl_context context;
};

static inline struct tegra210_xusb_padctl *
to_tegra210_xusb_padctl(struct tegra_xusb_padctl *padctl)
{
	return container_of(padctl, struct tegra210_xusb_padctl, base);
}

static const struct tegra_xusb_lane_map tegra210_usb3_map[] = {
	{ 0, "pcie", 6 },
	{ 1, "pcie", 5 },
	{ 2, "pcie", 0 },
	{ 2, "pcie", 3 },
	{ 3, "pcie", 4 },
	{ 3, "sata", 0 },
	{ 0, NULL,   0 }
};

static int tegra210_usb3_lane_map(struct tegra_xusb_lane *lane)
{
	const struct tegra_xusb_lane_map *map;

	for (map = tegra210_usb3_map; map->type; map++) {
		if (map->index == lane->index &&
		    strcmp(map->type, lane->pad->soc->name) == 0) {
			dev_dbg(lane->pad->padctl->dev, "lane = %s map to port = usb3-%d\n",
				lane->pad->soc->lanes[lane->index].name, map->port);
			return map->port;
		}
	}

	return -EINVAL;
}

/* must be called under padctl->lock */
static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl)
{
	struct tegra_xusb_pcie_pad *pcie = to_pcie_pad(padctl->pcie);
	unsigned long timeout;
	u32 value;
	unsigned int i;
	int err;

	if (pcie->enable)
		return 0;

	err = clk_prepare_enable(pcie->pll);
	if (err < 0)
		return err;

	if (tegra210_plle_hw_sequence_is_enabled())
		goto skip_pll_init;

	err = reset_control_deassert(pcie->rst);
	if (err < 0)
		goto disable;

	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
	value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK <<
		   XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT);
	value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_VAL <<
		 XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT;
	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);

	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
	value &= ~(XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_MASK <<
		   XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT);
	value |= XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_VAL <<
		 XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT;
	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL5);

Annotation

Implementation Notes