| // SPDX-License-Identifier: GPL-2.0-only | |
| /* | |
| * Copyright (c) 2024 AIROHA Inc | |
| * Author: Lorenzo Bianconi <lorenzo@kernel.org> | |
| */ | |
| #include <linux/bitfield.h> | |
| #include <linux/delay.h> | |
| #include <linux/io.h> | |
| #include <linux/module.h> | |
| #include <linux/of.h> | |
| #include <linux/phy/phy.h> | |
| #include <linux/platform_device.h> | |
| #include <linux/slab.h> | |
| #include "phy-airoha-pcie-regs.h" | |
| #define LEQ_LEN_CTRL_MAX_VAL 7 | |
| #define FREQ_LOCK_MAX_ATTEMPT 10 | |
| /* PCIe-PHY initialization time in ms needed by the hw to complete */ | |
| #define PHY_HW_INIT_TIME_MS 30 | |
| enum airoha_pcie_port_gen { | |
| PCIE_PORT_GEN1 = 1, | |
| PCIE_PORT_GEN2, | |
| PCIE_PORT_GEN3, | |
| }; | |
| /** | |
| * struct airoha_pcie_phy - PCIe phy driver main structure | |
| * @dev: pointer to device | |
| * @phy: pointer to generic phy | |
| * @csr_2l: Analogic lane IO mapped register base address | |
| * @pma0: IO mapped register base address of PMA0-PCIe | |
| * @pma1: IO mapped register base address of PMA1-PCIe | |
| * @p0_xr_dtime: IO mapped register base address of port0 Tx-Rx detection time | |
| * @p1_xr_dtime: IO mapped register base address of port1 Tx-Rx detection time | |
| * @rx_aeq: IO mapped register base address of Rx AEQ training | |
| */ | |
| 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, | |
| PCIE_PLL_FT_UNLOCK_CYCLECNT, | |
| lock_cyclecnt); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_UNLOCK_LOCKTH, 0x3); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_INJ_MODE, | |
| CSR_2L_PXP_CDR0_INJ_FORCE_OFF); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, | |
| PCIE_FORCE_DA_PXP_CDR_PR_PWDB); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, | |
| PCIE_FORCE_DA_PXP_CDR_PR_PWDB); | |
| for (i = 0; i < LEQ_LEN_CTRL_MAX_VAL; i++) { | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_DA_PXP_CDR_PR_IDAC, i << 8); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN); | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN, 0x3); | |
| usleep_range(10000, 15000); | |
| val = FIELD_GET(PCIE_RO_FL_OUT, | |
| readl(pcie_phy->pma0 + | |
| REG_PCIE_PMA_RO_RX_FREQDET)); | |
| if (val > fl_out_target) | |
| cdr_pr_idac_tmp = i << 8; | |
| } | |
| for (i = LEQ_LEN_CTRL_MAX_VAL; i >= 0; i--) { | |
| pr_idac = cdr_pr_idac_tmp | (0x1 << i); | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_DA_PXP_CDR_PR_IDAC, pr_idac); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN); | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN, 0x3); | |
| usleep_range(10000, 15000); | |
| val = FIELD_GET(PCIE_RO_FL_OUT, | |
| readl(pcie_phy->pma0 + | |
| REG_PCIE_PMA_RO_RX_FREQDET)); | |
| if (val < fl_out_target) | |
| pr_idac &= ~(0x1 << i); | |
| cdr_pr_idac_tmp = pr_idac; | |
| } | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_DA_PXP_CDR_PR_IDAC, | |
| cdr_pr_idac_tmp); | |
| for (i = 0; i < FREQ_LOCK_MAX_ATTEMPT; i++) { | |
| u32 val; | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN); | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN, 0x3); | |
| usleep_range(10000, 15000); | |
| val = readl(pcie_phy->pma0 + REG_PCIE_PMA_RO_RX_FREQDET); | |
| if (val & PCIE_RO_FBCK_LOCK) | |
| break; | |
| } | |
| /* turn off force mode and update band values */ | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_INJ_MODE, | |
| CSR_2L_PXP_CDR0_INJ_FORCE_OFF); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); | |
| if (gen == PCIE_PORT_GEN3) { | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_DIG_RESERVE_14, | |
| PCIE_FLL_IDAC_PCIEG3, | |
| cdr_pr_idac_tmp); | |
| } else { | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_DIG_RESERVE_13, | |
| PCIE_FLL_IDAC_PCIEG1, | |
| cdr_pr_idac_tmp); | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_DIG_RESERVE_13, | |
| PCIE_FLL_IDAC_PCIEG2, | |
| cdr_pr_idac_tmp); | |
| } | |
| } | |
| static void | |
| airoha_phy_init_lane1_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_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1, | |
| PCIE_LCPLL_MAN_PWDB); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, | |
| PCIE_LOCK_TARGET_BEG, | |
| fl_out_target - 100); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, | |
| PCIE_LOCK_TARGET_END, | |
| fl_out_target + 100); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, | |
| PCIE_PLL_FT_LOCK_CYCLECNT, lock_cyclecnt); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_LOCK_LOCKTH, 0x3); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, | |
| PCIE_UNLOCK_TARGET_BEG, | |
| fl_out_target - 100); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, | |
| PCIE_UNLOCK_TARGET_END, | |
| fl_out_target + 100); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, | |
| PCIE_PLL_FT_UNLOCK_CYCLECNT, | |
| lock_cyclecnt); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_UNLOCK_LOCKTH, 0x3); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_INJ_MODE, | |
| CSR_2L_PXP_CDR1_INJ_FORCE_OFF); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, | |
| PCIE_FORCE_DA_PXP_CDR_PR_PWDB); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, | |
| PCIE_FORCE_DA_PXP_CDR_PR_PWDB); | |
| for (i = 0; i < LEQ_LEN_CTRL_MAX_VAL; i++) { | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_DA_PXP_CDR_PR_IDAC, i << 8); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN); | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN, 0x3); | |
| usleep_range(10000, 15000); | |
| val = FIELD_GET(PCIE_RO_FL_OUT, | |
| readl(pcie_phy->pma1 + | |
| REG_PCIE_PMA_RO_RX_FREQDET)); | |
| if (val > fl_out_target) | |
| cdr_pr_idac_tmp = i << 8; | |
| } | |
| for (i = LEQ_LEN_CTRL_MAX_VAL; i >= 0; i--) { | |
| pr_idac = cdr_pr_idac_tmp | (0x1 << i); | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_DA_PXP_CDR_PR_IDAC, pr_idac); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN); | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN, 0x3); | |
| usleep_range(10000, 15000); | |
| val = FIELD_GET(PCIE_RO_FL_OUT, | |
| readl(pcie_phy->pma1 + | |
| REG_PCIE_PMA_RO_RX_FREQDET)); | |
| if (val < fl_out_target) | |
| pr_idac &= ~(0x1 << i); | |
| cdr_pr_idac_tmp = pr_idac; | |
| } | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_DA_PXP_CDR_PR_IDAC, | |
| cdr_pr_idac_tmp); | |
| for (i = 0; i < FREQ_LOCK_MAX_ATTEMPT; i++) { | |
| u32 val; | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN); | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_SS_RX_FREQ_DET4, | |
| PCIE_FREQLOCK_DET_EN, 0x3); | |
| usleep_range(10000, 15000); | |
| val = readl(pcie_phy->pma1 + REG_PCIE_PMA_RO_RX_FREQDET); | |
| if (val & PCIE_RO_FBCK_LOCK) | |
| break; | |
| } | |
| /* turn off force mode and update band values */ | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_INJ_MODE, | |
| CSR_2L_PXP_CDR1_INJ_FORCE_OFF); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); | |
| if (gen == PCIE_PORT_GEN3) { | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_DIG_RESERVE_14, | |
| PCIE_FLL_IDAC_PCIEG3, | |
| cdr_pr_idac_tmp); | |
| } else { | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_DIG_RESERVE_13, | |
| PCIE_FLL_IDAC_PCIEG1, | |
| cdr_pr_idac_tmp); | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_DIG_RESERVE_13, | |
| PCIE_FLL_IDAC_PCIEG2, | |
| cdr_pr_idac_tmp); | |
| } | |
| } | |
| static void airoha_pcie_phy_init_default(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CMN, | |
| CSR_2L_PXP_CMN_TRIM_MASK, 0x10); | |
| writel(0xcccbcccb, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_21); | |
| writel(0xcccb, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_22); | |
| writel(0xcccbcccb, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_21); | |
| writel(0xcccb, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_22); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CMN, | |
| CSR_2L_PXP_CMN_LANE_EN); | |
| } | |
| static void airoha_pcie_phy_init_clk_out(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_TXPLL_POSTDIV_D256, | |
| CSR_2L_PXP_CLKTX0_AMP, 0x5); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_CLKTX0_FORCE_OUT1, | |
| CSR_2L_PXP_CLKTX1_AMP, 0x5); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_TXPLL_POSTDIV_D256, | |
| CSR_2L_PXP_CLKTX0_OFFSET, 0x2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, | |
| CSR_2L_PXP_CLKTX1_OFFSET, 0x2); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX0_FORCE_OUT1, | |
| CSR_2L_PXP_CLKTX0_HZ); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, | |
| CSR_2L_PXP_CLKTX1_HZ); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_CLKTX0_FORCE_OUT1, | |
| CSR_2L_PXP_CLKTX0_IMP_SEL, 0x12); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CLKTX1_IMP_SEL, | |
| CSR_2L_PXP_CLKTX1_IMP_SEL, 0x12); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV_D256, | |
| CSR_2L_PXP_CLKTX0_SR); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, | |
| CSR_2L_PXP_CLKTX1_SR); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_PLL_CMN_RESERVE0, | |
| CSR_2L_PXP_PLL_RESERVE_MASK, 0xd0d); | |
| } | |
| static void airoha_pcie_phy_init_csr_2l(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, | |
| PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST | | |
| PCIE_SW_RX_RST); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, | |
| PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST | | |
| PCIE_SW_RX_RST); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET, | |
| PCIE_TX_TOP_RST | PCIE_TX_CAL_RST); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET, | |
| PCIE_TX_TOP_RST | PCIE_TX_CAL_RST); | |
| } | |
| static void airoha_pcie_phy_init_rx(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| writel(0x2a00090b, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_17); | |
| writel(0x2a00090b, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_17); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_MONPI, | |
| CSR_2L_PXP_CDR0_PR_XFICK_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_MONPI, | |
| CSR_2L_PXP_CDR1_PR_XFICK_EN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, | |
| REG_CSR_2L_CDR0_PD_PICAL_CKD8_INV, | |
| CSR_2L_PXP_CDR0_PD_EDGE_DISABLE); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, | |
| REG_CSR_2L_CDR1_PD_PICAL_CKD8_INV, | |
| CSR_2L_PXP_CDR1_PD_EDGE_DISABLE); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_PHYCK_DIV, | |
| CSR_2L_PXP_RX0_PHYCK_SEL, 0x1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_PHYCK_DIV, | |
| CSR_2L_PXP_RX1_PHYCK_SEL, 0x1); | |
| } | |
| static void airoha_pcie_phy_init_jcpll(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_JCPLL_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_JCPLL_EN); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_TCL_VTP_EN, | |
| CSR_2L_PXP_JCPLL_SPARE_LOW, 0x20); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, | |
| CSR_2L_PXP_JCPLL_RST); | |
| writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_JCPLL_SSC_DELTA1); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC_PERIOD, | |
| CSR_2L_PXP_JCPLL_SSC_PERIOD); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, | |
| CSR_2L_PXP_JCPLL_SSC_PHASE_INI); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, | |
| CSR_2L_PXP_JCPLL_SSC_TRI_EN); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, | |
| CSR_2L_PXP_JCPLL_LPF_BR, 0xa); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, | |
| CSR_2L_PXP_JCPLL_LPF_BP, 0xc); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, | |
| CSR_2L_PXP_JCPLL_LPF_BC, 0x1f); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, | |
| CSR_2L_PXP_JCPLL_LPF_BWC, 0x1e); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, | |
| CSR_2L_PXP_JCPLL_LPF_BWR, 0xa); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, | |
| CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE, | |
| 0x1); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, CSR_2L_PXP_JCPLL_MONCK, | |
| CSR_2L_PXP_JCPLL_REFIN_DIV); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS, | |
| PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS, | |
| PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW); | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW, | |
| PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW, | |
| 0x50000000); | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW, | |
| PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW, | |
| 0x50000000); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, | |
| REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, | |
| CSR_2L_PXP_JCPLL_POSTDIV_D5); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, | |
| REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, | |
| CSR_2L_PXP_JCPLL_POSTDIV_D2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, | |
| CSR_2L_PXP_JCPLL_RST_DLY, 0x4); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, | |
| CSR_2L_PXP_JCPLL_SDM_DI_LS); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_TCL_KBAND_VREF, | |
| CSR_2L_PXP_JCPLL_VCO_KBAND_MEAS_EN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, | |
| CSR_2L_PXP_JCPLL_CHP_IOFST); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, | |
| CSR_2L_PXP_JCPLL_CHP_IBIAS, 0xc); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, | |
| CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE, | |
| 0x1); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, | |
| CSR_2L_PXP_JCPLL_VCO_HALFLSB_EN); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, | |
| CSR_2L_PXP_JCPLL_VCO_CFIX, 0x1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, | |
| CSR_2L_PXP_JCPLL_VCO_SCAPWR, 0x4); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, | |
| REG_CSR_2L_JCPLL_LPF_SHCK_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, | |
| CSR_2L_PXP_JCPLL_POSTDIV_EN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, | |
| CSR_2L_PXP_JCPLL_KBAND_KFC); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, | |
| CSR_2L_PXP_JCPLL_KBAND_KF, 0x3); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, | |
| CSR_2L_PXP_JCPLL_KBAND_KS); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, | |
| CSR_2L_PXP_JCPLL_KBAND_DIV, 0x1); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SCAN_MODE, | |
| PCIE_FORCE_SEL_DA_PXP_JCPLL_KBAND_LOAD_EN); | |
| airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SCAN_MODE, | |
| PCIE_FORCE_DA_PXP_JCPLL_KBAND_LOAD_EN); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, | |
| CSR_2L_PXP_JCPLL_KBAND_CODE, 0xe4); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, | |
| CSR_2L_PXP_JCPLL_TCL_AMP_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_TCL_CMP, | |
| CSR_2L_PXP_JCPLL_TCL_LPF_EN); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_JCPLL_TCL_KBAND_VREF, | |
| CSR_2L_PXP_JCPLL_TCL_KBAND_VREF, 0xf); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, | |
| CSR_2L_PXP_JCPLL_TCL_AMP_GAIN, 0x1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, | |
| CSR_2L_PXP_JCPLL_TCL_AMP_VREF, 0x5); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_TCL_CMP, | |
| CSR_2L_PXP_JCPLL_TCL_LPF_BW, 0x1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCO_TCLVAR, | |
| CSR_2L_PXP_JCPLL_VCO_TCLVAR, 0x3); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_JCPLL_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_JCPLL_EN); | |
| } | |
| static void airoha_pcie_phy_txpll(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_TXPLL_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_TXPLL_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, | |
| CSR_2L_PXP_TXPLL_PLL_RSTB); | |
| writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_TXPLL_SSC_DELTA1); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC_PERIOD, | |
| CSR_2L_PXP_txpll_SSC_PERIOD); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, | |
| CSR_2L_PXP_TXPLL_CHP_IOFST, 0x1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_750M_SYS_CK, | |
| CSR_2L_PXP_TXPLL_CHP_IBIAS, 0x2d); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, | |
| CSR_2L_PXP_TXPLL_REFIN_DIV); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, | |
| CSR_2L_PXP_TXPLL_VCO_CFIX, 0x3); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW, | |
| PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW, | |
| 0xc800000); | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW, | |
| PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW, | |
| 0xc800000); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, | |
| CSR_2L_PXP_TXPLL_SDM_IFM); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, | |
| CSR_2L_PXP_TXPLL_SSC_PHASE_INI); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, | |
| CSR_2L_PXP_TXPLL_RST_DLY, 0x4); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, | |
| CSR_2L_PXP_TXPLL_SDM_DI_LS); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, | |
| CSR_2L_PXP_TXPLL_SDM_ORD, 0x3); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_KBAND_VREF, | |
| CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN); | |
| writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_TXPLL_SSC_DELTA1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, | |
| CSR_2L_PXP_TXPLL_LPF_BP, 0x1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, | |
| CSR_2L_PXP_TXPLL_LPF_BC, 0x18); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, | |
| CSR_2L_PXP_TXPLL_LPF_BR, 0x5); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, | |
| CSR_2L_PXP_TXPLL_CHP_IOFST, 0x1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_750M_SYS_CK, | |
| CSR_2L_PXP_TXPLL_CHP_IBIAS, 0x2d); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_VTP, | |
| CSR_2L_PXP_TXPLL_SPARE_L, 0x1); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, | |
| CSR_2L_PXP_TXPLL_LPF_BWC); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, | |
| CSR_2L_PXP_TXPLL_MMD_PREDIV_MODE); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, | |
| CSR_2L_PXP_TXPLL_REFIN_DIV); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, | |
| CSR_2L_PXP_TXPLL_VCO_HALFLSB_EN); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_VCO_SCAPWR, | |
| CSR_2L_PXP_TXPLL_VCO_SCAPWR, 0x7); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, | |
| CSR_2L_PXP_TXPLL_VCO_CFIX, 0x3); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, | |
| CSR_2L_PXP_TXPLL_SSC_PHASE_INI); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, | |
| CSR_2L_PXP_TXPLL_LPF_BWR); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_PHY_CK2, | |
| CSR_2L_PXP_TXPLL_REFIN_INTERNAL); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_KBAND_VREF, | |
| CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_VTP, | |
| CSR_2L_PXP_TXPLL_VTP_EN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, | |
| CSR_2L_PXP_TXPLL_PHY_CK1_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_PHY_CK2, | |
| CSR_2L_PXP_TXPLL_REFIN_INTERNAL); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, | |
| CSR_2L_PXP_TXPLL_SSC_EN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_750M_SYS_CK, | |
| CSR_2L_PXP_TXPLL_LPF_SHCK_EN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, | |
| CSR_2L_PXP_TXPLL_POSTDIV_EN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, | |
| CSR_2L_PXP_TXPLL_KBAND_KFC); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, | |
| CSR_2L_PXP_TXPLL_KBAND_KF, 0x3); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, | |
| CSR_2L_PXP_txpll_KBAND_KS, 0x1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, | |
| CSR_2L_PXP_TXPLL_KBAND_DIV, 0x4); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, | |
| CSR_2L_PXP_TXPLL_KBAND_CODE, 0xe4); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_OUT, | |
| CSR_2L_PXP_TXPLL_TCL_AMP_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_AMP_VREF, | |
| CSR_2L_PXP_TXPLL_TCL_LPF_EN); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_TXPLL_TCL_KBAND_VREF, | |
| CSR_2L_PXP_TXPLL_TCL_KBAND_VREF, 0xf); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_SDM_OUT, | |
| CSR_2L_PXP_TXPLL_TCL_AMP_GAIN, 0x3); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_TXPLL_TCL_AMP_VREF, | |
| CSR_2L_PXP_TXPLL_TCL_AMP_VREF, 0xb); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, | |
| CSR_2L_PXP_TXPLL_TCL_LPF_BW, 0x3); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_TXPLL_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, | |
| PCIE_FORCE_DA_PXP_TXPLL_EN); | |
| } | |
| static void airoha_pcie_phy_init_ssc_jcpll(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_DELTA1, | |
| CSR_2L_PXP_JCPLL_SSC_DELTA1, 0x106); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_DELTA1, | |
| CSR_2L_PXP_JCPLL_SSC_DELTA, 0x106); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_PERIOD, | |
| CSR_2L_PXP_JCPLL_SSC_PERIOD, 0x31b); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, | |
| CSR_2L_PXP_JCPLL_SSC_PHASE_INI); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, | |
| CSR_2L_PXP_JCPLL_SSC_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_IFM, | |
| CSR_2L_PXP_JCPLL_SDM_IFM); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, | |
| CSR_2L_PXP_JCPLL_SDM_HREN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, | |
| CSR_2L_PXP_JCPLL_SDM_DI_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, | |
| CSR_2L_PXP_JCPLL_SSC_TRI_EN); | |
| } | |
| static void | |
| airoha_pcie_phy_set_rxlan0_signal_detect(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_COR_HBW, | |
| CSR_2L_PXP_CDR0_PR_LDO_FORCE_ON); | |
| usleep_range(100, 200); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_19, | |
| PCIE_PCP_RX_REV0_PCIE_GEN1, 0x18b0); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, | |
| PCIE_PCP_RX_REV0_PCIE_GEN2, 0x18b0); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, | |
| PCIE_PCP_RX_REV0_PCIE_GEN3, 0x1030); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_DCTEST, | |
| CSR_2L_PXP_RX0_SIGDET_PEAK, 0x2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_VTH_SEL, | |
| CSR_2L_PXP_RX0_SIGDET_VTH_SEL, 0x5); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, | |
| CSR_2L_PXP_VOS_PNINV, 0x2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_DCTEST, | |
| CSR_2L_PXP_RX0_SIGDET_LPF_CTRL, 0x1); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_CAL2, | |
| PCIE_CAL_OUT_OS, 0x0); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_PXP_RX0_FE_VB_EQ2, | |
| CSR_2L_PXP_RX0_FE_VCM_GEN_PWDB); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, | |
| PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); | |
| airoha_phy_pma0_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, | |
| PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL, 0x3); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_RX_FORCE_MODE0, | |
| PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL, 0x1); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_SIGDET0, | |
| PCIE_SIGDET_WIN_NONVLD_TIMES, 0x3); | |
| airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SEQUENCE_DISB_CTRL1, | |
| PCIE_DISB_RX_SDCAL_EN); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, | |
| PCIE_FORCE_RX_SDCAL_EN); | |
| usleep_range(150, 200); | |
| airoha_phy_pma0_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, | |
| PCIE_FORCE_RX_SDCAL_EN); | |
| } | |
| static void | |
| airoha_pcie_phy_set_rxlan1_signal_detect(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_COR_HBW, | |
| CSR_2L_PXP_CDR1_PR_LDO_FORCE_ON); | |
| usleep_range(100, 200); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_19, | |
| PCIE_PCP_RX_REV0_PCIE_GEN1, 0x18b0); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, | |
| PCIE_PCP_RX_REV0_PCIE_GEN2, 0x18b0); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, | |
| PCIE_PCP_RX_REV0_PCIE_GEN3, 0x1030); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_SIGDET_NOVTH, | |
| CSR_2L_PXP_RX1_SIGDET_PEAK, 0x2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_SIGDET_NOVTH, | |
| CSR_2L_PXP_RX1_SIGDET_VTH_SEL, 0x5); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, | |
| CSR_2L_PXP_VOS_PNINV, 0x2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_DAC_RANGE_EYE, | |
| CSR_2L_PXP_RX1_SIGDET_LPF_CTRL, 0x1); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_CAL2, | |
| PCIE_CAL_OUT_OS, 0x0); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_FE_VB_EQ1, | |
| CSR_2L_PXP_RX1_FE_VCM_GEN_PWDB); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, | |
| PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); | |
| airoha_phy_pma1_update_field(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, | |
| PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL, 0x3); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_RX_FORCE_MODE0, | |
| PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL, 0x1); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_SIGDET0, | |
| PCIE_SIGDET_WIN_NONVLD_TIMES, 0x3); | |
| airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SEQUENCE_DISB_CTRL1, | |
| PCIE_DISB_RX_SDCAL_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, | |
| PCIE_FORCE_RX_SDCAL_EN); | |
| usleep_range(150, 200); | |
| airoha_phy_pma1_clear_bits(pcie_phy, | |
| REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, | |
| PCIE_FORCE_RX_SDCAL_EN); | |
| } | |
| static void airoha_pcie_phy_set_rxflow(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST, | |
| PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB | | |
| PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST, | |
| PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB | | |
| PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB, | |
| PCIE_FORCE_DA_PXP_CDR_PD_PWDB | | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB); | |
| airoha_phy_pma0_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB, | |
| PCIE_FORCE_DA_PXP_RX_FE_PWDB | | |
| PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB, | |
| PCIE_FORCE_DA_PXP_CDR_PD_PWDB | | |
| PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB); | |
| airoha_phy_pma1_set_bits(pcie_phy, | |
| REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB, | |
| PCIE_FORCE_DA_PXP_RX_FE_PWDB | | |
| PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX0_PHYCK_DIV, | |
| CSR_2L_PXP_RX0_PHYCK_RSTB | | |
| CSR_2L_PXP_RX0_TDC_CK_SEL); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_PHYCK_DIV, | |
| CSR_2L_PXP_RX1_PHYCK_RSTB | | |
| CSR_2L_PXP_RX1_TDC_CK_SEL); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, | |
| PCIE_SW_RX_FIFO_RST | PCIE_SW_TX_RST | | |
| PCIE_SW_PMA_RST | PCIE_SW_ALLPCS_RST | | |
| PCIE_SW_TX_FIFO_RST); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, | |
| PCIE_SW_RX_FIFO_RST | PCIE_SW_TX_RST | | |
| PCIE_SW_PMA_RST | PCIE_SW_ALLPCS_RST | | |
| PCIE_SW_TX_FIFO_RST); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_PXP_RX0_FE_VB_EQ2, | |
| CSR_2L_PXP_RX0_FE_VB_EQ2_EN | | |
| CSR_2L_PXP_RX0_FE_VB_EQ3_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX0_SIGDET_VTH_SEL, | |
| CSR_2L_PXP_RX0_FE_VB_EQ1_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_FE_VB_EQ1, | |
| CSR_2L_PXP_RX1_FE_VB_EQ1_EN | | |
| CSR_2L_PXP_RX1_FE_VB_EQ2_EN | | |
| CSR_2L_PXP_RX1_FE_VB_EQ3_EN); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, | |
| CSR_2L_PXP_FE_GAIN_NORMAL_MODE, 0x4); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, | |
| CSR_2L_PXP_FE_GAIN_TRAIN_MODE, 0x4); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, | |
| CSR_2L_PXP_FE_GAIN_NORMAL_MODE, 0x4); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, | |
| CSR_2L_PXP_FE_GAIN_TRAIN_MODE, 0x4); | |
| } | |
| static void airoha_pcie_phy_set_pr(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_VREG_IBAND, | |
| CSR_2L_PXP_CDR0_PR_VREG_IBAND, 0x5); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_VREG_IBAND, | |
| CSR_2L_PXP_CDR0_PR_VREG_CKBUF, 0x5); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_CKREF_DIV, | |
| CSR_2L_PXP_CDR0_PR_CKREF_DIV); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_COR_HBW, | |
| CSR_2L_PXP_CDR0_PR_CKREF_DIV1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL, | |
| CSR_2L_PXP_CDR1_PR_VREG_IBAND, 0x5); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL, | |
| CSR_2L_PXP_CDR1_PR_VREG_CKBUF, 0x5); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_CKREF_DIV, | |
| CSR_2L_PXP_CDR1_PR_CKREF_DIV); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_COR_HBW, | |
| CSR_2L_PXP_CDR1_PR_CKREF_DIV1); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_LPF_RATIO, | |
| CSR_2L_PXP_CDR0_LPF_TOP_LIM, 0x20000); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_LPF_RATIO, | |
| CSR_2L_PXP_CDR1_LPF_TOP_LIM, 0x20000); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_BETA_DAC, | |
| CSR_2L_PXP_CDR0_PR_BETA_SEL, 0x2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_BETA_DAC, | |
| CSR_2L_PXP_CDR1_PR_BETA_SEL, 0x2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_BETA_DAC, | |
| CSR_2L_PXP_CDR0_PR_KBAND_DIV, 0x4); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_BETA_DAC, | |
| CSR_2L_PXP_CDR1_PR_KBAND_DIV, 0x4); | |
| } | |
| static void airoha_pcie_phy_set_txflow(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX0_CKLDO, | |
| CSR_2L_PXP_TX0_CKLDO_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX1_CKLDO, | |
| CSR_2L_PXP_TX1_CKLDO_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX0_CKLDO, | |
| CSR_2L_PXP_TX0_DMEDGEGEN_EN); | |
| airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX1_CKLDO, | |
| CSR_2L_PXP_TX1_DMEDGEGEN_EN); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TX1_MULTLANE, | |
| CSR_2L_PXP_TX1_MULTLANE_EN); | |
| } | |
| static void airoha_pcie_phy_set_rx_mode(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| writel(0x804000, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_27); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, | |
| PCIE_PXP_RX_VTH_SEL_PCIE_G1, 0x5); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, | |
| PCIE_PXP_RX_VTH_SEL_PCIE_G2, 0x5); | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, | |
| PCIE_PXP_RX_VTH_SEL_PCIE_G3, 0x5); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_30, | |
| 0x77700); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_MONCK, | |
| CSR_2L_PXP_CDR0_PR_MONCK_ENABLE); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_MONCK, | |
| CSR_2L_PXP_CDR0_PR_RESERVE0, 0x2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_PXP_RX0_OSCAL_CTLE1IOS, | |
| CSR_2L_PXP_RX0_PR_OSCAL_VGA1IOS, 0x19); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS, | |
| CSR_2L_PXP_RX0_PR_OSCAL_VGA1VOS, 0x19); | |
| airoha_phy_csr_2l_update_field(pcie_phy, | |
| REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS, | |
| CSR_2L_PXP_RX0_PR_OSCAL_VGA2IOS, 0x14); | |
| writel(0x804000, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_27); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, | |
| PCIE_PXP_RX_VTH_SEL_PCIE_G1, 0x5); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, | |
| PCIE_PXP_RX_VTH_SEL_PCIE_G2, 0x5); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, | |
| PCIE_PXP_RX_VTH_SEL_PCIE_G3, 0x5); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_30, | |
| 0x77700); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_MONCK, | |
| CSR_2L_PXP_CDR1_PR_MONCK_ENABLE); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_MONCK, | |
| CSR_2L_PXP_CDR1_PR_RESERVE0, 0x2); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, | |
| CSR_2L_PXP_RX1_PR_OSCAL_VGA1IOS, 0x19); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, | |
| CSR_2L_PXP_RX1_PR_OSCAL_VGA1VOS, 0x19); | |
| airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, | |
| CSR_2L_PXP_RX1_PR_OSCAL_VGA2IOS, 0x14); | |
| } | |
| static void airoha_pcie_phy_load_kflow(struct airoha_pcie_phy *pcie_phy) | |
| { | |
| airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, | |
| PCIE_FORCE_PMA_RX_SPEED, 0xa); | |
| airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, | |
| PCIE_FORCE_PMA_RX_SPEED, 0xa); | |
| airoha_phy_init_lane0_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN3); | |
| airoha_phy_init_lane1_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN3); | |
| airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, | |
| PCIE_FORCE_PMA_RX_SPEED); | |
| airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, | |
| PCIE_FORCE_PMA_RX_SPEED); | |
| usleep_range(100, 200); | |
| airoha_phy_init_lane0_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN2); | |
| airoha_phy_init_lane1_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN2); | |
| } | |
| /** | |
| * airoha_pcie_phy_init() - Initialize the phy | |
| * @phy: the phy to be initialized | |
| * | |
| * Initialize the phy registers. | |
| * The hardware settings will be reset during suspend, it should be | |
| * reinitialized when the consumer calls phy_init() again on resume. | |
| */ | |
| static int airoha_pcie_phy_init(struct phy *phy) | |
| { | |
| struct airoha_pcie_phy *pcie_phy = phy_get_drvdata(phy); | |
| u32 val; | |
| /* Setup Tx-Rx detection time */ | |
| val = FIELD_PREP(PCIE_XTP_RXDET_VCM_OFF_STB_T_SEL, 0x33) | | |
| FIELD_PREP(PCIE_XTP_RXDET_EN_STB_T_SEL, 0x1) | | |
| FIELD_PREP(PCIE_XTP_RXDET_FINISH_STB_T_SEL, 0x2) | | |
| FIELD_PREP(PCIE_XTP_TXPD_TX_DATA_EN_DLY, 0x3) | | |
| FIELD_PREP(PCIE_XTP_RXDET_LATCH_STB_T_SEL, 0x1); | |
| writel(val, pcie_phy->p0_xr_dtime + REG_PCIE_PEXTP_DIG_GLB44); | |
| writel(val, pcie_phy->p1_xr_dtime + REG_PCIE_PEXTP_DIG_GLB44); | |
| /* Setup Rx AEQ training time */ | |
| val = FIELD_PREP(PCIE_XTP_LN_RX_PDOWN_L1P2_EXIT_WAIT, 0x32) | | |
| FIELD_PREP(PCIE_XTP_LN_RX_PDOWN_E0_AEQEN_WAIT, 0x5050); | |
| writel(val, pcie_phy->rx_aeq + REG_PCIE_PEXTP_DIG_LN_RX30_P0); | |
| writel(val, pcie_phy->rx_aeq + REG_PCIE_PEXTP_DIG_LN_RX30_P1); | |
| /* enable load FLL-K flow */ | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_14, | |
| PCIE_FLL_LOAD_EN); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_14, | |
| PCIE_FLL_LOAD_EN); | |
| airoha_pcie_phy_init_default(pcie_phy); | |
| airoha_pcie_phy_init_clk_out(pcie_phy); | |
| airoha_pcie_phy_init_csr_2l(pcie_phy); | |
| usleep_range(100, 200); | |
| airoha_pcie_phy_init_rx(pcie_phy); | |
| /* phase 1, no ssc for K TXPLL */ | |
| airoha_pcie_phy_init_jcpll(pcie_phy); | |
| usleep_range(500, 600); | |
| /* TX PLL settings */ | |
| airoha_pcie_phy_txpll(pcie_phy); | |
| usleep_range(200, 300); | |
| /* SSC JCPLL setting */ | |
| airoha_pcie_phy_init_ssc_jcpll(pcie_phy); | |
| usleep_range(100, 200); | |
| /* Rx lan0 signal detect */ | |
| airoha_pcie_phy_set_rxlan0_signal_detect(pcie_phy); | |
| /* Rx lan1 signal detect */ | |
| airoha_pcie_phy_set_rxlan1_signal_detect(pcie_phy); | |
| /* RX FLOW */ | |
| airoha_pcie_phy_set_rxflow(pcie_phy); | |
| usleep_range(100, 200); | |
| airoha_pcie_phy_set_pr(pcie_phy); | |
| /* TX FLOW */ | |
| airoha_pcie_phy_set_txflow(pcie_phy); | |
| usleep_range(100, 200); | |
| /* RX mode setting */ | |
| airoha_pcie_phy_set_rx_mode(pcie_phy); | |
| /* Load K-Flow */ | |
| airoha_pcie_phy_load_kflow(pcie_phy); | |
| airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, | |
| PCIE_DA_XPON_CDR_PR_PWDB); | |
| airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, | |
| PCIE_DA_XPON_CDR_PR_PWDB); | |
| usleep_range(100, 200); | |
| airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, | |
| PCIE_DA_XPON_CDR_PR_PWDB); | |
| airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, | |
| PCIE_DA_XPON_CDR_PR_PWDB); | |
| /* Wait for the PCIe PHY to complete initialization before returning */ | |
| msleep(PHY_HW_INIT_TIME_MS); | |
| return 0; | |
| } | |
| static int airoha_pcie_phy_exit(struct phy *phy) | |
| { | |
| struct airoha_pcie_phy *pcie_phy = phy_get_drvdata(phy); | |
| airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, | |
| PCIE_PMA_SW_RST); | |
| airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, | |
| PCIE_PMA_SW_RST); | |
| airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, | |
| CSR_2L_PXP_JCPLL_SSC_PHASE_INI | | |
| CSR_2L_PXP_JCPLL_SSC_TRI_EN | | |
| CSR_2L_PXP_JCPLL_SSC_EN); | |
| return 0; | |
| } | |
| static const struct phy_ops airoha_pcie_phy_ops = { | |
| .init = airoha_pcie_phy_init, | |
| .exit = airoha_pcie_phy_exit, | |
| .owner = THIS_MODULE, | |
| }; | |
| static int airoha_pcie_phy_probe(struct platform_device *pdev) | |
| { | |
| struct airoha_pcie_phy *pcie_phy; | |
| struct device *dev = &pdev->dev; | |
| struct phy_provider *provider; | |
| pcie_phy = devm_kzalloc(dev, sizeof(*pcie_phy), GFP_KERNEL); | |
| if (!pcie_phy) | |
| return -ENOMEM; | |
| pcie_phy->csr_2l = devm_platform_ioremap_resource_byname(pdev, "csr-2l"); | |
| if (IS_ERR(pcie_phy->csr_2l)) | |
| return dev_err_probe(dev, PTR_ERR(pcie_phy->csr_2l), | |
| "Failed to map phy-csr-2l base\n"); | |
| pcie_phy->pma0 = devm_platform_ioremap_resource_byname(pdev, "pma0"); | |
| if (IS_ERR(pcie_phy->pma0)) | |
| return dev_err_probe(dev, PTR_ERR(pcie_phy->pma0), | |
| "Failed to map phy-pma0 base\n"); | |
| pcie_phy->pma1 = devm_platform_ioremap_resource_byname(pdev, "pma1"); | |
| if (IS_ERR(pcie_phy->pma1)) | |
| return dev_err_probe(dev, PTR_ERR(pcie_phy->pma1), | |
| "Failed to map phy-pma1 base\n"); | |
| pcie_phy->phy = devm_phy_create(dev, dev->of_node, &airoha_pcie_phy_ops); | |
| if (IS_ERR(pcie_phy->phy)) | |
| return dev_err_probe(dev, PTR_ERR(pcie_phy->phy), | |
| "Failed to create PCIe phy\n"); | |
| pcie_phy->p0_xr_dtime = | |
| devm_platform_ioremap_resource_byname(pdev, "p0-xr-dtime"); | |
| if (IS_ERR(pcie_phy->p0_xr_dtime)) | |
| return dev_err_probe(dev, PTR_ERR(pcie_phy->p0_xr_dtime), | |
| "Failed to map P0 Tx-Rx dtime base\n"); | |
| pcie_phy->p1_xr_dtime = | |
| devm_platform_ioremap_resource_byname(pdev, "p1-xr-dtime"); | |
| if (IS_ERR(pcie_phy->p1_xr_dtime)) | |
| return dev_err_probe(dev, PTR_ERR(pcie_phy->p1_xr_dtime), | |
| "Failed to map P1 Tx-Rx dtime base\n"); | |
| pcie_phy->rx_aeq = devm_platform_ioremap_resource_byname(pdev, "rx-aeq"); | |
| if (IS_ERR(pcie_phy->rx_aeq)) | |
| return dev_err_probe(dev, PTR_ERR(pcie_phy->rx_aeq), | |
| "Failed to map Rx AEQ base\n"); | |
| pcie_phy->dev = dev; | |
| phy_set_drvdata(pcie_phy->phy, pcie_phy); | |
| provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | |
| if (IS_ERR(provider)) | |
| return dev_err_probe(dev, PTR_ERR(provider), | |
| "PCIe phy probe failed\n"); | |
| return 0; | |
| } | |
| static const struct of_device_id airoha_pcie_phy_of_match[] = { | |
| { .compatible = "airoha,en7581-pcie-phy" }, | |
| { /* sentinel */ } | |
| }; | |
| MODULE_DEVICE_TABLE(of, airoha_pcie_phy_of_match); | |
| static struct platform_driver airoha_pcie_phy_driver = { | |
| .probe = airoha_pcie_phy_probe, | |
| .driver = { | |
| .name = "airoha-pcie-phy", | |
| .of_match_table = airoha_pcie_phy_of_match, | |
| }, | |
| }; | |
| module_platform_driver(airoha_pcie_phy_driver); | |
| MODULE_DESCRIPTION("Airoha PCIe PHY driver"); | |
| MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | |
| MODULE_LICENSE("GPL"); |