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