phy-mvebu-cp110-comphy.c (36826B)
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/arm-smccc.h> 9#include <linux/clk.h> 10#include <linux/io.h> 11#include <linux/iopoll.h> 12#include <linux/mfd/syscon.h> 13#include <linux/module.h> 14#include <linux/phy.h> 15#include <linux/phy/phy.h> 16#include <linux/platform_device.h> 17#include <linux/regmap.h> 18 19/* Relative to priv->base */ 20#define MVEBU_COMPHY_SERDES_CFG0(n) (0x0 + (n) * 0x1000) 21#define MVEBU_COMPHY_SERDES_CFG0_PU_PLL BIT(1) 22#define MVEBU_COMPHY_SERDES_CFG0_GEN_RX(n) ((n) << 3) 23#define MVEBU_COMPHY_SERDES_CFG0_GEN_TX(n) ((n) << 7) 24#define MVEBU_COMPHY_SERDES_CFG0_PU_RX BIT(11) 25#define MVEBU_COMPHY_SERDES_CFG0_PU_TX BIT(12) 26#define MVEBU_COMPHY_SERDES_CFG0_HALF_BUS BIT(14) 27#define MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE BIT(15) 28#define MVEBU_COMPHY_SERDES_CFG1(n) (0x4 + (n) * 0x1000) 29#define MVEBU_COMPHY_SERDES_CFG1_RESET BIT(3) 30#define MVEBU_COMPHY_SERDES_CFG1_RX_INIT BIT(4) 31#define MVEBU_COMPHY_SERDES_CFG1_CORE_RESET BIT(5) 32#define MVEBU_COMPHY_SERDES_CFG1_RF_RESET BIT(6) 33#define MVEBU_COMPHY_SERDES_CFG2(n) (0x8 + (n) * 0x1000) 34#define MVEBU_COMPHY_SERDES_CFG2_DFE_EN BIT(4) 35#define MVEBU_COMPHY_SERDES_STATUS0(n) (0x18 + (n) * 0x1000) 36#define MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY BIT(2) 37#define MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY BIT(3) 38#define MVEBU_COMPHY_SERDES_STATUS0_RX_INIT BIT(4) 39#define MVEBU_COMPHY_PWRPLL_CTRL(n) (0x804 + (n) * 0x1000) 40#define MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(n) ((n) << 0) 41#define MVEBU_COMPHY_PWRPLL_PHY_MODE(n) ((n) << 5) 42#define MVEBU_COMPHY_IMP_CAL(n) (0x80c + (n) * 0x1000) 43#define MVEBU_COMPHY_IMP_CAL_TX_EXT(n) ((n) << 10) 44#define MVEBU_COMPHY_IMP_CAL_TX_EXT_EN BIT(15) 45#define MVEBU_COMPHY_DFE_RES(n) (0x81c + (n) * 0x1000) 46#define MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL BIT(15) 47#define MVEBU_COMPHY_COEF(n) (0x828 + (n) * 0x1000) 48#define MVEBU_COMPHY_COEF_DFE_EN BIT(14) 49#define MVEBU_COMPHY_COEF_DFE_CTRL BIT(15) 50#define MVEBU_COMPHY_GEN1_S0(n) (0x834 + (n) * 0x1000) 51#define MVEBU_COMPHY_GEN1_S0_TX_AMP(n) ((n) << 1) 52#define MVEBU_COMPHY_GEN1_S0_TX_EMPH(n) ((n) << 7) 53#define MVEBU_COMPHY_GEN1_S1(n) (0x838 + (n) * 0x1000) 54#define MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(n) ((n) << 0) 55#define MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(n) ((n) << 3) 56#define MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(n) ((n) << 6) 57#define MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(n) ((n) << 8) 58#define MVEBU_COMPHY_GEN1_S1_RX_DFE_EN BIT(10) 59#define MVEBU_COMPHY_GEN1_S1_RX_DIV(n) ((n) << 11) 60#define MVEBU_COMPHY_GEN1_S2(n) (0x8f4 + (n) * 0x1000) 61#define MVEBU_COMPHY_GEN1_S2_TX_EMPH(n) ((n) << 0) 62#define MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN BIT(4) 63#define MVEBU_COMPHY_LOOPBACK(n) (0x88c + (n) * 0x1000) 64#define MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(n) ((n) << 1) 65#define MVEBU_COMPHY_VDD_CAL0(n) (0x908 + (n) * 0x1000) 66#define MVEBU_COMPHY_VDD_CAL0_CONT_MODE BIT(15) 67#define MVEBU_COMPHY_EXT_SELV(n) (0x914 + (n) * 0x1000) 68#define MVEBU_COMPHY_EXT_SELV_RX_SAMPL(n) ((n) << 5) 69#define MVEBU_COMPHY_MISC_CTRL0(n) (0x93c + (n) * 0x1000) 70#define MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE BIT(5) 71#define MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL BIT(10) 72#define MVEBU_COMPHY_RX_CTRL1(n) (0x940 + (n) * 0x1000) 73#define MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL BIT(11) 74#define MVEBU_COMPHY_RX_CTRL1_CLK8T_EN BIT(12) 75#define MVEBU_COMPHY_SPEED_DIV(n) (0x954 + (n) * 0x1000) 76#define MVEBU_COMPHY_SPEED_DIV_TX_FORCE BIT(7) 77#define MVEBU_SP_CALIB(n) (0x96c + (n) * 0x1000) 78#define MVEBU_SP_CALIB_SAMPLER(n) ((n) << 8) 79#define MVEBU_SP_CALIB_SAMPLER_EN BIT(12) 80#define MVEBU_COMPHY_TX_SLEW_RATE(n) (0x974 + (n) * 0x1000) 81#define MVEBU_COMPHY_TX_SLEW_RATE_EMPH(n) ((n) << 5) 82#define MVEBU_COMPHY_TX_SLEW_RATE_SLC(n) ((n) << 10) 83#define MVEBU_COMPHY_DTL_CTRL(n) (0x984 + (n) * 0x1000) 84#define MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN BIT(2) 85#define MVEBU_COMPHY_FRAME_DETECT0(n) (0xa14 + (n) * 0x1000) 86#define MVEBU_COMPHY_FRAME_DETECT0_PATN(n) ((n) << 7) 87#define MVEBU_COMPHY_FRAME_DETECT3(n) (0xa20 + (n) * 0x1000) 88#define MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN BIT(12) 89#define MVEBU_COMPHY_DME(n) (0xa28 + (n) * 0x1000) 90#define MVEBU_COMPHY_DME_ETH_MODE BIT(7) 91#define MVEBU_COMPHY_TRAINING0(n) (0xa68 + (n) * 0x1000) 92#define MVEBU_COMPHY_TRAINING0_P2P_HOLD BIT(15) 93#define MVEBU_COMPHY_TRAINING5(n) (0xaa4 + (n) * 0x1000) 94#define MVEBU_COMPHY_TRAINING5_RX_TIMER(n) ((n) << 0) 95#define MVEBU_COMPHY_TX_TRAIN_PRESET(n) (0xb1c + (n) * 0x1000) 96#define MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN BIT(8) 97#define MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11 BIT(9) 98#define MVEBU_COMPHY_GEN1_S3(n) (0xc40 + (n) * 0x1000) 99#define MVEBU_COMPHY_GEN1_S3_FBCK_SEL BIT(9) 100#define MVEBU_COMPHY_GEN1_S4(n) (0xc44 + (n) * 0x1000) 101#define MVEBU_COMPHY_GEN1_S4_DFE_RES(n) ((n) << 8) 102#define MVEBU_COMPHY_TX_PRESET(n) (0xc68 + (n) * 0x1000) 103#define MVEBU_COMPHY_TX_PRESET_INDEX(n) ((n) << 0) 104#define MVEBU_COMPHY_GEN1_S5(n) (0xd38 + (n) * 0x1000) 105#define MVEBU_COMPHY_GEN1_S5_ICP(n) ((n) << 0) 106 107/* Relative to priv->regmap */ 108#define MVEBU_COMPHY_CONF1(n) (0x1000 + (n) * 0x28) 109#define MVEBU_COMPHY_CONF1_PWRUP BIT(1) 110#define MVEBU_COMPHY_CONF1_USB_PCIE BIT(2) /* 0: Ethernet/SATA */ 111#define MVEBU_COMPHY_CONF6(n) (0x1014 + (n) * 0x28) 112#define MVEBU_COMPHY_CONF6_40B BIT(18) 113#define MVEBU_COMPHY_SELECTOR 0x1140 114#define MVEBU_COMPHY_SELECTOR_PHY(n) ((n) * 0x4) 115#define MVEBU_COMPHY_PIPE_SELECTOR 0x1144 116#define MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n) ((n) * 0x4) 117#define MVEBU_COMPHY_SD1_CTRL1 0x1148 118#define MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN BIT(26) 119#define MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN BIT(27) 120 121#define MVEBU_COMPHY_LANES 6 122#define MVEBU_COMPHY_PORTS 3 123 124#define COMPHY_SIP_POWER_ON 0x82000001 125#define COMPHY_SIP_POWER_OFF 0x82000002 126 127/* 128 * A lane is described by the following bitfields: 129 * [ 1- 0]: COMPHY polarity invertion 130 * [ 2- 7]: COMPHY speed 131 * [ 5-11]: COMPHY port index 132 * [12-16]: COMPHY mode 133 * [17]: Clock source 134 * [18-20]: PCIe width (x1, x2, x4) 135 */ 136#define COMPHY_FW_POL_OFFSET 0 137#define COMPHY_FW_POL_MASK GENMASK(1, 0) 138#define COMPHY_FW_SPEED_OFFSET 2 139#define COMPHY_FW_SPEED_MASK GENMASK(7, 2) 140#define COMPHY_FW_SPEED_MAX COMPHY_FW_SPEED_MASK 141#define COMPHY_FW_SPEED_1250 0 142#define COMPHY_FW_SPEED_3125 2 143#define COMPHY_FW_SPEED_5000 3 144#define COMPHY_FW_SPEED_515625 4 145#define COMPHY_FW_SPEED_103125 6 146#define COMPHY_FW_PORT_OFFSET 8 147#define COMPHY_FW_PORT_MASK GENMASK(11, 8) 148#define COMPHY_FW_MODE_OFFSET 12 149#define COMPHY_FW_MODE_MASK GENMASK(16, 12) 150#define COMPHY_FW_WIDTH_OFFSET 18 151#define COMPHY_FW_WIDTH_MASK GENMASK(20, 18) 152 153#define COMPHY_FW_PARAM_FULL(mode, port, speed, pol, width) \ 154 ((((pol) << COMPHY_FW_POL_OFFSET) & COMPHY_FW_POL_MASK) | \ 155 (((mode) << COMPHY_FW_MODE_OFFSET) & COMPHY_FW_MODE_MASK) | \ 156 (((port) << COMPHY_FW_PORT_OFFSET) & COMPHY_FW_PORT_MASK) | \ 157 (((speed) << COMPHY_FW_SPEED_OFFSET) & COMPHY_FW_SPEED_MASK) | \ 158 (((width) << COMPHY_FW_WIDTH_OFFSET) & COMPHY_FW_WIDTH_MASK)) 159 160#define COMPHY_FW_PARAM(mode, port) \ 161 COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_MAX, 0, 0) 162 163#define COMPHY_FW_PARAM_ETH(mode, port, speed) \ 164 COMPHY_FW_PARAM_FULL(mode, port, speed, 0, 0) 165 166#define COMPHY_FW_PARAM_PCIE(mode, port, width) \ 167 COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_5000, 0, width) 168 169#define COMPHY_FW_MODE_SATA 0x1 170#define COMPHY_FW_MODE_SGMII 0x2 /* SGMII 1G */ 171#define COMPHY_FW_MODE_2500BASEX 0x3 /* 2500BASE-X */ 172#define COMPHY_FW_MODE_USB3H 0x4 173#define COMPHY_FW_MODE_USB3D 0x5 174#define COMPHY_FW_MODE_PCIE 0x6 175#define COMPHY_FW_MODE_RXAUI 0x7 176#define COMPHY_FW_MODE_XFI 0x8 /* SFI: 0x9 (is treated like XFI) */ 177 178struct mvebu_comphy_conf { 179 enum phy_mode mode; 180 int submode; 181 unsigned lane; 182 unsigned port; 183 u32 mux; 184 u32 fw_mode; 185}; 186 187#define ETH_CONF(_lane, _port, _submode, _mux, _fw) \ 188 { \ 189 .lane = _lane, \ 190 .port = _port, \ 191 .mode = PHY_MODE_ETHERNET, \ 192 .submode = _submode, \ 193 .mux = _mux, \ 194 .fw_mode = _fw, \ 195 } 196 197#define GEN_CONF(_lane, _port, _mode, _fw) \ 198 { \ 199 .lane = _lane, \ 200 .port = _port, \ 201 .mode = _mode, \ 202 .submode = PHY_INTERFACE_MODE_NA, \ 203 .mux = -1, \ 204 .fw_mode = _fw, \ 205 } 206 207static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { 208 /* lane 0 */ 209 GEN_CONF(0, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), 210 ETH_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), 211 ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX), 212 GEN_CONF(0, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), 213 /* lane 1 */ 214 GEN_CONF(1, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), 215 GEN_CONF(1, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D), 216 GEN_CONF(1, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), 217 GEN_CONF(1, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), 218 ETH_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), 219 ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX), 220 /* lane 2 */ 221 ETH_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), 222 ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX), 223 ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI), 224 ETH_CONF(2, 0, PHY_INTERFACE_MODE_5GBASER, 0x1, COMPHY_FW_MODE_XFI), 225 ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GBASER, 0x1, COMPHY_FW_MODE_XFI), 226 GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), 227 GEN_CONF(2, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), 228 GEN_CONF(2, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), 229 /* lane 3 */ 230 GEN_CONF(3, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), 231 ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), 232 ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_2500BASEX), 233 ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI), 234 GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), 235 GEN_CONF(3, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), 236 /* lane 4 */ 237 ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), 238 ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_2500BASEX), 239 ETH_CONF(4, 0, PHY_INTERFACE_MODE_5GBASER, 0x2, COMPHY_FW_MODE_XFI), 240 ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GBASER, 0x2, COMPHY_FW_MODE_XFI), 241 ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI), 242 GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D), 243 GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), 244 GEN_CONF(4, 1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), 245 ETH_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), 246 ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_2500BASEX), 247 ETH_CONF(4, 1, PHY_INTERFACE_MODE_5GBASER, -1, COMPHY_FW_MODE_XFI), 248 ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GBASER, -1, COMPHY_FW_MODE_XFI), 249 /* lane 5 */ 250 ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI), 251 GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), 252 ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), 253 ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX), 254 GEN_CONF(5, 2, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), 255}; 256 257struct mvebu_comphy_priv { 258 void __iomem *base; 259 struct regmap *regmap; 260 struct device *dev; 261 struct clk *mg_domain_clk; 262 struct clk *mg_core_clk; 263 struct clk *axi_clk; 264 unsigned long cp_phys; 265}; 266 267struct mvebu_comphy_lane { 268 struct mvebu_comphy_priv *priv; 269 unsigned id; 270 enum phy_mode mode; 271 int submode; 272 int port; 273}; 274 275static int mvebu_comphy_smc(unsigned long function, unsigned long phys, 276 unsigned long lane, unsigned long mode) 277{ 278 struct arm_smccc_res res; 279 s32 ret; 280 281 arm_smccc_smc(function, phys, lane, mode, 0, 0, 0, 0, &res); 282 ret = res.a0; 283 284 switch (ret) { 285 case SMCCC_RET_SUCCESS: 286 return 0; 287 case SMCCC_RET_NOT_SUPPORTED: 288 return -EOPNOTSUPP; 289 default: 290 return -EINVAL; 291 } 292} 293 294static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port, 295 enum phy_mode mode, int submode) 296{ 297 int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes); 298 /* Ignore PCIe submode: it represents the width */ 299 bool ignore_submode = (mode == PHY_MODE_PCIE); 300 const struct mvebu_comphy_conf *conf; 301 302 /* Unused PHY mux value is 0x0 */ 303 if (mode == PHY_MODE_INVALID) 304 return 0; 305 306 for (i = 0; i < n; i++) { 307 conf = &mvebu_comphy_cp110_modes[i]; 308 if (conf->lane == lane && 309 conf->port == port && 310 conf->mode == mode && 311 (conf->submode == submode || ignore_submode)) 312 break; 313 } 314 315 if (i == n) 316 return -EINVAL; 317 318 if (fw_mode) 319 return conf->fw_mode; 320 else 321 return conf->mux; 322} 323 324static inline int mvebu_comphy_get_mux(int lane, int port, 325 enum phy_mode mode, int submode) 326{ 327 return mvebu_comphy_get_mode(false, lane, port, mode, submode); 328} 329 330static inline int mvebu_comphy_get_fw_mode(int lane, int port, 331 enum phy_mode mode, int submode) 332{ 333 return mvebu_comphy_get_mode(true, lane, port, mode, submode); 334} 335 336static int mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane) 337{ 338 struct mvebu_comphy_priv *priv = lane->priv; 339 u32 val; 340 341 regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val); 342 val &= ~MVEBU_COMPHY_CONF1_USB_PCIE; 343 val |= MVEBU_COMPHY_CONF1_PWRUP; 344 regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val); 345 346 /* Select baud rates and PLLs */ 347 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); 348 val &= ~(MVEBU_COMPHY_SERDES_CFG0_PU_PLL | 349 MVEBU_COMPHY_SERDES_CFG0_PU_RX | 350 MVEBU_COMPHY_SERDES_CFG0_PU_TX | 351 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS | 352 MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) | 353 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf) | 354 MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE); 355 356 switch (lane->submode) { 357 case PHY_INTERFACE_MODE_10GBASER: 358 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) | 359 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe); 360 break; 361 case PHY_INTERFACE_MODE_RXAUI: 362 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xb) | 363 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xb) | 364 MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE; 365 break; 366 case PHY_INTERFACE_MODE_2500BASEX: 367 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) | 368 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) | 369 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS; 370 break; 371 case PHY_INTERFACE_MODE_SGMII: 372 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) | 373 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) | 374 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS; 375 break; 376 default: 377 dev_err(priv->dev, 378 "unsupported comphy submode (%d) on lane %d\n", 379 lane->submode, 380 lane->id); 381 return -ENOTSUPP; 382 } 383 384 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); 385 386 if (lane->submode == PHY_INTERFACE_MODE_RXAUI) { 387 regmap_read(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, &val); 388 389 switch (lane->id) { 390 case 2: 391 case 3: 392 val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN; 393 break; 394 case 4: 395 case 5: 396 val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN; 397 break; 398 default: 399 dev_err(priv->dev, 400 "RXAUI is not supported on comphy lane %d\n", 401 lane->id); 402 return -EINVAL; 403 } 404 405 regmap_write(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, val); 406 } 407 408 /* reset */ 409 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 410 val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET | 411 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET | 412 MVEBU_COMPHY_SERDES_CFG1_RF_RESET); 413 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 414 415 /* de-assert reset */ 416 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 417 val |= MVEBU_COMPHY_SERDES_CFG1_RESET | 418 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET; 419 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 420 421 /* wait until clocks are ready */ 422 mdelay(1); 423 424 /* exlicitly disable 40B, the bits isn't clear on reset */ 425 regmap_read(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), &val); 426 val &= ~MVEBU_COMPHY_CONF6_40B; 427 regmap_write(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), val); 428 429 /* refclk selection */ 430 val = readl(priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id)); 431 val &= ~MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL; 432 if (lane->submode == PHY_INTERFACE_MODE_10GBASER) 433 val |= MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE; 434 writel(val, priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id)); 435 436 /* power and pll selection */ 437 val = readl(priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id)); 438 val &= ~(MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1f) | 439 MVEBU_COMPHY_PWRPLL_PHY_MODE(0x7)); 440 val |= MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1) | 441 MVEBU_COMPHY_PWRPLL_PHY_MODE(0x4); 442 writel(val, priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id)); 443 444 val = readl(priv->base + MVEBU_COMPHY_LOOPBACK(lane->id)); 445 val &= ~MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x7); 446 val |= MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x1); 447 writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id)); 448 449 return 0; 450} 451 452static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane) 453{ 454 struct mvebu_comphy_priv *priv = lane->priv; 455 u32 val; 456 457 /* SERDES external config */ 458 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); 459 val |= MVEBU_COMPHY_SERDES_CFG0_PU_PLL | 460 MVEBU_COMPHY_SERDES_CFG0_PU_RX | 461 MVEBU_COMPHY_SERDES_CFG0_PU_TX; 462 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); 463 464 /* check rx/tx pll */ 465 readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id), 466 val, 467 val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY | 468 MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY), 469 1000, 150000); 470 if (!(val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY | 471 MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY))) 472 return -ETIMEDOUT; 473 474 /* rx init */ 475 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 476 val |= MVEBU_COMPHY_SERDES_CFG1_RX_INIT; 477 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 478 479 /* check rx */ 480 readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id), 481 val, val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT, 482 1000, 10000); 483 if (!(val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT)) 484 return -ETIMEDOUT; 485 486 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 487 val &= ~MVEBU_COMPHY_SERDES_CFG1_RX_INIT; 488 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 489 490 return 0; 491} 492 493static int mvebu_comphy_set_mode_sgmii(struct phy *phy) 494{ 495 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 496 struct mvebu_comphy_priv *priv = lane->priv; 497 u32 val; 498 int err; 499 500 err = mvebu_comphy_ethernet_init_reset(lane); 501 if (err) 502 return err; 503 504 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 505 val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; 506 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL; 507 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 508 509 val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); 510 val &= ~MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN; 511 writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); 512 513 regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val); 514 val &= ~MVEBU_COMPHY_CONF1_USB_PCIE; 515 val |= MVEBU_COMPHY_CONF1_PWRUP; 516 regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val); 517 518 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 519 val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf); 520 val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0x1); 521 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 522 523 return mvebu_comphy_init_plls(lane); 524} 525 526static int mvebu_comphy_set_mode_rxaui(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 int err; 532 533 err = mvebu_comphy_ethernet_init_reset(lane); 534 if (err) 535 return err; 536 537 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 538 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL | 539 MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; 540 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 541 542 val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); 543 val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN; 544 writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); 545 546 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id)); 547 val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN; 548 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id)); 549 550 val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id)); 551 val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL; 552 writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id)); 553 554 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 555 val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf); 556 val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xd); 557 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 558 559 val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id)); 560 val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) | 561 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7)); 562 val |= MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x1) | 563 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x1) | 564 MVEBU_COMPHY_GEN1_S1_RX_DFE_EN; 565 writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id)); 566 567 val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id)); 568 val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL); 569 writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id)); 570 571 val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id)); 572 val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3); 573 val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1); 574 writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id)); 575 576 return mvebu_comphy_init_plls(lane); 577} 578 579static int mvebu_comphy_set_mode_10gbaser(struct phy *phy) 580{ 581 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 582 struct mvebu_comphy_priv *priv = lane->priv; 583 u32 val; 584 int err; 585 586 err = mvebu_comphy_ethernet_init_reset(lane); 587 if (err) 588 return err; 589 590 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 591 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL | 592 MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; 593 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 594 595 val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); 596 val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN; 597 writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); 598 599 /* Speed divider */ 600 val = readl(priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id)); 601 val |= MVEBU_COMPHY_SPEED_DIV_TX_FORCE; 602 writel(val, priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id)); 603 604 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id)); 605 val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN; 606 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id)); 607 608 /* DFE resolution */ 609 val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id)); 610 val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL; 611 writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id)); 612 613 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 614 val &= ~(MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1f) | 615 MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf)); 616 val |= MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1c) | 617 MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xe); 618 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); 619 620 val = readl(priv->base + MVEBU_COMPHY_GEN1_S2(lane->id)); 621 val &= ~MVEBU_COMPHY_GEN1_S2_TX_EMPH(0xf); 622 val |= MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN; 623 writel(val, priv->base + MVEBU_COMPHY_GEN1_S2(lane->id)); 624 625 val = readl(priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id)); 626 val |= MVEBU_COMPHY_TX_SLEW_RATE_EMPH(0x3) | 627 MVEBU_COMPHY_TX_SLEW_RATE_SLC(0x3f); 628 writel(val, priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id)); 629 630 /* Impedance calibration */ 631 val = readl(priv->base + MVEBU_COMPHY_IMP_CAL(lane->id)); 632 val &= ~MVEBU_COMPHY_IMP_CAL_TX_EXT(0x1f); 633 val |= MVEBU_COMPHY_IMP_CAL_TX_EXT(0xe) | 634 MVEBU_COMPHY_IMP_CAL_TX_EXT_EN; 635 writel(val, priv->base + MVEBU_COMPHY_IMP_CAL(lane->id)); 636 637 val = readl(priv->base + MVEBU_COMPHY_GEN1_S5(lane->id)); 638 val &= ~MVEBU_COMPHY_GEN1_S5_ICP(0xf); 639 writel(val, priv->base + MVEBU_COMPHY_GEN1_S5(lane->id)); 640 641 val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id)); 642 val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) | 643 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7) | 644 MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(0x3) | 645 MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x3)); 646 val |= MVEBU_COMPHY_GEN1_S1_RX_DFE_EN | 647 MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x2) | 648 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x2) | 649 MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x1) | 650 MVEBU_COMPHY_GEN1_S1_RX_DIV(0x3); 651 writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id)); 652 653 val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id)); 654 val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL); 655 writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id)); 656 657 val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id)); 658 val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3); 659 val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1); 660 writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id)); 661 662 val = readl(priv->base + MVEBU_COMPHY_GEN1_S3(lane->id)); 663 val |= MVEBU_COMPHY_GEN1_S3_FBCK_SEL; 664 writel(val, priv->base + MVEBU_COMPHY_GEN1_S3(lane->id)); 665 666 /* rx training timer */ 667 val = readl(priv->base + MVEBU_COMPHY_TRAINING5(lane->id)); 668 val &= ~MVEBU_COMPHY_TRAINING5_RX_TIMER(0x3ff); 669 val |= MVEBU_COMPHY_TRAINING5_RX_TIMER(0x13); 670 writel(val, priv->base + MVEBU_COMPHY_TRAINING5(lane->id)); 671 672 /* tx train peak to peak hold */ 673 val = readl(priv->base + MVEBU_COMPHY_TRAINING0(lane->id)); 674 val |= MVEBU_COMPHY_TRAINING0_P2P_HOLD; 675 writel(val, priv->base + MVEBU_COMPHY_TRAINING0(lane->id)); 676 677 val = readl(priv->base + MVEBU_COMPHY_TX_PRESET(lane->id)); 678 val &= ~MVEBU_COMPHY_TX_PRESET_INDEX(0xf); 679 val |= MVEBU_COMPHY_TX_PRESET_INDEX(0x2); /* preset coeff */ 680 writel(val, priv->base + MVEBU_COMPHY_TX_PRESET(lane->id)); 681 682 val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id)); 683 val &= ~MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN; 684 writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id)); 685 686 val = readl(priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id)); 687 val |= MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN | 688 MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11; 689 writel(val, priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id)); 690 691 val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id)); 692 val &= ~MVEBU_COMPHY_FRAME_DETECT0_PATN(0x1ff); 693 val |= MVEBU_COMPHY_FRAME_DETECT0_PATN(0x88); 694 writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id)); 695 696 val = readl(priv->base + MVEBU_COMPHY_DME(lane->id)); 697 val |= MVEBU_COMPHY_DME_ETH_MODE; 698 writel(val, priv->base + MVEBU_COMPHY_DME(lane->id)); 699 700 val = readl(priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id)); 701 val |= MVEBU_COMPHY_VDD_CAL0_CONT_MODE; 702 writel(val, priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id)); 703 704 val = readl(priv->base + MVEBU_SP_CALIB(lane->id)); 705 val &= ~MVEBU_SP_CALIB_SAMPLER(0x3); 706 val |= MVEBU_SP_CALIB_SAMPLER(0x3) | 707 MVEBU_SP_CALIB_SAMPLER_EN; 708 writel(val, priv->base + MVEBU_SP_CALIB(lane->id)); 709 val &= ~MVEBU_SP_CALIB_SAMPLER_EN; 710 writel(val, priv->base + MVEBU_SP_CALIB(lane->id)); 711 712 /* External rx regulator */ 713 val = readl(priv->base + MVEBU_COMPHY_EXT_SELV(lane->id)); 714 val &= ~MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1f); 715 val |= MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1a); 716 writel(val, priv->base + MVEBU_COMPHY_EXT_SELV(lane->id)); 717 718 return mvebu_comphy_init_plls(lane); 719} 720 721static int mvebu_comphy_power_on_legacy(struct phy *phy) 722{ 723 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 724 struct mvebu_comphy_priv *priv = lane->priv; 725 int ret, mux; 726 u32 val; 727 728 mux = mvebu_comphy_get_mux(lane->id, lane->port, 729 lane->mode, lane->submode); 730 if (mux < 0) 731 return -ENOTSUPP; 732 733 regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val); 734 val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id)); 735 regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val); 736 737 regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val); 738 val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id)); 739 val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id); 740 regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val); 741 742 switch (lane->submode) { 743 case PHY_INTERFACE_MODE_SGMII: 744 case PHY_INTERFACE_MODE_2500BASEX: 745 ret = mvebu_comphy_set_mode_sgmii(phy); 746 break; 747 case PHY_INTERFACE_MODE_RXAUI: 748 ret = mvebu_comphy_set_mode_rxaui(phy); 749 break; 750 case PHY_INTERFACE_MODE_10GBASER: 751 ret = mvebu_comphy_set_mode_10gbaser(phy); 752 break; 753 default: 754 return -ENOTSUPP; 755 } 756 757 /* digital reset */ 758 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 759 val |= MVEBU_COMPHY_SERDES_CFG1_RF_RESET; 760 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 761 762 return ret; 763} 764 765static int mvebu_comphy_power_on(struct phy *phy) 766{ 767 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 768 struct mvebu_comphy_priv *priv = lane->priv; 769 int fw_mode, fw_speed; 770 u32 fw_param = 0; 771 int ret; 772 773 fw_mode = mvebu_comphy_get_fw_mode(lane->id, lane->port, 774 lane->mode, lane->submode); 775 if (fw_mode < 0) 776 goto try_legacy; 777 778 /* Try SMC flow first */ 779 switch (lane->mode) { 780 case PHY_MODE_ETHERNET: 781 switch (lane->submode) { 782 case PHY_INTERFACE_MODE_RXAUI: 783 dev_dbg(priv->dev, "set lane %d to RXAUI mode\n", 784 lane->id); 785 fw_speed = 0; 786 break; 787 case PHY_INTERFACE_MODE_SGMII: 788 dev_dbg(priv->dev, "set lane %d to 1000BASE-X mode\n", 789 lane->id); 790 fw_speed = COMPHY_FW_SPEED_1250; 791 break; 792 case PHY_INTERFACE_MODE_2500BASEX: 793 dev_dbg(priv->dev, "set lane %d to 2500BASE-X mode\n", 794 lane->id); 795 fw_speed = COMPHY_FW_SPEED_3125; 796 break; 797 case PHY_INTERFACE_MODE_5GBASER: 798 dev_dbg(priv->dev, "set lane %d to 5GBASE-R mode\n", 799 lane->id); 800 fw_speed = COMPHY_FW_SPEED_515625; 801 break; 802 case PHY_INTERFACE_MODE_10GBASER: 803 dev_dbg(priv->dev, "set lane %d to 10GBASE-R mode\n", 804 lane->id); 805 fw_speed = COMPHY_FW_SPEED_103125; 806 break; 807 default: 808 dev_err(priv->dev, "unsupported Ethernet mode (%d)\n", 809 lane->submode); 810 return -ENOTSUPP; 811 } 812 fw_param = COMPHY_FW_PARAM_ETH(fw_mode, lane->port, fw_speed); 813 break; 814 case PHY_MODE_USB_HOST_SS: 815 case PHY_MODE_USB_DEVICE_SS: 816 dev_dbg(priv->dev, "set lane %d to USB3 mode\n", lane->id); 817 fw_param = COMPHY_FW_PARAM(fw_mode, lane->port); 818 break; 819 case PHY_MODE_SATA: 820 dev_dbg(priv->dev, "set lane %d to SATA mode\n", lane->id); 821 fw_param = COMPHY_FW_PARAM(fw_mode, lane->port); 822 break; 823 case PHY_MODE_PCIE: 824 dev_dbg(priv->dev, "set lane %d to PCIe mode (x%d)\n", lane->id, 825 lane->submode); 826 fw_param = COMPHY_FW_PARAM_PCIE(fw_mode, lane->port, 827 lane->submode); 828 break; 829 default: 830 dev_err(priv->dev, "unsupported PHY mode (%d)\n", lane->mode); 831 return -ENOTSUPP; 832 } 833 834 ret = mvebu_comphy_smc(COMPHY_SIP_POWER_ON, priv->cp_phys, lane->id, 835 fw_param); 836 if (!ret) 837 return ret; 838 839 if (ret == -EOPNOTSUPP) 840 dev_err(priv->dev, 841 "unsupported SMC call, try updating your firmware\n"); 842 843 dev_warn(priv->dev, 844 "Firmware could not configure PHY %d with mode %d (ret: %d), trying legacy method\n", 845 lane->id, lane->mode, ret); 846 847try_legacy: 848 /* Fallback to Linux's implementation */ 849 return mvebu_comphy_power_on_legacy(phy); 850} 851 852static int mvebu_comphy_set_mode(struct phy *phy, 853 enum phy_mode mode, int submode) 854{ 855 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 856 857 if (submode == PHY_INTERFACE_MODE_1000BASEX) 858 submode = PHY_INTERFACE_MODE_SGMII; 859 860 if (mvebu_comphy_get_fw_mode(lane->id, lane->port, mode, submode) < 0) 861 return -EINVAL; 862 863 lane->mode = mode; 864 lane->submode = submode; 865 866 /* PCIe submode represents the width */ 867 if (mode == PHY_MODE_PCIE && !lane->submode) 868 lane->submode = 1; 869 870 return 0; 871} 872 873static int mvebu_comphy_power_off_legacy(struct phy *phy) 874{ 875 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 876 struct mvebu_comphy_priv *priv = lane->priv; 877 u32 val; 878 879 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 880 val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET | 881 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET | 882 MVEBU_COMPHY_SERDES_CFG1_RF_RESET); 883 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 884 885 regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val); 886 val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id)); 887 regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val); 888 889 regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val); 890 val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id)); 891 regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val); 892 893 return 0; 894} 895 896static int mvebu_comphy_power_off(struct phy *phy) 897{ 898 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 899 struct mvebu_comphy_priv *priv = lane->priv; 900 int ret; 901 902 ret = mvebu_comphy_smc(COMPHY_SIP_POWER_OFF, priv->cp_phys, 903 lane->id, 0); 904 if (!ret) 905 return ret; 906 907 /* Fallback to Linux's implementation */ 908 return mvebu_comphy_power_off_legacy(phy); 909} 910 911static const struct phy_ops mvebu_comphy_ops = { 912 .power_on = mvebu_comphy_power_on, 913 .power_off = mvebu_comphy_power_off, 914 .set_mode = mvebu_comphy_set_mode, 915 .owner = THIS_MODULE, 916}; 917 918static struct phy *mvebu_comphy_xlate(struct device *dev, 919 struct of_phandle_args *args) 920{ 921 struct mvebu_comphy_lane *lane; 922 struct phy *phy; 923 924 if (WARN_ON(args->args[0] >= MVEBU_COMPHY_PORTS)) 925 return ERR_PTR(-EINVAL); 926 927 phy = of_phy_simple_xlate(dev, args); 928 if (IS_ERR(phy)) 929 return phy; 930 931 lane = phy_get_drvdata(phy); 932 lane->port = args->args[0]; 933 934 return phy; 935} 936 937static int mvebu_comphy_init_clks(struct mvebu_comphy_priv *priv) 938{ 939 int ret; 940 941 priv->mg_domain_clk = devm_clk_get(priv->dev, "mg_clk"); 942 if (IS_ERR(priv->mg_domain_clk)) 943 return PTR_ERR(priv->mg_domain_clk); 944 945 ret = clk_prepare_enable(priv->mg_domain_clk); 946 if (ret < 0) 947 return ret; 948 949 priv->mg_core_clk = devm_clk_get(priv->dev, "mg_core_clk"); 950 if (IS_ERR(priv->mg_core_clk)) { 951 ret = PTR_ERR(priv->mg_core_clk); 952 goto dis_mg_domain_clk; 953 } 954 955 ret = clk_prepare_enable(priv->mg_core_clk); 956 if (ret < 0) 957 goto dis_mg_domain_clk; 958 959 priv->axi_clk = devm_clk_get(priv->dev, "axi_clk"); 960 if (IS_ERR(priv->axi_clk)) { 961 ret = PTR_ERR(priv->axi_clk); 962 goto dis_mg_core_clk; 963 } 964 965 ret = clk_prepare_enable(priv->axi_clk); 966 if (ret < 0) 967 goto dis_mg_core_clk; 968 969 return 0; 970 971dis_mg_core_clk: 972 clk_disable_unprepare(priv->mg_core_clk); 973 974dis_mg_domain_clk: 975 clk_disable_unprepare(priv->mg_domain_clk); 976 977 priv->mg_domain_clk = NULL; 978 priv->mg_core_clk = NULL; 979 priv->axi_clk = NULL; 980 981 return ret; 982}; 983 984static void mvebu_comphy_disable_unprepare_clks(struct mvebu_comphy_priv *priv) 985{ 986 if (priv->axi_clk) 987 clk_disable_unprepare(priv->axi_clk); 988 989 if (priv->mg_core_clk) 990 clk_disable_unprepare(priv->mg_core_clk); 991 992 if (priv->mg_domain_clk) 993 clk_disable_unprepare(priv->mg_domain_clk); 994} 995 996static int mvebu_comphy_probe(struct platform_device *pdev) 997{ 998 struct mvebu_comphy_priv *priv; 999 struct phy_provider *provider; 1000 struct device_node *child; 1001 struct resource *res; 1002 int ret; 1003 1004 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 1005 if (!priv) 1006 return -ENOMEM; 1007 1008 priv->dev = &pdev->dev; 1009 priv->regmap = 1010 syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 1011 "marvell,system-controller"); 1012 if (IS_ERR(priv->regmap)) 1013 return PTR_ERR(priv->regmap); 1014 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1015 priv->base = devm_ioremap_resource(&pdev->dev, res); 1016 if (IS_ERR(priv->base)) 1017 return PTR_ERR(priv->base); 1018 1019 /* 1020 * Ignore error if clocks have not been initialized properly for DT 1021 * compatibility reasons. 1022 */ 1023 ret = mvebu_comphy_init_clks(priv); 1024 if (ret) { 1025 if (ret == -EPROBE_DEFER) 1026 return ret; 1027 dev_warn(&pdev->dev, "cannot initialize clocks\n"); 1028 } 1029 1030 /* 1031 * Hack to retrieve a physical offset relative to this CP that will be 1032 * given to the firmware 1033 */ 1034 priv->cp_phys = res->start; 1035 1036 for_each_available_child_of_node(pdev->dev.of_node, child) { 1037 struct mvebu_comphy_lane *lane; 1038 struct phy *phy; 1039 u32 val; 1040 1041 ret = of_property_read_u32(child, "reg", &val); 1042 if (ret < 0) { 1043 dev_err(&pdev->dev, "missing 'reg' property (%d)\n", 1044 ret); 1045 continue; 1046 } 1047 1048 if (val >= MVEBU_COMPHY_LANES) { 1049 dev_err(&pdev->dev, "invalid 'reg' property\n"); 1050 continue; 1051 } 1052 1053 lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); 1054 if (!lane) { 1055 of_node_put(child); 1056 ret = -ENOMEM; 1057 goto disable_clks; 1058 } 1059 1060 phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops); 1061 if (IS_ERR(phy)) { 1062 of_node_put(child); 1063 ret = PTR_ERR(phy); 1064 goto disable_clks; 1065 } 1066 1067 lane->priv = priv; 1068 lane->mode = PHY_MODE_INVALID; 1069 lane->submode = PHY_INTERFACE_MODE_NA; 1070 lane->id = val; 1071 lane->port = -1; 1072 phy_set_drvdata(phy, lane); 1073 1074 /* 1075 * All modes are supported in this driver so we could call 1076 * mvebu_comphy_power_off(phy) here to avoid relying on the 1077 * bootloader/firmware configuration, but for compatibility 1078 * reasons we cannot de-configure the COMPHY without being sure 1079 * that the firmware is up-to-date and fully-featured. 1080 */ 1081 } 1082 1083 dev_set_drvdata(&pdev->dev, priv); 1084 provider = devm_of_phy_provider_register(&pdev->dev, 1085 mvebu_comphy_xlate); 1086 1087 return PTR_ERR_OR_ZERO(provider); 1088 1089disable_clks: 1090 mvebu_comphy_disable_unprepare_clks(priv); 1091 1092 return ret; 1093} 1094 1095static const struct of_device_id mvebu_comphy_of_match_table[] = { 1096 { .compatible = "marvell,comphy-cp110" }, 1097 { }, 1098}; 1099MODULE_DEVICE_TABLE(of, mvebu_comphy_of_match_table); 1100 1101static struct platform_driver mvebu_comphy_driver = { 1102 .probe = mvebu_comphy_probe, 1103 .driver = { 1104 .name = "mvebu-comphy", 1105 .of_match_table = mvebu_comphy_of_match_table, 1106 }, 1107}; 1108module_platform_driver(mvebu_comphy_driver); 1109 1110MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>"); 1111MODULE_DESCRIPTION("Common PHY driver for mvebu SoCs"); 1112MODULE_LICENSE("GPL v2");