drivers/phy/mediatek/phy-mtk-xfi-tphy.c

Source file repositories/reference/linux-study-clean/drivers/phy/mediatek/phy-mtk-xfi-tphy.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/mediatek/phy-mtk-xfi-tphy.c
Extension
.c
Size
14852 bytes
Lines
452
Domain
Driver Families
Bucket
drivers/phy
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 mtk_xfi_tphy {
	void __iomem		*base;
	struct device		*dev;
	struct reset_control	*reset;
	struct clk_bulk_data	clocks[MTK_XFI_TPHY_NUM_CLOCKS];
	bool			da_war;
};

/**
 * mtk_xfi_tphy_setup() - Setup phy for specified interface mode.
 * @xfi_tphy: XFI phy instance.
 * @interface: Ethernet interface mode
 *
 * The setup function is the condensed result of combining the 5 functions which
 * setup the phy in MediaTek's GPL licensed public SDK sources. They can be found
 * in mtk_sgmii.c[1] as well as mtk_usxgmii.c[2].
 *
 * Many magic values have been replaced by register and bit definitions, however,
 * that has not been possible in all cases. While the vendor driver uses a
 * sequence of 32-bit writes, here we try to only modify the actually required
 * bits.
 *
 * [1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/b72d6cba92bf9e29fb035c03052fa1e86664a25b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
 *
 * [2]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/dec96a1d9b82cdcda4a56453fd0b453d4cab4b85/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 */
static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
			       phy_interface_t interface)
{
	bool is_1g, is_2p5g, is_5g, is_10g, da_war, use_lynxi_pcs;

	/* shorthands for specific clock speeds depending on interface mode */
	is_1g = interface == PHY_INTERFACE_MODE_1000BASEX ||
		interface == PHY_INTERFACE_MODE_SGMII;
	is_2p5g = interface == PHY_INTERFACE_MODE_2500BASEX;
	is_5g = interface == PHY_INTERFACE_MODE_5GBASER;
	is_10g = interface == PHY_INTERFACE_MODE_10GBASER ||
		 interface == PHY_INTERFACE_MODE_USXGMII;

	/* Is overriding 10GBase-R tuning value required? */
	da_war = xfi_tphy->da_war && (interface == PHY_INTERFACE_MODE_10GBASER);

	/* configure input mux to either
	 *  - USXGMII PCS (64b/66b coding) for 5G/10G
	 *  - LynxI PCS (8b/10b coding) for 1G/2.5G
	 */
	use_lynxi_pcs = is_1g || is_2p5g;

	dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));

	/* Setup PLL setting */
	mtk_phy_update_bits(xfi_tphy->base + 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
	mtk_phy_update_bits(xfi_tphy->base + 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
	mtk_phy_update_bits(xfi_tphy->base + 0x2030, 0x500, is_1g ? 0x0 : 0x500);
	mtk_phy_update_bits(xfi_tphy->base + 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
	mtk_phy_update_bits(xfi_tphy->base + 0x2040, 0x340000, is_1g ? 0x200000 : 0x140000);

	/* Setup RXFE BW setting */
	mtk_phy_update_bits(xfi_tphy->base + 0x50f0, 0xc10, is_1g ? 0x410 : is_5g ? 0x800 : 0x400);
	mtk_phy_update_bits(xfi_tphy->base + 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);

	/* Setup RX CDR setting */
	mtk_phy_update_bits(xfi_tphy->base + 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
	mtk_phy_update_bits(xfi_tphy->base + 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
	mtk_phy_update_bits(xfi_tphy->base + 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
	mtk_phy_update_bits(xfi_tphy->base + 0x5078, 0xf000400, is_5g ? 0x8000000 :
									0x7000400);
	mtk_phy_update_bits(xfi_tphy->base + 0x507c, 0x5000500, is_5g ? 0x4000400 :
									0x1000100);
	mtk_phy_update_bits(xfi_tphy->base + 0x5080, 0x1410, is_1g ? 0x400 : is_5g ? 0x1010 : 0x0);
	mtk_phy_update_bits(xfi_tphy->base + 0x5084, 0x30300, is_1g ? 0x30300 :
							      is_5g ? 0x30100 :
								      0x100);
	mtk_phy_update_bits(xfi_tphy->base + 0x5088, 0x60200, is_1g ? 0x20200 :
							      is_5g ? 0x40000 :
								      0x20000);

	/* Setting RXFE adaptation range setting */
	mtk_phy_update_bits(xfi_tphy->base + 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
	mtk_phy_update_bits(xfi_tphy->base + 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
	mtk_phy_update_bits(xfi_tphy->base + 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
	mtk_phy_update_bits(xfi_tphy->base + 0x50a8, 0xee0000, is_5g ? 0x800000 :
								       0x6e0000);
	mtk_phy_update_bits(xfi_tphy->base + 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);

	if (is_10g)
		writel(0x01423342, xfi_tphy->base + 0x00f8);
	else if (is_5g)
		writel(0x00a132a1, xfi_tphy->base + 0x00f8);
	else if (is_2p5g)

Annotation

Implementation Notes