diff options
Diffstat (limited to 'drivers/phy/mediatek/phy-mtk-tphy.c')
-rw-r--r-- | drivers/phy/mediatek/phy-mtk-tphy.c | 608 |
1 files changed, 312 insertions, 296 deletions
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c index cdcef865fe9e..6d307102f4f6 100644 --- a/drivers/phy/mediatek/phy-mtk-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-tphy.c @@ -8,16 +8,18 @@ #include <dt-bindings/phy/phy.h> #include <linux/clk.h> #include <linux/delay.h> -#include <linux/io.h> #include <linux/iopoll.h> #include <linux/mfd/syscon.h> #include <linux/module.h> +#include <linux/nvmem-consumer.h> #include <linux/of_address.h> #include <linux/of_device.h> #include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include "phy-mtk-io.h" + /* version V1 sub-banks offset base address */ /* banks shared by multiple phys */ #define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */ @@ -41,6 +43,9 @@ #define SSUSB_SIFSLV_V2_U3PHYD 0x200 #define SSUSB_SIFSLV_V2_U3PHYA 0x400 +#define U3P_MISC_REG1 0x04 +#define MR1_EFUSE_AUTO_LOAD_DIS BIT(6) + #define U3P_USBPHYACR0 0x000 #define PA0_RG_U2PLL_FORCE_ON BIT(15) #define PA0_USB20_PLL_PREDIV GENMASK(7, 6) @@ -133,6 +138,8 @@ #define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24) #define U3P_U3_PHYA_REG0 0x000 +#define P3A_RG_IEXT_INTR GENMASK(15, 10) +#define P3A_RG_IEXT_INTR_VAL(x) ((0x3f & (x)) << 10) #define P3A_RG_CLKDRV_OFF GENMASK(3, 2) #define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2) @@ -187,6 +194,19 @@ #define P3D_RG_FWAKE_TH GENMASK(21, 16) #define P3D_RG_FWAKE_TH_VAL(x) ((0x3f & (x)) << 16) +#define U3P_U3_PHYD_IMPCAL0 0x010 +#define P3D_RG_FORCE_TX_IMPEL BIT(31) +#define P3D_RG_TX_IMPEL GENMASK(28, 24) +#define P3D_RG_TX_IMPEL_VAL(x) ((0x1f & (x)) << 24) + +#define U3P_U3_PHYD_IMPCAL1 0x014 +#define P3D_RG_FORCE_RX_IMPEL BIT(31) +#define P3D_RG_RX_IMPEL GENMASK(28, 24) +#define P3D_RG_RX_IMPEL_VAL(x) ((0x1f & (x)) << 24) + +#define U3P_U3_PHYD_RSV 0x054 +#define P3D_RG_EFUSE_AUTO_LOAD_DIS BIT(12) + #define U3P_U3_PHYD_CDR1 0x05c #define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24) #define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24) @@ -307,6 +327,11 @@ struct mtk_phy_pdata { * 48M PLL, fix it by switching PLL to 26M from default 48M */ bool sw_pll_48m_to_26m; + /* + * Some SoCs (e.g. mt8195) drop a bit when use auto load efuse, + * support sw way, also support it for v2/v3 optionally. + */ + bool sw_efuse_supported; enum mtk_phy_version version; }; @@ -336,6 +361,10 @@ struct mtk_phy_instance { struct regmap *type_sw; u32 type_sw_reg; u32 type_sw_index; + u32 efuse_sw_en; + u32 efuse_intr; + u32 efuse_tx_imp; + u32 efuse_rx_imp; int eye_src; int eye_vrt; int eye_term; @@ -373,15 +402,11 @@ static void hs_slew_rate_calibrate(struct mtk_tphy *tphy, return; /* enable USB ring oscillator */ - tmp = readl(com + U3P_USBPHYACR5); - tmp |= PA5_RG_U2_HSTX_SRCAL_EN; - writel(tmp, com + U3P_USBPHYACR5); + mtk_phy_set_bits(com + U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCAL_EN); udelay(1); /*enable free run clock */ - tmp = readl(fmreg + U3P_U2FREQ_FMMONR1); - tmp |= P2F_RG_FRCK_EN; - writel(tmp, fmreg + U3P_U2FREQ_FMMONR1); + mtk_phy_set_bits(fmreg + U3P_U2FREQ_FMMONR1, P2F_RG_FRCK_EN); /* set cycle count as 1024, and select u2 channel */ tmp = readl(fmreg + U3P_U2FREQ_FMCR0); @@ -393,9 +418,7 @@ static void hs_slew_rate_calibrate(struct mtk_tphy *tphy, writel(tmp, fmreg + U3P_U2FREQ_FMCR0); /* enable frequency meter */ - tmp = readl(fmreg + U3P_U2FREQ_FMCR0); - tmp |= P2F_RG_FREQDET_EN; - writel(tmp, fmreg + U3P_U2FREQ_FMCR0); + mtk_phy_set_bits(fmreg + U3P_U2FREQ_FMCR0, P2F_RG_FREQDET_EN); /* ignore return value */ readl_poll_timeout(fmreg + U3P_U2FREQ_FMMONR1, tmp, @@ -404,14 +427,10 @@ static void hs_slew_rate_calibrate(struct mtk_tphy *tphy, fm_out = readl(fmreg + U3P_U2FREQ_VALUE); /* disable frequency meter */ - tmp = readl(fmreg + U3P_U2FREQ_FMCR0); - tmp &= ~P2F_RG_FREQDET_EN; - writel(tmp, fmreg + U3P_U2FREQ_FMCR0); + mtk_phy_clear_bits(fmreg + U3P_U2FREQ_FMCR0, P2F_RG_FREQDET_EN); /*disable free run clock */ - tmp = readl(fmreg + U3P_U2FREQ_FMMONR1); - tmp &= ~P2F_RG_FRCK_EN; - writel(tmp, fmreg + U3P_U2FREQ_FMMONR1); + mtk_phy_clear_bits(fmreg + U3P_U2FREQ_FMMONR1, P2F_RG_FRCK_EN); if (fm_out) { /* ( 1024 / FM_OUT ) x reference clock frequency x coef */ @@ -427,63 +446,44 @@ static void hs_slew_rate_calibrate(struct mtk_tphy *tphy, tphy->src_ref_clk, tphy->src_coef); /* set HS slew rate */ - tmp = readl(com + U3P_USBPHYACR5); - tmp &= ~PA5_RG_U2_HSTX_SRCTRL; - tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(calibration_val); - writel(tmp, com + U3P_USBPHYACR5); + mtk_phy_update_bits(com + U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCTRL, + PA5_RG_U2_HSTX_SRCTRL_VAL(calibration_val)); /* disable USB ring oscillator */ - tmp = readl(com + U3P_USBPHYACR5); - tmp &= ~PA5_RG_U2_HSTX_SRCAL_EN; - writel(tmp, com + U3P_USBPHYACR5); + mtk_phy_clear_bits(com + U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCAL_EN); } static void u3_phy_instance_init(struct mtk_tphy *tphy, struct mtk_phy_instance *instance) { struct u3phy_banks *u3_banks = &instance->u3_banks; - u32 tmp; /* gating PCIe Analog XTAL clock */ - tmp = readl(u3_banks->spllc + U3P_SPLLC_XTALCTL3); - tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD; - writel(tmp, u3_banks->spllc + U3P_SPLLC_XTALCTL3); + mtk_phy_set_bits(u3_banks->spllc + U3P_SPLLC_XTALCTL3, + XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD); /* gating XSQ */ - tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0); - tmp &= ~P3A_RG_XTAL_EXT_EN_U3; - tmp |= P3A_RG_XTAL_EXT_EN_U3_VAL(2); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG0); - - tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG9); - tmp &= ~P3A_RG_RX_DAC_MUX; - tmp |= P3A_RG_RX_DAC_MUX_VAL(4); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG9); - - tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG6); - tmp &= ~P3A_RG_TX_EIDLE_CM; - tmp |= P3A_RG_TX_EIDLE_CM_VAL(0xe); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG6); - - tmp = readl(u3_banks->phyd + U3P_U3_PHYD_CDR1); - tmp &= ~(P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1); - tmp |= P3D_RG_CDR_BIR_LTD0_VAL(0xc) | P3D_RG_CDR_BIR_LTD1_VAL(0x3); - writel(tmp, u3_banks->phyd + U3P_U3_PHYD_CDR1); - - tmp = readl(u3_banks->phyd + U3P_U3_PHYD_LFPS1); - tmp &= ~P3D_RG_FWAKE_TH; - tmp |= P3D_RG_FWAKE_TH_VAL(0x34); - writel(tmp, u3_banks->phyd + U3P_U3_PHYD_LFPS1); - - tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET1); - tmp &= ~P3D_RG_RXDET_STB2_SET; - tmp |= P3D_RG_RXDET_STB2_SET_VAL(0x10); - writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET1); - - tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET2); - tmp &= ~P3D_RG_RXDET_STB2_SET_P3; - tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10); - writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2); + mtk_phy_update_bits(u3_banks->phya + U3P_U3_PHYA_DA_REG0, + P3A_RG_XTAL_EXT_EN_U3, P3A_RG_XTAL_EXT_EN_U3_VAL(2)); + + mtk_phy_update_bits(u3_banks->phya + U3P_U3_PHYA_REG9, + P3A_RG_RX_DAC_MUX, P3A_RG_RX_DAC_MUX_VAL(4)); + + mtk_phy_update_bits(u3_banks->phya + U3P_U3_PHYA_REG6, + P3A_RG_TX_EIDLE_CM, P3A_RG_TX_EIDLE_CM_VAL(0xe)); + + mtk_phy_update_bits(u3_banks->phyd + U3P_U3_PHYD_CDR1, + P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1, + P3D_RG_CDR_BIR_LTD0_VAL(0xc) | P3D_RG_CDR_BIR_LTD1_VAL(0x3)); + + mtk_phy_update_bits(u3_banks->phyd + U3P_U3_PHYD_LFPS1, + P3D_RG_FWAKE_TH, P3D_RG_FWAKE_TH_VAL(0x34)); + + mtk_phy_update_bits(u3_banks->phyd + U3P_U3_PHYD_RXDET1, + P3D_RG_RXDET_STB2_SET, P3D_RG_RXDET_STB2_SET_VAL(0x10)); + + mtk_phy_update_bits(u3_banks->phyd + U3P_U3_PHYD_RXDET2, + P3D_RG_RXDET_STB2_SET_P3, P3D_RG_RXDET_STB2_SET_P3_VAL(0x10)); dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index); } @@ -493,26 +493,20 @@ static void u2_phy_pll_26m_set(struct mtk_tphy *tphy, { struct u2phy_banks *u2_banks = &instance->u2_banks; void __iomem *com = u2_banks->com; - u32 tmp; if (!tphy->pdata->sw_pll_48m_to_26m) return; - tmp = readl(com + U3P_USBPHYACR0); - tmp &= ~PA0_USB20_PLL_PREDIV; - tmp |= PA0_USB20_PLL_PREDIV_VAL(0); - writel(tmp, com + U3P_USBPHYACR0); + mtk_phy_update_bits(com + U3P_USBPHYACR0, PA0_USB20_PLL_PREDIV, + PA0_USB20_PLL_PREDIV_VAL(0)); - tmp = readl(com + U3P_USBPHYACR2); - tmp &= ~PA2_RG_U2PLL_BW; - tmp |= PA2_RG_U2PLL_BW_VAL(3); - writel(tmp, com + U3P_USBPHYACR2); + mtk_phy_update_bits(com + U3P_USBPHYACR2, PA2_RG_U2PLL_BW, + PA2_RG_U2PLL_BW_VAL(3)); writel(P2R_RG_U2PLL_FBDIV_26M, com + U3P_U2PHYA_RESV); - tmp = readl(com + U3P_U2PHYA_RESV1); - tmp |= P2R_RG_U2PLL_FRA_EN | P2R_RG_U2PLL_REFCLK_SEL; - writel(tmp, com + U3P_U2PHYA_RESV1); + mtk_phy_set_bits(com + U3P_U2PHYA_RESV1, + P2R_RG_U2PLL_FRA_EN | P2R_RG_U2PLL_REFCLK_SEL); } static void u2_phy_instance_init(struct mtk_tphy *tphy, @@ -521,58 +515,40 @@ static void u2_phy_instance_init(struct mtk_tphy *tphy, struct u2phy_banks *u2_banks = &instance->u2_banks; void __iomem *com = u2_banks->com; u32 index = instance->index; - u32 tmp; /* switch to USB function, and enable usb pll */ - tmp = readl(com + U3P_U2PHYDTM0); - tmp &= ~(P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM); - tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0); - writel(tmp, com + U3P_U2PHYDTM0); + mtk_phy_clear_bits(com + U3P_U2PHYDTM0, P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM); + + mtk_phy_update_bits(com + U3P_U2PHYDTM0, P2C_RG_XCVRSEL | P2C_RG_DATAIN, + P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0)); - tmp = readl(com + U3P_U2PHYDTM1); - tmp &= ~P2C_RG_UART_EN; - writel(tmp, com + U3P_U2PHYDTM1); + mtk_phy_clear_bits(com + U3P_U2PHYDTM1, P2C_RG_UART_EN); - tmp = readl(com + U3P_USBPHYACR0); - tmp |= PA0_RG_USB20_INTR_EN; - writel(tmp, com + U3P_USBPHYACR0); + mtk_phy_set_bits(com + U3P_USBPHYACR0, PA0_RG_USB20_INTR_EN); /* disable switch 100uA current to SSUSB */ - tmp = readl(com + U3P_USBPHYACR5); - tmp &= ~PA5_RG_U2_HS_100U_U3_EN; - writel(tmp, com + U3P_USBPHYACR5); - - if (!index) { - tmp = readl(com + U3P_U2PHYACR4); - tmp &= ~P2C_U2_GPIO_CTR_MSK; - writel(tmp, com + U3P_U2PHYACR4); - } + mtk_phy_clear_bits(com + U3P_USBPHYACR5, PA5_RG_U2_HS_100U_U3_EN); + + if (!index) + mtk_phy_clear_bits(com + U3P_U2PHYACR4, P2C_U2_GPIO_CTR_MSK); if (tphy->pdata->avoid_rx_sen_degradation) { if (!index) { - tmp = readl(com + U3P_USBPHYACR2); - tmp |= PA2_RG_SIF_U2PLL_FORCE_EN; - writel(tmp, com + U3P_USBPHYACR2); + mtk_phy_set_bits(com + U3P_USBPHYACR2, PA2_RG_SIF_U2PLL_FORCE_EN); - tmp = readl(com + U3D_U2PHYDCR0); - tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; - writel(tmp, com + U3D_U2PHYDCR0); + mtk_phy_clear_bits(com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); } else { - tmp = readl(com + U3D_U2PHYDCR0); - tmp |= P2C_RG_SIF_U2PLL_FORCE_ON; - writel(tmp, com + U3D_U2PHYDCR0); + mtk_phy_set_bits(com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); - tmp = readl(com + U3P_U2PHYDTM0); - tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM; - writel(tmp, com + U3P_U2PHYDTM0); + mtk_phy_set_bits(com + U3P_U2PHYDTM0, + P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM); } } - tmp = readl(com + U3P_USBPHYACR6); - tmp &= ~PA6_RG_U2_BC11_SW_EN; /* DP/DM BC1.1 path Disable */ - tmp &= ~PA6_RG_U2_SQTH; - tmp |= PA6_RG_U2_SQTH_VAL(2); - writel(tmp, com + U3P_USBPHYACR6); + /* DP/DM BC1.1 path Disable */ + mtk_phy_clear_bits(com + U3P_USBPHYACR6, PA6_RG_U2_BC11_SW_EN); + + mtk_phy_update_bits(com + U3P_USBPHYACR6, PA6_RG_U2_SQTH, PA6_RG_U2_SQTH_VAL(2)); /* Workaround only for mt8195, HW fix it for others (V3) */ u2_phy_pll_26m_set(tphy, instance); @@ -586,30 +562,21 @@ static void u2_phy_instance_power_on(struct mtk_tphy *tphy, struct u2phy_banks *u2_banks = &instance->u2_banks; void __iomem *com = u2_banks->com; u32 index = instance->index; - u32 tmp; - tmp = readl(com + U3P_U2PHYDTM0); - tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK); - writel(tmp, com + U3P_U2PHYDTM0); + mtk_phy_clear_bits(com + U3P_U2PHYDTM0, + P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK); /* OTG Enable */ - tmp = readl(com + U3P_USBPHYACR6); - tmp |= PA6_RG_U2_OTG_VBUSCMP_EN; - writel(tmp, com + U3P_USBPHYACR6); + mtk_phy_set_bits(com + U3P_USBPHYACR6, PA6_RG_U2_OTG_VBUSCMP_EN); + + mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_RG_VBUSVALID | P2C_RG_AVALID); - tmp = readl(com + U3P_U2PHYDTM1); - tmp |= P2C_RG_VBUSVALID | P2C_RG_AVALID; - tmp &= ~P2C_RG_SESSEND; - writel(tmp, com + U3P_U2PHYDTM1); + mtk_phy_clear_bits(com + U3P_U2PHYDTM1, P2C_RG_SESSEND); if (tphy->pdata->avoid_rx_sen_degradation && index) { - tmp = readl(com + U3D_U2PHYDCR0); - tmp |= P2C_RG_SIF_U2PLL_FORCE_ON; - writel(tmp, com + U3D_U2PHYDCR0); + mtk_phy_set_bits(com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); - tmp = readl(com + U3P_U2PHYDTM0); - tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM; - writel(tmp, com + U3P_U2PHYDTM0); + mtk_phy_set_bits(com + U3P_U2PHYDTM0, P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM); } dev_dbg(tphy->dev, "%s(%d)\n", __func__, index); } @@ -620,30 +587,20 @@ static void u2_phy_instance_power_off(struct mtk_tphy *tphy, struct u2phy_banks *u2_banks = &instance->u2_banks; void __iomem *com = u2_banks->com; u32 index = instance->index; - u32 tmp; - tmp = readl(com + U3P_U2PHYDTM0); - tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN); - writel(tmp, com + U3P_U2PHYDTM0); + mtk_phy_clear_bits(com + U3P_U2PHYDTM0, P2C_RG_XCVRSEL | P2C_RG_DATAIN); /* OTG Disable */ - tmp = readl(com + U3P_USBPHYACR6); - tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN; - writel(tmp, com + U3P_USBPHYACR6); + mtk_phy_clear_bits(com + U3P_USBPHYACR6, PA6_RG_U2_OTG_VBUSCMP_EN); + + mtk_phy_clear_bits(com + U3P_U2PHYDTM1, P2C_RG_VBUSVALID | P2C_RG_AVALID); - tmp = readl(com + U3P_U2PHYDTM1); - tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID); - tmp |= P2C_RG_SESSEND; - writel(tmp, com + U3P_U2PHYDTM1); + mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_RG_SESSEND); if (tphy->pdata->avoid_rx_sen_degradation && index) { - tmp = readl(com + U3P_U2PHYDTM0); - tmp &= ~(P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM); - writel(tmp, com + U3P_U2PHYDTM0); + mtk_phy_clear_bits(com + U3P_U2PHYDTM0, P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM); - tmp = readl(com + U3D_U2PHYDCR0); - tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; - writel(tmp, com + U3D_U2PHYDCR0); + mtk_phy_clear_bits(com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); } dev_dbg(tphy->dev, "%s(%d)\n", __func__, index); @@ -655,16 +612,11 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy, struct u2phy_banks *u2_banks = &instance->u2_banks; void __iomem *com = u2_banks->com; u32 index = instance->index; - u32 tmp; if (tphy->pdata->avoid_rx_sen_degradation && index) { - tmp = readl(com + U3D_U2PHYDCR0); - tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; - writel(tmp, com + U3D_U2PHYDCR0); + mtk_phy_clear_bits(com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); - tmp = readl(com + U3P_U2PHYDTM0); - tmp &= ~P2C_FORCE_SUSPENDM; - writel(tmp, com + U3P_U2PHYDTM0); + mtk_phy_clear_bits(com + U3P_U2PHYDTM0, P2C_FORCE_SUSPENDM); } } @@ -697,69 +649,50 @@ static void pcie_phy_instance_init(struct mtk_tphy *tphy, struct mtk_phy_instance *instance) { struct u3phy_banks *u3_banks = &instance->u3_banks; - u32 tmp; + void __iomem *phya = u3_banks->phya; if (tphy->pdata->version != MTK_PHY_V1) return; - tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0); - tmp &= ~(P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H); - tmp |= P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG0); + mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG0, + P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H, + P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2)); /* ref clk drive */ - tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG1); - tmp &= ~P3A_RG_CLKDRV_AMP; - tmp |= P3A_RG_CLKDRV_AMP_VAL(0x4); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG1); + mtk_phy_update_bits(phya + U3P_U3_PHYA_REG1, P3A_RG_CLKDRV_AMP, + P3A_RG_CLKDRV_AMP_VAL(0x4)); - tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0); - tmp &= ~P3A_RG_CLKDRV_OFF; - tmp |= P3A_RG_CLKDRV_OFF_VAL(0x1); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0); + mtk_phy_update_bits(phya + U3P_U3_PHYA_REG0, P3A_RG_CLKDRV_OFF, + P3A_RG_CLKDRV_OFF_VAL(0x1)); /* SSC delta -5000ppm */ - tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG20); - tmp &= ~P3A_RG_PLL_DELTA1_PE2H; - tmp |= P3A_RG_PLL_DELTA1_PE2H_VAL(0x3c); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG20); + mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG20, P3A_RG_PLL_DELTA1_PE2H, + P3A_RG_PLL_DELTA1_PE2H_VAL(0x3c)); - tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG25); - tmp &= ~P3A_RG_PLL_DELTA_PE2H; - tmp |= P3A_RG_PLL_DELTA_PE2H_VAL(0x36); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG25); + mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG25, P3A_RG_PLL_DELTA_PE2H, + P3A_RG_PLL_DELTA_PE2H_VAL(0x36)); /* change pll BW 0.6M */ - tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG5); - tmp &= ~(P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H); - tmp |= P3A_RG_PLL_BR_PE2H_VAL(0x1) | P3A_RG_PLL_IC_PE2H_VAL(0x1); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG5); - - tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG4); - tmp &= ~(P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H); - tmp |= P3A_RG_PLL_BC_PE2H_VAL(0x3); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG4); - - tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG6); - tmp &= ~P3A_RG_PLL_IR_PE2H; - tmp |= P3A_RG_PLL_IR_PE2H_VAL(0x2); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG6); - - tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG7); - tmp &= ~P3A_RG_PLL_BP_PE2H; - tmp |= P3A_RG_PLL_BP_PE2H_VAL(0xa); - writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG7); + mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG5, + P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H, + P3A_RG_PLL_BR_PE2H_VAL(0x1) | P3A_RG_PLL_IC_PE2H_VAL(0x1)); + + mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG4, + P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H, + P3A_RG_PLL_BC_PE2H_VAL(0x3)); + + mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG6, P3A_RG_PLL_IR_PE2H, + P3A_RG_PLL_IR_PE2H_VAL(0x2)); + + mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG7, P3A_RG_PLL_BP_PE2H, + P3A_RG_PLL_BP_PE2H_VAL(0xa)); /* Tx Detect Rx Timing: 10us -> 5us */ - tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET1); - tmp &= ~P3D_RG_RXDET_STB2_SET; - tmp |= P3D_RG_RXDET_STB2_SET_VAL(0x10); - writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET1); + mtk_phy_update_bits(u3_banks->phyd + U3P_U3_PHYD_RXDET1, + P3D_RG_RXDET_STB2_SET, P3D_RG_RXDET_STB2_SET_VAL(0x10)); - tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET2); - tmp &= ~P3D_RG_RXDET_STB2_SET_P3; - tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10); - writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2); + mtk_phy_update_bits(u3_banks->phyd + U3P_U3_PHYD_RXDET2, + P3D_RG_RXDET_STB2_SET_P3, P3D_RG_RXDET_STB2_SET_P3_VAL(0x10)); /* wait for PCIe subsys register to active */ usleep_range(2500, 3000); @@ -770,15 +703,12 @@ static void pcie_phy_instance_power_on(struct mtk_tphy *tphy, struct mtk_phy_instance *instance) { struct u3phy_banks *bank = &instance->u3_banks; - u32 tmp; - tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD); - tmp &= ~(P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST); - writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD); + mtk_phy_clear_bits(bank->chip + U3P_U3_CHIP_GPIO_CTLD, + P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST); - tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE); - tmp &= ~(P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD); - writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE); + mtk_phy_clear_bits(bank->chip + U3P_U3_CHIP_GPIO_CTLE, + P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD); } static void pcie_phy_instance_power_off(struct mtk_tphy *tphy, @@ -786,15 +716,12 @@ static void pcie_phy_instance_power_off(struct mtk_tphy *tphy, { struct u3phy_banks *bank = &instance->u3_banks; - u32 tmp; - tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD); - tmp |= P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST; - writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD); + mtk_phy_set_bits(bank->chip + U3P_U3_CHIP_GPIO_CTLD, + P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST); - tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE); - tmp |= P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD; - writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE); + mtk_phy_set_bits(bank->chip + U3P_U3_CHIP_GPIO_CTLE, + P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD); } static void sata_phy_instance_init(struct mtk_tphy *tphy, @@ -802,55 +729,42 @@ static void sata_phy_instance_init(struct mtk_tphy *tphy, { struct u3phy_banks *u3_banks = &instance->u3_banks; void __iomem *phyd = u3_banks->phyd; - u32 tmp; /* charge current adjustment */ - tmp = readl(phyd + ANA_RG_CTRL_SIGNAL6); - tmp &= ~(RG_CDR_BIRLTR_GEN1_MSK | RG_CDR_BC_GEN1_MSK); - tmp |= RG_CDR_BIRLTR_GEN1_VAL(0x6) | RG_CDR_BC_GEN1_VAL(0x1a); - writel(tmp, phyd + ANA_RG_CTRL_SIGNAL6); - - tmp = readl(phyd + ANA_EQ_EYE_CTRL_SIGNAL4); - tmp &= ~RG_CDR_BIRLTD0_GEN1_MSK; - tmp |= RG_CDR_BIRLTD0_GEN1_VAL(0x18); - writel(tmp, phyd + ANA_EQ_EYE_CTRL_SIGNAL4); - - tmp = readl(phyd + ANA_EQ_EYE_CTRL_SIGNAL5); - tmp &= ~RG_CDR_BIRLTD0_GEN3_MSK; - tmp |= RG_CDR_BIRLTD0_GEN3_VAL(0x06); - writel(tmp, phyd + ANA_EQ_EYE_CTRL_SIGNAL5); - - tmp = readl(phyd + ANA_RG_CTRL_SIGNAL4); - tmp &= ~(RG_CDR_BICLTR_GEN1_MSK | RG_CDR_BR_GEN2_MSK); - tmp |= RG_CDR_BICLTR_GEN1_VAL(0x0c) | RG_CDR_BR_GEN2_VAL(0x07); - writel(tmp, phyd + ANA_RG_CTRL_SIGNAL4); - - tmp = readl(phyd + PHYD_CTRL_SIGNAL_MODE4); - tmp &= ~(RG_CDR_BICLTD0_GEN1_MSK | RG_CDR_BICLTD1_GEN1_MSK); - tmp |= RG_CDR_BICLTD0_GEN1_VAL(0x08) | RG_CDR_BICLTD1_GEN1_VAL(0x02); - writel(tmp, phyd + PHYD_CTRL_SIGNAL_MODE4); - - tmp = readl(phyd + PHYD_DESIGN_OPTION2); - tmp &= ~RG_LOCK_CNT_SEL_MSK; - tmp |= RG_LOCK_CNT_SEL_VAL(0x02); - writel(tmp, phyd + PHYD_DESIGN_OPTION2); - - tmp = readl(phyd + PHYD_DESIGN_OPTION9); - tmp &= ~(RG_T2_MIN_MSK | RG_TG_MIN_MSK | - RG_T2_MAX_MSK | RG_TG_MAX_MSK); - tmp |= RG_T2_MIN_VAL(0x12) | RG_TG_MIN_VAL(0x04) | - RG_T2_MAX_VAL(0x31) | RG_TG_MAX_VAL(0x0e); - writel(tmp, phyd + PHYD_DESIGN_OPTION9); - - tmp = readl(phyd + ANA_RG_CTRL_SIGNAL1); - tmp &= ~RG_IDRV_0DB_GEN1_MSK; - tmp |= RG_IDRV_0DB_GEN1_VAL(0x20); - writel(tmp, phyd + ANA_RG_CTRL_SIGNAL1); - - tmp = readl(phyd + ANA_EQ_EYE_CTRL_SIGNAL1); - tmp &= ~RG_EQ_DLEQ_LFI_GEN1_MSK; - tmp |= RG_EQ_DLEQ_LFI_GEN1_VAL(0x03); - writel(tmp, phyd + ANA_EQ_EYE_CTRL_SIGNAL1); + mtk_phy_update_bits(phyd + ANA_RG_CTRL_SIGNAL6, + RG_CDR_BIRLTR_GEN1_MSK | RG_CDR_BC_GEN1_MSK, + RG_CDR_BIRLTR_GEN1_VAL(0x6) | RG_CDR_BC_GEN1_VAL(0x1a)); + + mtk_phy_update_bits(phyd + ANA_EQ_EYE_CTRL_SIGNAL4, RG_CDR_BIRLTD0_GEN1_MSK, + RG_CDR_BIRLTD0_GEN1_VAL(0x18)); + + mtk_phy_update_bits(phyd + ANA_EQ_EYE_CTRL_SIGNAL5, RG_CDR_BIRLTD0_GEN3_MSK, + RG_CDR_BIRLTD0_GEN3_VAL(0x06)); + + mtk_phy_update_bits(phyd + ANA_RG_CTRL_SIGNAL4, + RG_CDR_BICLTR_GEN1_MSK | RG_CDR_BR_GEN2_MSK, + RG_CDR_BICLTR_GEN1_VAL(0x0c) | RG_CDR_BR_GEN2_VAL(0x07)); + + mtk_phy_update_bits(phyd + PHYD_CTRL_SIGNAL_MODE4, + RG_CDR_BICLTD0_GEN1_MSK | RG_CDR_BICLTD1_GEN1_MSK, + RG_CDR_BICLTD0_GEN1_VAL(0x08) | RG_CDR_BICLTD1_GEN1_VAL(0x02)); + + mtk_phy_update_bits(phyd + PHYD_DESIGN_OPTION2, RG_LOCK_CNT_SEL_MSK, + RG_LOCK_CNT_SEL_VAL(0x02)); + + mtk_phy_update_bits(phyd + PHYD_DESIGN_OPTION9, + RG_T2_MIN_MSK | RG_TG_MIN_MSK, + RG_T2_MIN_VAL(0x12) | RG_TG_MIN_VAL(0x04)); + + mtk_phy_update_bits(phyd + PHYD_DESIGN_OPTION9, + RG_T2_MAX_MSK | RG_TG_MAX_MSK, + RG_T2_MAX_VAL(0x31) | RG_TG_MAX_VAL(0x0e)); + + mtk_phy_update_bits(phyd + ANA_RG_CTRL_SIGNAL1, RG_IDRV_0DB_GEN1_MSK, + RG_IDRV_0DB_GEN1_VAL(0x20)); + + mtk_phy_update_bits(phyd + ANA_EQ_EYE_CTRL_SIGNAL1, RG_EQ_DLEQ_LFI_GEN1_MSK, + RG_EQ_DLEQ_LFI_GEN1_VAL(0x03)); dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index); } @@ -938,48 +852,29 @@ static void u2_phy_props_set(struct mtk_tphy *tphy, { struct u2phy_banks *u2_banks = &instance->u2_banks; void __iomem *com = u2_banks->com; - u32 tmp; - if (instance->bc12_en) { - tmp = readl(com + U3P_U2PHYBC12C); - tmp |= P2C_RG_CHGDT_EN; /* BC1.2 path Enable */ - writel(tmp, com + U3P_U2PHYBC12C); - } + if (instance->bc12_en) /* BC1.2 path Enable */ + mtk_phy_set_bits(com + U3P_U2PHYBC12C, P2C_RG_CHGDT_EN); - if (tphy->pdata->version < MTK_PHY_V3 && instance->eye_src) { - tmp = readl(com + U3P_USBPHYACR5); - tmp &= ~PA5_RG_U2_HSTX_SRCTRL; - tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(instance->eye_src); - writel(tmp, com + U3P_USBPHYACR5); - } + if (tphy->pdata->version < MTK_PHY_V3 && instance->eye_src) + mtk_phy_update_bits(com + U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCTRL, + PA5_RG_U2_HSTX_SRCTRL_VAL(instance->eye_src)); - if (instance->eye_vrt) { - tmp = readl(com + U3P_USBPHYACR1); - tmp &= ~PA1_RG_VRT_SEL; - tmp |= PA1_RG_VRT_SEL_VAL(instance->eye_vrt); - writel(tmp, com + U3P_USBPHYACR1); - } + if (instance->eye_vrt) + mtk_phy_update_bits(com + U3P_USBPHYACR1, PA1_RG_VRT_SEL, + PA1_RG_VRT_SEL_VAL(instance->eye_vrt)); - if (instance->eye_term) { - tmp = readl(com + U3P_USBPHYACR1); - tmp &= ~PA1_RG_TERM_SEL; - tmp |= PA1_RG_TERM_SEL_VAL(instance->eye_term); - writel(tmp, com + U3P_USBPHYACR1); - } + if (instance->eye_term) + mtk_phy_update_bits(com + U3P_USBPHYACR1, PA1_RG_TERM_SEL, + PA1_RG_TERM_SEL_VAL(instance->eye_term)); - if (instance->intr) { - tmp = readl(com + U3P_USBPHYACR1); - tmp &= ~PA1_RG_INTR_CAL; - tmp |= PA1_RG_INTR_CAL_VAL(instance->intr); - writel(tmp, com + U3P_USBPHYACR1); - } + if (instance->intr) + mtk_phy_update_bits(com + U3P_USBPHYACR1, PA1_RG_INTR_CAL, + PA1_RG_INTR_CAL_VAL(instance->intr)); - if (instance->discth) { - tmp = readl(com + U3P_USBPHYACR6); - tmp &= ~PA6_RG_U2_DISCTH; - tmp |= PA6_RG_U2_DISCTH_VAL(instance->discth); - writel(tmp, com + U3P_USBPHYACR6); - } + if (instance->discth) + mtk_phy_update_bits(com + U3P_USBPHYACR6, PA6_RG_U2_DISCTH, + PA6_RG_U2_DISCTH_VAL(instance->discth)); } /* type switch for usb3/pcie/sgmii/sata */ @@ -1040,6 +935,117 @@ static int phy_type_set(struct mtk_phy_instance *instance) return 0; } +static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instance) +{ + struct device *dev = &instance->phy->dev; + int ret = 0; + + /* tphy v1 doesn't support sw efuse, skip it */ + if (!tphy->pdata->sw_efuse_supported) { + instance->efuse_sw_en = 0; + return 0; + } + + /* software efuse is optional */ + instance->efuse_sw_en = device_property_read_bool(dev, "nvmem-cells"); + if (!instance->efuse_sw_en) + return 0; + + switch (instance->type) { + case PHY_TYPE_USB2: + ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr); + if (ret) { + dev_err(dev, "fail to get u2 intr efuse, %d\n", ret); + break; + } + + /* no efuse, ignore it */ + if (!instance->efuse_intr) { + dev_warn(dev, "no u2 intr efuse, but dts enable it\n"); + instance->efuse_sw_en = 0; + break; + } + + dev_dbg(dev, "u2 efuse - intr %x\n", instance->efuse_intr); + break; + + case PHY_TYPE_USB3: + case PHY_TYPE_PCIE: + ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr); + if (ret) { + dev_err(dev, "fail to get u3 intr efuse, %d\n", ret); + break; + } + + ret = nvmem_cell_read_variable_le_u32(dev, "rx_imp", &instance->efuse_rx_imp); + if (ret) { + dev_err(dev, "fail to get u3 rx_imp efuse, %d\n", ret); + break; + } + + ret = nvmem_cell_read_variable_le_u32(dev, "tx_imp", &instance->efuse_tx_imp); + if (ret) { + dev_err(dev, "fail to get u3 tx_imp efuse, %d\n", ret); + break; + } + + /* no efuse, ignore it */ + if (!instance->efuse_intr && + !instance->efuse_rx_imp && + !instance->efuse_rx_imp) { + dev_warn(dev, "no u3 intr efuse, but dts enable it\n"); + instance->efuse_sw_en = 0; + break; + } + + dev_dbg(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n", + instance->efuse_intr, instance->efuse_rx_imp,instance->efuse_tx_imp); + break; + default: + dev_err(dev, "no sw efuse for type %d\n", instance->type); + ret = -EINVAL; + } + + return ret; +} + +static void phy_efuse_set(struct mtk_phy_instance *instance) +{ + struct device *dev = &instance->phy->dev; + struct u2phy_banks *u2_banks = &instance->u2_banks; + struct u3phy_banks *u3_banks = &instance->u3_banks; + + if (!instance->efuse_sw_en) + return; + + switch (instance->type) { + case PHY_TYPE_USB2: + mtk_phy_set_bits(u2_banks->misc + U3P_MISC_REG1, MR1_EFUSE_AUTO_LOAD_DIS); + + mtk_phy_update_bits(u2_banks->com + U3P_USBPHYACR1, PA1_RG_INTR_CAL, + PA1_RG_INTR_CAL_VAL(instance->efuse_intr)); + break; + case PHY_TYPE_USB3: + case PHY_TYPE_PCIE: + mtk_phy_set_bits(u3_banks->phyd + U3P_U3_PHYD_RSV, P3D_RG_EFUSE_AUTO_LOAD_DIS); + + mtk_phy_update_bits(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_TX_IMPEL, + P3D_RG_TX_IMPEL_VAL(instance->efuse_tx_imp)); + mtk_phy_set_bits(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_FORCE_TX_IMPEL); + + mtk_phy_update_bits(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_RX_IMPEL, + P3D_RG_RX_IMPEL_VAL(instance->efuse_rx_imp)); + mtk_phy_set_bits(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_FORCE_RX_IMPEL); + + mtk_phy_update_bits(u3_banks->phya + U3P_U3_PHYA_REG0, P3A_RG_IEXT_INTR, + P3A_RG_IEXT_INTR_VAL(instance->efuse_intr)); + break; + default: + dev_warn(dev, "no sw efuse for type %d\n", instance->type); + break; + } +} + static int mtk_phy_init(struct phy *phy) { struct mtk_phy_instance *instance = phy_get_drvdata(phy); @@ -1050,6 +1056,8 @@ static int mtk_phy_init(struct phy *phy) if (ret) return ret; + phy_efuse_set(instance); + switch (instance->type) { case PHY_TYPE_USB2: u2_phy_instance_init(tphy, instance); @@ -1134,6 +1142,7 @@ static struct phy *mtk_phy_xlate(struct device *dev, struct mtk_phy_instance *instance = NULL; struct device_node *phy_np = args->np; int index; + int ret; if (args->args_count != 1) { dev_err(dev, "invalid number of cells in 'phy' property\n"); @@ -1174,6 +1183,10 @@ static struct phy *mtk_phy_xlate(struct device *dev, return ERR_PTR(-EINVAL); } + ret = phy_efuse_get(tphy, instance); + if (ret) + return ERR_PTR(ret); + phy_parse_property(tphy, instance); phy_type_set(instance); @@ -1196,10 +1209,12 @@ static const struct mtk_phy_pdata tphy_v1_pdata = { static const struct mtk_phy_pdata tphy_v2_pdata = { .avoid_rx_sen_degradation = false, + .sw_efuse_supported = true, .version = MTK_PHY_V2, }; static const struct mtk_phy_pdata tphy_v3_pdata = { + .sw_efuse_supported = true, .version = MTK_PHY_V3, }; @@ -1210,6 +1225,7 @@ static const struct mtk_phy_pdata mt8173_pdata = { static const struct mtk_phy_pdata mt8195_pdata = { .sw_pll_48m_to_26m = true, + .sw_efuse_supported = true, .version = MTK_PHY_V3, }; |