1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */ 3 4 #include <linux/pcs/pcs-xpcs.h> 5 #include <linux/mdio.h> 6 #include "pcs-xpcs.h" 7 8 /* VR_XS_PMA_MMD */ 9 #define TXGBE_PMA_MMD 0x8020 10 #define TXGBE_TX_GENCTL1 0x11 11 #define TXGBE_TX_GENCTL1_VBOOST_LVL GENMASK(10, 8) 12 #define TXGBE_TX_GENCTL1_VBOOST_EN0 BIT(4) 13 #define TXGBE_TX_GEN_CTL2 0x12 14 #define TXGBE_TX_GEN_CTL2_TX0_WIDTH(v) FIELD_PREP(GENMASK(9, 8), v) 15 #define TXGBE_TX_RATE_CTL 0x14 16 #define TXGBE_TX_RATE_CTL_TX0_RATE(v) FIELD_PREP(GENMASK(2, 0), v) 17 #define TXGBE_RX_GEN_CTL2 0x32 18 #define TXGBE_RX_GEN_CTL2_RX0_WIDTH(v) FIELD_PREP(GENMASK(9, 8), v) 19 #define TXGBE_RX_GEN_CTL3 0x33 20 #define TXGBE_RX_GEN_CTL3_LOS_TRSHLD0 GENMASK(2, 0) 21 #define TXGBE_RX_RATE_CTL 0x34 22 #define TXGBE_RX_RATE_CTL_RX0_RATE(v) FIELD_PREP(GENMASK(1, 0), v) 23 #define TXGBE_RX_EQ_ATTN_CTL 0x37 24 #define TXGBE_RX_EQ_ATTN_LVL0 GENMASK(2, 0) 25 #define TXGBE_RX_EQ_CTL0 0x38 26 #define TXGBE_RX_EQ_CTL0_VGA1_GAIN(v) FIELD_PREP(GENMASK(15, 12), v) 27 #define TXGBE_RX_EQ_CTL0_VGA2_GAIN(v) FIELD_PREP(GENMASK(11, 8), v) 28 #define TXGBE_RX_EQ_CTL0_CTLE_POLE(v) FIELD_PREP(GENMASK(7, 5), v) 29 #define TXGBE_RX_EQ_CTL0_CTLE_BOOST(v) FIELD_PREP(GENMASK(4, 0), v) 30 #define TXGBE_RX_EQ_CTL4 0x3C 31 #define TXGBE_RX_EQ_CTL4_CONT_OFF_CAN0 BIT(4) 32 #define TXGBE_RX_EQ_CTL4_CONT_ADAPT0 BIT(0) 33 #define TXGBE_AFE_DFE_ENABLE 0x3D 34 #define TXGBE_DFE_EN_0 BIT(4) 35 #define TXGBE_AFE_EN_0 BIT(0) 36 #define TXGBE_DFE_TAP_CTL0 0x3E 37 #define TXGBE_MPLLA_CTL0 0x51 38 #define TXGBE_MPLLA_CTL2 0x53 39 #define TXGBE_MPLLA_CTL2_DIV16P5_CLK_EN BIT(10) 40 #define TXGBE_MPLLA_CTL2_DIV10_CLK_EN BIT(9) 41 #define TXGBE_MPLLA_CTL3 0x57 42 #define TXGBE_MISC_CTL0 0x70 43 #define TXGBE_MISC_CTL0_PLL BIT(15) 44 #define TXGBE_MISC_CTL0_CR_PARA_SEL BIT(14) 45 #define TXGBE_MISC_CTL0_RX_VREF(v) FIELD_PREP(GENMASK(12, 8), v) 46 #define TXGBE_VCO_CAL_LD0 0x72 47 #define TXGBE_VCO_CAL_REF0 0x76 48 49 static int txgbe_read_pma(struct dw_xpcs *xpcs, int reg) 50 { 51 return xpcs_read(xpcs, MDIO_MMD_PMAPMD, TXGBE_PMA_MMD + reg); 52 } 53 54 static int txgbe_write_pma(struct dw_xpcs *xpcs, int reg, u16 val) 55 { 56 return xpcs_write(xpcs, MDIO_MMD_PMAPMD, TXGBE_PMA_MMD + reg, val); 57 } 58 59 static void txgbe_pma_config_10gbaser(struct dw_xpcs *xpcs) 60 { 61 int val; 62 63 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x21); 64 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0); 65 val = txgbe_read_pma(xpcs, TXGBE_TX_GENCTL1); 66 val = u16_replace_bits(val, 0x5, TXGBE_TX_GENCTL1_VBOOST_LVL); 67 txgbe_write_pma(xpcs, TXGBE_TX_GENCTL1, val); 68 txgbe_write_pma(xpcs, TXGBE_MISC_CTL0, TXGBE_MISC_CTL0_PLL | 69 TXGBE_MISC_CTL0_CR_PARA_SEL | TXGBE_MISC_CTL0_RX_VREF(0xF)); 70 txgbe_write_pma(xpcs, TXGBE_VCO_CAL_LD0, 0x549); 71 txgbe_write_pma(xpcs, TXGBE_VCO_CAL_REF0, 0x29); 72 txgbe_write_pma(xpcs, TXGBE_TX_RATE_CTL, 0); 73 txgbe_write_pma(xpcs, TXGBE_RX_RATE_CTL, 0); 74 txgbe_write_pma(xpcs, TXGBE_TX_GEN_CTL2, TXGBE_TX_GEN_CTL2_TX0_WIDTH(3)); 75 txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL2, TXGBE_RX_GEN_CTL2_RX0_WIDTH(3)); 76 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL2, TXGBE_MPLLA_CTL2_DIV16P5_CLK_EN | 77 TXGBE_MPLLA_CTL2_DIV10_CLK_EN); 78 79 txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL0, TXGBE_RX_EQ_CTL0_CTLE_POLE(2) | 80 TXGBE_RX_EQ_CTL0_CTLE_BOOST(5)); 81 val = txgbe_read_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL); 82 val &= ~TXGBE_RX_EQ_ATTN_LVL0; 83 txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val); 84 txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0xBE); 85 val = txgbe_read_pma(xpcs, TXGBE_AFE_DFE_ENABLE); 86 val &= ~(TXGBE_DFE_EN_0 | TXGBE_AFE_EN_0); 87 txgbe_write_pma(xpcs, TXGBE_AFE_DFE_ENABLE, val); 88 val = txgbe_read_pma(xpcs, TXGBE_RX_EQ_CTL4); 89 val &= ~TXGBE_RX_EQ_CTL4_CONT_ADAPT0; 90 txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL4, val); 91 } 92 93 static void txgbe_pma_config_1g(struct dw_xpcs *xpcs) 94 { 95 int val; 96 97 val = txgbe_read_pma(xpcs, TXGBE_TX_GENCTL1); 98 val = u16_replace_bits(val, 0x5, TXGBE_TX_GENCTL1_VBOOST_LVL); 99 val &= ~TXGBE_TX_GENCTL1_VBOOST_EN0; 100 txgbe_write_pma(xpcs, TXGBE_TX_GENCTL1, val); 101 txgbe_write_pma(xpcs, TXGBE_MISC_CTL0, TXGBE_MISC_CTL0_PLL | 102 TXGBE_MISC_CTL0_CR_PARA_SEL | TXGBE_MISC_CTL0_RX_VREF(0xF)); 103 104 txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL0, TXGBE_RX_EQ_CTL0_VGA1_GAIN(7) | 105 TXGBE_RX_EQ_CTL0_VGA2_GAIN(7) | TXGBE_RX_EQ_CTL0_CTLE_BOOST(6)); 106 val = txgbe_read_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL); 107 val &= ~TXGBE_RX_EQ_ATTN_LVL0; 108 txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val); 109 txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0); 110 val = txgbe_read_pma(xpcs, TXGBE_RX_GEN_CTL3); 111 val = u16_replace_bits(val, 0x4, TXGBE_RX_GEN_CTL3_LOS_TRSHLD0); 112 txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val); 113 114 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x20); 115 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0x46); 116 txgbe_write_pma(xpcs, TXGBE_VCO_CAL_LD0, 0x540); 117 txgbe_write_pma(xpcs, TXGBE_VCO_CAL_REF0, 0x2A); 118 txgbe_write_pma(xpcs, TXGBE_AFE_DFE_ENABLE, 0); 119 txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL4, TXGBE_RX_EQ_CTL4_CONT_OFF_CAN0); 120 txgbe_write_pma(xpcs, TXGBE_TX_RATE_CTL, TXGBE_TX_RATE_CTL_TX0_RATE(3)); 121 txgbe_write_pma(xpcs, TXGBE_RX_RATE_CTL, TXGBE_RX_RATE_CTL_RX0_RATE(3)); 122 txgbe_write_pma(xpcs, TXGBE_TX_GEN_CTL2, TXGBE_TX_GEN_CTL2_TX0_WIDTH(1)); 123 txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL2, TXGBE_RX_GEN_CTL2_RX0_WIDTH(1)); 124 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL2, TXGBE_MPLLA_CTL2_DIV10_CLK_EN); 125 } 126 127 static int txgbe_pcs_poll_power_up(struct dw_xpcs *xpcs) 128 { 129 int val, ret; 130 131 /* Wait xpcs power-up good */ 132 ret = read_poll_timeout(xpcs_read_vpcs, val, 133 (val & DW_PSEQ_ST) == DW_PSEQ_ST_GOOD, 134 10000, 1000000, false, 135 xpcs, DW_VR_XS_PCS_DIG_STS); 136 if (ret < 0) 137 dev_err(&xpcs->mdiodev->dev, "xpcs power-up timeout\n"); 138 139 return ret; 140 } 141 142 static int txgbe_pma_init_done(struct dw_xpcs *xpcs) 143 { 144 int val, ret; 145 146 xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_VR_RST | DW_EN_VSMMD1); 147 148 /* wait pma initialization done */ 149 ret = read_poll_timeout(xpcs_read_vpcs, val, !(val & DW_VR_RST), 150 100000, 10000000, false, 151 xpcs, DW_VR_XS_PCS_DIG_CTRL1); 152 if (ret < 0) 153 dev_err(&xpcs->mdiodev->dev, "xpcs pma initialization timeout\n"); 154 155 return ret; 156 } 157 158 static bool txgbe_xpcs_mode_quirk(struct dw_xpcs *xpcs) 159 { 160 int ret; 161 162 /* When txgbe do LAN reset, PCS will change to default 10GBASE-R mode */ 163 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_CTRL2); 164 ret &= MDIO_PCS_CTRL2_TYPE; 165 if ((ret == MDIO_PCS_CTRL2_10GBR && 166 xpcs->interface != PHY_INTERFACE_MODE_10GBASER) || 167 xpcs->interface == PHY_INTERFACE_MODE_SGMII) 168 return true; 169 170 return false; 171 } 172 173 int txgbe_xpcs_switch_mode(struct dw_xpcs *xpcs, phy_interface_t interface) 174 { 175 int val, ret; 176 177 switch (interface) { 178 case PHY_INTERFACE_MODE_10GBASER: 179 case PHY_INTERFACE_MODE_SGMII: 180 case PHY_INTERFACE_MODE_1000BASEX: 181 break; 182 default: 183 return 0; 184 } 185 186 if (xpcs->interface == interface && !txgbe_xpcs_mode_quirk(xpcs)) 187 return 0; 188 189 xpcs->interface = interface; 190 191 ret = txgbe_pcs_poll_power_up(xpcs); 192 if (ret < 0) 193 return ret; 194 195 if (interface == PHY_INTERFACE_MODE_10GBASER) { 196 xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2, MDIO_PCS_CTRL2_10GBR); 197 val = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1); 198 val |= MDIO_CTRL1_SPEED10G; 199 xpcs_write(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1, val); 200 txgbe_pma_config_10gbaser(xpcs); 201 } else { 202 xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2, MDIO_PCS_CTRL2_10GBX); 203 xpcs_write(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1, 0); 204 xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL1, 0); 205 txgbe_pma_config_1g(xpcs); 206 } 207 208 return txgbe_pma_init_done(xpcs); 209 } 210