1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2017 Marvell 4 * 5 * Antoine Tenart <antoine.tenart@free-electrons.com> 6 */ 7 8 #include <linux/io.h> 9 #include <linux/iopoll.h> 10 #include <linux/mfd/syscon.h> 11 #include <linux/module.h> 12 #include <linux/phy/phy.h> 13 #include <linux/platform_device.h> 14 #include <linux/regmap.h> 15 16 /* Relative to priv->base */ 17 #define MVEBU_COMPHY_SERDES_CFG0(n) (0x0 + (n) * 0x1000) 18 #define MVEBU_COMPHY_SERDES_CFG0_PU_PLL BIT(1) 19 #define MVEBU_COMPHY_SERDES_CFG0_GEN_RX(n) ((n) << 3) 20 #define MVEBU_COMPHY_SERDES_CFG0_GEN_TX(n) ((n) << 7) 21 #define MVEBU_COMPHY_SERDES_CFG0_PU_RX BIT(11) 22 #define MVEBU_COMPHY_SERDES_CFG0_PU_TX BIT(12) 23 #define MVEBU_COMPHY_SERDES_CFG0_HALF_BUS BIT(14) 24 #define MVEBU_COMPHY_SERDES_CFG1(n) (0x4 + (n) * 0x1000) 25 #define MVEBU_COMPHY_SERDES_CFG1_RESET BIT(3) 26 #define MVEBU_COMPHY_SERDES_CFG1_RX_INIT BIT(4) 27 #define MVEBU_COMPHY_SERDES_CFG1_CORE_RESET BIT(5) 28 #define MVEBU_COMPHY_SERDES_CFG1_RF_RESET BIT(6) 29 #define MVEBU_COMPHY_SERDES_CFG2(n) (0x8 + (n) * 0x1000) 30 #define MVEBU_COMPHY_SERDES_CFG2_DFE_EN BIT(4) 31 #define MVEBU_COMPHY_SERDES_STATUS0(n) (0x18 + (n) * 0x1000) 32 #define MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY BIT(2) 33 #define MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY BIT(3) 34 #define MVEBU_COMPHY_SERDES_STATUS0_RX_INIT BIT(4) 35 #define MVEBU_COMPHY_PWRPLL_CTRL(n) (0x804 + (n) * 0x1000) 36 #define MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(n) ((n) << 0) 37 #define MVEBU_COMPHY_PWRPLL_PHY_MODE(n) ((n) << 5) 38 #define MVEBU_COMPHY_IMP_CAL(n) (0x80c + (n) * 0x1000) 39 #define MVEBU_COMPHY_IMP_CAL_TX_EXT(n) ((n) << 10) 40 #define MVEBU_COMPHY_IMP_CAL_TX_EXT_EN BIT(15) 41 #define MVEBU_COMPHY_DFE_RES(n) (0x81c + (n) * 0x1000) 42 #define MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL BIT(15) 43 #define MVEBU_COMPHY_COEF(n) (0x828 + (n) * 0x1000) 44 #define MVEBU_COMPHY_COEF_DFE_EN BIT(14) 45 #define MVEBU_COMPHY_COEF_DFE_CTRL BIT(15) 46 #define MVEBU_COMPHY_GEN1_S0(n) (0x834 + (n) * 0x1000) 47 #define MVEBU_COMPHY_GEN1_S0_TX_AMP(n) ((n) << 1) 48 #define MVEBU_COMPHY_GEN1_S0_TX_EMPH(n) ((n) << 7) 49 #define MVEBU_COMPHY_GEN1_S1(n) (0x838 + (n) * 0x1000) 50 #define MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(n) ((n) << 0) 51 #define MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(n) ((n) << 3) 52 #define MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(n) ((n) << 6) 53 #define MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(n) ((n) << 8) 54 #define MVEBU_COMPHY_GEN1_S1_RX_DFE_EN BIT(10) 55 #define MVEBU_COMPHY_GEN1_S1_RX_DIV(n) ((n) << 11) 56 #define MVEBU_COMPHY_GEN1_S2(n) (0x8f4 + (n) * 0x1000) 57 #define MVEBU_COMPHY_GEN1_S2_TX_EMPH(n) ((n) << 0) 58 #define MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN BIT(4) 59 #define MVEBU_COMPHY_LOOPBACK(n) (0x88c + (n) * 0x1000) 60 #define MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(n) ((n) << 1) 61 #define MVEBU_COMPHY_VDD_CAL0(n) (0x908 + (n) * 0x1000) 62 #define MVEBU_COMPHY_VDD_CAL0_CONT_MODE BIT(15) 63 #define MVEBU_COMPHY_EXT_SELV(n) (0x914 + (n) * 0x1000) 64 #define MVEBU_COMPHY_EXT_SELV_RX_SAMPL(n) ((n) << 5) 65 #define MVEBU_COMPHY_MISC_CTRL0(n) (0x93c + (n) * 0x1000) 66 #define MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE BIT(5) 67 #define MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL BIT(10) 68 #define MVEBU_COMPHY_RX_CTRL1(n) (0x940 + (n) * 0x1000) 69 #define MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL BIT(11) 70 #define MVEBU_COMPHY_RX_CTRL1_CLK8T_EN BIT(12) 71 #define MVEBU_COMPHY_SPEED_DIV(n) (0x954 + (n) * 0x1000) 72 #define MVEBU_COMPHY_SPEED_DIV_TX_FORCE BIT(7) 73 #define MVEBU_SP_CALIB(n) (0x96c + (n) * 0x1000) 74 #define MVEBU_SP_CALIB_SAMPLER(n) ((n) << 8) 75 #define MVEBU_SP_CALIB_SAMPLER_EN BIT(12) 76 #define MVEBU_COMPHY_TX_SLEW_RATE(n) (0x974 + (n) * 0x1000) 77 #define MVEBU_COMPHY_TX_SLEW_RATE_EMPH(n) ((n) << 5) 78 #define MVEBU_COMPHY_TX_SLEW_RATE_SLC(n) ((n) << 10) 79 #define MVEBU_COMPHY_DLT_CTRL(n) (0x984 + (n) * 0x1000) 80 #define MVEBU_COMPHY_DLT_CTRL_DTL_FLOOP_EN BIT(2) 81 #define MVEBU_COMPHY_FRAME_DETECT0(n) (0xa14 + (n) * 0x1000) 82 #define MVEBU_COMPHY_FRAME_DETECT0_PATN(n) ((n) << 7) 83 #define MVEBU_COMPHY_FRAME_DETECT3(n) (0xa20 + (n) * 0x1000) 84 #define MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN BIT(12) 85 #define MVEBU_COMPHY_DME(n) (0xa28 + (n) * 0x1000) 86 #define MVEBU_COMPHY_DME_ETH_MODE BIT(7) 87 #define MVEBU_COMPHY_TRAINING0(n) (0xa68 + (n) * 0x1000) 88 #define MVEBU_COMPHY_TRAINING0_P2P_HOLD BIT(15) 89 #define MVEBU_COMPHY_TRAINING5(n) (0xaa4 + (n) * 0x1000) 90 #define MVEBU_COMPHY_TRAINING5_RX_TIMER(n) ((n) << 0) 91 #define MVEBU_COMPHY_TX_TRAIN_PRESET(n) (0xb1c + (n) * 0x1000) 92 #define MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN BIT(8) 93 #define MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11 BIT(9) 94 #define MVEBU_COMPHY_GEN1_S3(n) (0xc40 + (n) * 0x1000) 95 #define MVEBU_COMPHY_GEN1_S3_FBCK_SEL BIT(9) 96 #define MVEBU_COMPHY_GEN1_S4(n) (0xc44 + (n) * 0x1000) 97 #define MVEBU_COMPHY_GEN1_S4_DFE_RES(n) ((n) << 8) 98 #define MVEBU_COMPHY_TX_PRESET(n) (0xc68 + (n) * 0x1000) 99 #define MVEBU_COMPHY_TX_PRESET_INDEX(n) ((n) << 0) 100 #define MVEBU_COMPHY_GEN1_S5(n) (0xd38 + (n) * 0x1000) 101 #define MVEBU_COMPHY_GEN1_S5_ICP(n) ((n) << 0) 102 103 /* Relative to priv->regmap */ 104 #define MVEBU_COMPHY_CONF1(n) (0x1000 + (n) * 0x28) 105 #define MVEBU_COMPHY_CONF1_PWRUP BIT(1) 106 #define MVEBU_COMPHY_CONF1_USB_PCIE BIT(2) /* 0: Ethernet/SATA */ 107 #define MVEBU_COMPHY_CONF6(n) (0x1014 + (n) * 0x28) 108 #define MVEBU_COMPHY_CONF6_40B BIT(18) 109 #define MVEBU_COMPHY_SELECTOR 0x1140 110 #define MVEBU_COMPHY_SELECTOR_PHY(n) ((n) * 0x4) 111 #define MVEBU_COMPHY_PIPE_SELECTOR 0x1144 112 #define MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n) ((n) * 0x4) 113 114 #define MVEBU_COMPHY_LANES 6 115 #define MVEBU_COMPHY_PORTS 3 116 117 struct mvebu_comhy_conf { 118 enum phy_mode mode; 119 unsigned lane; 120 unsigned port; 121 u32 mux; 122 }; 123 124 #define MVEBU_COMPHY_CONF(_lane, _port, _mode, _mux) \ 125 { \ 126 .lane = _lane, \ 127 .port = _port, \ 128 .mode = _mode, \ 129 .mux = _mux, \ 130 } 131 132 static const struct mvebu_comhy_conf mvebu_comphy_cp110_modes[] = { 133 /* lane 0 */ 134 MVEBU_COMPHY_CONF(0, 1, PHY_MODE_SGMII, 0x1), 135 MVEBU_COMPHY_CONF(0, 1, PHY_MODE_2500SGMII, 0x1), 136 /* lane 1 */ 137 MVEBU_COMPHY_CONF(1, 2, PHY_MODE_SGMII, 0x1), 138 MVEBU_COMPHY_CONF(1, 2, PHY_MODE_2500SGMII, 0x1), 139 /* lane 2 */ 140 MVEBU_COMPHY_CONF(2, 0, PHY_MODE_SGMII, 0x1), 141 MVEBU_COMPHY_CONF(2, 0, PHY_MODE_2500SGMII, 0x1), 142 MVEBU_COMPHY_CONF(2, 0, PHY_MODE_10GKR, 0x1), 143 /* lane 3 */ 144 MVEBU_COMPHY_CONF(3, 1, PHY_MODE_SGMII, 0x2), 145 MVEBU_COMPHY_CONF(3, 1, PHY_MODE_2500SGMII, 0x2), 146 /* lane 4 */ 147 MVEBU_COMPHY_CONF(4, 0, PHY_MODE_SGMII, 0x2), 148 MVEBU_COMPHY_CONF(4, 0, PHY_MODE_2500SGMII, 0x2), 149 MVEBU_COMPHY_CONF(4, 0, PHY_MODE_10GKR, 0x2), 150 MVEBU_COMPHY_CONF(4, 1, PHY_MODE_SGMII, 0x1), 151 /* lane 5 */ 152 MVEBU_COMPHY_CONF(5, 2, PHY_MODE_SGMII, 0x1), 153 MVEBU_COMPHY_CONF(5, 2, PHY_MODE_2500SGMII, 0x1), 154 }; 155 156 struct mvebu_comphy_priv { 157 void __iomem *base; 158 struct regmap *regmap; 159 struct device *dev; 160 }; 161 162 struct mvebu_comphy_lane { 163 struct mvebu_comphy_priv *priv; 164 unsigned id; 165 enum phy_mode mode; 166 int port; 167 }; 168 169 static int mvebu_comphy_get_mux(int lane, int port, enum phy_mode mode) 170 { 171 int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes); 172 173 /* Unused PHY mux value is 0x0 */ 174 if (mode == PHY_MODE_INVALID) 175 return 0; 176 177 for (i = 0; i < n; i++) { 178 if (mvebu_comphy_cp110_modes[i].lane == lane && 179 mvebu_comphy_cp110_modes[i].port == port && 180 mvebu_comphy_cp110_modes[i].mode == mode) 181 break; 182 } 183 184 if (i == n) 185 return -EINVAL; 186 187 return mvebu_comphy_cp110_modes[i].mux; 188 } 189 190 static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane, 191 enum phy_mode mode) 192 { 193 struct mvebu_comphy_priv *priv = lane->priv; 194 u32 val; 195 196 regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val); 197 val &= ~MVEBU_COMPHY_CONF1_USB_PCIE; 198 val |= MVEBU_COMPHY_CONF1_PWRUP; 199 regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val); 200 201 /* Select baud rates and PLLs */ 202 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); 203 val &= ~(MVEBU_COMPHY_SERDES_CFG0_PU_PLL | 204 MVEBU_COMPHY_SERDES_CFG0_PU_RX | 205 MVEBU_COMPHY_SERDES_CFG0_PU_TX | 206 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS | 207 MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) | 208 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf)); 209 if (mode == PHY_MODE_10GKR) 210 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) | 211 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe); 212 else if (mode == PHY_MODE_2500SGMII) 213 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) | 214 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) | 215 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS; 216 else if (mode == PHY_MODE_SGMII) 217 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) | 218 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) | 219 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS; 220 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); 221 222 /* reset */ 223 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 224 val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET | 225 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET | 226 MVEBU_COMPHY_SERDES_CFG1_RF_RESET); 227 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 228 229 /* de-assert reset */ 230 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 231 val |= MVEBU_COMPHY_SERDES_CFG1_RESET | 232 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET; 233 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 234 235 /* wait until clocks are ready */ 236 mdelay(1); 237 238 /* exlicitly disable 40B, the bits isn't clear on reset */ 239 regmap_read(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), &val); 240 val &= ~MVEBU_COMPHY_CONF6_40B; 241 regmap_write(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), val); 242 243 /* refclk selection */ 244 val = readl(priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id)); 245 val &= ~MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL; 246 if (mode == PHY_MODE_10GKR) 247 val |= MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE; 248 writel(val, priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id)); 249 250 /* power and pll selection */ 251 val = readl(priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id)); 252 val &= ~(MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1f) | 253 MVEBU_COMPHY_PWRPLL_PHY_MODE(0x7)); 254 val |= MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1) | 255 MVEBU_COMPHY_PWRPLL_PHY_MODE(0x4); 256 writel(val, priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id)); 257 258 val = readl(priv->base + MVEBU_COMPHY_LOOPBACK(lane->id)); 259 val &= ~MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x7); 260 val |= MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x1); 261 writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id)); 262 } 263 264 static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane, 265 enum phy_mode mode) 266 { 267 struct mvebu_comphy_priv *priv = lane->priv; 268 u32 val; 269 270 /* SERDES external config */ 271 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); 272 val |= MVEBU_COMPHY_SERDES_CFG0_PU_PLL | 273 MVEBU_COMPHY_SERDES_CFG0_PU_RX | 274 MVEBU_COMPHY_SERDES_CFG0_PU_TX; 275 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); 276 277 /* check rx/tx pll */ 278 readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id), 279 val, 280 val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY | 281 MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY), 282 1000, 150000); 283 if (!(val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY | 284 MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY))) 285 return -ETIMEDOUT; 286 287 /* rx init */ 288 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 289 val |= MVEBU_COMPHY_SERDES_CFG1_RX_INIT; 290 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 291 292 /* check rx */ 293 readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id), 294 val, val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT, 295 1000, 10000); 296 if (!(val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT)) 297 return -ETIMEDOUT; 298 299 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 300 val &= ~MVEBU_COMPHY_SERDES_CFG1_RX_INIT; 301 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 302 303 return 0; 304 } 305 306 static int mvebu_comphy_set_mode_sgmii(struct phy *phy, enum phy_mode mode) 307 { 308 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 309 struct mvebu_comphy_priv *priv = lane->priv; 310 u32 val; 311 312 mvebu_comphy_ethernet_init_reset(lane, mode); 313 314 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 315 val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; 316 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL; 317 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 318 319 val = readl(priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); 320 val &= ~MVEBU_COMPHY_DLT_CTRL_DTL_FLOOP_EN; 321 writel(val, priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); 322 323 regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val); 324 val &= ~MVEBU_COMPHY_CONF1_USB_PCIE; 325 val |= MVEBU_COMPHY_CONF1_PWRUP; 326 regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val); 327 328 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 329 val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf); 330 val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0x1); 331 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 332 333 return mvebu_comphy_init_plls(lane, PHY_MODE_SGMII); 334 } 335 336 static int mvebu_comphy_set_mode_10gkr(struct phy *phy) 337 { 338 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 339 struct mvebu_comphy_priv *priv = lane->priv; 340 u32 val; 341 342 mvebu_comphy_ethernet_init_reset(lane, PHY_MODE_10GKR); 343 344 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 345 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL | 346 MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; 347 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 348 349 val = readl(priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); 350 val |= MVEBU_COMPHY_DLT_CTRL_DTL_FLOOP_EN; 351 writel(val, priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); 352 353 /* Speed divider */ 354 val = readl(priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id)); 355 val |= MVEBU_COMPHY_SPEED_DIV_TX_FORCE; 356 writel(val, priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id)); 357 358 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id)); 359 val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN; 360 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id)); 361 362 /* DFE resolution */ 363 val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id)); 364 val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL; 365 writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id)); 366 367 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 368 val &= ~(MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1f) | 369 MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf)); 370 val |= MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1c) | 371 MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xe); 372 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 373 374 val = readl(priv->base + MVEBU_COMPHY_GEN1_S2(lane->id)); 375 val &= ~MVEBU_COMPHY_GEN1_S2_TX_EMPH(0xf); 376 val |= MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN; 377 writel(val, priv->base + MVEBU_COMPHY_GEN1_S2(lane->id)); 378 379 val = readl(priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id)); 380 val |= MVEBU_COMPHY_TX_SLEW_RATE_EMPH(0x3) | 381 MVEBU_COMPHY_TX_SLEW_RATE_SLC(0x3f); 382 writel(val, priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id)); 383 384 /* Impedance calibration */ 385 val = readl(priv->base + MVEBU_COMPHY_IMP_CAL(lane->id)); 386 val &= ~MVEBU_COMPHY_IMP_CAL_TX_EXT(0x1f); 387 val |= MVEBU_COMPHY_IMP_CAL_TX_EXT(0xe) | 388 MVEBU_COMPHY_IMP_CAL_TX_EXT_EN; 389 writel(val, priv->base + MVEBU_COMPHY_IMP_CAL(lane->id)); 390 391 val = readl(priv->base + MVEBU_COMPHY_GEN1_S5(lane->id)); 392 val &= ~MVEBU_COMPHY_GEN1_S5_ICP(0xf); 393 writel(val, priv->base + MVEBU_COMPHY_GEN1_S5(lane->id)); 394 395 val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id)); 396 val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) | 397 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7) | 398 MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(0x3) | 399 MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x3)); 400 val |= MVEBU_COMPHY_GEN1_S1_RX_DFE_EN | 401 MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x2) | 402 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x2) | 403 MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x1) | 404 MVEBU_COMPHY_GEN1_S1_RX_DIV(0x3); 405 writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id)); 406 407 val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id)); 408 val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL); 409 writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id)); 410 411 val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id)); 412 val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3); 413 val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1); 414 writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id)); 415 416 val = readl(priv->base + MVEBU_COMPHY_GEN1_S3(lane->id)); 417 val |= MVEBU_COMPHY_GEN1_S3_FBCK_SEL; 418 writel(val, priv->base + MVEBU_COMPHY_GEN1_S3(lane->id)); 419 420 /* rx training timer */ 421 val = readl(priv->base + MVEBU_COMPHY_TRAINING5(lane->id)); 422 val &= ~MVEBU_COMPHY_TRAINING5_RX_TIMER(0x3ff); 423 val |= MVEBU_COMPHY_TRAINING5_RX_TIMER(0x13); 424 writel(val, priv->base + MVEBU_COMPHY_TRAINING5(lane->id)); 425 426 /* tx train peak to peak hold */ 427 val = readl(priv->base + MVEBU_COMPHY_TRAINING0(lane->id)); 428 val |= MVEBU_COMPHY_TRAINING0_P2P_HOLD; 429 writel(val, priv->base + MVEBU_COMPHY_TRAINING0(lane->id)); 430 431 val = readl(priv->base + MVEBU_COMPHY_TX_PRESET(lane->id)); 432 val &= ~MVEBU_COMPHY_TX_PRESET_INDEX(0xf); 433 val |= MVEBU_COMPHY_TX_PRESET_INDEX(0x2); /* preset coeff */ 434 writel(val, priv->base + MVEBU_COMPHY_TX_PRESET(lane->id)); 435 436 val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id)); 437 val &= ~MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN; 438 writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id)); 439 440 val = readl(priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id)); 441 val |= MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN | 442 MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11; 443 writel(val, priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id)); 444 445 val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id)); 446 val &= ~MVEBU_COMPHY_FRAME_DETECT0_PATN(0x1ff); 447 val |= MVEBU_COMPHY_FRAME_DETECT0_PATN(0x88); 448 writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id)); 449 450 val = readl(priv->base + MVEBU_COMPHY_DME(lane->id)); 451 val |= MVEBU_COMPHY_DME_ETH_MODE; 452 writel(val, priv->base + MVEBU_COMPHY_DME(lane->id)); 453 454 val = readl(priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id)); 455 val |= MVEBU_COMPHY_VDD_CAL0_CONT_MODE; 456 writel(val, priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id)); 457 458 val = readl(priv->base + MVEBU_SP_CALIB(lane->id)); 459 val &= ~MVEBU_SP_CALIB_SAMPLER(0x3); 460 val |= MVEBU_SP_CALIB_SAMPLER(0x3) | 461 MVEBU_SP_CALIB_SAMPLER_EN; 462 writel(val, priv->base + MVEBU_SP_CALIB(lane->id)); 463 val &= ~MVEBU_SP_CALIB_SAMPLER_EN; 464 writel(val, priv->base + MVEBU_SP_CALIB(lane->id)); 465 466 /* External rx regulator */ 467 val = readl(priv->base + MVEBU_COMPHY_EXT_SELV(lane->id)); 468 val &= ~MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1f); 469 val |= MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1a); 470 writel(val, priv->base + MVEBU_COMPHY_EXT_SELV(lane->id)); 471 472 return mvebu_comphy_init_plls(lane, PHY_MODE_10GKR); 473 } 474 475 static int mvebu_comphy_power_on(struct phy *phy) 476 { 477 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 478 struct mvebu_comphy_priv *priv = lane->priv; 479 int ret, mux; 480 u32 val; 481 482 mux = mvebu_comphy_get_mux(lane->id, lane->port, lane->mode); 483 if (mux < 0) 484 return -ENOTSUPP; 485 486 regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val); 487 val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id)); 488 regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val); 489 490 regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val); 491 val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id)); 492 val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id); 493 regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val); 494 495 switch (lane->mode) { 496 case PHY_MODE_SGMII: 497 case PHY_MODE_2500SGMII: 498 ret = mvebu_comphy_set_mode_sgmii(phy, lane->mode); 499 break; 500 case PHY_MODE_10GKR: 501 ret = mvebu_comphy_set_mode_10gkr(phy); 502 break; 503 default: 504 return -ENOTSUPP; 505 } 506 507 /* digital reset */ 508 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 509 val |= MVEBU_COMPHY_SERDES_CFG1_RF_RESET; 510 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 511 512 return ret; 513 } 514 515 static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode) 516 { 517 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 518 519 if (mvebu_comphy_get_mux(lane->id, lane->port, mode) < 0) 520 return -EINVAL; 521 522 lane->mode = mode; 523 return 0; 524 } 525 526 static int mvebu_comphy_power_off(struct phy *phy) 527 { 528 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 529 struct mvebu_comphy_priv *priv = lane->priv; 530 u32 val; 531 532 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 533 val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET | 534 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET | 535 MVEBU_COMPHY_SERDES_CFG1_RF_RESET); 536 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 537 538 regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val); 539 val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id)); 540 regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val); 541 542 regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val); 543 val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id)); 544 regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val); 545 546 return 0; 547 } 548 549 static const struct phy_ops mvebu_comphy_ops = { 550 .power_on = mvebu_comphy_power_on, 551 .power_off = mvebu_comphy_power_off, 552 .set_mode = mvebu_comphy_set_mode, 553 .owner = THIS_MODULE, 554 }; 555 556 static struct phy *mvebu_comphy_xlate(struct device *dev, 557 struct of_phandle_args *args) 558 { 559 struct mvebu_comphy_lane *lane; 560 struct phy *phy; 561 562 if (WARN_ON(args->args[0] >= MVEBU_COMPHY_PORTS)) 563 return ERR_PTR(-EINVAL); 564 565 phy = of_phy_simple_xlate(dev, args); 566 if (IS_ERR(phy)) 567 return phy; 568 569 lane = phy_get_drvdata(phy); 570 if (lane->port >= 0) 571 return ERR_PTR(-EBUSY); 572 lane->port = args->args[0]; 573 574 return phy; 575 } 576 577 static int mvebu_comphy_probe(struct platform_device *pdev) 578 { 579 struct mvebu_comphy_priv *priv; 580 struct phy_provider *provider; 581 struct device_node *child; 582 struct resource *res; 583 584 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 585 if (!priv) 586 return -ENOMEM; 587 588 priv->dev = &pdev->dev; 589 priv->regmap = 590 syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 591 "marvell,system-controller"); 592 if (IS_ERR(priv->regmap)) 593 return PTR_ERR(priv->regmap); 594 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 595 priv->base = devm_ioremap_resource(&pdev->dev, res); 596 if (IS_ERR(priv->base)) 597 return PTR_ERR(priv->base); 598 599 for_each_available_child_of_node(pdev->dev.of_node, child) { 600 struct mvebu_comphy_lane *lane; 601 struct phy *phy; 602 int ret; 603 u32 val; 604 605 ret = of_property_read_u32(child, "reg", &val); 606 if (ret < 0) { 607 dev_err(&pdev->dev, "missing 'reg' property (%d)\n", 608 ret); 609 continue; 610 } 611 612 if (val >= MVEBU_COMPHY_LANES) { 613 dev_err(&pdev->dev, "invalid 'reg' property\n"); 614 continue; 615 } 616 617 lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); 618 if (!lane) 619 return -ENOMEM; 620 621 phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops); 622 if (IS_ERR(phy)) 623 return PTR_ERR(phy); 624 625 lane->priv = priv; 626 lane->mode = PHY_MODE_INVALID; 627 lane->id = val; 628 lane->port = -1; 629 phy_set_drvdata(phy, lane); 630 631 /* 632 * Once all modes are supported in this driver we should call 633 * mvebu_comphy_power_off(phy) here to avoid relying on the 634 * bootloader/firmware configuration. 635 */ 636 } 637 638 dev_set_drvdata(&pdev->dev, priv); 639 provider = devm_of_phy_provider_register(&pdev->dev, 640 mvebu_comphy_xlate); 641 return PTR_ERR_OR_ZERO(provider); 642 } 643 644 static const struct of_device_id mvebu_comphy_of_match_table[] = { 645 { .compatible = "marvell,comphy-cp110" }, 646 { }, 647 }; 648 MODULE_DEVICE_TABLE(of, mvebu_comphy_of_match_table); 649 650 static struct platform_driver mvebu_comphy_driver = { 651 .probe = mvebu_comphy_probe, 652 .driver = { 653 .name = "mvebu-comphy", 654 .of_match_table = mvebu_comphy_of_match_table, 655 }, 656 }; 657 module_platform_driver(mvebu_comphy_driver); 658 659 MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>"); 660 MODULE_DESCRIPTION("Common PHY driver for mvebu SoCs"); 661 MODULE_LICENSE("GPL v2"); 662