1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2017, The Linux Foundation. All rights reserved. 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/clk-provider.h> 8 #include <linux/delay.h> 9 #include <linux/err.h> 10 #include <linux/io.h> 11 #include <linux/iopoll.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/of_device.h> 16 #include <linux/of_address.h> 17 #include <linux/phy/phy.h> 18 #include <linux/platform_device.h> 19 #include <linux/regulator/consumer.h> 20 #include <linux/reset.h> 21 #include <linux/slab.h> 22 23 #include <dt-bindings/phy/phy.h> 24 25 #include "phy-qcom-qmp.h" 26 27 /* QPHY_SW_RESET bit */ 28 #define SW_RESET BIT(0) 29 /* QPHY_POWER_DOWN_CONTROL */ 30 #define SW_PWRDN BIT(0) 31 /* QPHY_START_CONTROL bits */ 32 #define SERDES_START BIT(0) 33 #define PCS_START BIT(1) 34 /* QPHY_PCS_READY_STATUS bit */ 35 #define PCS_READY BIT(0) 36 37 #define PHY_INIT_COMPLETE_TIMEOUT 10000 38 39 struct qmp_phy_init_tbl { 40 unsigned int offset; 41 unsigned int val; 42 /* 43 * mask of lanes for which this register is written 44 * for cases when second lane needs different values 45 */ 46 u8 lane_mask; 47 }; 48 49 #define QMP_PHY_INIT_CFG(o, v) \ 50 { \ 51 .offset = o, \ 52 .val = v, \ 53 .lane_mask = 0xff, \ 54 } 55 56 #define QMP_PHY_INIT_CFG_LANE(o, v, l) \ 57 { \ 58 .offset = o, \ 59 .val = v, \ 60 .lane_mask = l, \ 61 } 62 63 /* set of registers with offsets different per-PHY */ 64 enum qphy_reg_layout { 65 /* PCS registers */ 66 QPHY_SW_RESET, 67 QPHY_START_CTRL, 68 QPHY_PCS_READY_STATUS, 69 QPHY_PCS_POWER_DOWN_CONTROL, 70 /* Keep last to ensure regs_layout arrays are properly initialized */ 71 QPHY_LAYOUT_SIZE 72 }; 73 74 static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = { 75 [QPHY_START_CTRL] = 0x00, 76 [QPHY_PCS_READY_STATUS] = 0x168, 77 [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04, 78 }; 79 80 static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = { 81 [QPHY_START_CTRL] = 0x00, 82 [QPHY_PCS_READY_STATUS] = 0x160, 83 [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04, 84 }; 85 86 static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = { 87 [QPHY_START_CTRL] = 0x00, 88 [QPHY_PCS_READY_STATUS] = 0x168, 89 [QPHY_PCS_POWER_DOWN_CONTROL] = 0x04, 90 }; 91 92 static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = { 93 [QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START, 94 [QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS, 95 [QPHY_SW_RESET] = QPHY_V4_PCS_UFS_SW_RESET, 96 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL, 97 }; 98 99 static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = { 100 QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e), 101 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7), 102 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), 103 QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06), 104 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), 105 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a), 106 QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05), 107 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a), 108 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a), 109 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01), 110 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10), 111 QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20), 112 QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00), 113 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00), 114 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff), 115 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f), 116 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54), 117 QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05), 118 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82), 119 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), 120 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00), 121 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00), 122 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), 123 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), 124 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), 125 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80), 126 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 127 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28), 128 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02), 129 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff), 130 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c), 131 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), 132 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98), 133 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00), 134 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00), 135 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00), 136 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b), 137 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16), 138 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28), 139 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80), 140 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00), 141 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6), 142 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00), 143 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32), 144 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f), 145 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00), 146 }; 147 148 static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = { 149 QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45), 150 QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02), 151 }; 152 153 static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = { 154 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24), 155 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02), 156 QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00), 157 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18), 158 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B), 159 QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b), 160 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff), 161 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f), 162 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff), 163 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f), 164 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E), 165 }; 166 167 static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = { 168 QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e), 169 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14), 170 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), 171 QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02), 172 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), 173 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a), 174 QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00), 175 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a), 176 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a), 177 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01), 178 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00), 179 QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20), 180 QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00), 181 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00), 182 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff), 183 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f), 184 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04), 185 QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05), 186 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82), 187 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), 188 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00), 189 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00), 190 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), 191 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), 192 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), 193 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80), 194 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 195 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28), 196 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02), 197 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff), 198 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c), 199 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), 200 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98), 201 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00), 202 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00), 203 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00), 204 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b), 205 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16), 206 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28), 207 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80), 208 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00), 209 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6), 210 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00), 211 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32), 212 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f), 213 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00), 214 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f), 215 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f), 216 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff), 217 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00), 218 219 /* Rate B */ 220 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44), 221 }; 222 223 static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = { 224 QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45), 225 QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06), 226 }; 227 228 static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = { 229 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24), 230 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F), 231 QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40), 232 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E), 233 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B), 234 QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B), 235 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF), 236 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F), 237 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF), 238 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F), 239 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D), 240 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04), 241 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04), 242 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04), 243 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B), 244 }; 245 246 static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = { 247 QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_PWM_GEAR_BAND, 0x15), 248 QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SIGDET_CTRL2, 0x6d), 249 QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_DRV_LVL, 0x0f), 250 QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_DRV_LVL, 0x02), 251 QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28), 252 QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SYM_RESYNC_CTRL, 0x03), 253 QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x12), 254 QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f), 255 QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */ 256 }; 257 258 static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = { 259 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02), 260 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04), 261 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a), 262 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), 263 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06), 264 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5), 265 QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20), 266 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), 267 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00), 268 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01), 269 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00), 270 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00), 271 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04), 272 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05), 273 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff), 274 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00), 275 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82), 276 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06), 277 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16), 278 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36), 279 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), 280 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 281 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda), 282 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01), 283 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff), 284 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c), 285 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98), 286 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06), 287 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16), 288 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36), 289 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f), 290 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00), 291 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1), 292 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00), 293 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32), 294 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f), 295 296 /* Rate B */ 297 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44), 298 }; 299 300 static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = { 301 QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06), 302 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04), 303 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07), 304 }; 305 306 static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = { 307 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24), 308 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f), 309 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), 310 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40), 311 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), 312 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b), 313 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), 314 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), 315 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b), 316 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04), 317 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04), 318 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04), 319 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b), 320 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81), 321 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), 322 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59), 323 }; 324 325 static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = { 326 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e), 327 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a), 328 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), 329 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03), 330 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 331 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f), 332 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a), 333 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 334 }; 335 336 static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = { 337 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9), 338 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11), 339 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00), 340 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01), 341 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02), 342 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f), 343 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00), 344 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), 345 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82), 346 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06), 347 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16), 348 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36), 349 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff), 350 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c), 351 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac), 352 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e), 353 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98), 354 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06), 355 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16), 356 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36), 357 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32), 358 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f), 359 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd), 360 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23), 361 362 /* Rate B */ 363 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06), 364 }; 365 366 static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = { 367 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06), 368 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03), 369 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01), 370 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00), 371 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05), 372 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c), 373 }; 374 375 static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = { 376 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24), 377 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f), 378 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), 379 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18), 380 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a), 381 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b), 382 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1), 383 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), 384 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80), 385 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c), 386 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04), 387 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b), 388 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), 389 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), 390 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d), 391 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00), 392 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10), 393 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0), 394 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00), 395 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36), 396 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36), 397 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6), 398 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b), 399 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d), 400 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0), 401 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8), 402 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8), 403 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b), 404 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1), 405 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0), 406 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8), 407 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8), 408 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b), 409 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1), 410 411 }; 412 413 static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = { 414 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d), 415 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a), 416 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), 417 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 418 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f), 419 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff), 420 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 421 }; 422 423 static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = { 424 QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9), 425 QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11), 426 QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00), 427 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42), 428 QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02), 429 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f), 430 QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00), 431 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), 432 QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82), 433 QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14), 434 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18), 435 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18), 436 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff), 437 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19), 438 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac), 439 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e), 440 QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98), 441 QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14), 442 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18), 443 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18), 444 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65), 445 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e), 446 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd), 447 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23), 448 449 /* Rate B */ 450 QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06), 451 }; 452 453 static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = { 454 QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06), 455 QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03), 456 QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01), 457 QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00), 458 QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5), 459 QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f), 460 QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09), 461 QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09), 462 QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c), 463 }; 464 465 static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = { 466 QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24), 467 QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f), 468 QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), 469 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18), 470 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a), 471 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a), 472 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1), 473 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), 474 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80), 475 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e), 476 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04), 477 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b), 478 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04), 479 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), 480 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), 481 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a), 482 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17), 483 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00), 484 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10), 485 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0), 486 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00), 487 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d), 488 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d), 489 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed), 490 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b), 491 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c), 492 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0), 493 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8), 494 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8), 495 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b), 496 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7), 497 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0), 498 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8), 499 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8), 500 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b), 501 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7), 502 QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c), 503 }; 504 505 static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = { 506 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d), 507 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a), 508 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), 509 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 510 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f), 511 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff), 512 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03), 513 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16), 514 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8), 515 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa), 516 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06), 517 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03), 518 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03), 519 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e), 520 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 521 }; 522 523 struct qmp_ufs_offsets { 524 u16 serdes; 525 u16 pcs; 526 u16 tx; 527 u16 rx; 528 u16 tx2; 529 u16 rx2; 530 }; 531 532 /* struct qmp_phy_cfg - per-PHY initialization config */ 533 struct qmp_phy_cfg { 534 int lanes; 535 536 const struct qmp_ufs_offsets *offsets; 537 538 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */ 539 const struct qmp_phy_init_tbl *serdes_tbl; 540 int serdes_tbl_num; 541 const struct qmp_phy_init_tbl *tx_tbl; 542 int tx_tbl_num; 543 const struct qmp_phy_init_tbl *rx_tbl; 544 int rx_tbl_num; 545 const struct qmp_phy_init_tbl *pcs_tbl; 546 int pcs_tbl_num; 547 548 /* clock ids to be requested */ 549 const char * const *clk_list; 550 int num_clks; 551 /* regulators to be requested */ 552 const char * const *vreg_list; 553 int num_vregs; 554 555 /* array of registers with different offsets */ 556 const unsigned int *regs; 557 558 /* true, if PCS block has no separate SW_RESET register */ 559 bool no_pcs_sw_reset; 560 }; 561 562 struct qmp_ufs { 563 struct device *dev; 564 565 const struct qmp_phy_cfg *cfg; 566 567 void __iomem *serdes; 568 void __iomem *pcs; 569 void __iomem *pcs_misc; 570 void __iomem *tx; 571 void __iomem *rx; 572 void __iomem *tx2; 573 void __iomem *rx2; 574 575 struct clk_bulk_data *clks; 576 struct regulator_bulk_data *vregs; 577 struct reset_control *ufs_reset; 578 579 struct phy *phy; 580 }; 581 582 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) 583 { 584 u32 reg; 585 586 reg = readl(base + offset); 587 reg |= val; 588 writel(reg, base + offset); 589 590 /* ensure that above write is through */ 591 readl(base + offset); 592 } 593 594 static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val) 595 { 596 u32 reg; 597 598 reg = readl(base + offset); 599 reg &= ~val; 600 writel(reg, base + offset); 601 602 /* ensure that above write is through */ 603 readl(base + offset); 604 } 605 606 /* list of clocks required by phy */ 607 static const char * const msm8996_ufs_phy_clk_l[] = { 608 "ref", 609 }; 610 611 /* the primary usb3 phy on sm8250 doesn't have a ref clock */ 612 static const char * const sm8450_ufs_phy_clk_l[] = { 613 "qref", "ref", "ref_aux", 614 }; 615 616 static const char * const sdm845_ufs_phy_clk_l[] = { 617 "ref", "ref_aux", 618 }; 619 620 /* list of regulators */ 621 static const char * const qmp_phy_vreg_l[] = { 622 "vdda-phy", "vdda-pll", 623 }; 624 625 static const struct qmp_ufs_offsets qmp_ufs_offsets_v5 = { 626 .serdes = 0, 627 .pcs = 0xc00, 628 .tx = 0x400, 629 .rx = 0x600, 630 .tx2 = 0x800, 631 .rx2 = 0xa00, 632 }; 633 634 static const struct qmp_phy_cfg msm8996_ufs_cfg = { 635 .lanes = 1, 636 637 .serdes_tbl = msm8996_ufs_serdes_tbl, 638 .serdes_tbl_num = ARRAY_SIZE(msm8996_ufs_serdes_tbl), 639 .tx_tbl = msm8996_ufs_tx_tbl, 640 .tx_tbl_num = ARRAY_SIZE(msm8996_ufs_tx_tbl), 641 .rx_tbl = msm8996_ufs_rx_tbl, 642 .rx_tbl_num = ARRAY_SIZE(msm8996_ufs_rx_tbl), 643 644 .clk_list = msm8996_ufs_phy_clk_l, 645 .num_clks = ARRAY_SIZE(msm8996_ufs_phy_clk_l), 646 647 .vreg_list = qmp_phy_vreg_l, 648 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 649 650 .regs = msm8996_ufsphy_regs_layout, 651 652 .no_pcs_sw_reset = true, 653 }; 654 655 static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = { 656 .lanes = 2, 657 658 .offsets = &qmp_ufs_offsets_v5, 659 660 .serdes_tbl = sm8350_ufsphy_serdes_tbl, 661 .serdes_tbl_num = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl), 662 .tx_tbl = sm8350_ufsphy_tx_tbl, 663 .tx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_tx_tbl), 664 .rx_tbl = sm8350_ufsphy_rx_tbl, 665 .rx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_rx_tbl), 666 .pcs_tbl = sm8350_ufsphy_pcs_tbl, 667 .pcs_tbl_num = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl), 668 .clk_list = sdm845_ufs_phy_clk_l, 669 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 670 .vreg_list = qmp_phy_vreg_l, 671 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 672 .regs = sm8150_ufsphy_regs_layout, 673 }; 674 675 static const struct qmp_phy_cfg sdm845_ufsphy_cfg = { 676 .lanes = 2, 677 678 .serdes_tbl = sdm845_ufsphy_serdes_tbl, 679 .serdes_tbl_num = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl), 680 .tx_tbl = sdm845_ufsphy_tx_tbl, 681 .tx_tbl_num = ARRAY_SIZE(sdm845_ufsphy_tx_tbl), 682 .rx_tbl = sdm845_ufsphy_rx_tbl, 683 .rx_tbl_num = ARRAY_SIZE(sdm845_ufsphy_rx_tbl), 684 .pcs_tbl = sdm845_ufsphy_pcs_tbl, 685 .pcs_tbl_num = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl), 686 .clk_list = sdm845_ufs_phy_clk_l, 687 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 688 .vreg_list = qmp_phy_vreg_l, 689 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 690 .regs = sdm845_ufsphy_regs_layout, 691 692 .no_pcs_sw_reset = true, 693 }; 694 695 static const struct qmp_phy_cfg sm6115_ufsphy_cfg = { 696 .lanes = 1, 697 698 .serdes_tbl = sm6115_ufsphy_serdes_tbl, 699 .serdes_tbl_num = ARRAY_SIZE(sm6115_ufsphy_serdes_tbl), 700 .tx_tbl = sm6115_ufsphy_tx_tbl, 701 .tx_tbl_num = ARRAY_SIZE(sm6115_ufsphy_tx_tbl), 702 .rx_tbl = sm6115_ufsphy_rx_tbl, 703 .rx_tbl_num = ARRAY_SIZE(sm6115_ufsphy_rx_tbl), 704 .pcs_tbl = sm6115_ufsphy_pcs_tbl, 705 .pcs_tbl_num = ARRAY_SIZE(sm6115_ufsphy_pcs_tbl), 706 .clk_list = sdm845_ufs_phy_clk_l, 707 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 708 .vreg_list = qmp_phy_vreg_l, 709 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 710 .regs = sm6115_ufsphy_regs_layout, 711 712 .no_pcs_sw_reset = true, 713 }; 714 715 static const struct qmp_phy_cfg sm8150_ufsphy_cfg = { 716 .lanes = 2, 717 718 .serdes_tbl = sm8150_ufsphy_serdes_tbl, 719 .serdes_tbl_num = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl), 720 .tx_tbl = sm8150_ufsphy_tx_tbl, 721 .tx_tbl_num = ARRAY_SIZE(sm8150_ufsphy_tx_tbl), 722 .rx_tbl = sm8150_ufsphy_rx_tbl, 723 .rx_tbl_num = ARRAY_SIZE(sm8150_ufsphy_rx_tbl), 724 .pcs_tbl = sm8150_ufsphy_pcs_tbl, 725 .pcs_tbl_num = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl), 726 .clk_list = sdm845_ufs_phy_clk_l, 727 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 728 .vreg_list = qmp_phy_vreg_l, 729 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 730 .regs = sm8150_ufsphy_regs_layout, 731 }; 732 733 static const struct qmp_phy_cfg sm8350_ufsphy_cfg = { 734 .lanes = 2, 735 736 .serdes_tbl = sm8350_ufsphy_serdes_tbl, 737 .serdes_tbl_num = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl), 738 .tx_tbl = sm8350_ufsphy_tx_tbl, 739 .tx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_tx_tbl), 740 .rx_tbl = sm8350_ufsphy_rx_tbl, 741 .rx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_rx_tbl), 742 .pcs_tbl = sm8350_ufsphy_pcs_tbl, 743 .pcs_tbl_num = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl), 744 .clk_list = sdm845_ufs_phy_clk_l, 745 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 746 .vreg_list = qmp_phy_vreg_l, 747 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 748 .regs = sm8150_ufsphy_regs_layout, 749 }; 750 751 static const struct qmp_phy_cfg sm8450_ufsphy_cfg = { 752 .lanes = 2, 753 754 .serdes_tbl = sm8350_ufsphy_serdes_tbl, 755 .serdes_tbl_num = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl), 756 .tx_tbl = sm8350_ufsphy_tx_tbl, 757 .tx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_tx_tbl), 758 .rx_tbl = sm8350_ufsphy_rx_tbl, 759 .rx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_rx_tbl), 760 .pcs_tbl = sm8350_ufsphy_pcs_tbl, 761 .pcs_tbl_num = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl), 762 .clk_list = sm8450_ufs_phy_clk_l, 763 .num_clks = ARRAY_SIZE(sm8450_ufs_phy_clk_l), 764 .vreg_list = qmp_phy_vreg_l, 765 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 766 .regs = sm8150_ufsphy_regs_layout, 767 }; 768 769 static void qmp_ufs_configure_lane(void __iomem *base, 770 const struct qmp_phy_init_tbl tbl[], 771 int num, 772 u8 lane_mask) 773 { 774 int i; 775 const struct qmp_phy_init_tbl *t = tbl; 776 777 if (!t) 778 return; 779 780 for (i = 0; i < num; i++, t++) { 781 if (!(t->lane_mask & lane_mask)) 782 continue; 783 784 writel(t->val, base + t->offset); 785 } 786 } 787 788 static void qmp_ufs_configure(void __iomem *base, 789 const struct qmp_phy_init_tbl tbl[], 790 int num) 791 { 792 qmp_ufs_configure_lane(base, tbl, num, 0xff); 793 } 794 795 static int qmp_ufs_serdes_init(struct qmp_ufs *qmp) 796 { 797 const struct qmp_phy_cfg *cfg = qmp->cfg; 798 void __iomem *serdes = qmp->serdes; 799 const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl; 800 int serdes_tbl_num = cfg->serdes_tbl_num; 801 802 qmp_ufs_configure(serdes, serdes_tbl, serdes_tbl_num); 803 804 return 0; 805 } 806 807 static int qmp_ufs_com_init(struct qmp_ufs *qmp) 808 { 809 const struct qmp_phy_cfg *cfg = qmp->cfg; 810 void __iomem *pcs = qmp->pcs; 811 int ret; 812 813 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); 814 if (ret) { 815 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); 816 return ret; 817 } 818 819 ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks); 820 if (ret) 821 goto err_disable_regulators; 822 823 qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); 824 825 return 0; 826 827 err_disable_regulators: 828 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); 829 830 return ret; 831 } 832 833 static int qmp_ufs_com_exit(struct qmp_ufs *qmp) 834 { 835 const struct qmp_phy_cfg *cfg = qmp->cfg; 836 837 reset_control_assert(qmp->ufs_reset); 838 839 clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks); 840 841 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); 842 843 return 0; 844 } 845 846 static int qmp_ufs_init(struct phy *phy) 847 { 848 struct qmp_ufs *qmp = phy_get_drvdata(phy); 849 const struct qmp_phy_cfg *cfg = qmp->cfg; 850 int ret; 851 dev_vdbg(qmp->dev, "Initializing QMP phy\n"); 852 853 if (cfg->no_pcs_sw_reset) { 854 /* 855 * Get UFS reset, which is delayed until now to avoid a 856 * circular dependency where UFS needs its PHY, but the PHY 857 * needs this UFS reset. 858 */ 859 if (!qmp->ufs_reset) { 860 qmp->ufs_reset = 861 devm_reset_control_get_exclusive(qmp->dev, 862 "ufsphy"); 863 864 if (IS_ERR(qmp->ufs_reset)) { 865 ret = PTR_ERR(qmp->ufs_reset); 866 dev_err(qmp->dev, 867 "failed to get UFS reset: %d\n", 868 ret); 869 870 qmp->ufs_reset = NULL; 871 return ret; 872 } 873 } 874 875 ret = reset_control_assert(qmp->ufs_reset); 876 if (ret) 877 return ret; 878 } 879 880 ret = qmp_ufs_com_init(qmp); 881 if (ret) 882 return ret; 883 884 return 0; 885 } 886 887 static int qmp_ufs_power_on(struct phy *phy) 888 { 889 struct qmp_ufs *qmp = phy_get_drvdata(phy); 890 const struct qmp_phy_cfg *cfg = qmp->cfg; 891 void __iomem *tx = qmp->tx; 892 void __iomem *rx = qmp->rx; 893 void __iomem *pcs = qmp->pcs; 894 void __iomem *status; 895 unsigned int val; 896 int ret; 897 898 qmp_ufs_serdes_init(qmp); 899 900 /* Tx, Rx, and PCS configurations */ 901 qmp_ufs_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); 902 qmp_ufs_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); 903 904 if (cfg->lanes >= 2) { 905 qmp_ufs_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); 906 qmp_ufs_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); 907 } 908 909 qmp_ufs_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); 910 911 ret = reset_control_deassert(qmp->ufs_reset); 912 if (ret) 913 return ret; 914 915 /* Pull PHY out of reset state */ 916 if (!cfg->no_pcs_sw_reset) 917 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 918 919 /* start SerDes */ 920 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START); 921 922 status = pcs + cfg->regs[QPHY_PCS_READY_STATUS]; 923 ret = readl_poll_timeout(status, val, (val & PCS_READY), 200, 924 PHY_INIT_COMPLETE_TIMEOUT); 925 if (ret) { 926 dev_err(qmp->dev, "phy initialization timed-out\n"); 927 return ret; 928 } 929 930 return 0; 931 } 932 933 static int qmp_ufs_power_off(struct phy *phy) 934 { 935 struct qmp_ufs *qmp = phy_get_drvdata(phy); 936 const struct qmp_phy_cfg *cfg = qmp->cfg; 937 938 /* PHY reset */ 939 if (!cfg->no_pcs_sw_reset) 940 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 941 942 /* stop SerDes */ 943 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START); 944 945 /* Put PHY into POWER DOWN state: active low */ 946 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], 947 SW_PWRDN); 948 949 return 0; 950 } 951 952 static int qmp_ufs_exit(struct phy *phy) 953 { 954 struct qmp_ufs *qmp = phy_get_drvdata(phy); 955 956 qmp_ufs_com_exit(qmp); 957 958 return 0; 959 } 960 961 static int qmp_ufs_enable(struct phy *phy) 962 { 963 int ret; 964 965 ret = qmp_ufs_init(phy); 966 if (ret) 967 return ret; 968 969 ret = qmp_ufs_power_on(phy); 970 if (ret) 971 qmp_ufs_exit(phy); 972 973 return ret; 974 } 975 976 static int qmp_ufs_disable(struct phy *phy) 977 { 978 int ret; 979 980 ret = qmp_ufs_power_off(phy); 981 if (ret) 982 return ret; 983 return qmp_ufs_exit(phy); 984 } 985 986 static const struct phy_ops qcom_qmp_ufs_phy_ops = { 987 .power_on = qmp_ufs_enable, 988 .power_off = qmp_ufs_disable, 989 .owner = THIS_MODULE, 990 }; 991 992 static int qmp_ufs_vreg_init(struct qmp_ufs *qmp) 993 { 994 const struct qmp_phy_cfg *cfg = qmp->cfg; 995 struct device *dev = qmp->dev; 996 int num = cfg->num_vregs; 997 int i; 998 999 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); 1000 if (!qmp->vregs) 1001 return -ENOMEM; 1002 1003 for (i = 0; i < num; i++) 1004 qmp->vregs[i].supply = cfg->vreg_list[i]; 1005 1006 return devm_regulator_bulk_get(dev, num, qmp->vregs); 1007 } 1008 1009 static int qmp_ufs_clk_init(struct qmp_ufs *qmp) 1010 { 1011 const struct qmp_phy_cfg *cfg = qmp->cfg; 1012 struct device *dev = qmp->dev; 1013 int num = cfg->num_clks; 1014 int i; 1015 1016 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL); 1017 if (!qmp->clks) 1018 return -ENOMEM; 1019 1020 for (i = 0; i < num; i++) 1021 qmp->clks[i].id = cfg->clk_list[i]; 1022 1023 return devm_clk_bulk_get(dev, num, qmp->clks); 1024 } 1025 1026 static int qmp_ufs_parse_dt_legacy(struct qmp_ufs *qmp, struct device_node *np) 1027 { 1028 struct platform_device *pdev = to_platform_device(qmp->dev); 1029 const struct qmp_phy_cfg *cfg = qmp->cfg; 1030 struct device *dev = qmp->dev; 1031 1032 qmp->serdes = devm_platform_ioremap_resource(pdev, 0); 1033 if (IS_ERR(qmp->serdes)) 1034 return PTR_ERR(qmp->serdes); 1035 1036 /* 1037 * Get memory resources for the PHY: 1038 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. 1039 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5 1040 * For single lane PHYs: pcs_misc (optional) -> 3. 1041 */ 1042 qmp->tx = devm_of_iomap(dev, np, 0, NULL); 1043 if (IS_ERR(qmp->tx)) 1044 return PTR_ERR(qmp->tx); 1045 1046 qmp->rx = devm_of_iomap(dev, np, 1, NULL); 1047 if (IS_ERR(qmp->rx)) 1048 return PTR_ERR(qmp->rx); 1049 1050 qmp->pcs = devm_of_iomap(dev, np, 2, NULL); 1051 if (IS_ERR(qmp->pcs)) 1052 return PTR_ERR(qmp->pcs); 1053 1054 if (cfg->lanes >= 2) { 1055 qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); 1056 if (IS_ERR(qmp->tx2)) 1057 return PTR_ERR(qmp->tx2); 1058 1059 qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); 1060 if (IS_ERR(qmp->rx2)) 1061 return PTR_ERR(qmp->rx2); 1062 1063 qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); 1064 } else { 1065 qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL); 1066 } 1067 1068 if (IS_ERR(qmp->pcs_misc)) 1069 dev_vdbg(dev, "PHY pcs_misc-reg not used\n"); 1070 1071 return 0; 1072 } 1073 1074 static int qmp_ufs_parse_dt(struct qmp_ufs *qmp) 1075 { 1076 struct platform_device *pdev = to_platform_device(qmp->dev); 1077 const struct qmp_phy_cfg *cfg = qmp->cfg; 1078 const struct qmp_ufs_offsets *offs = cfg->offsets; 1079 void __iomem *base; 1080 1081 if (!offs) 1082 return -EINVAL; 1083 1084 base = devm_platform_ioremap_resource(pdev, 0); 1085 if (IS_ERR(base)) 1086 return PTR_ERR(base); 1087 1088 qmp->serdes = base + offs->serdes; 1089 qmp->pcs = base + offs->pcs; 1090 qmp->tx = base + offs->tx; 1091 qmp->rx = base + offs->rx; 1092 1093 if (cfg->lanes >= 2) { 1094 qmp->tx2 = base + offs->tx2; 1095 qmp->rx2 = base + offs->rx2; 1096 } 1097 1098 return 0; 1099 } 1100 1101 static int qmp_ufs_probe(struct platform_device *pdev) 1102 { 1103 struct device *dev = &pdev->dev; 1104 struct phy_provider *phy_provider; 1105 struct device_node *np; 1106 struct qmp_ufs *qmp; 1107 int ret; 1108 1109 qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL); 1110 if (!qmp) 1111 return -ENOMEM; 1112 1113 qmp->dev = dev; 1114 1115 qmp->cfg = of_device_get_match_data(dev); 1116 if (!qmp->cfg) 1117 return -EINVAL; 1118 1119 ret = qmp_ufs_clk_init(qmp); 1120 if (ret) 1121 return ret; 1122 1123 ret = qmp_ufs_vreg_init(qmp); 1124 if (ret) 1125 return ret; 1126 1127 /* Check for legacy binding with child node. */ 1128 np = of_get_next_available_child(dev->of_node, NULL); 1129 if (np) { 1130 ret = qmp_ufs_parse_dt_legacy(qmp, np); 1131 } else { 1132 np = of_node_get(dev->of_node); 1133 ret = qmp_ufs_parse_dt(qmp); 1134 } 1135 if (ret) 1136 goto err_node_put; 1137 1138 qmp->phy = devm_phy_create(dev, np, &qcom_qmp_ufs_phy_ops); 1139 if (IS_ERR(qmp->phy)) { 1140 ret = PTR_ERR(qmp->phy); 1141 dev_err(dev, "failed to create PHY: %d\n", ret); 1142 goto err_node_put; 1143 } 1144 1145 phy_set_drvdata(qmp->phy, qmp); 1146 1147 of_node_put(np); 1148 1149 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 1150 1151 return PTR_ERR_OR_ZERO(phy_provider); 1152 1153 err_node_put: 1154 of_node_put(np); 1155 return ret; 1156 } 1157 1158 static const struct of_device_id qmp_ufs_of_match_table[] = { 1159 { 1160 .compatible = "qcom,msm8996-qmp-ufs-phy", 1161 .data = &msm8996_ufs_cfg, 1162 }, { 1163 .compatible = "qcom,msm8998-qmp-ufs-phy", 1164 .data = &sdm845_ufsphy_cfg, 1165 }, { 1166 .compatible = "qcom,sc8180x-qmp-ufs-phy", 1167 .data = &sm8150_ufsphy_cfg, 1168 }, { 1169 .compatible = "qcom,sc8280xp-qmp-ufs-phy", 1170 .data = &sc8280xp_ufsphy_cfg, 1171 }, { 1172 .compatible = "qcom,sdm845-qmp-ufs-phy", 1173 .data = &sdm845_ufsphy_cfg, 1174 }, { 1175 .compatible = "qcom,sm6115-qmp-ufs-phy", 1176 .data = &sm6115_ufsphy_cfg, 1177 }, { 1178 .compatible = "qcom,sm6350-qmp-ufs-phy", 1179 .data = &sdm845_ufsphy_cfg, 1180 }, { 1181 .compatible = "qcom,sm8150-qmp-ufs-phy", 1182 .data = &sm8150_ufsphy_cfg, 1183 }, { 1184 .compatible = "qcom,sm8250-qmp-ufs-phy", 1185 .data = &sm8150_ufsphy_cfg, 1186 }, { 1187 .compatible = "qcom,sm8350-qmp-ufs-phy", 1188 .data = &sm8350_ufsphy_cfg, 1189 }, { 1190 .compatible = "qcom,sm8450-qmp-ufs-phy", 1191 .data = &sm8450_ufsphy_cfg, 1192 }, 1193 { }, 1194 }; 1195 MODULE_DEVICE_TABLE(of, qmp_ufs_of_match_table); 1196 1197 static struct platform_driver qmp_ufs_driver = { 1198 .probe = qmp_ufs_probe, 1199 .driver = { 1200 .name = "qcom-qmp-ufs-phy", 1201 .of_match_table = qmp_ufs_of_match_table, 1202 }, 1203 }; 1204 1205 module_platform_driver(qmp_ufs_driver); 1206 1207 MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>"); 1208 MODULE_DESCRIPTION("Qualcomm QMP UFS PHY driver"); 1209 MODULE_LICENSE("GPL v2"); 1210