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