drivers/phy/phy-airoha-pcie.c

Source file repositories/reference/linux-study-clean/drivers/phy/phy-airoha-pcie.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/phy-airoha-pcie.c
Extension
.c
Size
50240 bytes
Lines
1291
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 airoha_pcie_phy {
	struct device *dev;
	struct phy *phy;
	void __iomem *csr_2l;
	void __iomem *pma0;
	void __iomem *pma1;
	void __iomem *p0_xr_dtime;
	void __iomem *p1_xr_dtime;
	void __iomem *rx_aeq;
};

static void airoha_phy_clear_bits(void __iomem *reg, u32 mask)
{
	u32 val = readl(reg) & ~mask;

	writel(val, reg);
}

static void airoha_phy_set_bits(void __iomem *reg, u32 mask)
{
	u32 val = readl(reg) | mask;

	writel(val, reg);
}

static void airoha_phy_update_bits(void __iomem *reg, u32 mask, u32 val)
{
	u32 tmp = readl(reg);

	tmp &= ~mask;
	tmp |= val & mask;
	writel(tmp, reg);
}

#define airoha_phy_update_field(reg, mask, val)					\
	do {									\
		BUILD_BUG_ON_MSG(!__builtin_constant_p((mask)),			\
				 "mask is not constant");			\
		airoha_phy_update_bits((reg), (mask),				\
				       FIELD_PREP((mask), (val)));		\
	} while (0)

#define airoha_phy_csr_2l_clear_bits(pcie_phy, reg, mask)			\
	airoha_phy_clear_bits((pcie_phy)->csr_2l + (reg), (mask))
#define airoha_phy_csr_2l_set_bits(pcie_phy, reg, mask)				\
	airoha_phy_set_bits((pcie_phy)->csr_2l + (reg), (mask))
#define airoha_phy_csr_2l_update_field(pcie_phy, reg, mask, val)		\
	airoha_phy_update_field((pcie_phy)->csr_2l + (reg), (mask), (val))
#define airoha_phy_pma0_clear_bits(pcie_phy, reg, mask)				\
	airoha_phy_clear_bits((pcie_phy)->pma0 + (reg), (mask))
#define airoha_phy_pma1_clear_bits(pcie_phy, reg, mask)				\
	airoha_phy_clear_bits((pcie_phy)->pma1 + (reg), (mask))
#define airoha_phy_pma0_set_bits(pcie_phy, reg, mask)				\
	airoha_phy_set_bits((pcie_phy)->pma0 + (reg), (mask))
#define airoha_phy_pma1_set_bits(pcie_phy, reg, mask)				\
	airoha_phy_set_bits((pcie_phy)->pma1 + (reg), (mask))
#define airoha_phy_pma0_update_field(pcie_phy, reg, mask, val)			\
	airoha_phy_update_field((pcie_phy)->pma0 + (reg), (mask), (val))
#define airoha_phy_pma1_update_field(pcie_phy, reg, mask, val)			\
	airoha_phy_update_field((pcie_phy)->pma1 + (reg), (mask), (val))

static void
airoha_phy_init_lane0_rx_fw_pre_calib(struct airoha_pcie_phy *pcie_phy,
				      enum airoha_pcie_port_gen gen)
{
	u32 fl_out_target = gen == PCIE_PORT_GEN3 ? 41600 : 41941;
	u32 lock_cyclecnt = gen == PCIE_PORT_GEN3 ? 26000 : 32767;
	u32 pr_idac, val, cdr_pr_idac_tmp = 0;
	int i;

	airoha_phy_pma0_set_bits(pcie_phy,
				 REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1,
				 PCIE_LCPLL_MAN_PWDB);
	airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2,
				     PCIE_LOCK_TARGET_BEG,
				     fl_out_target - 100);
	airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2,
				     PCIE_LOCK_TARGET_END,
				     fl_out_target + 100);
	airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1,
				     PCIE_PLL_FT_LOCK_CYCLECNT, lock_cyclecnt);
	airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4,
				     PCIE_LOCK_LOCKTH, 0x3);
	airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3,
				     PCIE_UNLOCK_TARGET_BEG,
				     fl_out_target - 100);
	airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3,
				     PCIE_UNLOCK_TARGET_END,
				     fl_out_target + 100);
	airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1,

Annotation

Implementation Notes