Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2017 Marvell
0004  *
0005  * Antoine Tenart <antoine.tenart@free-electrons.com>
0006  */
0007 
0008 #include <linux/arm-smccc.h>
0009 #include <linux/clk.h>
0010 #include <linux/io.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/mfd/syscon.h>
0013 #include <linux/module.h>
0014 #include <linux/phy.h>
0015 #include <linux/phy/phy.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/regmap.h>
0018 
0019 /* Relative to priv->base */
0020 #define MVEBU_COMPHY_SERDES_CFG0(n)     (0x0 + (n) * 0x1000)
0021 #define     MVEBU_COMPHY_SERDES_CFG0_PU_PLL BIT(1)
0022 #define     MVEBU_COMPHY_SERDES_CFG0_GEN_RX(n)  ((n) << 3)
0023 #define     MVEBU_COMPHY_SERDES_CFG0_GEN_TX(n)  ((n) << 7)
0024 #define     MVEBU_COMPHY_SERDES_CFG0_PU_RX  BIT(11)
0025 #define     MVEBU_COMPHY_SERDES_CFG0_PU_TX  BIT(12)
0026 #define     MVEBU_COMPHY_SERDES_CFG0_HALF_BUS   BIT(14)
0027 #define     MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE BIT(15)
0028 #define MVEBU_COMPHY_SERDES_CFG1(n)     (0x4 + (n) * 0x1000)
0029 #define     MVEBU_COMPHY_SERDES_CFG1_RESET  BIT(3)
0030 #define     MVEBU_COMPHY_SERDES_CFG1_RX_INIT    BIT(4)
0031 #define     MVEBU_COMPHY_SERDES_CFG1_CORE_RESET BIT(5)
0032 #define     MVEBU_COMPHY_SERDES_CFG1_RF_RESET   BIT(6)
0033 #define MVEBU_COMPHY_SERDES_CFG2(n)     (0x8 + (n) * 0x1000)
0034 #define     MVEBU_COMPHY_SERDES_CFG2_DFE_EN BIT(4)
0035 #define MVEBU_COMPHY_SERDES_STATUS0(n)      (0x18 + (n) * 0x1000)
0036 #define     MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY  BIT(2)
0037 #define     MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY  BIT(3)
0038 #define     MVEBU_COMPHY_SERDES_STATUS0_RX_INIT     BIT(4)
0039 #define MVEBU_COMPHY_PWRPLL_CTRL(n)     (0x804 + (n) * 0x1000)
0040 #define     MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(n)   ((n) << 0)
0041 #define     MVEBU_COMPHY_PWRPLL_PHY_MODE(n) ((n) << 5)
0042 #define MVEBU_COMPHY_IMP_CAL(n)         (0x80c + (n) * 0x1000)
0043 #define     MVEBU_COMPHY_IMP_CAL_TX_EXT(n)  ((n) << 10)
0044 #define     MVEBU_COMPHY_IMP_CAL_TX_EXT_EN  BIT(15)
0045 #define MVEBU_COMPHY_DFE_RES(n)         (0x81c + (n) * 0x1000)
0046 #define     MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL  BIT(15)
0047 #define MVEBU_COMPHY_COEF(n)            (0x828 + (n) * 0x1000)
0048 #define     MVEBU_COMPHY_COEF_DFE_EN        BIT(14)
0049 #define     MVEBU_COMPHY_COEF_DFE_CTRL      BIT(15)
0050 #define MVEBU_COMPHY_GEN1_S0(n)         (0x834 + (n) * 0x1000)
0051 #define     MVEBU_COMPHY_GEN1_S0_TX_AMP(n)  ((n) << 1)
0052 #define     MVEBU_COMPHY_GEN1_S0_TX_EMPH(n) ((n) << 7)
0053 #define MVEBU_COMPHY_GEN1_S1(n)         (0x838 + (n) * 0x1000)
0054 #define     MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(n)   ((n) << 0)
0055 #define     MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(n)   ((n) << 3)
0056 #define     MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(n)   ((n) << 6)
0057 #define     MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(n)   ((n) << 8)
0058 #define     MVEBU_COMPHY_GEN1_S1_RX_DFE_EN  BIT(10)
0059 #define     MVEBU_COMPHY_GEN1_S1_RX_DIV(n)  ((n) << 11)
0060 #define MVEBU_COMPHY_GEN1_S2(n)         (0x8f4 + (n) * 0x1000)
0061 #define     MVEBU_COMPHY_GEN1_S2_TX_EMPH(n) ((n) << 0)
0062 #define     MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN BIT(4)
0063 #define MVEBU_COMPHY_LOOPBACK(n)        (0x88c + (n) * 0x1000)
0064 #define     MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(n) ((n) << 1)
0065 #define MVEBU_COMPHY_VDD_CAL0(n)        (0x908 + (n) * 0x1000)
0066 #define     MVEBU_COMPHY_VDD_CAL0_CONT_MODE BIT(15)
0067 #define MVEBU_COMPHY_EXT_SELV(n)        (0x914 + (n) * 0x1000)
0068 #define     MVEBU_COMPHY_EXT_SELV_RX_SAMPL(n)   ((n) << 5)
0069 #define MVEBU_COMPHY_MISC_CTRL0(n)      (0x93c + (n) * 0x1000)
0070 #define     MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE   BIT(5)
0071 #define     MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL  BIT(10)
0072 #define MVEBU_COMPHY_RX_CTRL1(n)        (0x940 + (n) * 0x1000)
0073 #define     MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL   BIT(11)
0074 #define     MVEBU_COMPHY_RX_CTRL1_CLK8T_EN  BIT(12)
0075 #define MVEBU_COMPHY_SPEED_DIV(n)       (0x954 + (n) * 0x1000)
0076 #define     MVEBU_COMPHY_SPEED_DIV_TX_FORCE BIT(7)
0077 #define MVEBU_SP_CALIB(n)           (0x96c + (n) * 0x1000)
0078 #define     MVEBU_SP_CALIB_SAMPLER(n)       ((n) << 8)
0079 #define     MVEBU_SP_CALIB_SAMPLER_EN       BIT(12)
0080 #define MVEBU_COMPHY_TX_SLEW_RATE(n)        (0x974 + (n) * 0x1000)
0081 #define     MVEBU_COMPHY_TX_SLEW_RATE_EMPH(n)   ((n) << 5)
0082 #define     MVEBU_COMPHY_TX_SLEW_RATE_SLC(n)    ((n) << 10)
0083 #define MVEBU_COMPHY_DTL_CTRL(n)        (0x984 + (n) * 0x1000)
0084 #define     MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN  BIT(2)
0085 #define MVEBU_COMPHY_FRAME_DETECT0(n)       (0xa14 + (n) * 0x1000)
0086 #define     MVEBU_COMPHY_FRAME_DETECT0_PATN(n)  ((n) << 7)
0087 #define MVEBU_COMPHY_FRAME_DETECT3(n)       (0xa20 + (n) * 0x1000)
0088 #define     MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN  BIT(12)
0089 #define MVEBU_COMPHY_DME(n)         (0xa28 + (n) * 0x1000)
0090 #define     MVEBU_COMPHY_DME_ETH_MODE       BIT(7)
0091 #define MVEBU_COMPHY_TRAINING0(n)       (0xa68 + (n) * 0x1000)
0092 #define     MVEBU_COMPHY_TRAINING0_P2P_HOLD BIT(15)
0093 #define MVEBU_COMPHY_TRAINING5(n)       (0xaa4 + (n) * 0x1000)
0094 #define     MVEBU_COMPHY_TRAINING5_RX_TIMER(n)  ((n) << 0)
0095 #define MVEBU_COMPHY_TX_TRAIN_PRESET(n)     (0xb1c + (n) * 0x1000)
0096 #define     MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN    BIT(8)
0097 #define     MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11     BIT(9)
0098 #define MVEBU_COMPHY_GEN1_S3(n)         (0xc40 + (n) * 0x1000)
0099 #define     MVEBU_COMPHY_GEN1_S3_FBCK_SEL   BIT(9)
0100 #define MVEBU_COMPHY_GEN1_S4(n)         (0xc44 + (n) * 0x1000)
0101 #define     MVEBU_COMPHY_GEN1_S4_DFE_RES(n) ((n) << 8)
0102 #define MVEBU_COMPHY_TX_PRESET(n)       (0xc68 + (n) * 0x1000)
0103 #define     MVEBU_COMPHY_TX_PRESET_INDEX(n) ((n) << 0)
0104 #define MVEBU_COMPHY_GEN1_S5(n)         (0xd38 + (n) * 0x1000)
0105 #define     MVEBU_COMPHY_GEN1_S5_ICP(n)     ((n) << 0)
0106 
0107 /* Relative to priv->regmap */
0108 #define MVEBU_COMPHY_CONF1(n)           (0x1000 + (n) * 0x28)
0109 #define     MVEBU_COMPHY_CONF1_PWRUP        BIT(1)
0110 #define     MVEBU_COMPHY_CONF1_USB_PCIE     BIT(2)  /* 0: Ethernet/SATA */
0111 #define MVEBU_COMPHY_CONF6(n)           (0x1014 + (n) * 0x28)
0112 #define     MVEBU_COMPHY_CONF6_40B      BIT(18)
0113 #define MVEBU_COMPHY_SELECTOR           0x1140
0114 #define     MVEBU_COMPHY_SELECTOR_PHY(n)    ((n) * 0x4)
0115 #define MVEBU_COMPHY_PIPE_SELECTOR      0x1144
0116 #define     MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n)  ((n) * 0x4)
0117 #define MVEBU_COMPHY_SD1_CTRL1          0x1148
0118 #define     MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN    BIT(26)
0119 #define     MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN    BIT(27)
0120 
0121 #define MVEBU_COMPHY_LANES  6
0122 #define MVEBU_COMPHY_PORTS  3
0123 
0124 #define COMPHY_SIP_POWER_ON 0x82000001
0125 #define COMPHY_SIP_POWER_OFF    0x82000002
0126 
0127 /*
0128  * A lane is described by the following bitfields:
0129  * [ 1- 0]: COMPHY polarity invertion
0130  * [ 2- 7]: COMPHY speed
0131  * [ 5-11]: COMPHY port index
0132  * [12-16]: COMPHY mode
0133  * [17]: Clock source
0134  * [18-20]: PCIe width (x1, x2, x4)
0135  */
0136 #define COMPHY_FW_POL_OFFSET    0
0137 #define COMPHY_FW_POL_MASK  GENMASK(1, 0)
0138 #define COMPHY_FW_SPEED_OFFSET  2
0139 #define COMPHY_FW_SPEED_MASK    GENMASK(7, 2)
0140 #define COMPHY_FW_SPEED_MAX COMPHY_FW_SPEED_MASK
0141 #define COMPHY_FW_SPEED_1250    0
0142 #define COMPHY_FW_SPEED_3125    2
0143 #define COMPHY_FW_SPEED_5000    3
0144 #define COMPHY_FW_SPEED_515625  4
0145 #define COMPHY_FW_SPEED_103125  6
0146 #define COMPHY_FW_PORT_OFFSET   8
0147 #define COMPHY_FW_PORT_MASK GENMASK(11, 8)
0148 #define COMPHY_FW_MODE_OFFSET   12
0149 #define COMPHY_FW_MODE_MASK GENMASK(16, 12)
0150 #define COMPHY_FW_WIDTH_OFFSET  18
0151 #define COMPHY_FW_WIDTH_MASK    GENMASK(20, 18)
0152 
0153 #define COMPHY_FW_PARAM_FULL(mode, port, speed, pol, width)     \
0154     ((((pol) << COMPHY_FW_POL_OFFSET) & COMPHY_FW_POL_MASK) |   \
0155      (((mode) << COMPHY_FW_MODE_OFFSET) & COMPHY_FW_MODE_MASK) |    \
0156      (((port) << COMPHY_FW_PORT_OFFSET) & COMPHY_FW_PORT_MASK) |    \
0157      (((speed) << COMPHY_FW_SPEED_OFFSET) & COMPHY_FW_SPEED_MASK) | \
0158      (((width) << COMPHY_FW_WIDTH_OFFSET) & COMPHY_FW_WIDTH_MASK))
0159 
0160 #define COMPHY_FW_PARAM(mode, port)                 \
0161     COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_MAX, 0, 0)
0162 
0163 #define COMPHY_FW_PARAM_ETH(mode, port, speed)              \
0164     COMPHY_FW_PARAM_FULL(mode, port, speed, 0, 0)
0165 
0166 #define COMPHY_FW_PARAM_PCIE(mode, port, width)             \
0167     COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_5000, 0, width)
0168 
0169 #define COMPHY_FW_MODE_SATA     0x1
0170 #define COMPHY_FW_MODE_SGMII        0x2 /* SGMII 1G */
0171 #define COMPHY_FW_MODE_2500BASEX    0x3 /* 2500BASE-X */
0172 #define COMPHY_FW_MODE_USB3H        0x4
0173 #define COMPHY_FW_MODE_USB3D        0x5
0174 #define COMPHY_FW_MODE_PCIE     0x6
0175 #define COMPHY_FW_MODE_RXAUI        0x7
0176 #define COMPHY_FW_MODE_XFI      0x8 /* SFI: 0x9 (is treated like XFI) */
0177 
0178 struct mvebu_comphy_conf {
0179     enum phy_mode mode;
0180     int submode;
0181     unsigned lane;
0182     unsigned port;
0183     u32 mux;
0184     u32 fw_mode;
0185 };
0186 
0187 #define ETH_CONF(_lane, _port, _submode, _mux, _fw) \
0188     {                       \
0189         .lane = _lane,              \
0190         .port = _port,              \
0191         .mode = PHY_MODE_ETHERNET,      \
0192         .submode = _submode,            \
0193         .mux = _mux,                \
0194         .fw_mode = _fw,             \
0195     }
0196 
0197 #define GEN_CONF(_lane, _port, _mode, _fw)      \
0198     {                       \
0199         .lane = _lane,              \
0200         .port = _port,              \
0201         .mode = _mode,              \
0202         .submode = PHY_INTERFACE_MODE_NA,   \
0203         .mux = -1,              \
0204         .fw_mode = _fw,             \
0205     }
0206 
0207 static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
0208     /* lane 0 */
0209     GEN_CONF(0, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
0210     ETH_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
0211     ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
0212     GEN_CONF(0, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
0213     /* lane 1 */
0214     GEN_CONF(1, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
0215     GEN_CONF(1, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D),
0216     GEN_CONF(1, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
0217     GEN_CONF(1, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
0218     ETH_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
0219     ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
0220     /* lane 2 */
0221     ETH_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
0222     ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
0223     ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
0224     ETH_CONF(2, 0, PHY_INTERFACE_MODE_5GBASER, 0x1, COMPHY_FW_MODE_XFI),
0225     ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GBASER, 0x1, COMPHY_FW_MODE_XFI),
0226     GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
0227     GEN_CONF(2, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
0228     GEN_CONF(2, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
0229     /* lane 3 */
0230     GEN_CONF(3, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
0231     ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
0232     ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_2500BASEX),
0233     ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
0234     GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
0235     GEN_CONF(3, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
0236     /* lane 4 */
0237     ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
0238     ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_2500BASEX),
0239     ETH_CONF(4, 0, PHY_INTERFACE_MODE_5GBASER, 0x2, COMPHY_FW_MODE_XFI),
0240     ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GBASER, 0x2, COMPHY_FW_MODE_XFI),
0241     ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
0242     GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D),
0243     GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
0244     GEN_CONF(4, 1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
0245     ETH_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
0246     ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_2500BASEX),
0247     ETH_CONF(4, 1, PHY_INTERFACE_MODE_5GBASER, -1, COMPHY_FW_MODE_XFI),
0248     ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GBASER, -1, COMPHY_FW_MODE_XFI),
0249     /* lane 5 */
0250     ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
0251     GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
0252     ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
0253     ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
0254     GEN_CONF(5, 2, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
0255 };
0256 
0257 struct mvebu_comphy_priv {
0258     void __iomem *base;
0259     struct regmap *regmap;
0260     struct device *dev;
0261     struct clk *mg_domain_clk;
0262     struct clk *mg_core_clk;
0263     struct clk *axi_clk;
0264     unsigned long cp_phys;
0265 };
0266 
0267 struct mvebu_comphy_lane {
0268     struct mvebu_comphy_priv *priv;
0269     unsigned id;
0270     enum phy_mode mode;
0271     int submode;
0272     int port;
0273 };
0274 
0275 static int mvebu_comphy_smc(unsigned long function, unsigned long phys,
0276                 unsigned long lane, unsigned long mode)
0277 {
0278     struct arm_smccc_res res;
0279     s32 ret;
0280 
0281     arm_smccc_smc(function, phys, lane, mode, 0, 0, 0, 0, &res);
0282     ret = res.a0;
0283 
0284     switch (ret) {
0285     case SMCCC_RET_SUCCESS:
0286         return 0;
0287     case SMCCC_RET_NOT_SUPPORTED:
0288         return -EOPNOTSUPP;
0289     default:
0290         return -EINVAL;
0291     }
0292 }
0293 
0294 static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port,
0295                  enum phy_mode mode, int submode)
0296 {
0297     int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes);
0298     /* Ignore PCIe submode: it represents the width */
0299     bool ignore_submode = (mode == PHY_MODE_PCIE);
0300     const struct mvebu_comphy_conf *conf;
0301 
0302     /* Unused PHY mux value is 0x0 */
0303     if (mode == PHY_MODE_INVALID)
0304         return 0;
0305 
0306     for (i = 0; i < n; i++) {
0307         conf = &mvebu_comphy_cp110_modes[i];
0308         if (conf->lane == lane &&
0309             conf->port == port &&
0310             conf->mode == mode &&
0311             (conf->submode == submode || ignore_submode))
0312             break;
0313     }
0314 
0315     if (i == n)
0316         return -EINVAL;
0317 
0318     if (fw_mode)
0319         return conf->fw_mode;
0320     else
0321         return conf->mux;
0322 }
0323 
0324 static inline int mvebu_comphy_get_mux(int lane, int port,
0325                        enum phy_mode mode, int submode)
0326 {
0327     return mvebu_comphy_get_mode(false, lane, port, mode, submode);
0328 }
0329 
0330 static inline int mvebu_comphy_get_fw_mode(int lane, int port,
0331                        enum phy_mode mode, int submode)
0332 {
0333     return mvebu_comphy_get_mode(true, lane, port, mode, submode);
0334 }
0335 
0336 static int mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane)
0337 {
0338     struct mvebu_comphy_priv *priv = lane->priv;
0339     u32 val;
0340 
0341     regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
0342     val &= ~MVEBU_COMPHY_CONF1_USB_PCIE;
0343     val |= MVEBU_COMPHY_CONF1_PWRUP;
0344     regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
0345 
0346     /* Select baud rates and PLLs */
0347     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
0348     val &= ~(MVEBU_COMPHY_SERDES_CFG0_PU_PLL |
0349          MVEBU_COMPHY_SERDES_CFG0_PU_RX |
0350          MVEBU_COMPHY_SERDES_CFG0_PU_TX |
0351          MVEBU_COMPHY_SERDES_CFG0_HALF_BUS |
0352          MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) |
0353          MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf) |
0354          MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE);
0355 
0356     switch (lane->submode) {
0357     case PHY_INTERFACE_MODE_10GBASER:
0358         val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) |
0359                MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe);
0360         break;
0361     case PHY_INTERFACE_MODE_RXAUI:
0362         val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xb) |
0363                MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xb) |
0364                MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE;
0365         break;
0366     case PHY_INTERFACE_MODE_2500BASEX:
0367         val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) |
0368                MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) |
0369                MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
0370         break;
0371     case PHY_INTERFACE_MODE_SGMII:
0372         val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) |
0373                MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) |
0374                MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
0375         break;
0376     default:
0377         dev_err(priv->dev,
0378             "unsupported comphy submode (%d) on lane %d\n",
0379             lane->submode,
0380             lane->id);
0381         return -ENOTSUPP;
0382     }
0383 
0384     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
0385 
0386     if (lane->submode == PHY_INTERFACE_MODE_RXAUI) {
0387         regmap_read(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, &val);
0388 
0389         switch (lane->id) {
0390         case 2:
0391         case 3:
0392             val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN;
0393             break;
0394         case 4:
0395         case 5:
0396             val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN;
0397             break;
0398         default:
0399             dev_err(priv->dev,
0400                 "RXAUI is not supported on comphy lane %d\n",
0401                 lane->id);
0402             return -EINVAL;
0403         }
0404 
0405         regmap_write(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, val);
0406     }
0407 
0408     /* reset */
0409     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0410     val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET |
0411          MVEBU_COMPHY_SERDES_CFG1_CORE_RESET |
0412          MVEBU_COMPHY_SERDES_CFG1_RF_RESET);
0413     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0414 
0415     /* de-assert reset */
0416     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0417     val |= MVEBU_COMPHY_SERDES_CFG1_RESET |
0418            MVEBU_COMPHY_SERDES_CFG1_CORE_RESET;
0419     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0420 
0421     /* wait until clocks are ready */
0422     mdelay(1);
0423 
0424     /* exlicitly disable 40B, the bits isn't clear on reset */
0425     regmap_read(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), &val);
0426     val &= ~MVEBU_COMPHY_CONF6_40B;
0427     regmap_write(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), val);
0428 
0429     /* refclk selection */
0430     val = readl(priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
0431     val &= ~MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL;
0432     if (lane->submode == PHY_INTERFACE_MODE_10GBASER)
0433         val |= MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE;
0434     writel(val, priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
0435 
0436     /* power and pll selection */
0437     val = readl(priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
0438     val &= ~(MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1f) |
0439          MVEBU_COMPHY_PWRPLL_PHY_MODE(0x7));
0440     val |= MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1) |
0441            MVEBU_COMPHY_PWRPLL_PHY_MODE(0x4);
0442     writel(val, priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
0443 
0444     val = readl(priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
0445     val &= ~MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x7);
0446     val |= MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x1);
0447     writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
0448 
0449     return 0;
0450 }
0451 
0452 static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane)
0453 {
0454     struct mvebu_comphy_priv *priv = lane->priv;
0455     u32 val;
0456 
0457     /* SERDES external config */
0458     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
0459     val |= MVEBU_COMPHY_SERDES_CFG0_PU_PLL |
0460            MVEBU_COMPHY_SERDES_CFG0_PU_RX |
0461            MVEBU_COMPHY_SERDES_CFG0_PU_TX;
0462     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
0463 
0464     /* check rx/tx pll */
0465     readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
0466                val,
0467                val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY |
0468                   MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY),
0469                1000, 150000);
0470     if (!(val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY |
0471              MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY)))
0472         return -ETIMEDOUT;
0473 
0474     /* rx init */
0475     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0476     val |= MVEBU_COMPHY_SERDES_CFG1_RX_INIT;
0477     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0478 
0479     /* check rx */
0480     readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
0481                val, val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT,
0482                1000, 10000);
0483     if (!(val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT))
0484         return -ETIMEDOUT;
0485 
0486     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0487     val &= ~MVEBU_COMPHY_SERDES_CFG1_RX_INIT;
0488     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0489 
0490     return 0;
0491 }
0492 
0493 static int mvebu_comphy_set_mode_sgmii(struct phy *phy)
0494 {
0495     struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
0496     struct mvebu_comphy_priv *priv = lane->priv;
0497     u32 val;
0498     int err;
0499 
0500     err = mvebu_comphy_ethernet_init_reset(lane);
0501     if (err)
0502         return err;
0503 
0504     val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
0505     val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
0506     val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL;
0507     writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
0508 
0509     val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
0510     val &= ~MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN;
0511     writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
0512 
0513     regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
0514     val &= ~MVEBU_COMPHY_CONF1_USB_PCIE;
0515     val |= MVEBU_COMPHY_CONF1_PWRUP;
0516     regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
0517 
0518     val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
0519     val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf);
0520     val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0x1);
0521     writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
0522 
0523     return mvebu_comphy_init_plls(lane);
0524 }
0525 
0526 static int mvebu_comphy_set_mode_rxaui(struct phy *phy)
0527 {
0528     struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
0529     struct mvebu_comphy_priv *priv = lane->priv;
0530     u32 val;
0531     int err;
0532 
0533     err = mvebu_comphy_ethernet_init_reset(lane);
0534     if (err)
0535         return err;
0536 
0537     val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
0538     val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
0539            MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
0540     writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
0541 
0542     val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
0543     val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN;
0544     writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
0545 
0546     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
0547     val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN;
0548     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
0549 
0550     val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
0551     val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL;
0552     writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
0553 
0554     val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
0555     val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf);
0556     val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xd);
0557     writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
0558 
0559     val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
0560     val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) |
0561          MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7));
0562     val |= MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x1) |
0563            MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x1) |
0564            MVEBU_COMPHY_GEN1_S1_RX_DFE_EN;
0565     writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
0566 
0567     val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
0568     val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL);
0569     writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
0570 
0571     val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
0572     val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3);
0573     val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1);
0574     writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
0575 
0576     return mvebu_comphy_init_plls(lane);
0577 }
0578 
0579 static int mvebu_comphy_set_mode_10gbaser(struct phy *phy)
0580 {
0581     struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
0582     struct mvebu_comphy_priv *priv = lane->priv;
0583     u32 val;
0584     int err;
0585 
0586     err = mvebu_comphy_ethernet_init_reset(lane);
0587     if (err)
0588         return err;
0589 
0590     val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
0591     val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
0592            MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
0593     writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
0594 
0595     val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
0596     val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN;
0597     writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
0598 
0599     /* Speed divider */
0600     val = readl(priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
0601     val |= MVEBU_COMPHY_SPEED_DIV_TX_FORCE;
0602     writel(val, priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
0603 
0604     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
0605     val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN;
0606     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
0607 
0608     /* DFE resolution */
0609     val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
0610     val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL;
0611     writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
0612 
0613     val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
0614     val &= ~(MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1f) |
0615          MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf));
0616     val |= MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1c) |
0617            MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xe);
0618     writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
0619 
0620     val = readl(priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
0621     val &= ~MVEBU_COMPHY_GEN1_S2_TX_EMPH(0xf);
0622     val |= MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN;
0623     writel(val, priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
0624 
0625     val = readl(priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
0626     val |= MVEBU_COMPHY_TX_SLEW_RATE_EMPH(0x3) |
0627            MVEBU_COMPHY_TX_SLEW_RATE_SLC(0x3f);
0628     writel(val, priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
0629 
0630     /* Impedance calibration */
0631     val = readl(priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
0632     val &= ~MVEBU_COMPHY_IMP_CAL_TX_EXT(0x1f);
0633     val |= MVEBU_COMPHY_IMP_CAL_TX_EXT(0xe) |
0634            MVEBU_COMPHY_IMP_CAL_TX_EXT_EN;
0635     writel(val, priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
0636 
0637     val = readl(priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
0638     val &= ~MVEBU_COMPHY_GEN1_S5_ICP(0xf);
0639     writel(val, priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
0640 
0641     val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
0642     val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) |
0643          MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7) |
0644          MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(0x3) |
0645          MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x3));
0646     val |= MVEBU_COMPHY_GEN1_S1_RX_DFE_EN |
0647            MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x2) |
0648            MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x2) |
0649            MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x1) |
0650            MVEBU_COMPHY_GEN1_S1_RX_DIV(0x3);
0651     writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
0652 
0653     val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
0654     val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL);
0655     writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
0656 
0657     val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
0658     val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3);
0659     val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1);
0660     writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
0661 
0662     val = readl(priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
0663     val |= MVEBU_COMPHY_GEN1_S3_FBCK_SEL;
0664     writel(val, priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
0665 
0666     /* rx training timer */
0667     val = readl(priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
0668     val &= ~MVEBU_COMPHY_TRAINING5_RX_TIMER(0x3ff);
0669     val |= MVEBU_COMPHY_TRAINING5_RX_TIMER(0x13);
0670     writel(val, priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
0671 
0672     /* tx train peak to peak hold */
0673     val = readl(priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
0674     val |= MVEBU_COMPHY_TRAINING0_P2P_HOLD;
0675     writel(val, priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
0676 
0677     val = readl(priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
0678     val &= ~MVEBU_COMPHY_TX_PRESET_INDEX(0xf);
0679     val |= MVEBU_COMPHY_TX_PRESET_INDEX(0x2);   /* preset coeff */
0680     writel(val, priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
0681 
0682     val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
0683     val &= ~MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN;
0684     writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
0685 
0686     val = readl(priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
0687     val |= MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN |
0688            MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11;
0689     writel(val, priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
0690 
0691     val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
0692     val &= ~MVEBU_COMPHY_FRAME_DETECT0_PATN(0x1ff);
0693     val |= MVEBU_COMPHY_FRAME_DETECT0_PATN(0x88);
0694     writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
0695 
0696     val = readl(priv->base + MVEBU_COMPHY_DME(lane->id));
0697     val |= MVEBU_COMPHY_DME_ETH_MODE;
0698     writel(val, priv->base + MVEBU_COMPHY_DME(lane->id));
0699 
0700     val = readl(priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
0701     val |= MVEBU_COMPHY_VDD_CAL0_CONT_MODE;
0702     writel(val, priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
0703 
0704     val = readl(priv->base + MVEBU_SP_CALIB(lane->id));
0705     val &= ~MVEBU_SP_CALIB_SAMPLER(0x3);
0706     val |= MVEBU_SP_CALIB_SAMPLER(0x3) |
0707            MVEBU_SP_CALIB_SAMPLER_EN;
0708     writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
0709     val &= ~MVEBU_SP_CALIB_SAMPLER_EN;
0710     writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
0711 
0712     /* External rx regulator */
0713     val = readl(priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
0714     val &= ~MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1f);
0715     val |= MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1a);
0716     writel(val, priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
0717 
0718     return mvebu_comphy_init_plls(lane);
0719 }
0720 
0721 static int mvebu_comphy_power_on_legacy(struct phy *phy)
0722 {
0723     struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
0724     struct mvebu_comphy_priv *priv = lane->priv;
0725     int ret, mux;
0726     u32 val;
0727 
0728     mux = mvebu_comphy_get_mux(lane->id, lane->port,
0729                    lane->mode, lane->submode);
0730     if (mux < 0)
0731         return -ENOTSUPP;
0732 
0733     regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
0734     val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
0735     regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
0736 
0737     regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
0738     val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
0739     val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id);
0740     regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
0741 
0742     switch (lane->submode) {
0743     case PHY_INTERFACE_MODE_SGMII:
0744     case PHY_INTERFACE_MODE_2500BASEX:
0745         ret = mvebu_comphy_set_mode_sgmii(phy);
0746         break;
0747     case PHY_INTERFACE_MODE_RXAUI:
0748         ret = mvebu_comphy_set_mode_rxaui(phy);
0749         break;
0750     case PHY_INTERFACE_MODE_10GBASER:
0751         ret = mvebu_comphy_set_mode_10gbaser(phy);
0752         break;
0753     default:
0754         return -ENOTSUPP;
0755     }
0756 
0757     /* digital reset */
0758     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0759     val |= MVEBU_COMPHY_SERDES_CFG1_RF_RESET;
0760     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0761 
0762     return ret;
0763 }
0764 
0765 static int mvebu_comphy_power_on(struct phy *phy)
0766 {
0767     struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
0768     struct mvebu_comphy_priv *priv = lane->priv;
0769     int fw_mode, fw_speed;
0770     u32 fw_param = 0;
0771     int ret;
0772 
0773     fw_mode = mvebu_comphy_get_fw_mode(lane->id, lane->port,
0774                        lane->mode, lane->submode);
0775     if (fw_mode < 0)
0776         goto try_legacy;
0777 
0778     /* Try SMC flow first */
0779     switch (lane->mode) {
0780     case PHY_MODE_ETHERNET:
0781         switch (lane->submode) {
0782         case PHY_INTERFACE_MODE_RXAUI:
0783             dev_dbg(priv->dev, "set lane %d to RXAUI mode\n",
0784                 lane->id);
0785             fw_speed = 0;
0786             break;
0787         case PHY_INTERFACE_MODE_SGMII:
0788             dev_dbg(priv->dev, "set lane %d to 1000BASE-X mode\n",
0789                 lane->id);
0790             fw_speed = COMPHY_FW_SPEED_1250;
0791             break;
0792         case PHY_INTERFACE_MODE_2500BASEX:
0793             dev_dbg(priv->dev, "set lane %d to 2500BASE-X mode\n",
0794                 lane->id);
0795             fw_speed = COMPHY_FW_SPEED_3125;
0796             break;
0797         case PHY_INTERFACE_MODE_5GBASER:
0798             dev_dbg(priv->dev, "set lane %d to 5GBASE-R mode\n",
0799                 lane->id);
0800             fw_speed = COMPHY_FW_SPEED_515625;
0801             break;
0802         case PHY_INTERFACE_MODE_10GBASER:
0803             dev_dbg(priv->dev, "set lane %d to 10GBASE-R mode\n",
0804                 lane->id);
0805             fw_speed = COMPHY_FW_SPEED_103125;
0806             break;
0807         default:
0808             dev_err(priv->dev, "unsupported Ethernet mode (%d)\n",
0809                 lane->submode);
0810             return -ENOTSUPP;
0811         }
0812         fw_param = COMPHY_FW_PARAM_ETH(fw_mode, lane->port, fw_speed);
0813         break;
0814     case PHY_MODE_USB_HOST_SS:
0815     case PHY_MODE_USB_DEVICE_SS:
0816         dev_dbg(priv->dev, "set lane %d to USB3 mode\n", lane->id);
0817         fw_param = COMPHY_FW_PARAM(fw_mode, lane->port);
0818         break;
0819     case PHY_MODE_SATA:
0820         dev_dbg(priv->dev, "set lane %d to SATA mode\n", lane->id);
0821         fw_param = COMPHY_FW_PARAM(fw_mode, lane->port);
0822         break;
0823     case PHY_MODE_PCIE:
0824         dev_dbg(priv->dev, "set lane %d to PCIe mode (x%d)\n", lane->id,
0825             lane->submode);
0826         fw_param = COMPHY_FW_PARAM_PCIE(fw_mode, lane->port,
0827                         lane->submode);
0828         break;
0829     default:
0830         dev_err(priv->dev, "unsupported PHY mode (%d)\n", lane->mode);
0831         return -ENOTSUPP;
0832     }
0833 
0834     ret = mvebu_comphy_smc(COMPHY_SIP_POWER_ON, priv->cp_phys, lane->id,
0835                    fw_param);
0836     if (!ret)
0837         return ret;
0838 
0839     if (ret == -EOPNOTSUPP)
0840         dev_err(priv->dev,
0841             "unsupported SMC call, try updating your firmware\n");
0842 
0843     dev_warn(priv->dev,
0844          "Firmware could not configure PHY %d with mode %d (ret: %d), trying legacy method\n",
0845          lane->id, lane->mode, ret);
0846 
0847 try_legacy:
0848     /* Fallback to Linux's implementation */
0849     return mvebu_comphy_power_on_legacy(phy);
0850 }
0851 
0852 static int mvebu_comphy_set_mode(struct phy *phy,
0853                  enum phy_mode mode, int submode)
0854 {
0855     struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
0856 
0857     if (submode == PHY_INTERFACE_MODE_1000BASEX)
0858         submode = PHY_INTERFACE_MODE_SGMII;
0859 
0860     if (mvebu_comphy_get_fw_mode(lane->id, lane->port, mode, submode) < 0)
0861         return -EINVAL;
0862 
0863     lane->mode = mode;
0864     lane->submode = submode;
0865 
0866     /* PCIe submode represents the width */
0867     if (mode == PHY_MODE_PCIE && !lane->submode)
0868         lane->submode = 1;
0869 
0870     return 0;
0871 }
0872 
0873 static int mvebu_comphy_power_off_legacy(struct phy *phy)
0874 {
0875     struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
0876     struct mvebu_comphy_priv *priv = lane->priv;
0877     u32 val;
0878 
0879     val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0880     val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET |
0881          MVEBU_COMPHY_SERDES_CFG1_CORE_RESET |
0882          MVEBU_COMPHY_SERDES_CFG1_RF_RESET);
0883     writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
0884 
0885     regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
0886     val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
0887     regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
0888 
0889     regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
0890     val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
0891     regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
0892 
0893     return 0;
0894 }
0895 
0896 static int mvebu_comphy_power_off(struct phy *phy)
0897 {
0898     struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
0899     struct mvebu_comphy_priv *priv = lane->priv;
0900     int ret;
0901 
0902     ret = mvebu_comphy_smc(COMPHY_SIP_POWER_OFF, priv->cp_phys,
0903                    lane->id, 0);
0904     if (!ret)
0905         return ret;
0906 
0907     /* Fallback to Linux's implementation */
0908     return mvebu_comphy_power_off_legacy(phy);
0909 }
0910 
0911 static const struct phy_ops mvebu_comphy_ops = {
0912     .power_on   = mvebu_comphy_power_on,
0913     .power_off  = mvebu_comphy_power_off,
0914     .set_mode   = mvebu_comphy_set_mode,
0915     .owner      = THIS_MODULE,
0916 };
0917 
0918 static struct phy *mvebu_comphy_xlate(struct device *dev,
0919                       struct of_phandle_args *args)
0920 {
0921     struct mvebu_comphy_lane *lane;
0922     struct phy *phy;
0923 
0924     if (WARN_ON(args->args[0] >= MVEBU_COMPHY_PORTS))
0925         return ERR_PTR(-EINVAL);
0926 
0927     phy = of_phy_simple_xlate(dev, args);
0928     if (IS_ERR(phy))
0929         return phy;
0930 
0931     lane = phy_get_drvdata(phy);
0932     lane->port = args->args[0];
0933 
0934     return phy;
0935 }
0936 
0937 static int mvebu_comphy_init_clks(struct mvebu_comphy_priv *priv)
0938 {
0939     int ret;
0940 
0941     priv->mg_domain_clk = devm_clk_get(priv->dev, "mg_clk");
0942     if (IS_ERR(priv->mg_domain_clk))
0943         return PTR_ERR(priv->mg_domain_clk);
0944 
0945     ret = clk_prepare_enable(priv->mg_domain_clk);
0946     if (ret < 0)
0947         return ret;
0948 
0949     priv->mg_core_clk = devm_clk_get(priv->dev, "mg_core_clk");
0950     if (IS_ERR(priv->mg_core_clk)) {
0951         ret = PTR_ERR(priv->mg_core_clk);
0952         goto dis_mg_domain_clk;
0953     }
0954 
0955     ret = clk_prepare_enable(priv->mg_core_clk);
0956     if (ret < 0)
0957         goto dis_mg_domain_clk;
0958 
0959     priv->axi_clk = devm_clk_get(priv->dev, "axi_clk");
0960     if (IS_ERR(priv->axi_clk)) {
0961         ret = PTR_ERR(priv->axi_clk);
0962         goto dis_mg_core_clk;
0963     }
0964 
0965     ret = clk_prepare_enable(priv->axi_clk);
0966     if (ret < 0)
0967         goto dis_mg_core_clk;
0968 
0969     return 0;
0970 
0971 dis_mg_core_clk:
0972     clk_disable_unprepare(priv->mg_core_clk);
0973 
0974 dis_mg_domain_clk:
0975     clk_disable_unprepare(priv->mg_domain_clk);
0976 
0977     priv->mg_domain_clk = NULL;
0978     priv->mg_core_clk = NULL;
0979     priv->axi_clk = NULL;
0980 
0981     return ret;
0982 };
0983 
0984 static void mvebu_comphy_disable_unprepare_clks(struct mvebu_comphy_priv *priv)
0985 {
0986     if (priv->axi_clk)
0987         clk_disable_unprepare(priv->axi_clk);
0988 
0989     if (priv->mg_core_clk)
0990         clk_disable_unprepare(priv->mg_core_clk);
0991 
0992     if (priv->mg_domain_clk)
0993         clk_disable_unprepare(priv->mg_domain_clk);
0994 }
0995 
0996 static int mvebu_comphy_probe(struct platform_device *pdev)
0997 {
0998     struct mvebu_comphy_priv *priv;
0999     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 
1089 disable_clks:
1090     mvebu_comphy_disable_unprepare_clks(priv);
1091 
1092     return ret;
1093 }
1094 
1095 static const struct of_device_id mvebu_comphy_of_match_table[] = {
1096     { .compatible = "marvell,comphy-cp110" },
1097     { },
1098 };
1099 MODULE_DEVICE_TABLE(of, mvebu_comphy_of_match_table);
1100 
1101 static 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 };
1108 module_platform_driver(mvebu_comphy_driver);
1109 
1110 MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");
1111 MODULE_DESCRIPTION("Common PHY driver for mvebu SoCs");
1112 MODULE_LICENSE("GPL v2");