Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.14-rc4 197 lines 7.0 kB view raw
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 49static int txgbe_write_pma(struct dw_xpcs *xpcs, int reg, u16 val) 50{ 51 return xpcs_write(xpcs, MDIO_MMD_PMAPMD, TXGBE_PMA_MMD + reg, val); 52} 53 54static int txgbe_modify_pma(struct dw_xpcs *xpcs, int reg, u16 mask, u16 set) 55{ 56 return xpcs_modify(xpcs, MDIO_MMD_PMAPMD, TXGBE_PMA_MMD + reg, mask, 57 set); 58} 59 60static void txgbe_pma_config_10gbaser(struct dw_xpcs *xpcs) 61{ 62 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x21); 63 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0); 64 txgbe_modify_pma(xpcs, TXGBE_TX_GENCTL1, TXGBE_TX_GENCTL1_VBOOST_LVL, 65 FIELD_PREP(TXGBE_TX_GENCTL1_VBOOST_LVL, 0x5)); 66 txgbe_write_pma(xpcs, TXGBE_MISC_CTL0, TXGBE_MISC_CTL0_PLL | 67 TXGBE_MISC_CTL0_CR_PARA_SEL | TXGBE_MISC_CTL0_RX_VREF(0xF)); 68 txgbe_write_pma(xpcs, TXGBE_VCO_CAL_LD0, 0x549); 69 txgbe_write_pma(xpcs, TXGBE_VCO_CAL_REF0, 0x29); 70 txgbe_write_pma(xpcs, TXGBE_TX_RATE_CTL, 0); 71 txgbe_write_pma(xpcs, TXGBE_RX_RATE_CTL, 0); 72 txgbe_write_pma(xpcs, TXGBE_TX_GEN_CTL2, TXGBE_TX_GEN_CTL2_TX0_WIDTH(3)); 73 txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL2, TXGBE_RX_GEN_CTL2_RX0_WIDTH(3)); 74 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL2, TXGBE_MPLLA_CTL2_DIV16P5_CLK_EN | 75 TXGBE_MPLLA_CTL2_DIV10_CLK_EN); 76 77 txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL0, TXGBE_RX_EQ_CTL0_CTLE_POLE(2) | 78 TXGBE_RX_EQ_CTL0_CTLE_BOOST(5)); 79 txgbe_modify_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, TXGBE_RX_EQ_ATTN_LVL0, 0); 80 txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0xBE); 81 txgbe_modify_pma(xpcs, TXGBE_AFE_DFE_ENABLE, 82 TXGBE_DFE_EN_0 | TXGBE_AFE_EN_0, 0); 83 txgbe_modify_pma(xpcs, TXGBE_RX_EQ_CTL4, TXGBE_RX_EQ_CTL4_CONT_ADAPT0, 84 0); 85} 86 87static void txgbe_pma_config_1g(struct dw_xpcs *xpcs) 88{ 89 txgbe_modify_pma(xpcs, TXGBE_TX_GENCTL1, 90 TXGBE_TX_GENCTL1_VBOOST_LVL | 91 TXGBE_TX_GENCTL1_VBOOST_EN0, 92 FIELD_PREP(TXGBE_TX_GENCTL1_VBOOST_LVL, 0x5)); 93 txgbe_write_pma(xpcs, TXGBE_MISC_CTL0, TXGBE_MISC_CTL0_PLL | 94 TXGBE_MISC_CTL0_CR_PARA_SEL | TXGBE_MISC_CTL0_RX_VREF(0xF)); 95 96 txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL0, TXGBE_RX_EQ_CTL0_VGA1_GAIN(7) | 97 TXGBE_RX_EQ_CTL0_VGA2_GAIN(7) | TXGBE_RX_EQ_CTL0_CTLE_BOOST(6)); 98 txgbe_modify_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, TXGBE_RX_EQ_ATTN_LVL0, 0); 99 txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0); 100 txgbe_modify_pma(xpcs, TXGBE_RX_GEN_CTL3, TXGBE_RX_GEN_CTL3_LOS_TRSHLD0, 101 FIELD_PREP(TXGBE_RX_GEN_CTL3_LOS_TRSHLD0, 0x4)); 102 103 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x20); 104 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0x46); 105 txgbe_write_pma(xpcs, TXGBE_VCO_CAL_LD0, 0x540); 106 txgbe_write_pma(xpcs, TXGBE_VCO_CAL_REF0, 0x2A); 107 txgbe_write_pma(xpcs, TXGBE_AFE_DFE_ENABLE, 0); 108 txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL4, TXGBE_RX_EQ_CTL4_CONT_OFF_CAN0); 109 txgbe_write_pma(xpcs, TXGBE_TX_RATE_CTL, TXGBE_TX_RATE_CTL_TX0_RATE(3)); 110 txgbe_write_pma(xpcs, TXGBE_RX_RATE_CTL, TXGBE_RX_RATE_CTL_RX0_RATE(3)); 111 txgbe_write_pma(xpcs, TXGBE_TX_GEN_CTL2, TXGBE_TX_GEN_CTL2_TX0_WIDTH(1)); 112 txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL2, TXGBE_RX_GEN_CTL2_RX0_WIDTH(1)); 113 txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL2, TXGBE_MPLLA_CTL2_DIV10_CLK_EN); 114} 115 116static int txgbe_pcs_poll_power_up(struct dw_xpcs *xpcs) 117{ 118 int val, ret; 119 120 /* Wait xpcs power-up good */ 121 ret = read_poll_timeout(xpcs_read_vpcs, val, 122 (val & DW_PSEQ_ST) == DW_PSEQ_ST_GOOD, 123 10000, 1000000, false, 124 xpcs, DW_VR_XS_PCS_DIG_STS); 125 if (ret < 0) 126 dev_err(&xpcs->mdiodev->dev, "xpcs power-up timeout\n"); 127 128 return ret; 129} 130 131static int txgbe_pma_init_done(struct dw_xpcs *xpcs) 132{ 133 int val, ret; 134 135 xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_VR_RST | DW_EN_VSMMD1); 136 137 /* wait pma initialization done */ 138 ret = read_poll_timeout(xpcs_read_vpcs, val, !(val & DW_VR_RST), 139 100000, 10000000, false, 140 xpcs, DW_VR_XS_PCS_DIG_CTRL1); 141 if (ret < 0) 142 dev_err(&xpcs->mdiodev->dev, "xpcs pma initialization timeout\n"); 143 144 return ret; 145} 146 147static bool txgbe_xpcs_mode_quirk(struct dw_xpcs *xpcs) 148{ 149 int ret; 150 151 /* When txgbe do LAN reset, PCS will change to default 10GBASE-R mode */ 152 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_CTRL2); 153 ret &= MDIO_PCS_CTRL2_TYPE; 154 if ((ret == MDIO_PCS_CTRL2_10GBR && 155 xpcs->interface != PHY_INTERFACE_MODE_10GBASER) || 156 xpcs->interface == PHY_INTERFACE_MODE_SGMII) 157 return true; 158 159 return false; 160} 161 162int txgbe_xpcs_switch_mode(struct dw_xpcs *xpcs, phy_interface_t interface) 163{ 164 int ret; 165 166 switch (interface) { 167 case PHY_INTERFACE_MODE_10GBASER: 168 case PHY_INTERFACE_MODE_SGMII: 169 case PHY_INTERFACE_MODE_1000BASEX: 170 break; 171 default: 172 return 0; 173 } 174 175 if (xpcs->interface == interface && !txgbe_xpcs_mode_quirk(xpcs)) 176 return 0; 177 178 xpcs->interface = interface; 179 180 ret = txgbe_pcs_poll_power_up(xpcs); 181 if (ret < 0) 182 return ret; 183 184 if (interface == PHY_INTERFACE_MODE_10GBASER) { 185 xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2, MDIO_PCS_CTRL2_10GBR); 186 xpcs_modify(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1, 187 MDIO_CTRL1_SPEED10G, MDIO_CTRL1_SPEED10G); 188 txgbe_pma_config_10gbaser(xpcs); 189 } else { 190 xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2, MDIO_PCS_CTRL2_10GBX); 191 xpcs_write(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1, 0); 192 xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL1, 0); 193 txgbe_pma_config_1g(xpcs); 194 } 195 196 return txgbe_pma_init_done(xpcs); 197}