1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2023, Linaro Limited 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/ethtool.h> 8 #include <linux/module.h> 9 #include <linux/of.h> 10 #include <linux/phy/phy.h> 11 #include <linux/platform_device.h> 12 #include <linux/regmap.h> 13 14 #define QSERDES_QMP_PLL 0x0 15 #define QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0 (QSERDES_QMP_PLL + 0x1ac) 16 #define QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0 (QSERDES_QMP_PLL + 0x1b0) 17 #define QSERDES_COM_BIN_VCOCAL_HSCLK_SEL (QSERDES_QMP_PLL + 0x1bc) 18 #define QSERDES_COM_CORE_CLK_EN (QSERDES_QMP_PLL + 0x174) 19 #define QSERDES_COM_CORECLK_DIV_MODE0 (QSERDES_QMP_PLL + 0x168) 20 #define QSERDES_COM_CP_CTRL_MODE0 (QSERDES_QMP_PLL + 0x74) 21 #define QSERDES_COM_DEC_START_MODE0 (QSERDES_QMP_PLL + 0xbc) 22 #define QSERDES_COM_DIV_FRAC_START1_MODE0 (QSERDES_QMP_PLL + 0xcc) 23 #define QSERDES_COM_DIV_FRAC_START2_MODE0 (QSERDES_QMP_PLL + 0xd0) 24 #define QSERDES_COM_DIV_FRAC_START3_MODE0 (QSERDES_QMP_PLL + 0xd4) 25 #define QSERDES_COM_HSCLK_HS_SWITCH_SEL (QSERDES_QMP_PLL + 0x15c) 26 #define QSERDES_COM_HSCLK_SEL (QSERDES_QMP_PLL + 0x158) 27 #define QSERDES_COM_LOCK_CMP1_MODE0 (QSERDES_QMP_PLL + 0xac) 28 #define QSERDES_COM_LOCK_CMP2_MODE0 (QSERDES_QMP_PLL + 0xb0) 29 #define QSERDES_COM_PLL_CCTRL_MODE0 (QSERDES_QMP_PLL + 0x84) 30 #define QSERDES_COM_PLL_IVCO (QSERDES_QMP_PLL + 0x58) 31 #define QSERDES_COM_PLL_RCTRL_MODE0 (QSERDES_QMP_PLL + 0x7c) 32 #define QSERDES_COM_SYSCLK_EN_SEL (QSERDES_QMP_PLL + 0x94) 33 #define QSERDES_COM_VCO_TUNE1_MODE0 (QSERDES_QMP_PLL + 0x110) 34 #define QSERDES_COM_VCO_TUNE2_MODE0 (QSERDES_QMP_PLL + 0x114) 35 #define QSERDES_COM_VCO_TUNE_INITVAL2 (QSERDES_QMP_PLL + 0x124) 36 #define QSERDES_COM_C_READY_STATUS (QSERDES_QMP_PLL + 0x178) 37 #define QSERDES_COM_CMN_STATUS (QSERDES_QMP_PLL + 0x140) 38 39 #define QSERDES_RX 0x600 40 #define QSERDES_RX_UCDR_FO_GAIN (QSERDES_RX + 0x8) 41 #define QSERDES_RX_UCDR_SO_GAIN (QSERDES_RX + 0x14) 42 #define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN (QSERDES_RX + 0x30) 43 #define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE (QSERDES_RX + 0x34) 44 #define QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW (QSERDES_RX + 0x3c) 45 #define QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH (QSERDES_RX + 0x40) 46 #define QSERDES_RX_UCDR_PI_CONTROLS (QSERDES_RX + 0x44) 47 #define QSERDES_RX_UCDR_PI_CTRL2 (QSERDES_RX + 0x48) 48 #define QSERDES_RX_RX_TERM_BW (QSERDES_RX + 0x80) 49 #define QSERDES_RX_VGA_CAL_CNTRL2 (QSERDES_RX + 0xd8) 50 #define QSERDES_RX_GM_CAL (QSERDES_RX + 0xdc) 51 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1 (QSERDES_RX + 0xe8) 52 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 (QSERDES_RX + 0xec) 53 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 (QSERDES_RX + 0xf0) 54 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 (QSERDES_RX + 0xf4) 55 #define QSERDES_RX_RX_IDAC_TSETTLE_LOW (QSERDES_RX + 0xf8) 56 #define QSERDES_RX_RX_IDAC_TSETTLE_HIGH (QSERDES_RX + 0xfc) 57 #define QSERDES_RX_RX_IDAC_MEASURE_TIME (QSERDES_RX + 0x100) 58 #define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 (QSERDES_RX + 0x110) 59 #define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 (QSERDES_RX + 0x114) 60 #define QSERDES_RX_SIGDET_CNTRL (QSERDES_RX + 0x11c) 61 #define QSERDES_RX_SIGDET_DEGLITCH_CNTRL (QSERDES_RX + 0x124) 62 #define QSERDES_RX_RX_BAND (QSERDES_RX + 0x128) 63 #define QSERDES_RX_RX_MODE_00_LOW (QSERDES_RX + 0x15c) 64 #define QSERDES_RX_RX_MODE_00_HIGH (QSERDES_RX + 0x160) 65 #define QSERDES_RX_RX_MODE_00_HIGH2 (QSERDES_RX + 0x164) 66 #define QSERDES_RX_RX_MODE_00_HIGH3 (QSERDES_RX + 0x168) 67 #define QSERDES_RX_RX_MODE_00_HIGH4 (QSERDES_RX + 0x16c) 68 #define QSERDES_RX_RX_MODE_01_LOW (QSERDES_RX + 0x170) 69 #define QSERDES_RX_RX_MODE_01_HIGH (QSERDES_RX + 0x174) 70 #define QSERDES_RX_RX_MODE_01_HIGH2 (QSERDES_RX + 0x178) 71 #define QSERDES_RX_RX_MODE_01_HIGH3 (QSERDES_RX + 0x17c) 72 #define QSERDES_RX_RX_MODE_01_HIGH4 (QSERDES_RX + 0x180) 73 #define QSERDES_RX_RX_MODE_10_LOW (QSERDES_RX + 0x184) 74 #define QSERDES_RX_RX_MODE_10_HIGH (QSERDES_RX + 0x188) 75 #define QSERDES_RX_RX_MODE_10_HIGH2 (QSERDES_RX + 0x18c) 76 #define QSERDES_RX_RX_MODE_10_HIGH3 (QSERDES_RX + 0x190) 77 #define QSERDES_RX_RX_MODE_10_HIGH4 (QSERDES_RX + 0x194) 78 #define QSERDES_RX_DCC_CTRL1 (QSERDES_RX + 0x1a8) 79 80 #define QSERDES_TX 0x400 81 #define QSERDES_TX_TX_BAND (QSERDES_TX + 0x24) 82 #define QSERDES_TX_SLEW_CNTL (QSERDES_TX + 0x28) 83 #define QSERDES_TX_RES_CODE_LANE_OFFSET_TX (QSERDES_TX + 0x3c) 84 #define QSERDES_TX_RES_CODE_LANE_OFFSET_RX (QSERDES_TX + 0x40) 85 #define QSERDES_TX_LANE_MODE_1 (QSERDES_TX + 0x84) 86 #define QSERDES_TX_LANE_MODE_3 (QSERDES_TX + 0x8c) 87 #define QSERDES_TX_RCV_DETECT_LVL_2 (QSERDES_TX + 0xa4) 88 #define QSERDES_TX_TRAN_DRVR_EMP_EN (QSERDES_TX + 0xc0) 89 90 #define QSERDES_PCS 0xC00 91 #define QSERDES_PCS_PHY_START (QSERDES_PCS + 0x0) 92 #define QSERDES_PCS_POWER_DOWN_CONTROL (QSERDES_PCS + 0x4) 93 #define QSERDES_PCS_SW_RESET (QSERDES_PCS + 0x8) 94 #define QSERDES_PCS_LINE_RESET_TIME (QSERDES_PCS + 0xc) 95 #define QSERDES_PCS_TX_LARGE_AMP_DRV_LVL (QSERDES_PCS + 0x20) 96 #define QSERDES_PCS_TX_SMALL_AMP_DRV_LVL (QSERDES_PCS + 0x28) 97 #define QSERDES_PCS_TX_MID_TERM_CTRL1 (QSERDES_PCS + 0xd8) 98 #define QSERDES_PCS_TX_MID_TERM_CTRL2 (QSERDES_PCS + 0xdc) 99 #define QSERDES_PCS_SGMII_MISC_CTRL8 (QSERDES_PCS + 0x118) 100 #define QSERDES_PCS_PCS_READY_STATUS (QSERDES_PCS + 0x94) 101 102 #define QSERDES_COM_C_READY BIT(0) 103 #define QSERDES_PCS_READY BIT(0) 104 #define QSERDES_PCS_SGMIIPHY_READY BIT(7) 105 #define QSERDES_COM_C_PLL_LOCKED BIT(1) 106 107 struct qcom_dwmac_sgmii_phy_data { 108 struct regmap *regmap; 109 struct clk *refclk; 110 int speed; 111 }; 112 113 static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap) 114 { 115 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01); 116 regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01); 117 118 regmap_write(regmap, QSERDES_COM_PLL_IVCO, 0x0F); 119 regmap_write(regmap, QSERDES_COM_CP_CTRL_MODE0, 0x06); 120 regmap_write(regmap, QSERDES_COM_PLL_RCTRL_MODE0, 0x16); 121 regmap_write(regmap, QSERDES_COM_PLL_CCTRL_MODE0, 0x36); 122 regmap_write(regmap, QSERDES_COM_SYSCLK_EN_SEL, 0x1A); 123 regmap_write(regmap, QSERDES_COM_LOCK_CMP1_MODE0, 0x0A); 124 regmap_write(regmap, QSERDES_COM_LOCK_CMP2_MODE0, 0x1A); 125 regmap_write(regmap, QSERDES_COM_DEC_START_MODE0, 0x82); 126 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55); 127 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55); 128 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03); 129 regmap_write(regmap, QSERDES_COM_VCO_TUNE1_MODE0, 0x24); 130 131 regmap_write(regmap, QSERDES_COM_VCO_TUNE2_MODE0, 0x02); 132 regmap_write(regmap, QSERDES_COM_VCO_TUNE_INITVAL2, 0x00); 133 regmap_write(regmap, QSERDES_COM_HSCLK_SEL, 0x04); 134 regmap_write(regmap, QSERDES_COM_HSCLK_HS_SWITCH_SEL, 0x00); 135 regmap_write(regmap, QSERDES_COM_CORECLK_DIV_MODE0, 0x0A); 136 regmap_write(regmap, QSERDES_COM_CORE_CLK_EN, 0x00); 137 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xB9); 138 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1E); 139 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_HSCLK_SEL, 0x11); 140 141 regmap_write(regmap, QSERDES_TX_TX_BAND, 0x05); 142 regmap_write(regmap, QSERDES_TX_SLEW_CNTL, 0x0A); 143 regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_TX, 0x09); 144 regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_RX, 0x09); 145 regmap_write(regmap, QSERDES_TX_LANE_MODE_1, 0x05); 146 regmap_write(regmap, QSERDES_TX_LANE_MODE_3, 0x00); 147 regmap_write(regmap, QSERDES_TX_RCV_DETECT_LVL_2, 0x12); 148 regmap_write(regmap, QSERDES_TX_TRAN_DRVR_EMP_EN, 0x0C); 149 150 regmap_write(regmap, QSERDES_RX_UCDR_FO_GAIN, 0x0A); 151 regmap_write(regmap, QSERDES_RX_UCDR_SO_GAIN, 0x06); 152 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A); 153 regmap_write(regmap, QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F); 154 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00); 155 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01); 156 regmap_write(regmap, QSERDES_RX_UCDR_PI_CONTROLS, 0x81); 157 regmap_write(regmap, QSERDES_RX_UCDR_PI_CTRL2, 0x80); 158 regmap_write(regmap, QSERDES_RX_RX_TERM_BW, 0x04); 159 regmap_write(regmap, QSERDES_RX_VGA_CAL_CNTRL2, 0x08); 160 regmap_write(regmap, QSERDES_RX_GM_CAL, 0x0F); 161 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04); 162 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00); 163 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A); 164 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A); 165 regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_LOW, 0x80); 166 regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_HIGH, 0x01); 167 regmap_write(regmap, QSERDES_RX_RX_IDAC_MEASURE_TIME, 0x20); 168 regmap_write(regmap, QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17); 169 regmap_write(regmap, QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00); 170 regmap_write(regmap, QSERDES_RX_SIGDET_CNTRL, 0x0F); 171 regmap_write(regmap, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E); 172 regmap_write(regmap, QSERDES_RX_RX_BAND, 0x05); 173 regmap_write(regmap, QSERDES_RX_RX_MODE_00_LOW, 0xE0); 174 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH, 0xC8); 175 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH2, 0xC8); 176 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH3, 0x09); 177 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH4, 0xB1); 178 regmap_write(regmap, QSERDES_RX_RX_MODE_01_LOW, 0xE0); 179 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH, 0xC8); 180 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH2, 0xC8); 181 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH3, 0x09); 182 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH4, 0xB1); 183 regmap_write(regmap, QSERDES_RX_RX_MODE_10_LOW, 0xE0); 184 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH, 0xC8); 185 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH2, 0xC8); 186 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH3, 0x3B); 187 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH4, 0xB7); 188 regmap_write(regmap, QSERDES_RX_DCC_CTRL1, 0x0C); 189 190 regmap_write(regmap, QSERDES_PCS_LINE_RESET_TIME, 0x0C); 191 regmap_write(regmap, QSERDES_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F); 192 regmap_write(regmap, QSERDES_PCS_TX_SMALL_AMP_DRV_LVL, 0x03); 193 regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL1, 0x83); 194 regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08); 195 regmap_write(regmap, QSERDES_PCS_SGMII_MISC_CTRL8, 0x0C); 196 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x00); 197 198 regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01); 199 } 200 201 static void qcom_dwmac_sgmii_phy_init_2p5g(struct regmap *regmap) 202 { 203 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01); 204 regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01); 205 206 regmap_write(regmap, QSERDES_COM_PLL_IVCO, 0x0F); 207 regmap_write(regmap, QSERDES_COM_CP_CTRL_MODE0, 0x06); 208 regmap_write(regmap, QSERDES_COM_PLL_RCTRL_MODE0, 0x16); 209 regmap_write(regmap, QSERDES_COM_PLL_CCTRL_MODE0, 0x36); 210 regmap_write(regmap, QSERDES_COM_SYSCLK_EN_SEL, 0x1A); 211 regmap_write(regmap, QSERDES_COM_LOCK_CMP1_MODE0, 0x1A); 212 regmap_write(regmap, QSERDES_COM_LOCK_CMP2_MODE0, 0x41); 213 regmap_write(regmap, QSERDES_COM_DEC_START_MODE0, 0x7A); 214 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00); 215 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START2_MODE0, 0x20); 216 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START3_MODE0, 0x01); 217 regmap_write(regmap, QSERDES_COM_VCO_TUNE1_MODE0, 0xA1); 218 219 regmap_write(regmap, QSERDES_COM_VCO_TUNE2_MODE0, 0x02); 220 regmap_write(regmap, QSERDES_COM_VCO_TUNE_INITVAL2, 0x00); 221 regmap_write(regmap, QSERDES_COM_HSCLK_SEL, 0x03); 222 regmap_write(regmap, QSERDES_COM_HSCLK_HS_SWITCH_SEL, 0x00); 223 regmap_write(regmap, QSERDES_COM_CORECLK_DIV_MODE0, 0x05); 224 regmap_write(regmap, QSERDES_COM_CORE_CLK_EN, 0x00); 225 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xCD); 226 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1C); 227 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_HSCLK_SEL, 0x11); 228 229 regmap_write(regmap, QSERDES_TX_TX_BAND, 0x04); 230 regmap_write(regmap, QSERDES_TX_SLEW_CNTL, 0x0A); 231 regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_TX, 0x09); 232 regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_RX, 0x02); 233 regmap_write(regmap, QSERDES_TX_LANE_MODE_1, 0x05); 234 regmap_write(regmap, QSERDES_TX_LANE_MODE_3, 0x00); 235 regmap_write(regmap, QSERDES_TX_RCV_DETECT_LVL_2, 0x12); 236 regmap_write(regmap, QSERDES_TX_TRAN_DRVR_EMP_EN, 0x0C); 237 238 regmap_write(regmap, QSERDES_RX_UCDR_FO_GAIN, 0x0A); 239 regmap_write(regmap, QSERDES_RX_UCDR_SO_GAIN, 0x06); 240 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A); 241 regmap_write(regmap, QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F); 242 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00); 243 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01); 244 regmap_write(regmap, QSERDES_RX_UCDR_PI_CONTROLS, 0x81); 245 regmap_write(regmap, QSERDES_RX_UCDR_PI_CTRL2, 0x80); 246 regmap_write(regmap, QSERDES_RX_RX_TERM_BW, 0x00); 247 regmap_write(regmap, QSERDES_RX_VGA_CAL_CNTRL2, 0x08); 248 regmap_write(regmap, QSERDES_RX_GM_CAL, 0x0F); 249 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04); 250 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00); 251 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A); 252 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A); 253 regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_LOW, 0x80); 254 regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_HIGH, 0x01); 255 regmap_write(regmap, QSERDES_RX_RX_IDAC_MEASURE_TIME, 0x20); 256 regmap_write(regmap, QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17); 257 regmap_write(regmap, QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00); 258 regmap_write(regmap, QSERDES_RX_SIGDET_CNTRL, 0x0F); 259 regmap_write(regmap, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E); 260 regmap_write(regmap, QSERDES_RX_RX_BAND, 0x18); 261 regmap_write(regmap, QSERDES_RX_RX_MODE_00_LOW, 0x18); 262 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH, 0xC8); 263 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH2, 0xC8); 264 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH3, 0x0C); 265 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH4, 0xB8); 266 regmap_write(regmap, QSERDES_RX_RX_MODE_01_LOW, 0xE0); 267 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH, 0xC8); 268 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH2, 0xC8); 269 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH3, 0x09); 270 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH4, 0xB1); 271 regmap_write(regmap, QSERDES_RX_RX_MODE_10_LOW, 0xE0); 272 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH, 0xC8); 273 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH2, 0xC8); 274 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH3, 0x3B); 275 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH4, 0xB7); 276 regmap_write(regmap, QSERDES_RX_DCC_CTRL1, 0x0C); 277 278 regmap_write(regmap, QSERDES_PCS_LINE_RESET_TIME, 0x0C); 279 regmap_write(regmap, QSERDES_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F); 280 regmap_write(regmap, QSERDES_PCS_TX_SMALL_AMP_DRV_LVL, 0x03); 281 regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL1, 0x83); 282 regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08); 283 regmap_write(regmap, QSERDES_PCS_SGMII_MISC_CTRL8, 0x8C); 284 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x00); 285 286 regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01); 287 } 288 289 static inline int 290 qcom_dwmac_sgmii_phy_poll_status(struct regmap *regmap, unsigned int reg, 291 unsigned int bit) 292 { 293 unsigned int val; 294 295 return regmap_read_poll_timeout(regmap, reg, val, 296 val & bit, 1500, 750000); 297 } 298 299 static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy) 300 { 301 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); 302 struct device *dev = phy->dev.parent; 303 304 switch (data->speed) { 305 case SPEED_10: 306 case SPEED_100: 307 case SPEED_1000: 308 qcom_dwmac_sgmii_phy_init_1g(data->regmap); 309 break; 310 case SPEED_2500: 311 qcom_dwmac_sgmii_phy_init_2p5g(data->regmap); 312 break; 313 } 314 315 if (qcom_dwmac_sgmii_phy_poll_status(data->regmap, 316 QSERDES_COM_C_READY_STATUS, 317 QSERDES_COM_C_READY)) { 318 dev_err(dev, "QSERDES_COM_C_READY_STATUS timed-out"); 319 return -ETIMEDOUT; 320 } 321 322 if (qcom_dwmac_sgmii_phy_poll_status(data->regmap, 323 QSERDES_PCS_PCS_READY_STATUS, 324 QSERDES_PCS_READY)) { 325 dev_err(dev, "PCS_READY timed-out"); 326 return -ETIMEDOUT; 327 } 328 329 if (qcom_dwmac_sgmii_phy_poll_status(data->regmap, 330 QSERDES_PCS_PCS_READY_STATUS, 331 QSERDES_PCS_SGMIIPHY_READY)) { 332 dev_err(dev, "SGMIIPHY_READY timed-out"); 333 return -ETIMEDOUT; 334 } 335 336 if (qcom_dwmac_sgmii_phy_poll_status(data->regmap, 337 QSERDES_COM_CMN_STATUS, 338 QSERDES_COM_C_PLL_LOCKED)) { 339 dev_err(dev, "PLL Lock Status timed-out"); 340 return -ETIMEDOUT; 341 } 342 343 return 0; 344 } 345 346 static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy) 347 { 348 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); 349 350 return clk_prepare_enable(data->refclk); 351 } 352 353 static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy) 354 { 355 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); 356 357 regmap_write(data->regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08); 358 regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x01); 359 udelay(100); 360 regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x00); 361 regmap_write(data->regmap, QSERDES_PCS_PHY_START, 0x01); 362 363 clk_disable_unprepare(data->refclk); 364 365 return 0; 366 } 367 368 static int qcom_dwmac_sgmii_phy_set_speed(struct phy *phy, int speed) 369 { 370 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); 371 372 if (speed != data->speed) 373 data->speed = speed; 374 375 return qcom_dwmac_sgmii_phy_calibrate(phy); 376 } 377 378 static const struct phy_ops qcom_dwmac_sgmii_phy_ops = { 379 .power_on = qcom_dwmac_sgmii_phy_power_on, 380 .power_off = qcom_dwmac_sgmii_phy_power_off, 381 .set_speed = qcom_dwmac_sgmii_phy_set_speed, 382 .calibrate = qcom_dwmac_sgmii_phy_calibrate, 383 .owner = THIS_MODULE, 384 }; 385 386 static const struct regmap_config qcom_dwmac_sgmii_phy_regmap_cfg = { 387 .reg_bits = 32, 388 .val_bits = 32, 389 .reg_stride = 4, 390 .use_relaxed_mmio = true, 391 .disable_locking = true, 392 }; 393 394 static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev) 395 { 396 struct qcom_dwmac_sgmii_phy_data *data; 397 struct device *dev = &pdev->dev; 398 struct phy_provider *provider; 399 void __iomem *base; 400 struct phy *phy; 401 402 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 403 if (!data) 404 return -ENOMEM; 405 406 data->speed = SPEED_10; 407 408 base = devm_platform_ioremap_resource(pdev, 0); 409 if (IS_ERR(base)) 410 return PTR_ERR(base); 411 412 data->regmap = devm_regmap_init_mmio(dev, base, 413 &qcom_dwmac_sgmii_phy_regmap_cfg); 414 if (IS_ERR(data->regmap)) 415 return PTR_ERR(data->regmap); 416 417 phy = devm_phy_create(dev, NULL, &qcom_dwmac_sgmii_phy_ops); 418 if (IS_ERR(phy)) 419 return PTR_ERR(phy); 420 421 data->refclk = devm_clk_get(dev, "sgmi_ref"); 422 if (IS_ERR(data->refclk)) 423 return PTR_ERR(data->refclk); 424 425 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 426 if (IS_ERR(provider)) 427 return PTR_ERR(provider); 428 429 phy_set_drvdata(phy, data); 430 431 return 0; 432 } 433 434 static const struct of_device_id qcom_dwmac_sgmii_phy_of_match[] = { 435 { .compatible = "qcom,sa8775p-dwmac-sgmii-phy" }, 436 { }, 437 }; 438 MODULE_DEVICE_TABLE(of, qcom_dwmac_sgmii_phy_of_match); 439 440 static struct platform_driver qcom_dwmac_sgmii_phy_driver = { 441 .probe = qcom_dwmac_sgmii_phy_probe, 442 .driver = { 443 .name = "qcom-dwmac-sgmii-phy", 444 .of_match_table = qcom_dwmac_sgmii_phy_of_match, 445 } 446 }; 447 448 module_platform_driver(qcom_dwmac_sgmii_phy_driver); 449 450 MODULE_DESCRIPTION("Qualcomm DWMAC SGMII PHY driver"); 451 MODULE_LICENSE("GPL"); 452