0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/bitfield.h>
0017 #include <linux/clk.h>
0018 #include <linux/io.h>
0019 #include <linux/iopoll.h>
0020 #include <linux/mfd/syscon.h>
0021 #include <linux/module.h>
0022 #include <linux/phy.h>
0023 #include <linux/phy/phy.h>
0024 #include <linux/platform_device.h>
0025 #include <linux/spinlock.h>
0026
0027 #define PLL_SET_DELAY_US 600
0028 #define COMPHY_PLL_SLEEP 1000
0029 #define COMPHY_PLL_TIMEOUT 150000
0030
0031
0032 #define COMPHY_LANE2_INDIR_ADDR 0x0
0033 #define COMPHY_LANE2_INDIR_DATA 0x4
0034
0035
0036 #define COMPHY_LANE2_REGS_BASE 0x200
0037
0038
0039
0040
0041
0042 #define COMPHY_LANE_REG_DIRECT(reg) (((reg) & 0x7FF) << 1)
0043
0044
0045 #define COMPHY_POWER_PLL_CTRL 0x01
0046 #define PU_IVREF_BIT BIT(15)
0047 #define PU_PLL_BIT BIT(14)
0048 #define PU_RX_BIT BIT(13)
0049 #define PU_TX_BIT BIT(12)
0050 #define PU_TX_INTP_BIT BIT(11)
0051 #define PU_DFE_BIT BIT(10)
0052 #define RESET_DTL_RX_BIT BIT(9)
0053 #define PLL_LOCK_BIT BIT(8)
0054 #define REF_FREF_SEL_MASK GENMASK(4, 0)
0055 #define REF_FREF_SEL_SERDES_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x1)
0056 #define REF_FREF_SEL_SERDES_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3)
0057 #define REF_FREF_SEL_SERDES_50MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x4)
0058 #define REF_FREF_SEL_PCIE_USB3_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x2)
0059 #define REF_FREF_SEL_PCIE_USB3_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3)
0060 #define COMPHY_MODE_MASK GENMASK(7, 5)
0061 #define COMPHY_MODE_SATA FIELD_PREP(COMPHY_MODE_MASK, 0x0)
0062 #define COMPHY_MODE_PCIE FIELD_PREP(COMPHY_MODE_MASK, 0x3)
0063 #define COMPHY_MODE_SERDES FIELD_PREP(COMPHY_MODE_MASK, 0x4)
0064 #define COMPHY_MODE_USB3 FIELD_PREP(COMPHY_MODE_MASK, 0x5)
0065
0066 #define COMPHY_KVCO_CAL_CTRL 0x02
0067 #define USE_MAX_PLL_RATE_BIT BIT(12)
0068 #define SPEED_PLL_MASK GENMASK(7, 2)
0069 #define SPEED_PLL_VALUE_16 FIELD_PREP(SPEED_PLL_MASK, 0x10)
0070
0071 #define COMPHY_DIG_LOOPBACK_EN 0x23
0072 #define SEL_DATA_WIDTH_MASK GENMASK(11, 10)
0073 #define DATA_WIDTH_10BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x0)
0074 #define DATA_WIDTH_20BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x1)
0075 #define DATA_WIDTH_40BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x2)
0076 #define PLL_READY_TX_BIT BIT(4)
0077
0078 #define COMPHY_SYNC_PATTERN 0x24
0079 #define TXD_INVERT_BIT BIT(10)
0080 #define RXD_INVERT_BIT BIT(11)
0081
0082 #define COMPHY_SYNC_MASK_GEN 0x25
0083 #define PHY_GEN_MAX_MASK GENMASK(11, 10)
0084 #define PHY_GEN_MAX_USB3_5G FIELD_PREP(PHY_GEN_MAX_MASK, 0x1)
0085
0086 #define COMPHY_ISOLATION_CTRL 0x26
0087 #define PHY_ISOLATE_MODE BIT(15)
0088
0089 #define COMPHY_GEN2_SET2 0x3e
0090 #define GS2_TX_SSC_AMP_MASK GENMASK(15, 9)
0091 #define GS2_TX_SSC_AMP_4128 FIELD_PREP(GS2_TX_SSC_AMP_MASK, 0x20)
0092 #define GS2_VREG_RXTX_MAS_ISET_MASK GENMASK(8, 7)
0093 #define GS2_VREG_RXTX_MAS_ISET_60U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
0094 0x0)
0095 #define GS2_VREG_RXTX_MAS_ISET_80U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
0096 0x1)
0097 #define GS2_VREG_RXTX_MAS_ISET_100U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
0098 0x2)
0099 #define GS2_VREG_RXTX_MAS_ISET_120U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
0100 0x3)
0101 #define GS2_RSVD_6_0_MASK GENMASK(6, 0)
0102
0103 #define COMPHY_GEN3_SET2 0x3f
0104
0105 #define COMPHY_IDLE_SYNC_EN 0x48
0106 #define IDLE_SYNC_EN BIT(12)
0107
0108 #define COMPHY_MISC_CTRL0 0x4F
0109 #define CLK100M_125M_EN BIT(4)
0110 #define TXDCLK_2X_SEL BIT(6)
0111 #define CLK500M_EN BIT(7)
0112 #define PHY_REF_CLK_SEL BIT(10)
0113
0114 #define COMPHY_SFT_RESET 0x52
0115 #define SFT_RST BIT(9)
0116 #define SFT_RST_NO_REG BIT(10)
0117
0118 #define COMPHY_MISC_CTRL1 0x73
0119 #define SEL_BITS_PCIE_FORCE BIT(15)
0120
0121 #define COMPHY_GEN2_SET3 0x112
0122 #define GS3_FFE_CAP_SEL_MASK GENMASK(3, 0)
0123 #define GS3_FFE_CAP_SEL_VALUE FIELD_PREP(GS3_FFE_CAP_SEL_MASK, 0xF)
0124
0125
0126 #define COMPHY_PIPE_LANE_CFG0 0x180
0127 #define PRD_TXDEEMPH0_MASK BIT(0)
0128 #define PRD_TXMARGIN_MASK GENMASK(3, 1)
0129 #define PRD_TXSWING_MASK BIT(4)
0130 #define CFG_TX_ALIGN_POS_MASK GENMASK(8, 5)
0131
0132 #define COMPHY_PIPE_LANE_CFG1 0x181
0133 #define PRD_TXDEEMPH1_MASK BIT(15)
0134 #define USE_MAX_PLL_RATE_EN BIT(9)
0135 #define TX_DET_RX_MODE BIT(6)
0136 #define GEN2_TX_DATA_DLY_MASK GENMASK(4, 3)
0137 #define GEN2_TX_DATA_DLY_DEFT FIELD_PREP(GEN2_TX_DATA_DLY_MASK, 2)
0138 #define TX_ELEC_IDLE_MODE_EN BIT(0)
0139
0140 #define COMPHY_PIPE_LANE_STAT1 0x183
0141 #define TXDCLK_PCLK_EN BIT(0)
0142
0143 #define COMPHY_PIPE_LANE_CFG4 0x188
0144 #define SPREAD_SPECTRUM_CLK_EN BIT(7)
0145
0146 #define COMPHY_PIPE_RST_CLK_CTRL 0x1C1
0147 #define PIPE_SOFT_RESET BIT(0)
0148 #define PIPE_REG_RESET BIT(1)
0149 #define MODE_CORE_CLK_FREQ_SEL BIT(9)
0150 #define MODE_PIPE_WIDTH_32 BIT(3)
0151 #define MODE_REFDIV_MASK GENMASK(5, 4)
0152 #define MODE_REFDIV_BY_4 FIELD_PREP(MODE_REFDIV_MASK, 0x2)
0153
0154 #define COMPHY_PIPE_TEST_MODE_CTRL 0x1C2
0155 #define MODE_MARGIN_OVERRIDE BIT(2)
0156
0157 #define COMPHY_PIPE_CLK_SRC_LO 0x1C3
0158 #define MODE_CLK_SRC BIT(0)
0159 #define BUNDLE_PERIOD_SEL BIT(1)
0160 #define BUNDLE_PERIOD_SCALE_MASK GENMASK(3, 2)
0161 #define BUNDLE_SAMPLE_CTRL BIT(4)
0162 #define PLL_READY_DLY_MASK GENMASK(7, 5)
0163 #define CFG_SEL_20B BIT(15)
0164
0165 #define COMPHY_PIPE_PWR_MGM_TIM1 0x1D0
0166 #define CFG_PM_OSCCLK_WAIT_MASK GENMASK(15, 12)
0167 #define CFG_PM_RXDEN_WAIT_MASK GENMASK(11, 8)
0168 #define CFG_PM_RXDEN_WAIT_1_UNIT FIELD_PREP(CFG_PM_RXDEN_WAIT_MASK, 0x1)
0169 #define CFG_PM_RXDLOZ_WAIT_MASK GENMASK(7, 0)
0170 #define CFG_PM_RXDLOZ_WAIT_7_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0x7)
0171 #define CFG_PM_RXDLOZ_WAIT_12_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0xC)
0172
0173
0174
0175
0176
0177
0178
0179 #define COMPHY_RESERVED_REG 0x0E
0180 #define PHYCTRL_FRM_PIN_BIT BIT(13)
0181
0182
0183 #define COMPHY_PHY_REG(lane, reg) (((1 - (lane)) * 0x28) + ((reg) & 0x3f))
0184
0185
0186
0187
0188
0189
0190 #define COMPHY_PHY_CFG1 0x0
0191 #define PIN_PU_IVREF_BIT BIT(1)
0192 #define PIN_RESET_CORE_BIT BIT(11)
0193 #define PIN_RESET_COMPHY_BIT BIT(12)
0194 #define PIN_PU_PLL_BIT BIT(16)
0195 #define PIN_PU_RX_BIT BIT(17)
0196 #define PIN_PU_TX_BIT BIT(18)
0197 #define PIN_TX_IDLE_BIT BIT(19)
0198 #define GEN_RX_SEL_MASK GENMASK(25, 22)
0199 #define GEN_RX_SEL_VALUE(val) FIELD_PREP(GEN_RX_SEL_MASK, (val))
0200 #define GEN_TX_SEL_MASK GENMASK(29, 26)
0201 #define GEN_TX_SEL_VALUE(val) FIELD_PREP(GEN_TX_SEL_MASK, (val))
0202 #define SERDES_SPEED_1_25_G 0x6
0203 #define SERDES_SPEED_3_125_G 0x8
0204 #define PHY_RX_INIT_BIT BIT(30)
0205
0206
0207
0208
0209
0210
0211 #define COMPHY_PHY_STAT1 0x18
0212 #define PHY_RX_INIT_DONE_BIT BIT(0)
0213 #define PHY_PLL_READY_RX_BIT BIT(2)
0214 #define PHY_PLL_READY_TX_BIT BIT(3)
0215
0216
0217 #define COMPHY_SELECTOR_PHY_REG 0xFC
0218
0219 #define COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT BIT(0)
0220
0221 #define COMPHY_SELECTOR_USB3_GBE1_SEL_BIT BIT(4)
0222
0223 #define COMPHY_SELECTOR_USB3_PHY_SEL_BIT BIT(8)
0224
0225 struct mvebu_a3700_comphy_conf {
0226 unsigned int lane;
0227 enum phy_mode mode;
0228 int submode;
0229 };
0230
0231 #define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode) \
0232 { \
0233 .lane = _lane, \
0234 .mode = _mode, \
0235 .submode = _smode, \
0236 }
0237
0238 #define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode) \
0239 MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA)
0240
0241 #define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode) \
0242 MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode)
0243
0244 static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = {
0245
0246 MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS),
0247 MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII),
0248 MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_1000BASEX),
0249 MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX),
0250
0251 MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE),
0252 MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII),
0253 MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_1000BASEX),
0254 MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX),
0255
0256 MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA),
0257 MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS),
0258 };
0259
0260 struct mvebu_a3700_comphy_priv {
0261 void __iomem *comphy_regs;
0262 void __iomem *lane0_phy_regs;
0263 void __iomem *lane1_phy_regs;
0264 void __iomem *lane2_phy_indirect;
0265 spinlock_t lock;
0266 bool xtal_is_40m;
0267 };
0268
0269 struct mvebu_a3700_comphy_lane {
0270 struct mvebu_a3700_comphy_priv *priv;
0271 struct device *dev;
0272 unsigned int id;
0273 enum phy_mode mode;
0274 int submode;
0275 bool invert_tx;
0276 bool invert_rx;
0277 };
0278
0279 struct gbe_phy_init_data_fix {
0280 u16 addr;
0281 u16 value;
0282 };
0283
0284
0285 static struct gbe_phy_init_data_fix gbe_phy_init_fix[] = {
0286 { 0x005, 0x07CC }, { 0x015, 0x0000 }, { 0x01B, 0x0000 },
0287 { 0x01D, 0x0000 }, { 0x01E, 0x0000 }, { 0x01F, 0x0000 },
0288 { 0x020, 0x0000 }, { 0x021, 0x0030 }, { 0x026, 0x0888 },
0289 { 0x04D, 0x0152 }, { 0x04F, 0xA020 }, { 0x050, 0x07CC },
0290 { 0x053, 0xE9CA }, { 0x055, 0xBD97 }, { 0x071, 0x3015 },
0291 { 0x076, 0x03AA }, { 0x07C, 0x0FDF }, { 0x0C2, 0x3030 },
0292 { 0x0C3, 0x8000 }, { 0x0E2, 0x5550 }, { 0x0E3, 0x12A4 },
0293 { 0x0E4, 0x7D00 }, { 0x0E6, 0x0C83 }, { 0x101, 0xFCC0 },
0294 { 0x104, 0x0C10 }
0295 };
0296
0297
0298 static u16 gbe_phy_init[512] = {
0299
0300
0301
0302 0x3110, 0xFD83, 0x6430, 0x412F, 0x82C0, 0x06FA, 0x4500, 0x6D26,
0303 0xAFC0, 0x8000, 0xC000, 0x0000, 0x2000, 0x49CC, 0x0BC9, 0x2A52,
0304 0x0BD2, 0x0CDE, 0x13D2, 0x0CE8, 0x1149, 0x10E0, 0x0000, 0x0000,
0305 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x4134, 0x0D2D, 0xFFFF,
0306 0xFFE0, 0x4030, 0x1016, 0x0030, 0x0000, 0x0800, 0x0866, 0x0000,
0307 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0308 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0309 0x0000, 0x0000, 0x000F, 0x6A62, 0x1988, 0x3100, 0x3100, 0x3100,
0310 0x3100, 0xA708, 0x2430, 0x0830, 0x1030, 0x4610, 0xFF00, 0xFF00,
0311 0x0060, 0x1000, 0x0400, 0x0040, 0x00F0, 0x0155, 0x1100, 0xA02A,
0312 0x06FA, 0x0080, 0xB008, 0xE3ED, 0x5002, 0xB592, 0x7A80, 0x0001,
0313 0x020A, 0x8820, 0x6014, 0x8054, 0xACAA, 0xFC88, 0x2A02, 0x45CF,
0314 0x000F, 0x1817, 0x2860, 0x064F, 0x0000, 0x0204, 0x1800, 0x6000,
0315 0x810F, 0x4F23, 0x4000, 0x4498, 0x0850, 0x0000, 0x000E, 0x1002,
0316 0x9D3A, 0x3009, 0xD066, 0x0491, 0x0001, 0x6AB0, 0x0399, 0x3780,
0317 0x0040, 0x5AC0, 0x4A80, 0x0000, 0x01DF, 0x0000, 0x0007, 0x0000,
0318 0x2D54, 0x00A1, 0x4000, 0x0100, 0xA20A, 0x0000, 0x0000, 0x0000,
0319 0x0000, 0x0000, 0x0000, 0x7400, 0x0E81, 0x1000, 0x1242, 0x0210,
0320 0x80DF, 0x0F1F, 0x2F3F, 0x4F5F, 0x6F7F, 0x0F1F, 0x2F3F, 0x4F5F,
0321 0x6F7F, 0x4BAD, 0x0000, 0x0000, 0x0800, 0x0000, 0x2400, 0xB651,
0322 0xC9E0, 0x4247, 0x0A24, 0x0000, 0xAF19, 0x1004, 0x0000, 0x0000,
0323 0x0000, 0x0013, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0324 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0325 0x0000, 0x0000, 0x0000, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000,
0326 0x0000, 0x0000, 0x3010, 0xFA00, 0x0000, 0x0000, 0x0000, 0x0003,
0327 0x1618, 0x8200, 0x8000, 0x0400, 0x050F, 0x0000, 0x0000, 0x0000,
0328 0x4C93, 0x0000, 0x1000, 0x1120, 0x0010, 0x1242, 0x1242, 0x1E00,
0329 0x0000, 0x0000, 0x0000, 0x00F8, 0x0000, 0x0041, 0x0800, 0x0000,
0330 0x82A0, 0x572E, 0x2490, 0x14A9, 0x4E00, 0x0000, 0x0803, 0x0541,
0331 0x0C15, 0x0000, 0x0000, 0x0400, 0x2626, 0x0000, 0x0000, 0x4200,
0332 0x0000, 0xAA55, 0x1020, 0x0000, 0x0000, 0x5010, 0x0000, 0x0000,
0333 0x0000, 0x0000, 0x5000, 0x0000, 0x0000, 0x0000, 0x02F2, 0x0000,
0334 0x101F, 0xFDC0, 0x4000, 0x8010, 0x0110, 0x0006, 0x0000, 0x0000,
0335 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0336 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04C6, 0x0000,
0337 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0338 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0339 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0340 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0341 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0342 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0343 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0344 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0345 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0346 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0347 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0348 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0349 0x0000, 0x0000, 0x0000, 0x00F0, 0x08A2, 0x3112, 0x0A14, 0x0000,
0350 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0351 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0352 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0353 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0354 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0355 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0356 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0357 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0358 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0359 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0360 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0361 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0362 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0363 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0364 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0365 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
0366 };
0367
0368 static inline void comphy_reg_set(void __iomem *addr, u32 data, u32 mask)
0369 {
0370 u32 val;
0371
0372 val = readl(addr);
0373 val = (val & ~mask) | (data & mask);
0374 writel(val, addr);
0375 }
0376
0377 static inline void comphy_reg_set16(void __iomem *addr, u16 data, u16 mask)
0378 {
0379 u16 val;
0380
0381 val = readw(addr);
0382 val = (val & ~mask) | (data & mask);
0383 writew(val, addr);
0384 }
0385
0386
0387 static void comphy_set_indirect(struct mvebu_a3700_comphy_priv *priv,
0388 u32 offset, u16 data, u16 mask)
0389 {
0390 writel(offset,
0391 priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_ADDR);
0392 comphy_reg_set(priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_DATA,
0393 data, mask);
0394 }
0395
0396 static void comphy_lane_reg_set(struct mvebu_a3700_comphy_lane *lane,
0397 u16 reg, u16 data, u16 mask)
0398 {
0399 if (lane->id == 2) {
0400
0401 comphy_set_indirect(lane->priv,
0402 reg + COMPHY_LANE2_REGS_BASE,
0403 data, mask);
0404 } else {
0405 void __iomem *base = lane->id == 1 ?
0406 lane->priv->lane1_phy_regs :
0407 lane->priv->lane0_phy_regs;
0408
0409 comphy_reg_set16(base + COMPHY_LANE_REG_DIRECT(reg),
0410 data, mask);
0411 }
0412 }
0413
0414 static int comphy_lane_reg_poll(struct mvebu_a3700_comphy_lane *lane,
0415 u16 reg, u16 bits,
0416 ulong sleep_us, ulong timeout_us)
0417 {
0418 int ret;
0419
0420 if (lane->id == 2) {
0421 u32 data;
0422
0423
0424 writel(reg + COMPHY_LANE2_REGS_BASE,
0425 lane->priv->lane2_phy_indirect +
0426 COMPHY_LANE2_INDIR_ADDR);
0427
0428 ret = readl_poll_timeout(lane->priv->lane2_phy_indirect +
0429 COMPHY_LANE2_INDIR_DATA,
0430 data, (data & bits) == bits,
0431 sleep_us, timeout_us);
0432 } else {
0433 void __iomem *base = lane->id == 1 ?
0434 lane->priv->lane1_phy_regs :
0435 lane->priv->lane0_phy_regs;
0436 u16 data;
0437
0438 ret = readw_poll_timeout(base + COMPHY_LANE_REG_DIRECT(reg),
0439 data, (data & bits) == bits,
0440 sleep_us, timeout_us);
0441 }
0442
0443 return ret;
0444 }
0445
0446 static void comphy_periph_reg_set(struct mvebu_a3700_comphy_lane *lane,
0447 u8 reg, u32 data, u32 mask)
0448 {
0449 comphy_reg_set(lane->priv->comphy_regs + COMPHY_PHY_REG(lane->id, reg),
0450 data, mask);
0451 }
0452
0453 static int comphy_periph_reg_poll(struct mvebu_a3700_comphy_lane *lane,
0454 u8 reg, u32 bits,
0455 ulong sleep_us, ulong timeout_us)
0456 {
0457 u32 data;
0458
0459 return readl_poll_timeout(lane->priv->comphy_regs +
0460 COMPHY_PHY_REG(lane->id, reg),
0461 data, (data & bits) == bits,
0462 sleep_us, timeout_us);
0463 }
0464
0465
0466 static int
0467 mvebu_a3700_comphy_set_phy_selector(struct mvebu_a3700_comphy_lane *lane)
0468 {
0469 u32 old, new, clr = 0, set = 0;
0470 unsigned long flags;
0471
0472 switch (lane->mode) {
0473 case PHY_MODE_SATA:
0474
0475 if (lane->id == 2)
0476 clr = COMPHY_SELECTOR_USB3_PHY_SEL_BIT;
0477 else
0478 goto error;
0479 break;
0480
0481 case PHY_MODE_ETHERNET:
0482 if (lane->id == 0)
0483 clr = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT;
0484 else if (lane->id == 1)
0485 clr = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT;
0486 else
0487 goto error;
0488 break;
0489
0490 case PHY_MODE_USB_HOST_SS:
0491 if (lane->id == 2)
0492 set = COMPHY_SELECTOR_USB3_PHY_SEL_BIT;
0493 else if (lane->id == 0)
0494 set = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT;
0495 else
0496 goto error;
0497 break;
0498
0499 case PHY_MODE_PCIE:
0500
0501 if (lane->id == 1)
0502 set = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT;
0503 else
0504 goto error;
0505 break;
0506
0507 default:
0508 goto error;
0509 }
0510
0511 spin_lock_irqsave(&lane->priv->lock, flags);
0512
0513 old = readl(lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG);
0514 new = (old & ~clr) | set;
0515 writel(new, lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG);
0516
0517 spin_unlock_irqrestore(&lane->priv->lock, flags);
0518
0519 dev_dbg(lane->dev,
0520 "COMPHY[%d] mode[%d] changed PHY selector 0x%08x -> 0x%08x\n",
0521 lane->id, lane->mode, old, new);
0522
0523 return 0;
0524 error:
0525 dev_err(lane->dev, "COMPHY[%d] mode[%d] is invalid\n", lane->id,
0526 lane->mode);
0527 return -EINVAL;
0528 }
0529
0530 static int
0531 mvebu_a3700_comphy_sata_power_on(struct mvebu_a3700_comphy_lane *lane)
0532 {
0533 u32 mask, data, ref_clk;
0534 int ret;
0535
0536
0537 ret = mvebu_a3700_comphy_set_phy_selector(lane);
0538 if (ret)
0539 return ret;
0540
0541
0542 comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL,
0543 0x0, PHY_ISOLATE_MODE);
0544
0545
0546 data = 0x0;
0547 if (lane->invert_tx)
0548 data |= TXD_INVERT_BIT;
0549 if (lane->invert_rx)
0550 data |= RXD_INVERT_BIT;
0551 mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
0552 comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);
0553
0554
0555 comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN,
0556 DATA_WIDTH_40BIT, SEL_DATA_WIDTH_MASK);
0557
0558
0559 if (lane->priv->xtal_is_40m)
0560 ref_clk = REF_FREF_SEL_SERDES_40MHZ;
0561 else
0562 ref_clk = REF_FREF_SEL_SERDES_25MHZ;
0563
0564 data = ref_clk | COMPHY_MODE_SATA;
0565 mask = REF_FREF_SEL_MASK | COMPHY_MODE_MASK;
0566 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
0567
0568
0569 comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL,
0570 USE_MAX_PLL_RATE_BIT, USE_MAX_PLL_RATE_BIT);
0571
0572
0573 comphy_set_indirect(lane->priv, COMPHY_RESERVED_REG,
0574 0x0, PHYCTRL_FRM_PIN_BIT);
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586 udelay(PLL_SET_DELAY_US);
0587
0588
0589 ret = comphy_lane_reg_poll(lane, COMPHY_DIG_LOOPBACK_EN,
0590 PLL_READY_TX_BIT, COMPHY_PLL_SLEEP,
0591 COMPHY_PLL_TIMEOUT);
0592 if (ret)
0593 dev_err(lane->dev, "Failed to lock SATA PLL\n");
0594
0595 return ret;
0596 }
0597
0598 static void comphy_gbe_phy_init(struct mvebu_a3700_comphy_lane *lane,
0599 bool is_1gbps)
0600 {
0601 int addr, fix_idx;
0602 u16 val;
0603
0604 fix_idx = 0;
0605 for (addr = 0; addr < 512; addr++) {
0606
0607
0608
0609
0610
0611
0612
0613 if (!is_1gbps && gbe_phy_init_fix[fix_idx].addr == addr) {
0614
0615 val = gbe_phy_init_fix[fix_idx].value;
0616 if (fix_idx < ARRAY_SIZE(gbe_phy_init_fix))
0617 fix_idx++;
0618 } else {
0619 val = gbe_phy_init[addr];
0620 }
0621
0622 comphy_lane_reg_set(lane, addr, val, 0xFFFF);
0623 }
0624 }
0625
0626 static int
0627 mvebu_a3700_comphy_ethernet_power_on(struct mvebu_a3700_comphy_lane *lane)
0628 {
0629 u32 mask, data, speed_sel;
0630 int ret;
0631
0632
0633 ret = mvebu_a3700_comphy_set_phy_selector(lane);
0634 if (ret)
0635 return ret;
0636
0637
0638
0639
0640
0641
0642
0643 data = PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT | PIN_RESET_COMPHY_BIT;
0644 mask = data | PIN_RESET_CORE_BIT | PIN_PU_PLL_BIT | PIN_PU_RX_BIT |
0645 PIN_PU_TX_BIT | PHY_RX_INIT_BIT;
0646 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
0647
0648
0649 data = 0x0;
0650 mask = PIN_RESET_COMPHY_BIT;
0651 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
0652
0653
0654
0655
0656
0657 switch (lane->submode) {
0658 case PHY_INTERFACE_MODE_SGMII:
0659 case PHY_INTERFACE_MODE_1000BASEX:
0660
0661 speed_sel = SERDES_SPEED_1_25_G;
0662 break;
0663 case PHY_INTERFACE_MODE_2500BASEX:
0664
0665 speed_sel = SERDES_SPEED_3_125_G;
0666 break;
0667 default:
0668
0669 dev_err(lane->dev,
0670 "unsupported phy speed %d on comphy lane%d\n",
0671 lane->submode, lane->id);
0672 return -EINVAL;
0673 }
0674 data = GEN_RX_SEL_VALUE(speed_sel) | GEN_TX_SEL_VALUE(speed_sel);
0675 mask = GEN_RX_SEL_MASK | GEN_TX_SEL_MASK;
0676 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
0677
0678
0679
0680
0681
0682 mdelay(10);
0683
0684
0685 data = COMPHY_MODE_SERDES;
0686 mask = COMPHY_MODE_MASK;
0687 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
0688
0689
0690
0691
0692
0693 data = 0x0;
0694 mask = PHY_REF_CLK_SEL;
0695 comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask);
0696
0697
0698
0699
0700
0701 if (lane->priv->xtal_is_40m)
0702 data = REF_FREF_SEL_SERDES_50MHZ;
0703 else
0704 data = REF_FREF_SEL_SERDES_25MHZ;
0705
0706 mask = REF_FREF_SEL_MASK;
0707 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721 data = DATA_WIDTH_10BIT;
0722 mask = SEL_DATA_WIDTH_MASK;
0723 comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, data, mask);
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742 dev_dbg(lane->dev, "Running C-DPI phy init %s mode\n",
0743 lane->submode == PHY_INTERFACE_MODE_2500BASEX ? "2G5" : "1G");
0744 if (lane->priv->xtal_is_40m)
0745 comphy_gbe_phy_init(lane,
0746 lane->submode != PHY_INTERFACE_MODE_2500BASEX);
0747
0748
0749
0750
0751 data = 0x0;
0752 if (lane->invert_tx)
0753 data |= TXD_INVERT_BIT;
0754 if (lane->invert_rx)
0755 data |= RXD_INVERT_BIT;
0756 mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
0757 comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);
0758
0759
0760
0761
0762
0763
0764
0765 data = PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT;
0766 mask = data;
0767 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
0768
0769
0770
0771
0772
0773 ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1,
0774 PHY_PLL_READY_TX_BIT |
0775 PHY_PLL_READY_RX_BIT,
0776 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
0777 if (ret) {
0778 dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n",
0779 lane->id);
0780 return ret;
0781 }
0782
0783
0784
0785
0786 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, 0x0, PIN_TX_IDLE_BIT);
0787
0788
0789
0790
0791
0792
0793
0794
0795 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1,
0796 PHY_RX_INIT_BIT, PHY_RX_INIT_BIT);
0797
0798 ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1,
0799 PHY_PLL_READY_TX_BIT |
0800 PHY_PLL_READY_RX_BIT,
0801 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
0802 if (ret) {
0803 dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n",
0804 lane->id);
0805 return ret;
0806 }
0807
0808 ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1,
0809 PHY_RX_INIT_DONE_BIT,
0810 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
0811 if (ret)
0812 dev_err(lane->dev, "Failed to init RX of SERDES PHY %d\n",
0813 lane->id);
0814
0815 return ret;
0816 }
0817
0818 static int
0819 mvebu_a3700_comphy_usb3_power_on(struct mvebu_a3700_comphy_lane *lane)
0820 {
0821 u32 mask, data, cfg, ref_clk;
0822 int ret;
0823
0824
0825 ret = mvebu_a3700_comphy_set_phy_selector(lane);
0826 if (ret)
0827 return ret;
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837 data = PRD_TXDEEMPH0_MASK;
0838 mask = PRD_TXDEEMPH0_MASK | PRD_TXMARGIN_MASK | PRD_TXSWING_MASK |
0839 CFG_TX_ALIGN_POS_MASK;
0840 comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG0, data, mask);
0841
0842
0843
0844
0845
0846
0847
0848
0849 data = TX_DET_RX_MODE | GEN2_TX_DATA_DLY_DEFT | TX_ELEC_IDLE_MODE_EN;
0850 mask = PRD_TXDEEMPH1_MASK | TX_DET_RX_MODE | GEN2_TX_DATA_DLY_MASK |
0851 TX_ELEC_IDLE_MODE_EN;
0852 comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1, data, mask);
0853
0854
0855
0856
0857 comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG4,
0858 SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN);
0859
0860
0861
0862
0863
0864 comphy_lane_reg_set(lane, COMPHY_PIPE_TEST_MODE_CTRL,
0865 MODE_MARGIN_OVERRIDE, 0xFFFF);
0866
0867
0868
0869
0870
0871 data = 0x0;
0872 mask = MODE_CLK_SRC | BUNDLE_PERIOD_SEL | BUNDLE_PERIOD_SCALE_MASK |
0873 BUNDLE_SAMPLE_CTRL | PLL_READY_DLY_MASK;
0874 comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO, data, mask);
0875
0876
0877
0878
0879 comphy_lane_reg_set(lane, COMPHY_GEN2_SET2,
0880 GS2_TX_SSC_AMP_4128, GS2_TX_SSC_AMP_MASK);
0881
0882
0883
0884
0885
0886 data = GS2_VREG_RXTX_MAS_ISET_60U;
0887 mask = GS2_TX_SSC_AMP_MASK | GS2_VREG_RXTX_MAS_ISET_MASK |
0888 GS2_RSVD_6_0_MASK;
0889 comphy_lane_reg_set(lane, COMPHY_GEN3_SET2, data, mask);
0890
0891
0892
0893
0894
0895 if (lane->priv->xtal_is_40m) {
0896 ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ;
0897 cfg = CFG_PM_RXDLOZ_WAIT_12_UNIT;
0898 } else {
0899 ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ;
0900 cfg = CFG_PM_RXDLOZ_WAIT_7_UNIT;
0901 }
0902
0903 data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |
0904 PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_USB3 | ref_clk;
0905 mask = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |
0906 PU_TX_INTP_BIT | PU_DFE_BIT | PLL_LOCK_BIT | COMPHY_MODE_MASK |
0907 REF_FREF_SEL_MASK;
0908 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
0909
0910 data = CFG_PM_RXDEN_WAIT_1_UNIT | cfg;
0911 mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK |
0912 CFG_PM_RXDLOZ_WAIT_MASK;
0913 comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask);
0914
0915
0916
0917
0918 comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN,
0919 IDLE_SYNC_EN, IDLE_SYNC_EN);
0920
0921
0922
0923
0924 comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, CLK500M_EN, CLK500M_EN);
0925
0926
0927
0928
0929 comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN,
0930 DATA_WIDTH_20BIT, 0xFFFF);
0931
0932
0933
0934
0935 data = SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT;
0936 mask = 0xFFFF;
0937 comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, data, mask);
0938
0939
0940
0941
0942 data = 0x0;
0943 if (lane->invert_tx)
0944 data |= TXD_INVERT_BIT;
0945 if (lane->invert_rx)
0946 data |= RXD_INVERT_BIT;
0947 mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
0948 comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);
0949
0950
0951
0952
0953 comphy_lane_reg_set(lane, COMPHY_SYNC_MASK_GEN,
0954 PHY_GEN_MAX_USB3_5G, PHY_GEN_MAX_MASK);
0955
0956
0957
0958
0959 comphy_lane_reg_set(lane, COMPHY_GEN2_SET3,
0960 GS3_FFE_CAP_SEL_VALUE, GS3_FFE_CAP_SEL_MASK);
0961
0962
0963
0964
0965 data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32 | MODE_REFDIV_BY_4;
0966 mask = 0xFFFF;
0967 comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask);
0968
0969
0970 udelay(PLL_SET_DELAY_US);
0971
0972 ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN,
0973 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
0974 if (ret)
0975 dev_err(lane->dev, "Failed to lock USB3 PLL\n");
0976
0977 return ret;
0978 }
0979
0980 static int
0981 mvebu_a3700_comphy_pcie_power_on(struct mvebu_a3700_comphy_lane *lane)
0982 {
0983 u32 mask, data, ref_clk;
0984 int ret;
0985
0986
0987 ret = mvebu_a3700_comphy_set_phy_selector(lane);
0988 if (ret)
0989 return ret;
0990
0991
0992 comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1,
0993 USE_MAX_PLL_RATE_EN, USE_MAX_PLL_RATE_EN);
0994
0995
0996 comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO,
0997 CFG_SEL_20B, CFG_SEL_20B);
0998
0999
1000 comphy_lane_reg_set(lane, COMPHY_MISC_CTRL1,
1001 SEL_BITS_PCIE_FORCE, SEL_BITS_PCIE_FORCE);
1002
1003
1004 data = CFG_PM_RXDEN_WAIT_1_UNIT | CFG_PM_RXDLOZ_WAIT_12_UNIT;
1005 mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK |
1006 CFG_PM_RXDLOZ_WAIT_MASK;
1007 comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask);
1008
1009
1010 comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN,
1011 IDLE_SYNC_EN, IDLE_SYNC_EN);
1012
1013
1014 data = CLK500M_EN | TXDCLK_2X_SEL | CLK100M_125M_EN;
1015 mask = data;
1016 comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask);
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 if (lane->priv->xtal_is_40m)
1029 ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ;
1030 else
1031 ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ;
1032
1033 data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |
1034 PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_PCIE | ref_clk;
1035 mask = 0xFFFF;
1036 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);
1037
1038
1039 comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL,
1040 SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT,
1041 0xFFFF);
1042
1043
1044 data = 0x0;
1045 if (lane->invert_tx)
1046 data |= TXD_INVERT_BIT;
1047 if (lane->invert_rx)
1048 data |= RXD_INVERT_BIT;
1049 mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
1050 comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);
1051
1052
1053 data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32;
1054 mask = data | PIPE_SOFT_RESET | MODE_REFDIV_MASK;
1055 comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask);
1056
1057
1058 udelay(PLL_SET_DELAY_US);
1059
1060 ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN,
1061 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);
1062 if (ret)
1063 dev_err(lane->dev, "Failed to lock PCIE PLL\n");
1064
1065 return ret;
1066 }
1067
1068 static void
1069 mvebu_a3700_comphy_sata_power_off(struct mvebu_a3700_comphy_lane *lane)
1070 {
1071
1072 comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL,
1073 PHY_ISOLATE_MODE, PHY_ISOLATE_MODE);
1074
1075
1076 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL,
1077 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT);
1078 }
1079
1080 static void
1081 mvebu_a3700_comphy_ethernet_power_off(struct mvebu_a3700_comphy_lane *lane)
1082 {
1083 u32 mask, data;
1084
1085 data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT | PIN_PU_IVREF_BIT |
1086 PHY_RX_INIT_BIT;
1087 mask = data;
1088 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);
1089 }
1090
1091 static void
1092 mvebu_a3700_comphy_pcie_power_off(struct mvebu_a3700_comphy_lane *lane)
1093 {
1094
1095 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL,
1096 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT);
1097 }
1098
1099 static void mvebu_a3700_comphy_usb3_power_off(struct mvebu_a3700_comphy_lane *lane)
1100 {
1101
1102
1103
1104
1105 }
1106
1107 static bool mvebu_a3700_comphy_check_mode(int lane,
1108 enum phy_mode mode,
1109 int submode)
1110 {
1111 int i, n = ARRAY_SIZE(mvebu_a3700_comphy_modes);
1112
1113
1114 if (mode == PHY_MODE_INVALID)
1115 return false;
1116
1117 for (i = 0; i < n; i++) {
1118 if (mvebu_a3700_comphy_modes[i].lane == lane &&
1119 mvebu_a3700_comphy_modes[i].mode == mode &&
1120 mvebu_a3700_comphy_modes[i].submode == submode)
1121 break;
1122 }
1123
1124 if (i == n)
1125 return false;
1126
1127 return true;
1128 }
1129
1130 static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode,
1131 int submode)
1132 {
1133 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
1134
1135 if (!mvebu_a3700_comphy_check_mode(lane->id, mode, submode)) {
1136 dev_err(lane->dev, "invalid COMPHY mode\n");
1137 return -EINVAL;
1138 }
1139
1140
1141 if (phy->power_count &&
1142 (lane->mode != mode || lane->submode != submode))
1143 return -EBUSY;
1144
1145
1146 lane->mode = mode;
1147 lane->submode = submode;
1148
1149 return 0;
1150 }
1151
1152 static int mvebu_a3700_comphy_power_on(struct phy *phy)
1153 {
1154 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
1155
1156 if (!mvebu_a3700_comphy_check_mode(lane->id, lane->mode,
1157 lane->submode)) {
1158 dev_err(lane->dev, "invalid COMPHY mode\n");
1159 return -EINVAL;
1160 }
1161
1162 switch (lane->mode) {
1163 case PHY_MODE_USB_HOST_SS:
1164 dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id);
1165 return mvebu_a3700_comphy_usb3_power_on(lane);
1166 case PHY_MODE_SATA:
1167 dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id);
1168 return mvebu_a3700_comphy_sata_power_on(lane);
1169 case PHY_MODE_ETHERNET:
1170 dev_dbg(lane->dev, "set lane %d to Ethernet mode\n", lane->id);
1171 return mvebu_a3700_comphy_ethernet_power_on(lane);
1172 case PHY_MODE_PCIE:
1173 dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id);
1174 return mvebu_a3700_comphy_pcie_power_on(lane);
1175 default:
1176 dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode);
1177 return -EOPNOTSUPP;
1178 }
1179 }
1180
1181 static int mvebu_a3700_comphy_power_off(struct phy *phy)
1182 {
1183 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);
1184
1185 switch (lane->id) {
1186 case 0:
1187 mvebu_a3700_comphy_usb3_power_off(lane);
1188 mvebu_a3700_comphy_ethernet_power_off(lane);
1189 return 0;
1190 case 1:
1191 mvebu_a3700_comphy_pcie_power_off(lane);
1192 mvebu_a3700_comphy_ethernet_power_off(lane);
1193 return 0;
1194 case 2:
1195 mvebu_a3700_comphy_usb3_power_off(lane);
1196 mvebu_a3700_comphy_sata_power_off(lane);
1197 return 0;
1198 default:
1199 dev_err(lane->dev, "invalid COMPHY mode\n");
1200 return -EINVAL;
1201 }
1202 }
1203
1204 static const struct phy_ops mvebu_a3700_comphy_ops = {
1205 .power_on = mvebu_a3700_comphy_power_on,
1206 .power_off = mvebu_a3700_comphy_power_off,
1207 .set_mode = mvebu_a3700_comphy_set_mode,
1208 .owner = THIS_MODULE,
1209 };
1210
1211 static struct phy *mvebu_a3700_comphy_xlate(struct device *dev,
1212 struct of_phandle_args *args)
1213 {
1214 struct mvebu_a3700_comphy_lane *lane;
1215 unsigned int port;
1216 struct phy *phy;
1217
1218 phy = of_phy_simple_xlate(dev, args);
1219 if (IS_ERR(phy))
1220 return phy;
1221
1222 lane = phy_get_drvdata(phy);
1223
1224 port = args->args[0];
1225 if (port != 0 && (port != 1 || lane->id != 0)) {
1226 dev_err(lane->dev, "invalid port number %u\n", port);
1227 return ERR_PTR(-EINVAL);
1228 }
1229
1230 lane->invert_tx = args->args[1] & BIT(0);
1231 lane->invert_rx = args->args[1] & BIT(1);
1232
1233 return phy;
1234 }
1235
1236 static int mvebu_a3700_comphy_probe(struct platform_device *pdev)
1237 {
1238 struct mvebu_a3700_comphy_priv *priv;
1239 struct phy_provider *provider;
1240 struct device_node *child;
1241 struct resource *res;
1242 struct clk *clk;
1243 int ret;
1244
1245 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1246 if (!priv)
1247 return -ENOMEM;
1248
1249 spin_lock_init(&priv->lock);
1250
1251 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "comphy");
1252 priv->comphy_regs = devm_ioremap_resource(&pdev->dev, res);
1253 if (IS_ERR(priv->comphy_regs))
1254 return PTR_ERR(priv->comphy_regs);
1255
1256 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1257 "lane1_pcie_gbe");
1258 priv->lane1_phy_regs = devm_ioremap_resource(&pdev->dev, res);
1259 if (IS_ERR(priv->lane1_phy_regs))
1260 return PTR_ERR(priv->lane1_phy_regs);
1261
1262 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1263 "lane0_usb3_gbe");
1264 priv->lane0_phy_regs = devm_ioremap_resource(&pdev->dev, res);
1265 if (IS_ERR(priv->lane0_phy_regs))
1266 return PTR_ERR(priv->lane0_phy_regs);
1267
1268 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1269 "lane2_sata_usb3");
1270 priv->lane2_phy_indirect = devm_ioremap_resource(&pdev->dev, res);
1271 if (IS_ERR(priv->lane2_phy_indirect))
1272 return PTR_ERR(priv->lane2_phy_indirect);
1273
1274
1275
1276
1277
1278
1279 clk = clk_get(&pdev->dev, "xtal");
1280 if (IS_ERR(clk)) {
1281 if (PTR_ERR(clk) == -EPROBE_DEFER)
1282 return -EPROBE_DEFER;
1283 dev_warn(&pdev->dev, "missing 'xtal' clk (%ld)\n",
1284 PTR_ERR(clk));
1285 } else {
1286 ret = clk_prepare_enable(clk);
1287 if (ret) {
1288 dev_warn(&pdev->dev, "enabling xtal clk failed (%d)\n",
1289 ret);
1290 } else {
1291 if (clk_get_rate(clk) == 40000000)
1292 priv->xtal_is_40m = true;
1293 clk_disable_unprepare(clk);
1294 }
1295 clk_put(clk);
1296 }
1297
1298 dev_set_drvdata(&pdev->dev, priv);
1299
1300 for_each_available_child_of_node(pdev->dev.of_node, child) {
1301 struct mvebu_a3700_comphy_lane *lane;
1302 struct phy *phy;
1303 int ret;
1304 u32 lane_id;
1305
1306 ret = of_property_read_u32(child, "reg", &lane_id);
1307 if (ret < 0) {
1308 dev_err(&pdev->dev, "missing 'reg' property (%d)\n",
1309 ret);
1310 continue;
1311 }
1312
1313 if (lane_id >= 3) {
1314 dev_err(&pdev->dev, "invalid 'reg' property\n");
1315 continue;
1316 }
1317
1318 lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL);
1319 if (!lane) {
1320 of_node_put(child);
1321 return -ENOMEM;
1322 }
1323
1324 phy = devm_phy_create(&pdev->dev, child,
1325 &mvebu_a3700_comphy_ops);
1326 if (IS_ERR(phy)) {
1327 of_node_put(child);
1328 return PTR_ERR(phy);
1329 }
1330
1331 lane->priv = priv;
1332 lane->dev = &pdev->dev;
1333 lane->mode = PHY_MODE_INVALID;
1334 lane->submode = PHY_INTERFACE_MODE_NA;
1335 lane->id = lane_id;
1336 lane->invert_tx = false;
1337 lane->invert_rx = false;
1338 phy_set_drvdata(phy, lane);
1339
1340
1341
1342
1343
1344 mvebu_a3700_comphy_power_off(phy);
1345 }
1346
1347 provider = devm_of_phy_provider_register(&pdev->dev,
1348 mvebu_a3700_comphy_xlate);
1349
1350 return PTR_ERR_OR_ZERO(provider);
1351 }
1352
1353 static const struct of_device_id mvebu_a3700_comphy_of_match_table[] = {
1354 { .compatible = "marvell,comphy-a3700" },
1355 { },
1356 };
1357 MODULE_DEVICE_TABLE(of, mvebu_a3700_comphy_of_match_table);
1358
1359 static struct platform_driver mvebu_a3700_comphy_driver = {
1360 .probe = mvebu_a3700_comphy_probe,
1361 .driver = {
1362 .name = "mvebu-a3700-comphy",
1363 .of_match_table = mvebu_a3700_comphy_of_match_table,
1364 },
1365 };
1366 module_platform_driver(mvebu_a3700_comphy_driver);
1367
1368 MODULE_AUTHOR("Miquèl Raynal <miquel.raynal@bootlin.com>");
1369 MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");
1370 MODULE_AUTHOR("Marek Behún <kabel@kernel.org>");
1371 MODULE_DESCRIPTION("Common PHY driver for A3700");
1372 MODULE_LICENSE("GPL v2");