drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
Extension
.c
Size
12111 bytes
Lines
419
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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 tegra_mgbe {
	struct device *dev;

	struct clk_bulk_data *clks;

	struct reset_control *rst_mac;
	struct reset_control *rst_pcs;

	u32 iommu_sid;

	void __iomem *hv;
	void __iomem *regs;
	void __iomem *xpcs;

	struct mii_bus *mii;
};

#define XPCS_WRAP_UPHY_RX_CONTROL 0x801c
#define XPCS_WRAP_UPHY_RX_CONTROL_RX_SW_OVRD BIT(31)
#define XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY BIT(10)
#define XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET BIT(9)
#define XPCS_WRAP_UPHY_RX_CONTROL_RX_CAL_EN BIT(8)
#define XPCS_WRAP_UPHY_RX_CONTROL_RX_SLEEP (BIT(7) | BIT(6))
#define XPCS_WRAP_UPHY_RX_CONTROL_AUX_RX_IDDQ BIT(5)
#define XPCS_WRAP_UPHY_RX_CONTROL_RX_IDDQ BIT(4)
#define XPCS_WRAP_UPHY_RX_CONTROL_RX_DATA_EN BIT(0)
#define XPCS_WRAP_UPHY_HW_INIT_CTRL 0x8020
#define XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN BIT(0)
#define XPCS_WRAP_UPHY_HW_INIT_CTRL_RX_EN BIT(2)
#define XPCS_WRAP_UPHY_STATUS 0x8044
#define XPCS_WRAP_UPHY_STATUS_TX_P_UP BIT(0)
#define XPCS_WRAP_IRQ_STATUS 0x8050
#define XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS BIT(6)

#define XPCS_REG_ADDR_SHIFT 10
#define XPCS_REG_ADDR_MASK 0x1fff
#define XPCS_ADDR 0x3fc

#define MGBE_WRAP_COMMON_INTR_ENABLE	0x8704
#define MAC_SBD_INTR			BIT(2)
#define MGBE_WRAP_AXI_ASID0_CTRL	0x8400

static int __maybe_unused tegra_mgbe_suspend(struct device *dev)
{
	struct tegra_mgbe *mgbe = get_stmmac_bsp_priv(dev);
	int err;

	err = stmmac_suspend(dev);
	if (err)
		return err;

	clk_bulk_disable_unprepare(ARRAY_SIZE(mgbe_clks), mgbe->clks);

	return reset_control_assert(mgbe->rst_mac);
}

static int __maybe_unused tegra_mgbe_resume(struct device *dev)
{
	struct tegra_mgbe *mgbe = get_stmmac_bsp_priv(dev);
	u32 value;
	int err;

	err = clk_bulk_prepare_enable(ARRAY_SIZE(mgbe_clks), mgbe->clks);
	if (err < 0)
		return err;

	err = reset_control_deassert(mgbe->rst_mac);
	if (err < 0)
		return err;

	/* Enable common interrupt at wrapper level */
	writel(MAC_SBD_INTR, mgbe->regs + MGBE_WRAP_COMMON_INTR_ENABLE);

	/* Program SID */
	writel(mgbe->iommu_sid, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL);

	value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_STATUS);
	if ((value & XPCS_WRAP_UPHY_STATUS_TX_P_UP) == 0) {
		value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_HW_INIT_CTRL);
		value |= XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN;
		writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_HW_INIT_CTRL);
	}

	err = readl_poll_timeout(mgbe->xpcs + XPCS_WRAP_UPHY_HW_INIT_CTRL, value,
				 (value & XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN) == 0,
				 500, 500 * 2000);
	if (err < 0) {
		dev_err(mgbe->dev, "timeout waiting for TX lane to become enabled\n");
		clk_bulk_disable_unprepare(ARRAY_SIZE(mgbe_clks), mgbe->clks);
		return err;

Annotation

Implementation Notes