Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2014 STMicroelectronics
0004  *
0005  * STMicroelectronics PHY driver MiPHY28lp (for SoC STiH407).
0006  *
0007  * Author: Alexandre Torgue <alexandre.torgue@st.com>
0008  */
0009 
0010 #include <linux/platform_device.h>
0011 #include <linux/io.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/of_platform.h>
0016 #include <linux/of_address.h>
0017 #include <linux/clk.h>
0018 #include <linux/phy/phy.h>
0019 #include <linux/delay.h>
0020 #include <linux/mfd/syscon.h>
0021 #include <linux/regmap.h>
0022 #include <linux/reset.h>
0023 
0024 #include <dt-bindings/phy/phy.h>
0025 
0026 /* MiPHY registers */
0027 #define MIPHY_CONF_RESET        0x00
0028 #define RST_APPLI_SW        BIT(0)
0029 #define RST_CONF_SW     BIT(1)
0030 #define RST_MACRO_SW        BIT(2)
0031 
0032 #define MIPHY_RESET         0x01
0033 #define RST_PLL_SW      BIT(0)
0034 #define RST_COMP_SW     BIT(2)
0035 
0036 #define MIPHY_STATUS_1          0x02
0037 #define PHY_RDY         BIT(0)
0038 #define HFC_RDY         BIT(1)
0039 #define HFC_PLL         BIT(2)
0040 
0041 #define MIPHY_CONTROL           0x04
0042 #define TERM_EN_SW      BIT(2)
0043 #define DIS_LINK_RST        BIT(3)
0044 #define AUTO_RST_RX     BIT(4)
0045 #define PX_RX_POL       BIT(5)
0046 
0047 #define MIPHY_BOUNDARY_SEL      0x0a
0048 #define TX_SEL          BIT(6)
0049 #define SSC_SEL         BIT(4)
0050 #define GENSEL_SEL      BIT(0)
0051 
0052 #define MIPHY_BOUNDARY_1        0x0b
0053 #define MIPHY_BOUNDARY_2        0x0c
0054 #define SSC_EN_SW       BIT(2)
0055 
0056 #define MIPHY_PLL_CLKREF_FREQ       0x0d
0057 #define MIPHY_SPEED         0x0e
0058 #define TX_SPDSEL_80DEC     0
0059 #define TX_SPDSEL_40DEC     1
0060 #define TX_SPDSEL_20DEC     2
0061 #define RX_SPDSEL_80DEC     0
0062 #define RX_SPDSEL_40DEC     (1 << 2)
0063 #define RX_SPDSEL_20DEC     (2 << 2)
0064 
0065 #define MIPHY_CONF          0x0f
0066 #define MIPHY_CTRL_TEST_SEL     0x20
0067 #define MIPHY_CTRL_TEST_1       0x21
0068 #define MIPHY_CTRL_TEST_2       0x22
0069 #define MIPHY_CTRL_TEST_3       0x23
0070 #define MIPHY_CTRL_TEST_4       0x24
0071 #define MIPHY_FEEDBACK_TEST     0x25
0072 #define MIPHY_DEBUG_BUS         0x26
0073 #define MIPHY_DEBUG_STATUS_MSB      0x27
0074 #define MIPHY_DEBUG_STATUS_LSB      0x28
0075 #define MIPHY_PWR_RAIL_1        0x29
0076 #define MIPHY_PWR_RAIL_2        0x2a
0077 #define MIPHY_SYNCHAR_CONTROL       0x30
0078 
0079 #define MIPHY_COMP_FSM_1        0x3a
0080 #define COMP_START      BIT(6)
0081 
0082 #define MIPHY_COMP_FSM_6        0x3f
0083 #define COMP_DONE       BIT(7)
0084 
0085 #define MIPHY_COMP_POSTP        0x42
0086 #define MIPHY_TX_CTRL_1         0x49
0087 #define TX_REG_STEP_0V      0
0088 #define TX_REG_STEP_P_25MV  1
0089 #define TX_REG_STEP_P_50MV  2
0090 #define TX_REG_STEP_N_25MV  7
0091 #define TX_REG_STEP_N_50MV  6
0092 #define TX_REG_STEP_N_75MV  5
0093 
0094 #define MIPHY_TX_CTRL_2         0x4a
0095 #define TX_SLEW_SW_40_PS    0
0096 #define TX_SLEW_SW_80_PS    1
0097 #define TX_SLEW_SW_120_PS   2
0098 
0099 #define MIPHY_TX_CTRL_3         0x4b
0100 #define MIPHY_TX_CAL_MAN        0x4e
0101 #define TX_SLEW_CAL_MAN_EN  BIT(0)
0102 
0103 #define MIPHY_TST_BIAS_BOOST_2      0x62
0104 #define MIPHY_BIAS_BOOST_1      0x63
0105 #define MIPHY_BIAS_BOOST_2      0x64
0106 #define MIPHY_RX_DESBUFF_FDB_2      0x67
0107 #define MIPHY_RX_DESBUFF_FDB_3      0x68
0108 #define MIPHY_SIGDET_COMPENS1       0x69
0109 #define MIPHY_SIGDET_COMPENS2       0x6a
0110 #define MIPHY_JITTER_PERIOD     0x6b
0111 #define MIPHY_JITTER_AMPLITUDE_1    0x6c
0112 #define MIPHY_JITTER_AMPLITUDE_2    0x6d
0113 #define MIPHY_JITTER_AMPLITUDE_3    0x6e
0114 #define MIPHY_RX_K_GAIN         0x78
0115 #define MIPHY_RX_BUFFER_CTRL        0x7a
0116 #define VGA_GAIN        BIT(0)
0117 #define EQ_DC_GAIN      BIT(2)
0118 #define EQ_BOOST_GAIN       BIT(3)
0119 
0120 #define MIPHY_RX_VGA_GAIN       0x7b
0121 #define MIPHY_RX_EQU_GAIN_1     0x7f
0122 #define MIPHY_RX_EQU_GAIN_2     0x80
0123 #define MIPHY_RX_EQU_GAIN_3     0x81
0124 #define MIPHY_RX_CAL_CTRL_1     0x97
0125 #define MIPHY_RX_CAL_CTRL_2     0x98
0126 
0127 #define MIPHY_RX_CAL_OFFSET_CTRL    0x99
0128 #define CAL_OFFSET_VGA_64   (0x03 << 0)
0129 #define CAL_OFFSET_THRESHOLD_64 (0x03 << 2)
0130 #define VGA_OFFSET_POLARITY BIT(4)
0131 #define OFFSET_COMPENSATION_EN  BIT(6)
0132 
0133 #define MIPHY_RX_CAL_VGA_STEP       0x9a
0134 #define MIPHY_RX_CAL_EYE_MIN        0x9d
0135 #define MIPHY_RX_CAL_OPT_LENGTH     0x9f
0136 #define MIPHY_RX_LOCK_CTRL_1        0xc1
0137 #define MIPHY_RX_LOCK_SETTINGS_OPT  0xc2
0138 #define MIPHY_RX_LOCK_STEP      0xc4
0139 
0140 #define MIPHY_RX_SIGDET_SLEEP_OA    0xc9
0141 #define MIPHY_RX_SIGDET_SLEEP_SEL   0xca
0142 #define MIPHY_RX_SIGDET_WAIT_SEL    0xcb
0143 #define MIPHY_RX_SIGDET_DATA_SEL    0xcc
0144 #define EN_ULTRA_LOW_POWER  BIT(0)
0145 #define EN_FIRST_HALF       BIT(1)
0146 #define EN_SECOND_HALF      BIT(2)
0147 #define EN_DIGIT_SIGNAL_CHECK   BIT(3)
0148 
0149 #define MIPHY_RX_POWER_CTRL_1       0xcd
0150 #define MIPHY_RX_POWER_CTRL_2       0xce
0151 #define MIPHY_PLL_CALSET_CTRL       0xd3
0152 #define MIPHY_PLL_CALSET_1      0xd4
0153 #define MIPHY_PLL_CALSET_2      0xd5
0154 #define MIPHY_PLL_CALSET_3      0xd6
0155 #define MIPHY_PLL_CALSET_4      0xd7
0156 #define MIPHY_PLL_SBR_1         0xe3
0157 #define SET_NEW_CHANGE      BIT(1)
0158 
0159 #define MIPHY_PLL_SBR_2         0xe4
0160 #define MIPHY_PLL_SBR_3         0xe5
0161 #define MIPHY_PLL_SBR_4         0xe6
0162 #define MIPHY_PLL_COMMON_MISC_2     0xe9
0163 #define START_ACT_FILT      BIT(6)
0164 
0165 #define MIPHY_PLL_SPAREIN       0xeb
0166 
0167 /*
0168  * On STiH407 the glue logic can be different among MiPHY devices; for example:
0169  * MiPHY0: OSC_FORCE_EXT means:
0170  *  0: 30MHz crystal clk - 1: 100MHz ext clk routed through MiPHY1
0171  * MiPHY1: OSC_FORCE_EXT means:
0172  *  1: 30MHz crystal clk - 0: 100MHz ext clk routed through MiPHY1
0173  * Some devices have not the possibility to check if the osc is ready.
0174  */
0175 #define MIPHY_OSC_FORCE_EXT BIT(3)
0176 #define MIPHY_OSC_RDY       BIT(5)
0177 
0178 #define MIPHY_CTRL_MASK     0x0f
0179 #define MIPHY_CTRL_DEFAULT  0
0180 #define MIPHY_CTRL_SYNC_D_EN    BIT(2)
0181 
0182 /* SATA / PCIe defines */
0183 #define SATA_CTRL_MASK      0x07
0184 #define PCIE_CTRL_MASK      0xff
0185 #define SATA_CTRL_SELECT_SATA   1
0186 #define SATA_CTRL_SELECT_PCIE   0
0187 #define SYSCFG_PCIE_PCIE_VAL    0x80
0188 #define SATA_SPDMODE        1
0189 
0190 #define MIPHY_SATA_BANK_NB  3
0191 #define MIPHY_PCIE_BANK_NB  2
0192 
0193 enum {
0194     SYSCFG_CTRL,
0195     SYSCFG_STATUS,
0196     SYSCFG_PCI,
0197     SYSCFG_SATA,
0198     SYSCFG_REG_MAX,
0199 };
0200 
0201 struct miphy28lp_phy {
0202     struct phy *phy;
0203     struct miphy28lp_dev *phydev;
0204     void __iomem *base;
0205     void __iomem *pipebase;
0206 
0207     bool osc_force_ext;
0208     bool osc_rdy;
0209     bool px_rx_pol_inv;
0210     bool ssc;
0211     bool tx_impedance;
0212 
0213     struct reset_control *miphy_rst;
0214 
0215     u32 sata_gen;
0216 
0217     /* Sysconfig registers offsets needed to configure the device */
0218     u32 syscfg_reg[SYSCFG_REG_MAX];
0219     u8 type;
0220 };
0221 
0222 struct miphy28lp_dev {
0223     struct device *dev;
0224     struct regmap *regmap;
0225     struct mutex miphy_mutex;
0226     struct miphy28lp_phy **phys;
0227     int nphys;
0228 };
0229 
0230 struct miphy_initval {
0231     u16 reg;
0232     u16 val;
0233 };
0234 
0235 enum miphy_sata_gen { SATA_GEN1, SATA_GEN2, SATA_GEN3 };
0236 
0237 static char *PHY_TYPE_name[] = { "sata-up", "pcie-up", "", "usb3-up" };
0238 
0239 struct pll_ratio {
0240     int clk_ref;
0241     int calset_1;
0242     int calset_2;
0243     int calset_3;
0244     int calset_4;
0245     int cal_ctrl;
0246 };
0247 
0248 static struct pll_ratio sata_pll_ratio = {
0249     .clk_ref = 0x1e,
0250     .calset_1 = 0xc8,
0251     .calset_2 = 0x00,
0252     .calset_3 = 0x00,
0253     .calset_4 = 0x00,
0254     .cal_ctrl = 0x00,
0255 };
0256 
0257 static struct pll_ratio pcie_pll_ratio = {
0258     .clk_ref = 0x1e,
0259     .calset_1 = 0xa6,
0260     .calset_2 = 0xaa,
0261     .calset_3 = 0xaa,
0262     .calset_4 = 0x00,
0263     .cal_ctrl = 0x00,
0264 };
0265 
0266 static struct pll_ratio usb3_pll_ratio = {
0267     .clk_ref = 0x1e,
0268     .calset_1 = 0xa6,
0269     .calset_2 = 0xaa,
0270     .calset_3 = 0xaa,
0271     .calset_4 = 0x04,
0272     .cal_ctrl = 0x00,
0273 };
0274 
0275 struct miphy28lp_pll_gen {
0276     int bank;
0277     int speed;
0278     int bias_boost_1;
0279     int bias_boost_2;
0280     int tx_ctrl_1;
0281     int tx_ctrl_2;
0282     int tx_ctrl_3;
0283     int rx_k_gain;
0284     int rx_vga_gain;
0285     int rx_equ_gain_1;
0286     int rx_equ_gain_2;
0287     int rx_equ_gain_3;
0288     int rx_buff_ctrl;
0289 };
0290 
0291 static struct miphy28lp_pll_gen sata_pll_gen[] = {
0292     {
0293         .bank       = 0x00,
0294         .speed      = TX_SPDSEL_80DEC | RX_SPDSEL_80DEC,
0295         .bias_boost_1   = 0x00,
0296         .bias_boost_2   = 0xae,
0297         .tx_ctrl_2  = 0x53,
0298         .tx_ctrl_3  = 0x00,
0299         .rx_buff_ctrl   = EQ_BOOST_GAIN | EQ_DC_GAIN | VGA_GAIN,
0300         .rx_vga_gain    = 0x00,
0301         .rx_equ_gain_1  = 0x7d,
0302         .rx_equ_gain_2  = 0x56,
0303         .rx_equ_gain_3  = 0x00,
0304     },
0305     {
0306         .bank       = 0x01,
0307         .speed      = TX_SPDSEL_40DEC | RX_SPDSEL_40DEC,
0308         .bias_boost_1   = 0x00,
0309         .bias_boost_2   = 0xae,
0310         .tx_ctrl_2  = 0x72,
0311         .tx_ctrl_3  = 0x20,
0312         .rx_buff_ctrl   = EQ_BOOST_GAIN | EQ_DC_GAIN | VGA_GAIN,
0313         .rx_vga_gain    = 0x00,
0314         .rx_equ_gain_1  = 0x7d,
0315         .rx_equ_gain_2  = 0x56,
0316         .rx_equ_gain_3  = 0x00,
0317     },
0318     {
0319         .bank       = 0x02,
0320         .speed      = TX_SPDSEL_20DEC | RX_SPDSEL_20DEC,
0321         .bias_boost_1   = 0x00,
0322         .bias_boost_2   = 0xae,
0323         .tx_ctrl_2  = 0xc0,
0324         .tx_ctrl_3  = 0x20,
0325         .rx_buff_ctrl   = EQ_BOOST_GAIN | EQ_DC_GAIN | VGA_GAIN,
0326         .rx_vga_gain    = 0x00,
0327         .rx_equ_gain_1  = 0x7d,
0328         .rx_equ_gain_2  = 0x56,
0329         .rx_equ_gain_3  = 0x00,
0330     },
0331 };
0332 
0333 static struct miphy28lp_pll_gen pcie_pll_gen[] = {
0334     {
0335         .bank       = 0x00,
0336         .speed      = TX_SPDSEL_40DEC | RX_SPDSEL_40DEC,
0337         .bias_boost_1   = 0x00,
0338         .bias_boost_2   = 0xa5,
0339         .tx_ctrl_1  = TX_REG_STEP_N_25MV,
0340         .tx_ctrl_2  = 0x71,
0341         .tx_ctrl_3  = 0x60,
0342         .rx_k_gain  = 0x98,
0343         .rx_buff_ctrl   = EQ_BOOST_GAIN | EQ_DC_GAIN | VGA_GAIN,
0344         .rx_vga_gain    = 0x00,
0345         .rx_equ_gain_1  = 0x79,
0346         .rx_equ_gain_2  = 0x56,
0347     },
0348     {
0349         .bank       = 0x01,
0350         .speed      = TX_SPDSEL_20DEC | RX_SPDSEL_20DEC,
0351         .bias_boost_1   = 0x00,
0352         .bias_boost_2   = 0xa5,
0353         .tx_ctrl_1  = TX_REG_STEP_N_25MV,
0354         .tx_ctrl_2  = 0x70,
0355         .tx_ctrl_3  = 0x60,
0356         .rx_k_gain  = 0xcc,
0357         .rx_buff_ctrl   = EQ_BOOST_GAIN | EQ_DC_GAIN | VGA_GAIN,
0358         .rx_vga_gain    = 0x00,
0359         .rx_equ_gain_1  = 0x78,
0360         .rx_equ_gain_2  = 0x07,
0361     },
0362 };
0363 
0364 static inline void miphy28lp_set_reset(struct miphy28lp_phy *miphy_phy)
0365 {
0366     void __iomem *base = miphy_phy->base;
0367     u8 val;
0368 
0369     /* Putting Macro in reset */
0370     writeb_relaxed(RST_APPLI_SW, base + MIPHY_CONF_RESET);
0371 
0372     val = RST_APPLI_SW | RST_CONF_SW;
0373     writeb_relaxed(val, base + MIPHY_CONF_RESET);
0374 
0375     writeb_relaxed(RST_APPLI_SW, base + MIPHY_CONF_RESET);
0376 
0377     /* Bringing the MIPHY-CPU registers out of reset */
0378     if (miphy_phy->type == PHY_TYPE_PCIE) {
0379         val = AUTO_RST_RX | TERM_EN_SW;
0380         writeb_relaxed(val, base + MIPHY_CONTROL);
0381     } else {
0382         val = AUTO_RST_RX | TERM_EN_SW | DIS_LINK_RST;
0383         writeb_relaxed(val, base + MIPHY_CONTROL);
0384     }
0385 }
0386 
0387 static inline void miphy28lp_pll_calibration(struct miphy28lp_phy *miphy_phy,
0388         struct pll_ratio *pll_ratio)
0389 {
0390     void __iomem *base = miphy_phy->base;
0391     u8 val;
0392 
0393     /* Applying PLL Settings */
0394     writeb_relaxed(0x1d, base + MIPHY_PLL_SPAREIN);
0395     writeb_relaxed(pll_ratio->clk_ref, base + MIPHY_PLL_CLKREF_FREQ);
0396 
0397     /* PLL Ratio */
0398     writeb_relaxed(pll_ratio->calset_1, base + MIPHY_PLL_CALSET_1);
0399     writeb_relaxed(pll_ratio->calset_2, base + MIPHY_PLL_CALSET_2);
0400     writeb_relaxed(pll_ratio->calset_3, base + MIPHY_PLL_CALSET_3);
0401     writeb_relaxed(pll_ratio->calset_4, base + MIPHY_PLL_CALSET_4);
0402     writeb_relaxed(pll_ratio->cal_ctrl, base + MIPHY_PLL_CALSET_CTRL);
0403 
0404     writeb_relaxed(TX_SEL, base + MIPHY_BOUNDARY_SEL);
0405 
0406     val = (0x68 << 1) | TX_SLEW_CAL_MAN_EN;
0407     writeb_relaxed(val, base + MIPHY_TX_CAL_MAN);
0408 
0409     val = VGA_OFFSET_POLARITY | CAL_OFFSET_THRESHOLD_64 | CAL_OFFSET_VGA_64;
0410 
0411     if (miphy_phy->type != PHY_TYPE_SATA)
0412         val |= OFFSET_COMPENSATION_EN;
0413 
0414     writeb_relaxed(val, base + MIPHY_RX_CAL_OFFSET_CTRL);
0415 
0416     if (miphy_phy->type == PHY_TYPE_USB3) {
0417         writeb_relaxed(0x00, base + MIPHY_CONF);
0418         writeb_relaxed(0x70, base + MIPHY_RX_LOCK_STEP);
0419         writeb_relaxed(EN_FIRST_HALF, base + MIPHY_RX_SIGDET_SLEEP_OA);
0420         writeb_relaxed(EN_FIRST_HALF, base + MIPHY_RX_SIGDET_SLEEP_SEL);
0421         writeb_relaxed(EN_FIRST_HALF, base + MIPHY_RX_SIGDET_WAIT_SEL);
0422 
0423         val = EN_DIGIT_SIGNAL_CHECK | EN_FIRST_HALF;
0424         writeb_relaxed(val, base + MIPHY_RX_SIGDET_DATA_SEL);
0425     }
0426 
0427 }
0428 
0429 static inline void miphy28lp_sata_config_gen(struct miphy28lp_phy *miphy_phy)
0430 {
0431     void __iomem *base = miphy_phy->base;
0432     int i;
0433 
0434     for (i = 0; i < ARRAY_SIZE(sata_pll_gen); i++) {
0435         struct miphy28lp_pll_gen *gen = &sata_pll_gen[i];
0436 
0437         /* Banked settings */
0438         writeb_relaxed(gen->bank, base + MIPHY_CONF);
0439         writeb_relaxed(gen->speed, base + MIPHY_SPEED);
0440         writeb_relaxed(gen->bias_boost_1, base + MIPHY_BIAS_BOOST_1);
0441         writeb_relaxed(gen->bias_boost_2, base + MIPHY_BIAS_BOOST_2);
0442 
0443         /* TX buffer Settings */
0444         writeb_relaxed(gen->tx_ctrl_2, base + MIPHY_TX_CTRL_2);
0445         writeb_relaxed(gen->tx_ctrl_3, base + MIPHY_TX_CTRL_3);
0446 
0447         /* RX Buffer Settings */
0448         writeb_relaxed(gen->rx_buff_ctrl, base + MIPHY_RX_BUFFER_CTRL);
0449         writeb_relaxed(gen->rx_vga_gain, base + MIPHY_RX_VGA_GAIN);
0450         writeb_relaxed(gen->rx_equ_gain_1, base + MIPHY_RX_EQU_GAIN_1);
0451         writeb_relaxed(gen->rx_equ_gain_2, base + MIPHY_RX_EQU_GAIN_2);
0452         writeb_relaxed(gen->rx_equ_gain_3, base + MIPHY_RX_EQU_GAIN_3);
0453     }
0454 }
0455 
0456 static inline void miphy28lp_pcie_config_gen(struct miphy28lp_phy *miphy_phy)
0457 {
0458     void __iomem *base = miphy_phy->base;
0459     int i;
0460 
0461     for (i = 0; i < ARRAY_SIZE(pcie_pll_gen); i++) {
0462         struct miphy28lp_pll_gen *gen = &pcie_pll_gen[i];
0463 
0464         /* Banked settings */
0465         writeb_relaxed(gen->bank, base + MIPHY_CONF);
0466         writeb_relaxed(gen->speed, base + MIPHY_SPEED);
0467         writeb_relaxed(gen->bias_boost_1, base + MIPHY_BIAS_BOOST_1);
0468         writeb_relaxed(gen->bias_boost_2, base + MIPHY_BIAS_BOOST_2);
0469 
0470         /* TX buffer Settings */
0471         writeb_relaxed(gen->tx_ctrl_1, base + MIPHY_TX_CTRL_1);
0472         writeb_relaxed(gen->tx_ctrl_2, base + MIPHY_TX_CTRL_2);
0473         writeb_relaxed(gen->tx_ctrl_3, base + MIPHY_TX_CTRL_3);
0474 
0475         writeb_relaxed(gen->rx_k_gain, base + MIPHY_RX_K_GAIN);
0476 
0477         /* RX Buffer Settings */
0478         writeb_relaxed(gen->rx_buff_ctrl, base + MIPHY_RX_BUFFER_CTRL);
0479         writeb_relaxed(gen->rx_vga_gain, base + MIPHY_RX_VGA_GAIN);
0480         writeb_relaxed(gen->rx_equ_gain_1, base + MIPHY_RX_EQU_GAIN_1);
0481         writeb_relaxed(gen->rx_equ_gain_2, base + MIPHY_RX_EQU_GAIN_2);
0482     }
0483 }
0484 
0485 static inline int miphy28lp_wait_compensation(struct miphy28lp_phy *miphy_phy)
0486 {
0487     unsigned long finish = jiffies + 5 * HZ;
0488     u8 val;
0489 
0490     /* Waiting for Compensation to complete */
0491     do {
0492         val = readb_relaxed(miphy_phy->base + MIPHY_COMP_FSM_6);
0493 
0494         if (time_after_eq(jiffies, finish))
0495             return -EBUSY;
0496         cpu_relax();
0497     } while (!(val & COMP_DONE));
0498 
0499     return 0;
0500 }
0501 
0502 
0503 static inline int miphy28lp_compensation(struct miphy28lp_phy *miphy_phy,
0504         struct pll_ratio *pll_ratio)
0505 {
0506     void __iomem *base = miphy_phy->base;
0507 
0508     /* Poll for HFC ready after reset release */
0509     /* Compensation measurement */
0510     writeb_relaxed(RST_PLL_SW | RST_COMP_SW, base + MIPHY_RESET);
0511 
0512     writeb_relaxed(0x00, base + MIPHY_PLL_COMMON_MISC_2);
0513     writeb_relaxed(pll_ratio->clk_ref, base + MIPHY_PLL_CLKREF_FREQ);
0514     writeb_relaxed(COMP_START, base + MIPHY_COMP_FSM_1);
0515 
0516     if (miphy_phy->type == PHY_TYPE_PCIE)
0517         writeb_relaxed(RST_PLL_SW, base + MIPHY_RESET);
0518 
0519     writeb_relaxed(0x00, base + MIPHY_RESET);
0520     writeb_relaxed(START_ACT_FILT, base + MIPHY_PLL_COMMON_MISC_2);
0521     writeb_relaxed(SET_NEW_CHANGE, base + MIPHY_PLL_SBR_1);
0522 
0523     /* TX compensation offset to re-center TX impedance */
0524     writeb_relaxed(0x00, base + MIPHY_COMP_POSTP);
0525 
0526     if (miphy_phy->type == PHY_TYPE_PCIE)
0527         return miphy28lp_wait_compensation(miphy_phy);
0528 
0529     return 0;
0530 }
0531 
0532 static inline void miphy28_usb3_miphy_reset(struct miphy28lp_phy *miphy_phy)
0533 {
0534     void __iomem *base = miphy_phy->base;
0535     u8 val;
0536 
0537     /* MIPHY Reset */
0538     writeb_relaxed(RST_APPLI_SW, base + MIPHY_CONF_RESET);
0539     writeb_relaxed(0x00, base + MIPHY_CONF_RESET);
0540     writeb_relaxed(RST_COMP_SW, base + MIPHY_RESET);
0541 
0542     val = RST_COMP_SW | RST_PLL_SW;
0543     writeb_relaxed(val, base + MIPHY_RESET);
0544 
0545     writeb_relaxed(0x00, base + MIPHY_PLL_COMMON_MISC_2);
0546     writeb_relaxed(0x1e, base + MIPHY_PLL_CLKREF_FREQ);
0547     writeb_relaxed(COMP_START, base + MIPHY_COMP_FSM_1);
0548     writeb_relaxed(RST_PLL_SW, base + MIPHY_RESET);
0549     writeb_relaxed(0x00, base + MIPHY_RESET);
0550     writeb_relaxed(START_ACT_FILT, base + MIPHY_PLL_COMMON_MISC_2);
0551     writeb_relaxed(0x00, base + MIPHY_CONF);
0552     writeb_relaxed(0x00, base + MIPHY_BOUNDARY_1);
0553     writeb_relaxed(0x00, base + MIPHY_TST_BIAS_BOOST_2);
0554     writeb_relaxed(0x00, base + MIPHY_CONF);
0555     writeb_relaxed(SET_NEW_CHANGE, base + MIPHY_PLL_SBR_1);
0556     writeb_relaxed(0xa5, base + MIPHY_DEBUG_BUS);
0557     writeb_relaxed(0x00, base + MIPHY_CONF);
0558 }
0559 
0560 static void miphy_sata_tune_ssc(struct miphy28lp_phy *miphy_phy)
0561 {
0562     void __iomem *base = miphy_phy->base;
0563     u8 val;
0564 
0565     /* Compensate Tx impedance to avoid out of range values */
0566     /*
0567      * Enable the SSC on PLL for all banks
0568      * SSC Modulation @ 31 KHz and 4000 ppm modulation amp
0569      */
0570     val = readb_relaxed(base + MIPHY_BOUNDARY_2);
0571     val |= SSC_EN_SW;
0572     writeb_relaxed(val, base + MIPHY_BOUNDARY_2);
0573 
0574     val = readb_relaxed(base + MIPHY_BOUNDARY_SEL);
0575     val |= SSC_SEL;
0576     writeb_relaxed(val, base + MIPHY_BOUNDARY_SEL);
0577 
0578     for (val = 0; val < MIPHY_SATA_BANK_NB; val++) {
0579         writeb_relaxed(val, base + MIPHY_CONF);
0580 
0581         /* Add value to each reference clock cycle  */
0582         /* and define the period length of the SSC */
0583         writeb_relaxed(0x3c, base + MIPHY_PLL_SBR_2);
0584         writeb_relaxed(0x6c, base + MIPHY_PLL_SBR_3);
0585         writeb_relaxed(0x81, base + MIPHY_PLL_SBR_4);
0586 
0587         /* Clear any previous request */
0588         writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1);
0589 
0590         /* requests the PLL to take in account new parameters */
0591         writeb_relaxed(SET_NEW_CHANGE, base + MIPHY_PLL_SBR_1);
0592 
0593         /* To be sure there is no other pending requests */
0594         writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1);
0595     }
0596 }
0597 
0598 static void miphy_pcie_tune_ssc(struct miphy28lp_phy *miphy_phy)
0599 {
0600     void __iomem *base = miphy_phy->base;
0601     u8 val;
0602 
0603     /* Compensate Tx impedance to avoid out of range values */
0604     /*
0605      * Enable the SSC on PLL for all banks
0606      * SSC Modulation @ 31 KHz and 4000 ppm modulation amp
0607      */
0608     val = readb_relaxed(base + MIPHY_BOUNDARY_2);
0609     val |= SSC_EN_SW;
0610     writeb_relaxed(val, base + MIPHY_BOUNDARY_2);
0611 
0612     val = readb_relaxed(base + MIPHY_BOUNDARY_SEL);
0613     val |= SSC_SEL;
0614     writeb_relaxed(val, base + MIPHY_BOUNDARY_SEL);
0615 
0616     for (val = 0; val < MIPHY_PCIE_BANK_NB; val++) {
0617         writeb_relaxed(val, base + MIPHY_CONF);
0618 
0619         /* Validate Step component */
0620         writeb_relaxed(0x69, base + MIPHY_PLL_SBR_3);
0621         writeb_relaxed(0x21, base + MIPHY_PLL_SBR_4);
0622 
0623         /* Validate Period component */
0624         writeb_relaxed(0x3c, base + MIPHY_PLL_SBR_2);
0625         writeb_relaxed(0x21, base + MIPHY_PLL_SBR_4);
0626 
0627         /* Clear any previous request */
0628         writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1);
0629 
0630         /* requests the PLL to take in account new parameters */
0631         writeb_relaxed(SET_NEW_CHANGE, base + MIPHY_PLL_SBR_1);
0632 
0633         /* To be sure there is no other pending requests */
0634         writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1);
0635     }
0636 }
0637 
0638 static inline void miphy_tune_tx_impedance(struct miphy28lp_phy *miphy_phy)
0639 {
0640     /* Compensate Tx impedance to avoid out of range values */
0641     writeb_relaxed(0x02, miphy_phy->base + MIPHY_COMP_POSTP);
0642 }
0643 
0644 static inline int miphy28lp_configure_sata(struct miphy28lp_phy *miphy_phy)
0645 {
0646     void __iomem *base = miphy_phy->base;
0647     int err;
0648     u8 val;
0649 
0650     /* Putting Macro in reset */
0651     miphy28lp_set_reset(miphy_phy);
0652 
0653     /* PLL calibration */
0654     miphy28lp_pll_calibration(miphy_phy, &sata_pll_ratio);
0655 
0656     /* Banked settings Gen1/Gen2/Gen3 */
0657     miphy28lp_sata_config_gen(miphy_phy);
0658 
0659     /* Power control */
0660     /* Input bridge enable, manual input bridge control */
0661     writeb_relaxed(0x21, base + MIPHY_RX_POWER_CTRL_1);
0662 
0663     /* Macro out of reset */
0664     writeb_relaxed(0x00, base + MIPHY_CONF_RESET);
0665 
0666     /* Poll for HFC ready after reset release */
0667     /* Compensation measurement */
0668     err = miphy28lp_compensation(miphy_phy, &sata_pll_ratio);
0669     if (err)
0670         return err;
0671 
0672     if (miphy_phy->px_rx_pol_inv) {
0673         /* Invert Rx polarity */
0674         val = readb_relaxed(miphy_phy->base + MIPHY_CONTROL);
0675         val |= PX_RX_POL;
0676         writeb_relaxed(val, miphy_phy->base + MIPHY_CONTROL);
0677     }
0678 
0679     if (miphy_phy->ssc)
0680         miphy_sata_tune_ssc(miphy_phy);
0681 
0682     if (miphy_phy->tx_impedance)
0683         miphy_tune_tx_impedance(miphy_phy);
0684 
0685     return 0;
0686 }
0687 
0688 static inline int miphy28lp_configure_pcie(struct miphy28lp_phy *miphy_phy)
0689 {
0690     void __iomem *base = miphy_phy->base;
0691     int err;
0692 
0693     /* Putting Macro in reset */
0694     miphy28lp_set_reset(miphy_phy);
0695 
0696     /* PLL calibration */
0697     miphy28lp_pll_calibration(miphy_phy, &pcie_pll_ratio);
0698 
0699     /* Banked settings Gen1/Gen2 */
0700     miphy28lp_pcie_config_gen(miphy_phy);
0701 
0702     /* Power control */
0703     /* Input bridge enable, manual input bridge control */
0704     writeb_relaxed(0x21, base + MIPHY_RX_POWER_CTRL_1);
0705 
0706     /* Macro out of reset */
0707     writeb_relaxed(0x00, base + MIPHY_CONF_RESET);
0708 
0709     /* Poll for HFC ready after reset release */
0710     /* Compensation measurement */
0711     err = miphy28lp_compensation(miphy_phy, &pcie_pll_ratio);
0712     if (err)
0713         return err;
0714 
0715     if (miphy_phy->ssc)
0716         miphy_pcie_tune_ssc(miphy_phy);
0717 
0718     if (miphy_phy->tx_impedance)
0719         miphy_tune_tx_impedance(miphy_phy);
0720 
0721     return 0;
0722 }
0723 
0724 
0725 static inline void miphy28lp_configure_usb3(struct miphy28lp_phy *miphy_phy)
0726 {
0727     void __iomem *base = miphy_phy->base;
0728     u8 val;
0729 
0730     /* Putting Macro in reset */
0731     miphy28lp_set_reset(miphy_phy);
0732 
0733     /* PLL calibration */
0734     miphy28lp_pll_calibration(miphy_phy, &usb3_pll_ratio);
0735 
0736     /* Writing The Speed Rate */
0737     writeb_relaxed(0x00, base + MIPHY_CONF);
0738 
0739     val = RX_SPDSEL_20DEC | TX_SPDSEL_20DEC;
0740     writeb_relaxed(val, base + MIPHY_SPEED);
0741 
0742     /* RX Channel compensation and calibration */
0743     writeb_relaxed(0x1c, base + MIPHY_RX_LOCK_SETTINGS_OPT);
0744     writeb_relaxed(0x51, base + MIPHY_RX_CAL_CTRL_1);
0745     writeb_relaxed(0x70, base + MIPHY_RX_CAL_CTRL_2);
0746 
0747     val = OFFSET_COMPENSATION_EN | VGA_OFFSET_POLARITY |
0748           CAL_OFFSET_THRESHOLD_64 | CAL_OFFSET_VGA_64;
0749     writeb_relaxed(val, base + MIPHY_RX_CAL_OFFSET_CTRL);
0750     writeb_relaxed(0x22, base + MIPHY_RX_CAL_VGA_STEP);
0751     writeb_relaxed(0x0e, base + MIPHY_RX_CAL_OPT_LENGTH);
0752 
0753     val = EQ_DC_GAIN | VGA_GAIN;
0754     writeb_relaxed(val, base + MIPHY_RX_BUFFER_CTRL);
0755     writeb_relaxed(0x78, base + MIPHY_RX_EQU_GAIN_1);
0756     writeb_relaxed(0x1b, base + MIPHY_SYNCHAR_CONTROL);
0757 
0758     /* TX compensation offset to re-center TX impedance */
0759     writeb_relaxed(0x02, base + MIPHY_COMP_POSTP);
0760 
0761     /* Enable GENSEL_SEL and SSC */
0762     /* TX_SEL=0 swing preemp forced by pipe registres */
0763     val = SSC_SEL | GENSEL_SEL;
0764     writeb_relaxed(val, base + MIPHY_BOUNDARY_SEL);
0765 
0766     /* MIPHY Bias boost */
0767     writeb_relaxed(0x00, base + MIPHY_BIAS_BOOST_1);
0768     writeb_relaxed(0xa7, base + MIPHY_BIAS_BOOST_2);
0769 
0770     /* SSC modulation */
0771     writeb_relaxed(SSC_EN_SW, base + MIPHY_BOUNDARY_2);
0772 
0773     /* MIPHY TX control */
0774     writeb_relaxed(0x00, base + MIPHY_CONF);
0775 
0776     /* Validate Step component */
0777     writeb_relaxed(0x5a, base + MIPHY_PLL_SBR_3);
0778     writeb_relaxed(0xa0, base + MIPHY_PLL_SBR_4);
0779 
0780     /* Validate Period component */
0781     writeb_relaxed(0x3c, base + MIPHY_PLL_SBR_2);
0782     writeb_relaxed(0xa1, base + MIPHY_PLL_SBR_4);
0783 
0784     /* Clear any previous request */
0785     writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1);
0786 
0787     /* requests the PLL to take in account new parameters */
0788     writeb_relaxed(0x02, base + MIPHY_PLL_SBR_1);
0789 
0790     /* To be sure there is no other pending requests */
0791     writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1);
0792 
0793     /* Rx PI controller settings */
0794     writeb_relaxed(0xca, base + MIPHY_RX_K_GAIN);
0795 
0796     /* MIPHY RX input bridge control */
0797     /* INPUT_BRIDGE_EN_SW=1, manual input bridge control[0]=1 */
0798     writeb_relaxed(0x21, base + MIPHY_RX_POWER_CTRL_1);
0799     writeb_relaxed(0x29, base + MIPHY_RX_POWER_CTRL_1);
0800     writeb_relaxed(0x1a, base + MIPHY_RX_POWER_CTRL_2);
0801 
0802     /* MIPHY Reset for usb3 */
0803     miphy28_usb3_miphy_reset(miphy_phy);
0804 }
0805 
0806 static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy)
0807 {
0808     unsigned long finish = jiffies + 5 * HZ;
0809     u8 mask = HFC_PLL | HFC_RDY;
0810     u8 val;
0811 
0812     /*
0813      * For PCIe and USB3 check only that PLL and HFC are ready
0814      * For SATA check also that phy is ready!
0815      */
0816     if (miphy_phy->type == PHY_TYPE_SATA)
0817         mask |= PHY_RDY;
0818 
0819     do {
0820         val = readb_relaxed(miphy_phy->base + MIPHY_STATUS_1);
0821         if ((val & mask) != mask)
0822             cpu_relax();
0823         else
0824             return 0;
0825     } while (!time_after_eq(jiffies, finish));
0826 
0827     return -EBUSY;
0828 }
0829 
0830 static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy)
0831 {
0832     struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
0833     unsigned long finish = jiffies + 5 * HZ;
0834     u32 val;
0835 
0836     if (!miphy_phy->osc_rdy)
0837         return 0;
0838 
0839     if (!miphy_phy->syscfg_reg[SYSCFG_STATUS])
0840         return -EINVAL;
0841 
0842     do {
0843         regmap_read(miphy_dev->regmap,
0844                 miphy_phy->syscfg_reg[SYSCFG_STATUS], &val);
0845 
0846         if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY)
0847             cpu_relax();
0848         else
0849             return 0;
0850     } while (!time_after_eq(jiffies, finish));
0851 
0852     return -EBUSY;
0853 }
0854 
0855 static int miphy28lp_get_resource_byname(struct device_node *child,
0856                       char *rname, struct resource *res)
0857 {
0858     int index;
0859 
0860     index = of_property_match_string(child, "reg-names", rname);
0861     if (index < 0)
0862         return -ENODEV;
0863 
0864     return of_address_to_resource(child, index, res);
0865 }
0866 
0867 static int miphy28lp_get_one_addr(struct device *dev,
0868                   struct device_node *child, char *rname,
0869                   void __iomem **base)
0870 {
0871     struct resource res;
0872     int ret;
0873 
0874     ret = miphy28lp_get_resource_byname(child, rname, &res);
0875     if (!ret) {
0876         *base = devm_ioremap(dev, res.start, resource_size(&res));
0877         if (!*base) {
0878             dev_err(dev, "failed to ioremap %s address region\n"
0879                     , rname);
0880             return -ENOENT;
0881         }
0882     }
0883 
0884     return 0;
0885 }
0886 
0887 /* MiPHY reset and sysconf setup */
0888 static int miphy28lp_setup(struct miphy28lp_phy *miphy_phy, u32 miphy_val)
0889 {
0890     int err;
0891     struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
0892 
0893     if (!miphy_phy->syscfg_reg[SYSCFG_CTRL])
0894         return -EINVAL;
0895 
0896     err = reset_control_assert(miphy_phy->miphy_rst);
0897     if (err) {
0898         dev_err(miphy_dev->dev, "unable to bring out of miphy reset\n");
0899         return err;
0900     }
0901 
0902     if (miphy_phy->osc_force_ext)
0903         miphy_val |= MIPHY_OSC_FORCE_EXT;
0904 
0905     regmap_update_bits(miphy_dev->regmap,
0906                miphy_phy->syscfg_reg[SYSCFG_CTRL],
0907                MIPHY_CTRL_MASK, miphy_val);
0908 
0909     err = reset_control_deassert(miphy_phy->miphy_rst);
0910     if (err) {
0911         dev_err(miphy_dev->dev, "unable to bring out of miphy reset\n");
0912         return err;
0913     }
0914 
0915     return miphy_osc_is_ready(miphy_phy);
0916 }
0917 
0918 static int miphy28lp_init_sata(struct miphy28lp_phy *miphy_phy)
0919 {
0920     struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
0921     int err, sata_conf = SATA_CTRL_SELECT_SATA;
0922 
0923     if ((!miphy_phy->syscfg_reg[SYSCFG_SATA]) ||
0924             (!miphy_phy->syscfg_reg[SYSCFG_PCI]) ||
0925             (!miphy_phy->base))
0926         return -EINVAL;
0927 
0928     dev_info(miphy_dev->dev, "sata-up mode, addr 0x%p\n", miphy_phy->base);
0929 
0930     /* Configure the glue-logic */
0931     sata_conf |= ((miphy_phy->sata_gen - SATA_GEN1) << SATA_SPDMODE);
0932 
0933     regmap_update_bits(miphy_dev->regmap,
0934                miphy_phy->syscfg_reg[SYSCFG_SATA],
0935                SATA_CTRL_MASK, sata_conf);
0936 
0937     regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_reg[SYSCFG_PCI],
0938                PCIE_CTRL_MASK, SATA_CTRL_SELECT_PCIE);
0939 
0940     /* MiPHY path and clocking init */
0941     err = miphy28lp_setup(miphy_phy, MIPHY_CTRL_DEFAULT);
0942 
0943     if (err) {
0944         dev_err(miphy_dev->dev, "SATA phy setup failed\n");
0945         return err;
0946     }
0947 
0948     /* initialize miphy */
0949     miphy28lp_configure_sata(miphy_phy);
0950 
0951     return miphy_is_ready(miphy_phy);
0952 }
0953 
0954 static int miphy28lp_init_pcie(struct miphy28lp_phy *miphy_phy)
0955 {
0956     struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
0957     int err;
0958 
0959     if ((!miphy_phy->syscfg_reg[SYSCFG_SATA]) ||
0960             (!miphy_phy->syscfg_reg[SYSCFG_PCI])
0961         || (!miphy_phy->base) || (!miphy_phy->pipebase))
0962         return -EINVAL;
0963 
0964     dev_info(miphy_dev->dev, "pcie-up mode, addr 0x%p\n", miphy_phy->base);
0965 
0966     /* Configure the glue-logic */
0967     regmap_update_bits(miphy_dev->regmap,
0968                miphy_phy->syscfg_reg[SYSCFG_SATA],
0969                SATA_CTRL_MASK, SATA_CTRL_SELECT_PCIE);
0970 
0971     regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_reg[SYSCFG_PCI],
0972                PCIE_CTRL_MASK, SYSCFG_PCIE_PCIE_VAL);
0973 
0974     /* MiPHY path and clocking init */
0975     err = miphy28lp_setup(miphy_phy, MIPHY_CTRL_DEFAULT);
0976 
0977     if (err) {
0978         dev_err(miphy_dev->dev, "PCIe phy setup failed\n");
0979         return err;
0980     }
0981 
0982     /* initialize miphy */
0983     err = miphy28lp_configure_pcie(miphy_phy);
0984     if (err)
0985         return err;
0986 
0987     /* PIPE Wrapper Configuration */
0988     writeb_relaxed(0x68, miphy_phy->pipebase + 0x104); /* Rise_0 */
0989     writeb_relaxed(0x61, miphy_phy->pipebase + 0x105); /* Rise_1 */
0990     writeb_relaxed(0x68, miphy_phy->pipebase + 0x108); /* Fall_0 */
0991     writeb_relaxed(0x61, miphy_phy->pipebase + 0x109); /* Fall-1 */
0992     writeb_relaxed(0x68, miphy_phy->pipebase + 0x10c); /* Threshold_0 */
0993     writeb_relaxed(0x60, miphy_phy->pipebase + 0x10d); /* Threshold_1 */
0994 
0995     /* Wait for phy_ready */
0996     return miphy_is_ready(miphy_phy);
0997 }
0998 
0999 static int miphy28lp_init_usb3(struct miphy28lp_phy *miphy_phy)
1000 {
1001     struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
1002     int err;
1003 
1004     if ((!miphy_phy->base) || (!miphy_phy->pipebase))
1005         return -EINVAL;
1006 
1007     dev_info(miphy_dev->dev, "usb3-up mode, addr 0x%p\n", miphy_phy->base);
1008 
1009     /* MiPHY path and clocking init */
1010     err = miphy28lp_setup(miphy_phy, MIPHY_CTRL_SYNC_D_EN);
1011     if (err) {
1012         dev_err(miphy_dev->dev, "USB3 phy setup failed\n");
1013         return err;
1014     }
1015 
1016     /* initialize miphy */
1017     miphy28lp_configure_usb3(miphy_phy);
1018 
1019     /* PIPE Wrapper Configuration */
1020     writeb_relaxed(0x68, miphy_phy->pipebase + 0x23);
1021     writeb_relaxed(0x61, miphy_phy->pipebase + 0x24);
1022     writeb_relaxed(0x68, miphy_phy->pipebase + 0x26);
1023     writeb_relaxed(0x61, miphy_phy->pipebase + 0x27);
1024     writeb_relaxed(0x18, miphy_phy->pipebase + 0x29);
1025     writeb_relaxed(0x61, miphy_phy->pipebase + 0x2a);
1026 
1027     /* pipe Wrapper usb3 TX swing de-emph margin PREEMPH[7:4], SWING[3:0] */
1028     writeb_relaxed(0X67, miphy_phy->pipebase + 0x68);
1029     writeb_relaxed(0x0d, miphy_phy->pipebase + 0x69);
1030     writeb_relaxed(0X67, miphy_phy->pipebase + 0x6a);
1031     writeb_relaxed(0X0d, miphy_phy->pipebase + 0x6b);
1032     writeb_relaxed(0X67, miphy_phy->pipebase + 0x6c);
1033     writeb_relaxed(0X0d, miphy_phy->pipebase + 0x6d);
1034     writeb_relaxed(0X67, miphy_phy->pipebase + 0x6e);
1035     writeb_relaxed(0X0d, miphy_phy->pipebase + 0x6f);
1036 
1037     return miphy_is_ready(miphy_phy);
1038 }
1039 
1040 static int miphy28lp_init(struct phy *phy)
1041 {
1042     struct miphy28lp_phy *miphy_phy = phy_get_drvdata(phy);
1043     struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
1044     int ret;
1045 
1046     mutex_lock(&miphy_dev->miphy_mutex);
1047 
1048     switch (miphy_phy->type) {
1049 
1050     case PHY_TYPE_SATA:
1051         ret = miphy28lp_init_sata(miphy_phy);
1052         break;
1053     case PHY_TYPE_PCIE:
1054         ret = miphy28lp_init_pcie(miphy_phy);
1055         break;
1056     case PHY_TYPE_USB3:
1057         ret = miphy28lp_init_usb3(miphy_phy);
1058         break;
1059     default:
1060         ret = -EINVAL;
1061         break;
1062     }
1063 
1064     mutex_unlock(&miphy_dev->miphy_mutex);
1065 
1066     return ret;
1067 }
1068 
1069 static int miphy28lp_get_addr(struct miphy28lp_phy *miphy_phy)
1070 {
1071     struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
1072     struct device_node *phynode = miphy_phy->phy->dev.of_node;
1073     int err;
1074 
1075     if ((miphy_phy->type != PHY_TYPE_SATA) &&
1076         (miphy_phy->type != PHY_TYPE_PCIE) &&
1077         (miphy_phy->type != PHY_TYPE_USB3)) {
1078         return -EINVAL;
1079     }
1080 
1081     err = miphy28lp_get_one_addr(miphy_dev->dev, phynode,
1082             PHY_TYPE_name[miphy_phy->type - PHY_TYPE_SATA],
1083             &miphy_phy->base);
1084     if (err)
1085         return err;
1086 
1087     if ((miphy_phy->type == PHY_TYPE_PCIE) ||
1088         (miphy_phy->type == PHY_TYPE_USB3)) {
1089         err = miphy28lp_get_one_addr(miphy_dev->dev, phynode, "pipew",
1090                          &miphy_phy->pipebase);
1091         if (err)
1092             return err;
1093     }
1094 
1095     return 0;
1096 }
1097 
1098 static struct phy *miphy28lp_xlate(struct device *dev,
1099                    struct of_phandle_args *args)
1100 {
1101     struct miphy28lp_dev *miphy_dev = dev_get_drvdata(dev);
1102     struct miphy28lp_phy *miphy_phy = NULL;
1103     struct device_node *phynode = args->np;
1104     int ret, index = 0;
1105 
1106     if (args->args_count != 1) {
1107         dev_err(dev, "Invalid number of cells in 'phy' property\n");
1108         return ERR_PTR(-EINVAL);
1109     }
1110 
1111     for (index = 0; index < miphy_dev->nphys; index++)
1112         if (phynode == miphy_dev->phys[index]->phy->dev.of_node) {
1113             miphy_phy = miphy_dev->phys[index];
1114             break;
1115         }
1116 
1117     if (!miphy_phy) {
1118         dev_err(dev, "Failed to find appropriate phy\n");
1119         return ERR_PTR(-EINVAL);
1120     }
1121 
1122     miphy_phy->type = args->args[0];
1123 
1124     ret = miphy28lp_get_addr(miphy_phy);
1125     if (ret < 0)
1126         return ERR_PTR(ret);
1127 
1128     return miphy_phy->phy;
1129 }
1130 
1131 static const struct phy_ops miphy28lp_ops = {
1132     .init = miphy28lp_init,
1133     .owner = THIS_MODULE,
1134 };
1135 
1136 static int miphy28lp_probe_resets(struct device_node *node,
1137                   struct miphy28lp_phy *miphy_phy)
1138 {
1139     struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
1140     int err;
1141 
1142     miphy_phy->miphy_rst =
1143         of_reset_control_get_shared(node, "miphy-sw-rst");
1144 
1145     if (IS_ERR(miphy_phy->miphy_rst)) {
1146         dev_err(miphy_dev->dev,
1147                 "miphy soft reset control not defined\n");
1148         return PTR_ERR(miphy_phy->miphy_rst);
1149     }
1150 
1151     err = reset_control_deassert(miphy_phy->miphy_rst);
1152     if (err) {
1153         dev_err(miphy_dev->dev, "unable to bring out of miphy reset\n");
1154         return err;
1155     }
1156 
1157     return 0;
1158 }
1159 
1160 static int miphy28lp_of_probe(struct device_node *np,
1161                   struct miphy28lp_phy *miphy_phy)
1162 {
1163     int i;
1164     u32 ctrlreg;
1165 
1166     miphy_phy->osc_force_ext =
1167         of_property_read_bool(np, "st,osc-force-ext");
1168 
1169     miphy_phy->osc_rdy = of_property_read_bool(np, "st,osc-rdy");
1170 
1171     miphy_phy->px_rx_pol_inv =
1172         of_property_read_bool(np, "st,px_rx_pol_inv");
1173 
1174     miphy_phy->ssc = of_property_read_bool(np, "st,ssc-on");
1175 
1176     miphy_phy->tx_impedance =
1177         of_property_read_bool(np, "st,tx-impedance-comp");
1178 
1179     of_property_read_u32(np, "st,sata-gen", &miphy_phy->sata_gen);
1180     if (!miphy_phy->sata_gen)
1181         miphy_phy->sata_gen = SATA_GEN1;
1182 
1183     for (i = 0; i < SYSCFG_REG_MAX; i++) {
1184         if (!of_property_read_u32_index(np, "st,syscfg", i, &ctrlreg))
1185             miphy_phy->syscfg_reg[i] = ctrlreg;
1186     }
1187 
1188     return 0;
1189 }
1190 
1191 static int miphy28lp_probe(struct platform_device *pdev)
1192 {
1193     struct device_node *child, *np = pdev->dev.of_node;
1194     struct miphy28lp_dev *miphy_dev;
1195     struct phy_provider *provider;
1196     struct phy *phy;
1197     int ret, port = 0;
1198 
1199     miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL);
1200     if (!miphy_dev)
1201         return -ENOMEM;
1202 
1203     miphy_dev->nphys = of_get_child_count(np);
1204     miphy_dev->phys = devm_kcalloc(&pdev->dev, miphy_dev->nphys,
1205                        sizeof(*miphy_dev->phys), GFP_KERNEL);
1206     if (!miphy_dev->phys)
1207         return -ENOMEM;
1208 
1209     miphy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
1210     if (IS_ERR(miphy_dev->regmap)) {
1211         dev_err(miphy_dev->dev, "No syscfg phandle specified\n");
1212         return PTR_ERR(miphy_dev->regmap);
1213     }
1214 
1215     miphy_dev->dev = &pdev->dev;
1216 
1217     dev_set_drvdata(&pdev->dev, miphy_dev);
1218 
1219     mutex_init(&miphy_dev->miphy_mutex);
1220 
1221     for_each_child_of_node(np, child) {
1222         struct miphy28lp_phy *miphy_phy;
1223 
1224         miphy_phy = devm_kzalloc(&pdev->dev, sizeof(*miphy_phy),
1225                      GFP_KERNEL);
1226         if (!miphy_phy) {
1227             ret = -ENOMEM;
1228             goto put_child;
1229         }
1230 
1231         miphy_dev->phys[port] = miphy_phy;
1232 
1233         phy = devm_phy_create(&pdev->dev, child, &miphy28lp_ops);
1234         if (IS_ERR(phy)) {
1235             dev_err(&pdev->dev, "failed to create PHY\n");
1236             ret = PTR_ERR(phy);
1237             goto put_child;
1238         }
1239 
1240         miphy_dev->phys[port]->phy = phy;
1241         miphy_dev->phys[port]->phydev = miphy_dev;
1242 
1243         ret = miphy28lp_of_probe(child, miphy_phy);
1244         if (ret)
1245             goto put_child;
1246 
1247         ret = miphy28lp_probe_resets(child, miphy_dev->phys[port]);
1248         if (ret)
1249             goto put_child;
1250 
1251         phy_set_drvdata(phy, miphy_dev->phys[port]);
1252         port++;
1253 
1254     }
1255 
1256     provider = devm_of_phy_provider_register(&pdev->dev, miphy28lp_xlate);
1257     return PTR_ERR_OR_ZERO(provider);
1258 put_child:
1259     of_node_put(child);
1260     return ret;
1261 }
1262 
1263 static const struct of_device_id miphy28lp_of_match[] = {
1264     {.compatible = "st,miphy28lp-phy", },
1265     {},
1266 };
1267 
1268 MODULE_DEVICE_TABLE(of, miphy28lp_of_match);
1269 
1270 static struct platform_driver miphy28lp_driver = {
1271     .probe = miphy28lp_probe,
1272     .driver = {
1273         .name = "miphy28lp-phy",
1274         .of_match_table = miphy28lp_of_match,
1275     }
1276 };
1277 
1278 module_platform_driver(miphy28lp_driver);
1279 
1280 MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@st.com>");
1281 MODULE_DESCRIPTION("STMicroelectronics miphy28lp driver");
1282 MODULE_LICENSE("GPL v2");