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