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 <ufs/unipro.h> 24 #include "phy-qcom-qmp.h" 25 #include "phy-qcom-qmp-pcs-ufs-v2.h" 26 #include "phy-qcom-qmp-pcs-ufs-v3.h" 27 #include "phy-qcom-qmp-pcs-ufs-v4.h" 28 #include "phy-qcom-qmp-pcs-ufs-v5.h" 29 #include "phy-qcom-qmp-pcs-ufs-v6.h" 30 31 #include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h" 32 33 /* QPHY_SW_RESET bit */ 34 #define SW_RESET BIT(0) 35 /* QPHY_POWER_DOWN_CONTROL */ 36 #define SW_PWRDN BIT(0) 37 /* QPHY_START_CONTROL bits */ 38 #define SERDES_START BIT(0) 39 #define PCS_START BIT(1) 40 /* QPHY_PCS_READY_STATUS bit */ 41 #define PCS_READY BIT(0) 42 43 #define PHY_INIT_COMPLETE_TIMEOUT 10000 44 45 struct qmp_phy_init_tbl { 46 unsigned int offset; 47 unsigned int val; 48 /* 49 * mask of lanes for which this register is written 50 * for cases when second lane needs different values 51 */ 52 u8 lane_mask; 53 }; 54 55 #define QMP_PHY_INIT_CFG(o, v) \ 56 { \ 57 .offset = o, \ 58 .val = v, \ 59 .lane_mask = 0xff, \ 60 } 61 62 #define QMP_PHY_INIT_CFG_LANE(o, v, l) \ 63 { \ 64 .offset = o, \ 65 .val = v, \ 66 .lane_mask = l, \ 67 } 68 69 /* set of registers with offsets different per-PHY */ 70 enum qphy_reg_layout { 71 /* PCS registers */ 72 QPHY_SW_RESET, 73 QPHY_START_CTRL, 74 QPHY_PCS_READY_STATUS, 75 QPHY_PCS_POWER_DOWN_CONTROL, 76 /* Keep last to ensure regs_layout arrays are properly initialized */ 77 QPHY_LAYOUT_SIZE 78 }; 79 80 static const unsigned int ufsphy_v2_regs_layout[QPHY_LAYOUT_SIZE] = { 81 [QPHY_START_CTRL] = QPHY_V2_PCS_UFS_PHY_START, 82 [QPHY_PCS_READY_STATUS] = QPHY_V2_PCS_UFS_READY_STATUS, 83 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V2_PCS_UFS_POWER_DOWN_CONTROL, 84 }; 85 86 static const unsigned int ufsphy_v3_regs_layout[QPHY_LAYOUT_SIZE] = { 87 [QPHY_START_CTRL] = QPHY_V3_PCS_UFS_PHY_START, 88 [QPHY_PCS_READY_STATUS] = QPHY_V3_PCS_UFS_READY_STATUS, 89 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_UFS_POWER_DOWN_CONTROL, 90 }; 91 92 static const unsigned int ufsphy_v4_regs_layout[QPHY_LAYOUT_SIZE] = { 93 [QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START, 94 [QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS, 95 [QPHY_SW_RESET] = QPHY_V4_PCS_UFS_SW_RESET, 96 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL, 97 }; 98 99 static const unsigned int ufsphy_v5_regs_layout[QPHY_LAYOUT_SIZE] = { 100 [QPHY_START_CTRL] = QPHY_V5_PCS_UFS_PHY_START, 101 [QPHY_PCS_READY_STATUS] = QPHY_V5_PCS_UFS_READY_STATUS, 102 [QPHY_SW_RESET] = QPHY_V5_PCS_UFS_SW_RESET, 103 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V5_PCS_UFS_POWER_DOWN_CONTROL, 104 }; 105 106 static const unsigned int ufsphy_v6_regs_layout[QPHY_LAYOUT_SIZE] = { 107 [QPHY_START_CTRL] = QPHY_V6_PCS_UFS_PHY_START, 108 [QPHY_PCS_READY_STATUS] = QPHY_V6_PCS_UFS_READY_STATUS, 109 [QPHY_SW_RESET] = QPHY_V6_PCS_UFS_SW_RESET, 110 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL, 111 }; 112 113 static const struct qmp_phy_init_tbl msm8996_ufsphy_serdes[] = { 114 QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e), 115 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7), 116 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), 117 QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06), 118 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), 119 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a), 120 QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05), 121 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a), 122 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a), 123 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01), 124 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10), 125 QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20), 126 QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00), 127 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00), 128 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff), 129 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f), 130 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54), 131 QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05), 132 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82), 133 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), 134 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00), 135 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00), 136 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), 137 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), 138 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), 139 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80), 140 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 141 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28), 142 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02), 143 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff), 144 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c), 145 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), 146 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98), 147 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00), 148 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00), 149 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00), 150 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b), 151 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16), 152 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28), 153 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80), 154 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00), 155 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6), 156 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00), 157 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32), 158 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f), 159 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00), 160 }; 161 162 static const struct qmp_phy_init_tbl msm8996_ufsphy_tx[] = { 163 QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45), 164 QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02), 165 }; 166 167 static const struct qmp_phy_init_tbl msm8996_ufsphy_rx[] = { 168 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24), 169 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02), 170 QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00), 171 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18), 172 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B), 173 QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b), 174 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff), 175 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f), 176 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff), 177 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f), 178 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E), 179 }; 180 181 static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes[] = { 182 QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e), 183 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14), 184 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), 185 QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02), 186 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), 187 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a), 188 QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00), 189 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a), 190 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a), 191 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01), 192 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00), 193 QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20), 194 QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00), 195 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00), 196 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff), 197 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f), 198 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04), 199 QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05), 200 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82), 201 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), 202 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00), 203 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00), 204 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), 205 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), 206 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), 207 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80), 208 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 209 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28), 210 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02), 211 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff), 212 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c), 213 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), 214 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98), 215 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00), 216 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00), 217 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00), 218 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b), 219 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16), 220 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28), 221 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80), 222 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00), 223 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6), 224 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00), 225 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32), 226 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f), 227 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00), 228 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f), 229 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f), 230 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff), 231 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00), 232 }; 233 234 static const struct qmp_phy_init_tbl sm6115_ufsphy_hs_b_serdes[] = { 235 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44), 236 }; 237 238 static const struct qmp_phy_init_tbl sm6115_ufsphy_tx[] = { 239 QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45), 240 QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06), 241 }; 242 243 static const struct qmp_phy_init_tbl sm6115_ufsphy_rx[] = { 244 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24), 245 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F), 246 QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40), 247 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E), 248 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B), 249 QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B), 250 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF), 251 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F), 252 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF), 253 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F), 254 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D), 255 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04), 256 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04), 257 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04), 258 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B), 259 }; 260 261 static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs[] = { 262 QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_PWM_GEAR_BAND, 0x15), 263 QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SIGDET_CTRL2, 0x6d), 264 QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f), 265 QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), 266 QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28), 267 QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03), 268 QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_POST_EMP_LVL, 0x12), 269 QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f), 270 QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */ 271 }; 272 273 static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes[] = { 274 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02), 275 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04), 276 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a), 277 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), 278 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06), 279 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5), 280 QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20), 281 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), 282 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00), 283 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01), 284 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00), 285 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00), 286 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04), 287 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05), 288 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff), 289 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00), 290 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82), 291 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06), 292 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16), 293 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36), 294 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), 295 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 296 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda), 297 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01), 298 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff), 299 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c), 300 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98), 301 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06), 302 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16), 303 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36), 304 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f), 305 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00), 306 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1), 307 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00), 308 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32), 309 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f), 310 }; 311 312 static const struct qmp_phy_init_tbl sdm845_ufsphy_hs_b_serdes[] = { 313 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44), 314 }; 315 316 static const struct qmp_phy_init_tbl sdm845_ufsphy_tx[] = { 317 QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06), 318 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04), 319 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07), 320 }; 321 322 static const struct qmp_phy_init_tbl sdm845_ufsphy_rx[] = { 323 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24), 324 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f), 325 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), 326 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40), 327 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), 328 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b), 329 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), 330 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), 331 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b), 332 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04), 333 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04), 334 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04), 335 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b), 336 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81), 337 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), 338 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59), 339 }; 340 341 static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs[] = { 342 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e), 343 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a), 344 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), 345 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03), 346 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 347 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f), 348 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a), 349 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 350 }; 351 352 static const struct qmp_phy_init_tbl sm7150_ufsphy_rx[] = { 353 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24), 354 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f), 355 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), 356 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40), 357 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), 358 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b), 359 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), 360 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), 361 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b), 362 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04), 363 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04), 364 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04), 365 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5b), 366 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81), 367 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), 368 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59), 369 }; 370 371 static const struct qmp_phy_init_tbl sm7150_ufsphy_pcs[] = { 372 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6f), 373 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f), 374 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), 375 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03), 376 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 377 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f), 378 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff), 379 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 380 }; 381 382 static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes[] = { 383 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9), 384 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11), 385 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00), 386 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01), 387 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02), 388 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f), 389 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00), 390 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), 391 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82), 392 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06), 393 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16), 394 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36), 395 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff), 396 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c), 397 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac), 398 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e), 399 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98), 400 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06), 401 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16), 402 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36), 403 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32), 404 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f), 405 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd), 406 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23), 407 }; 408 409 static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_b_serdes[] = { 410 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06), 411 }; 412 413 static const struct qmp_phy_init_tbl sm8150_ufsphy_tx[] = { 414 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06), 415 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03), 416 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01), 417 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00), 418 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05), 419 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c), 420 }; 421 422 static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_g4_tx[] = { 423 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x75), 424 }; 425 426 static const struct qmp_phy_init_tbl sm8150_ufsphy_rx[] = { 427 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24), 428 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f), 429 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), 430 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18), 431 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a), 432 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b), 433 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1), 434 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), 435 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80), 436 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c), 437 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04), 438 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b), 439 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), 440 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), 441 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d), 442 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00), 443 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10), 444 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0), 445 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00), 446 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36), 447 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36), 448 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6), 449 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b), 450 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d), 451 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0), 452 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8), 453 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8), 454 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b), 455 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1), 456 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0), 457 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8), 458 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8), 459 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b), 460 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1), 461 }; 462 463 static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_g4_rx[] = { 464 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a), 465 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81), 466 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e), 467 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f), 468 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20), 469 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80), 470 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01), 471 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f), 472 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff), 473 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff), 474 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f), 475 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x6c), 476 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d), 477 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d), 478 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed), 479 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c), 480 }; 481 482 static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs[] = { 483 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d), 484 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a), 485 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), 486 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 487 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f), 488 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff), 489 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 490 }; 491 492 static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_g4_pcs[] = { 493 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x10), 494 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a), 495 }; 496 497 static const struct qmp_phy_init_tbl sm8250_ufsphy_hs_g4_tx[] = { 498 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xe5), 499 }; 500 501 static const struct qmp_phy_init_tbl sm8250_ufsphy_hs_g4_rx[] = { 502 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a), 503 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81), 504 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e), 505 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f), 506 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04), 507 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00), 508 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09), 509 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07), 510 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17), 511 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20), 512 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80), 513 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01), 514 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f), 515 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff), 516 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff), 517 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f), 518 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x2c), 519 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d), 520 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d), 521 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed), 522 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c), 523 }; 524 525 static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes[] = { 526 QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9), 527 QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11), 528 QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00), 529 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42), 530 QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02), 531 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f), 532 QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00), 533 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), 534 QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82), 535 QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14), 536 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18), 537 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18), 538 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff), 539 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19), 540 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac), 541 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e), 542 QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98), 543 QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14), 544 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18), 545 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18), 546 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65), 547 QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e), 548 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd), 549 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23), 550 }; 551 552 static const struct qmp_phy_init_tbl sm8350_ufsphy_hs_b_serdes[] = { 553 QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06), 554 }; 555 556 static const struct qmp_phy_init_tbl sm8350_ufsphy_tx[] = { 557 QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06), 558 QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03), 559 QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01), 560 QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00), 561 QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5), 562 QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f), 563 QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09), 564 QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09), 565 QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c), 566 }; 567 568 static const struct qmp_phy_init_tbl sm8350_ufsphy_rx[] = { 569 QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24), 570 QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f), 571 QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), 572 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18), 573 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a), 574 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a), 575 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1), 576 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), 577 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80), 578 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e), 579 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04), 580 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b), 581 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04), 582 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), 583 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), 584 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a), 585 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17), 586 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00), 587 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10), 588 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0), 589 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00), 590 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d), 591 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d), 592 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed), 593 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b), 594 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c), 595 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0), 596 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8), 597 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8), 598 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b), 599 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7), 600 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0), 601 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8), 602 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8), 603 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b), 604 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7), 605 QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c), 606 }; 607 608 static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs[] = { 609 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d), 610 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a), 611 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), 612 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 613 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f), 614 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff), 615 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e), 616 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 617 }; 618 619 static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_tx[] = { 620 QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xe5), 621 }; 622 623 static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_rx[] = { 624 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x81), 625 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x6f), 626 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00), 627 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a), 628 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a), 629 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x20), 630 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0x80), 631 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x01), 632 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbf), 633 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xbf), 634 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0x7f), 635 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x7f), 636 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x2d), 637 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x6d), 638 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x6d), 639 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xed), 640 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0x3c), 641 }; 642 643 static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_pcs[] = { 644 QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a), 645 }; 646 647 static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = { 648 QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9), 649 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16), 650 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11), 651 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), 652 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01), 653 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04), 654 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f), 655 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00), 656 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41), 657 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a), 658 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18), 659 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14), 660 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f), 661 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06), 662 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c), 663 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a), 664 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18), 665 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14), 666 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99), 667 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07), 668 }; 669 670 static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = { 671 QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05), 672 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07), 673 }; 674 675 static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = { 676 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c), 677 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f), 678 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e), 679 680 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2), 681 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2), 682 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a), 683 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60), 684 685 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e), 686 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60), 687 688 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e), 689 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e), 690 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36), 691 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02), 692 }; 693 694 static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = { 695 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69), 696 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f), 697 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 698 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b), 699 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 700 }; 701 702 struct qmp_ufs_offsets { 703 u16 serdes; 704 u16 pcs; 705 u16 tx; 706 u16 rx; 707 u16 tx2; 708 u16 rx2; 709 }; 710 711 struct qmp_phy_cfg_tbls { 712 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */ 713 const struct qmp_phy_init_tbl *serdes; 714 int serdes_num; 715 const struct qmp_phy_init_tbl *tx; 716 int tx_num; 717 const struct qmp_phy_init_tbl *rx; 718 int rx_num; 719 const struct qmp_phy_init_tbl *pcs; 720 int pcs_num; 721 }; 722 723 /* struct qmp_phy_cfg - per-PHY initialization config */ 724 struct qmp_phy_cfg { 725 int lanes; 726 727 const struct qmp_ufs_offsets *offsets; 728 729 /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */ 730 const struct qmp_phy_cfg_tbls tbls; 731 /* Additional sequence for HS Series B */ 732 const struct qmp_phy_cfg_tbls tbls_hs_b; 733 /* Additional sequence for HS G4 */ 734 const struct qmp_phy_cfg_tbls tbls_hs_g4; 735 736 /* clock ids to be requested */ 737 const char * const *clk_list; 738 int num_clks; 739 /* regulators to be requested */ 740 const char * const *vreg_list; 741 int num_vregs; 742 743 /* array of registers with different offsets */ 744 const unsigned int *regs; 745 746 /* true, if PCS block has no separate SW_RESET register */ 747 bool no_pcs_sw_reset; 748 }; 749 750 struct qmp_ufs { 751 struct device *dev; 752 753 const struct qmp_phy_cfg *cfg; 754 755 void __iomem *serdes; 756 void __iomem *pcs; 757 void __iomem *pcs_misc; 758 void __iomem *tx; 759 void __iomem *rx; 760 void __iomem *tx2; 761 void __iomem *rx2; 762 763 struct clk_bulk_data *clks; 764 struct regulator_bulk_data *vregs; 765 struct reset_control *ufs_reset; 766 767 struct phy *phy; 768 u32 mode; 769 u32 submode; 770 }; 771 772 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) 773 { 774 u32 reg; 775 776 reg = readl(base + offset); 777 reg |= val; 778 writel(reg, base + offset); 779 780 /* ensure that above write is through */ 781 readl(base + offset); 782 } 783 784 static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val) 785 { 786 u32 reg; 787 788 reg = readl(base + offset); 789 reg &= ~val; 790 writel(reg, base + offset); 791 792 /* ensure that above write is through */ 793 readl(base + offset); 794 } 795 796 /* list of clocks required by phy */ 797 static const char * const msm8996_ufs_phy_clk_l[] = { 798 "ref", 799 }; 800 801 /* the primary usb3 phy on sm8250 doesn't have a ref clock */ 802 static const char * const sm8450_ufs_phy_clk_l[] = { 803 "qref", "ref", "ref_aux", 804 }; 805 806 static const char * const sdm845_ufs_phy_clk_l[] = { 807 "ref", "ref_aux", 808 }; 809 810 /* list of regulators */ 811 static const char * const qmp_phy_vreg_l[] = { 812 "vdda-phy", "vdda-pll", 813 }; 814 815 static const struct qmp_ufs_offsets qmp_ufs_offsets = { 816 .serdes = 0, 817 .pcs = 0xc00, 818 .tx = 0x400, 819 .rx = 0x600, 820 .tx2 = 0x800, 821 .rx2 = 0xa00, 822 }; 823 824 static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = { 825 .serdes = 0, 826 .pcs = 0x0400, 827 .tx = 0x1000, 828 .rx = 0x1200, 829 .tx2 = 0x1800, 830 .rx2 = 0x1a00, 831 }; 832 833 static const struct qmp_phy_cfg msm8996_ufsphy_cfg = { 834 .lanes = 1, 835 836 .tbls = { 837 .serdes = msm8996_ufsphy_serdes, 838 .serdes_num = ARRAY_SIZE(msm8996_ufsphy_serdes), 839 .tx = msm8996_ufsphy_tx, 840 .tx_num = ARRAY_SIZE(msm8996_ufsphy_tx), 841 .rx = msm8996_ufsphy_rx, 842 .rx_num = ARRAY_SIZE(msm8996_ufsphy_rx), 843 }, 844 845 .clk_list = msm8996_ufs_phy_clk_l, 846 .num_clks = ARRAY_SIZE(msm8996_ufs_phy_clk_l), 847 848 .vreg_list = qmp_phy_vreg_l, 849 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 850 851 .regs = ufsphy_v2_regs_layout, 852 853 .no_pcs_sw_reset = true, 854 }; 855 856 static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = { 857 .lanes = 2, 858 859 .offsets = &qmp_ufs_offsets, 860 861 .tbls = { 862 .serdes = sm8350_ufsphy_serdes, 863 .serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes), 864 .tx = sm8350_ufsphy_tx, 865 .tx_num = ARRAY_SIZE(sm8350_ufsphy_tx), 866 .rx = sm8350_ufsphy_rx, 867 .rx_num = ARRAY_SIZE(sm8350_ufsphy_rx), 868 .pcs = sm8350_ufsphy_pcs, 869 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs), 870 }, 871 .tbls_hs_b = { 872 .serdes = sm8350_ufsphy_hs_b_serdes, 873 .serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes), 874 }, 875 .tbls_hs_g4 = { 876 .tx = sm8350_ufsphy_g4_tx, 877 .tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx), 878 .rx = sm8350_ufsphy_g4_rx, 879 .rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx), 880 .pcs = sm8350_ufsphy_g4_pcs, 881 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 882 }, 883 .clk_list = sm8450_ufs_phy_clk_l, 884 .num_clks = ARRAY_SIZE(sm8450_ufs_phy_clk_l), 885 .vreg_list = qmp_phy_vreg_l, 886 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 887 .regs = ufsphy_v5_regs_layout, 888 }; 889 890 static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = { 891 .lanes = 2, 892 893 .offsets = &qmp_ufs_offsets, 894 895 .tbls = { 896 .serdes = sm8350_ufsphy_serdes, 897 .serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes), 898 .tx = sm8350_ufsphy_tx, 899 .tx_num = ARRAY_SIZE(sm8350_ufsphy_tx), 900 .rx = sm8350_ufsphy_rx, 901 .rx_num = ARRAY_SIZE(sm8350_ufsphy_rx), 902 .pcs = sm8350_ufsphy_pcs, 903 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs), 904 }, 905 .tbls_hs_b = { 906 .serdes = sm8350_ufsphy_hs_b_serdes, 907 .serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes), 908 }, 909 .tbls_hs_g4 = { 910 .tx = sm8350_ufsphy_g4_tx, 911 .tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx), 912 .rx = sm8350_ufsphy_g4_rx, 913 .rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx), 914 .pcs = sm8350_ufsphy_g4_pcs, 915 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 916 }, 917 .clk_list = sdm845_ufs_phy_clk_l, 918 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 919 .vreg_list = qmp_phy_vreg_l, 920 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 921 .regs = ufsphy_v5_regs_layout, 922 }; 923 924 static const struct qmp_phy_cfg sdm845_ufsphy_cfg = { 925 .lanes = 2, 926 927 .tbls = { 928 .serdes = sdm845_ufsphy_serdes, 929 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_serdes), 930 .tx = sdm845_ufsphy_tx, 931 .tx_num = ARRAY_SIZE(sdm845_ufsphy_tx), 932 .rx = sdm845_ufsphy_rx, 933 .rx_num = ARRAY_SIZE(sdm845_ufsphy_rx), 934 .pcs = sdm845_ufsphy_pcs, 935 .pcs_num = ARRAY_SIZE(sdm845_ufsphy_pcs), 936 }, 937 .tbls_hs_b = { 938 .serdes = sdm845_ufsphy_hs_b_serdes, 939 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes), 940 }, 941 .clk_list = sdm845_ufs_phy_clk_l, 942 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 943 .vreg_list = qmp_phy_vreg_l, 944 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 945 .regs = ufsphy_v3_regs_layout, 946 947 .no_pcs_sw_reset = true, 948 }; 949 950 static const struct qmp_phy_cfg sm6115_ufsphy_cfg = { 951 .lanes = 1, 952 953 .offsets = &qmp_ufs_offsets, 954 955 .tbls = { 956 .serdes = sm6115_ufsphy_serdes, 957 .serdes_num = ARRAY_SIZE(sm6115_ufsphy_serdes), 958 .tx = sm6115_ufsphy_tx, 959 .tx_num = ARRAY_SIZE(sm6115_ufsphy_tx), 960 .rx = sm6115_ufsphy_rx, 961 .rx_num = ARRAY_SIZE(sm6115_ufsphy_rx), 962 .pcs = sm6115_ufsphy_pcs, 963 .pcs_num = ARRAY_SIZE(sm6115_ufsphy_pcs), 964 }, 965 .tbls_hs_b = { 966 .serdes = sm6115_ufsphy_hs_b_serdes, 967 .serdes_num = ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes), 968 }, 969 .clk_list = sdm845_ufs_phy_clk_l, 970 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 971 .vreg_list = qmp_phy_vreg_l, 972 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 973 .regs = ufsphy_v2_regs_layout, 974 975 .no_pcs_sw_reset = true, 976 }; 977 978 static const struct qmp_phy_cfg sm7150_ufsphy_cfg = { 979 .lanes = 1, 980 981 .offsets = &qmp_ufs_offsets, 982 983 .tbls = { 984 .serdes = sdm845_ufsphy_serdes, 985 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_serdes), 986 .tx = sdm845_ufsphy_tx, 987 .tx_num = ARRAY_SIZE(sdm845_ufsphy_tx), 988 .rx = sm7150_ufsphy_rx, 989 .rx_num = ARRAY_SIZE(sm7150_ufsphy_rx), 990 .pcs = sm7150_ufsphy_pcs, 991 .pcs_num = ARRAY_SIZE(sm7150_ufsphy_pcs), 992 }, 993 .tbls_hs_b = { 994 .serdes = sdm845_ufsphy_hs_b_serdes, 995 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes), 996 }, 997 .clk_list = sdm845_ufs_phy_clk_l, 998 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 999 .vreg_list = qmp_phy_vreg_l, 1000 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1001 .regs = ufsphy_v3_regs_layout, 1002 1003 .no_pcs_sw_reset = true, 1004 }; 1005 1006 static const struct qmp_phy_cfg sm8150_ufsphy_cfg = { 1007 .lanes = 2, 1008 1009 .tbls = { 1010 .serdes = sm8150_ufsphy_serdes, 1011 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes), 1012 .tx = sm8150_ufsphy_tx, 1013 .tx_num = ARRAY_SIZE(sm8150_ufsphy_tx), 1014 .rx = sm8150_ufsphy_rx, 1015 .rx_num = ARRAY_SIZE(sm8150_ufsphy_rx), 1016 .pcs = sm8150_ufsphy_pcs, 1017 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs), 1018 }, 1019 .tbls_hs_b = { 1020 .serdes = sm8150_ufsphy_hs_b_serdes, 1021 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes), 1022 }, 1023 .tbls_hs_g4 = { 1024 .tx = sm8150_ufsphy_hs_g4_tx, 1025 .tx_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_tx), 1026 .rx = sm8150_ufsphy_hs_g4_rx, 1027 .rx_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_rx), 1028 .pcs = sm8150_ufsphy_hs_g4_pcs, 1029 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), 1030 }, 1031 .clk_list = sdm845_ufs_phy_clk_l, 1032 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 1033 .vreg_list = qmp_phy_vreg_l, 1034 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1035 .regs = ufsphy_v4_regs_layout, 1036 }; 1037 1038 static const struct qmp_phy_cfg sm8250_ufsphy_cfg = { 1039 .lanes = 2, 1040 1041 .tbls = { 1042 .serdes = sm8150_ufsphy_serdes, 1043 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes), 1044 .tx = sm8150_ufsphy_tx, 1045 .tx_num = ARRAY_SIZE(sm8150_ufsphy_tx), 1046 .rx = sm8150_ufsphy_rx, 1047 .rx_num = ARRAY_SIZE(sm8150_ufsphy_rx), 1048 .pcs = sm8150_ufsphy_pcs, 1049 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs), 1050 }, 1051 .tbls_hs_b = { 1052 .serdes = sm8150_ufsphy_hs_b_serdes, 1053 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes), 1054 }, 1055 .tbls_hs_g4 = { 1056 .tx = sm8250_ufsphy_hs_g4_tx, 1057 .tx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx), 1058 .rx = sm8250_ufsphy_hs_g4_rx, 1059 .rx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_rx), 1060 .pcs = sm8150_ufsphy_hs_g4_pcs, 1061 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), 1062 }, 1063 .clk_list = sdm845_ufs_phy_clk_l, 1064 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 1065 .vreg_list = qmp_phy_vreg_l, 1066 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1067 .regs = ufsphy_v4_regs_layout, 1068 }; 1069 1070 static const struct qmp_phy_cfg sm8350_ufsphy_cfg = { 1071 .lanes = 2, 1072 1073 .tbls = { 1074 .serdes = sm8350_ufsphy_serdes, 1075 .serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes), 1076 .tx = sm8350_ufsphy_tx, 1077 .tx_num = ARRAY_SIZE(sm8350_ufsphy_tx), 1078 .rx = sm8350_ufsphy_rx, 1079 .rx_num = ARRAY_SIZE(sm8350_ufsphy_rx), 1080 .pcs = sm8350_ufsphy_pcs, 1081 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs), 1082 }, 1083 .tbls_hs_b = { 1084 .serdes = sm8350_ufsphy_hs_b_serdes, 1085 .serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes), 1086 }, 1087 .tbls_hs_g4 = { 1088 .tx = sm8350_ufsphy_g4_tx, 1089 .tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx), 1090 .rx = sm8350_ufsphy_g4_rx, 1091 .rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx), 1092 .pcs = sm8350_ufsphy_g4_pcs, 1093 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1094 }, 1095 .clk_list = sdm845_ufs_phy_clk_l, 1096 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 1097 .vreg_list = qmp_phy_vreg_l, 1098 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1099 .regs = ufsphy_v5_regs_layout, 1100 }; 1101 1102 static const struct qmp_phy_cfg sm8450_ufsphy_cfg = { 1103 .lanes = 2, 1104 1105 .tbls = { 1106 .serdes = sm8350_ufsphy_serdes, 1107 .serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes), 1108 .tx = sm8350_ufsphy_tx, 1109 .tx_num = ARRAY_SIZE(sm8350_ufsphy_tx), 1110 .rx = sm8350_ufsphy_rx, 1111 .rx_num = ARRAY_SIZE(sm8350_ufsphy_rx), 1112 .pcs = sm8350_ufsphy_pcs, 1113 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs), 1114 }, 1115 .tbls_hs_b = { 1116 .serdes = sm8350_ufsphy_hs_b_serdes, 1117 .serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes), 1118 }, 1119 .tbls_hs_g4 = { 1120 .tx = sm8350_ufsphy_g4_tx, 1121 .tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx), 1122 .rx = sm8350_ufsphy_g4_rx, 1123 .rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx), 1124 .pcs = sm8350_ufsphy_g4_pcs, 1125 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1126 }, 1127 .clk_list = sm8450_ufs_phy_clk_l, 1128 .num_clks = ARRAY_SIZE(sm8450_ufs_phy_clk_l), 1129 .vreg_list = qmp_phy_vreg_l, 1130 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1131 .regs = ufsphy_v5_regs_layout, 1132 }; 1133 1134 static const struct qmp_phy_cfg sm8550_ufsphy_cfg = { 1135 .lanes = 2, 1136 1137 .offsets = &qmp_ufs_offsets_v6, 1138 1139 .tbls = { 1140 .serdes = sm8550_ufsphy_serdes, 1141 .serdes_num = ARRAY_SIZE(sm8550_ufsphy_serdes), 1142 .tx = sm8550_ufsphy_tx, 1143 .tx_num = ARRAY_SIZE(sm8550_ufsphy_tx), 1144 .rx = sm8550_ufsphy_rx, 1145 .rx_num = ARRAY_SIZE(sm8550_ufsphy_rx), 1146 .pcs = sm8550_ufsphy_pcs, 1147 .pcs_num = ARRAY_SIZE(sm8550_ufsphy_pcs), 1148 }, 1149 .clk_list = sdm845_ufs_phy_clk_l, 1150 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 1151 .vreg_list = qmp_phy_vreg_l, 1152 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1153 .regs = ufsphy_v6_regs_layout, 1154 }; 1155 1156 static void qmp_ufs_configure_lane(void __iomem *base, 1157 const struct qmp_phy_init_tbl tbl[], 1158 int num, 1159 u8 lane_mask) 1160 { 1161 int i; 1162 const struct qmp_phy_init_tbl *t = tbl; 1163 1164 if (!t) 1165 return; 1166 1167 for (i = 0; i < num; i++, t++) { 1168 if (!(t->lane_mask & lane_mask)) 1169 continue; 1170 1171 writel(t->val, base + t->offset); 1172 } 1173 } 1174 1175 static void qmp_ufs_configure(void __iomem *base, 1176 const struct qmp_phy_init_tbl tbl[], 1177 int num) 1178 { 1179 qmp_ufs_configure_lane(base, tbl, num, 0xff); 1180 } 1181 1182 static void qmp_ufs_serdes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls) 1183 { 1184 void __iomem *serdes = qmp->serdes; 1185 1186 qmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num); 1187 } 1188 1189 static void qmp_ufs_lanes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls) 1190 { 1191 const struct qmp_phy_cfg *cfg = qmp->cfg; 1192 void __iomem *tx = qmp->tx; 1193 void __iomem *rx = qmp->rx; 1194 1195 qmp_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1); 1196 qmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1); 1197 1198 if (cfg->lanes >= 2) { 1199 qmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2); 1200 qmp_ufs_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2); 1201 } 1202 } 1203 1204 static void qmp_ufs_pcs_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls) 1205 { 1206 void __iomem *pcs = qmp->pcs; 1207 1208 qmp_ufs_configure(pcs, tbls->pcs, tbls->pcs_num); 1209 } 1210 1211 static void qmp_ufs_init_registers(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg) 1212 { 1213 qmp_ufs_serdes_init(qmp, &cfg->tbls); 1214 if (qmp->mode == PHY_MODE_UFS_HS_B) 1215 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b); 1216 qmp_ufs_lanes_init(qmp, &cfg->tbls); 1217 if (qmp->submode == UFS_HS_G4) 1218 qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g4); 1219 qmp_ufs_pcs_init(qmp, &cfg->tbls); 1220 if (qmp->submode == UFS_HS_G4) 1221 qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g4); 1222 } 1223 1224 static int qmp_ufs_com_init(struct qmp_ufs *qmp) 1225 { 1226 const struct qmp_phy_cfg *cfg = qmp->cfg; 1227 void __iomem *pcs = qmp->pcs; 1228 int ret; 1229 1230 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); 1231 if (ret) { 1232 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); 1233 return ret; 1234 } 1235 1236 ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks); 1237 if (ret) 1238 goto err_disable_regulators; 1239 1240 qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); 1241 1242 return 0; 1243 1244 err_disable_regulators: 1245 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); 1246 1247 return ret; 1248 } 1249 1250 static int qmp_ufs_com_exit(struct qmp_ufs *qmp) 1251 { 1252 const struct qmp_phy_cfg *cfg = qmp->cfg; 1253 1254 reset_control_assert(qmp->ufs_reset); 1255 1256 clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks); 1257 1258 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); 1259 1260 return 0; 1261 } 1262 1263 static int qmp_ufs_init(struct phy *phy) 1264 { 1265 struct qmp_ufs *qmp = phy_get_drvdata(phy); 1266 const struct qmp_phy_cfg *cfg = qmp->cfg; 1267 int ret; 1268 dev_vdbg(qmp->dev, "Initializing QMP phy\n"); 1269 1270 if (cfg->no_pcs_sw_reset) { 1271 /* 1272 * Get UFS reset, which is delayed until now to avoid a 1273 * circular dependency where UFS needs its PHY, but the PHY 1274 * needs this UFS reset. 1275 */ 1276 if (!qmp->ufs_reset) { 1277 qmp->ufs_reset = 1278 devm_reset_control_get_exclusive(qmp->dev, 1279 "ufsphy"); 1280 1281 if (IS_ERR(qmp->ufs_reset)) { 1282 ret = PTR_ERR(qmp->ufs_reset); 1283 dev_err(qmp->dev, 1284 "failed to get UFS reset: %d\n", 1285 ret); 1286 1287 qmp->ufs_reset = NULL; 1288 return ret; 1289 } 1290 } 1291 1292 ret = reset_control_assert(qmp->ufs_reset); 1293 if (ret) 1294 return ret; 1295 } 1296 1297 ret = qmp_ufs_com_init(qmp); 1298 if (ret) 1299 return ret; 1300 1301 return 0; 1302 } 1303 1304 static int qmp_ufs_power_on(struct phy *phy) 1305 { 1306 struct qmp_ufs *qmp = phy_get_drvdata(phy); 1307 const struct qmp_phy_cfg *cfg = qmp->cfg; 1308 void __iomem *pcs = qmp->pcs; 1309 void __iomem *status; 1310 unsigned int val; 1311 int ret; 1312 1313 qmp_ufs_init_registers(qmp, cfg); 1314 1315 ret = reset_control_deassert(qmp->ufs_reset); 1316 if (ret) 1317 return ret; 1318 1319 /* Pull PHY out of reset state */ 1320 if (!cfg->no_pcs_sw_reset) 1321 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 1322 1323 /* start SerDes */ 1324 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START); 1325 1326 status = pcs + cfg->regs[QPHY_PCS_READY_STATUS]; 1327 ret = readl_poll_timeout(status, val, (val & PCS_READY), 200, 1328 PHY_INIT_COMPLETE_TIMEOUT); 1329 if (ret) { 1330 dev_err(qmp->dev, "phy initialization timed-out\n"); 1331 return ret; 1332 } 1333 1334 return 0; 1335 } 1336 1337 static int qmp_ufs_power_off(struct phy *phy) 1338 { 1339 struct qmp_ufs *qmp = phy_get_drvdata(phy); 1340 const struct qmp_phy_cfg *cfg = qmp->cfg; 1341 1342 /* PHY reset */ 1343 if (!cfg->no_pcs_sw_reset) 1344 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 1345 1346 /* stop SerDes */ 1347 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START); 1348 1349 /* Put PHY into POWER DOWN state: active low */ 1350 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], 1351 SW_PWRDN); 1352 1353 return 0; 1354 } 1355 1356 static int qmp_ufs_exit(struct phy *phy) 1357 { 1358 struct qmp_ufs *qmp = phy_get_drvdata(phy); 1359 1360 qmp_ufs_com_exit(qmp); 1361 1362 return 0; 1363 } 1364 1365 static int qmp_ufs_enable(struct phy *phy) 1366 { 1367 int ret; 1368 1369 ret = qmp_ufs_init(phy); 1370 if (ret) 1371 return ret; 1372 1373 ret = qmp_ufs_power_on(phy); 1374 if (ret) 1375 qmp_ufs_exit(phy); 1376 1377 return ret; 1378 } 1379 1380 static int qmp_ufs_disable(struct phy *phy) 1381 { 1382 int ret; 1383 1384 ret = qmp_ufs_power_off(phy); 1385 if (ret) 1386 return ret; 1387 return qmp_ufs_exit(phy); 1388 } 1389 1390 static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode) 1391 { 1392 struct qmp_ufs *qmp = phy_get_drvdata(phy); 1393 1394 qmp->mode = mode; 1395 qmp->submode = submode; 1396 1397 return 0; 1398 } 1399 1400 static const struct phy_ops qcom_qmp_ufs_phy_ops = { 1401 .power_on = qmp_ufs_enable, 1402 .power_off = qmp_ufs_disable, 1403 .set_mode = qmp_ufs_set_mode, 1404 .owner = THIS_MODULE, 1405 }; 1406 1407 static int qmp_ufs_vreg_init(struct qmp_ufs *qmp) 1408 { 1409 const struct qmp_phy_cfg *cfg = qmp->cfg; 1410 struct device *dev = qmp->dev; 1411 int num = cfg->num_vregs; 1412 int i; 1413 1414 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); 1415 if (!qmp->vregs) 1416 return -ENOMEM; 1417 1418 for (i = 0; i < num; i++) 1419 qmp->vregs[i].supply = cfg->vreg_list[i]; 1420 1421 return devm_regulator_bulk_get(dev, num, qmp->vregs); 1422 } 1423 1424 static int qmp_ufs_clk_init(struct qmp_ufs *qmp) 1425 { 1426 const struct qmp_phy_cfg *cfg = qmp->cfg; 1427 struct device *dev = qmp->dev; 1428 int num = cfg->num_clks; 1429 int i; 1430 1431 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL); 1432 if (!qmp->clks) 1433 return -ENOMEM; 1434 1435 for (i = 0; i < num; i++) 1436 qmp->clks[i].id = cfg->clk_list[i]; 1437 1438 return devm_clk_bulk_get(dev, num, qmp->clks); 1439 } 1440 1441 static void qmp_ufs_clk_release_provider(void *res) 1442 { 1443 of_clk_del_provider(res); 1444 } 1445 1446 #define UFS_SYMBOL_CLOCKS 3 1447 1448 static int qmp_ufs_register_clocks(struct qmp_ufs *qmp, struct device_node *np) 1449 { 1450 struct clk_hw_onecell_data *clk_data; 1451 struct clk_hw *hw; 1452 char name[64]; 1453 int ret; 1454 1455 clk_data = devm_kzalloc(qmp->dev, 1456 struct_size(clk_data, hws, UFS_SYMBOL_CLOCKS), 1457 GFP_KERNEL); 1458 if (!clk_data) 1459 return -ENOMEM; 1460 1461 clk_data->num = UFS_SYMBOL_CLOCKS; 1462 1463 snprintf(name, sizeof(name), "%s::rx_symbol_0", dev_name(qmp->dev)); 1464 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); 1465 if (IS_ERR(hw)) 1466 return PTR_ERR(hw); 1467 1468 clk_data->hws[0] = hw; 1469 1470 snprintf(name, sizeof(name), "%s::rx_symbol_1", dev_name(qmp->dev)); 1471 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); 1472 if (IS_ERR(hw)) 1473 return PTR_ERR(hw); 1474 1475 clk_data->hws[1] = hw; 1476 1477 snprintf(name, sizeof(name), "%s::tx_symbol_0", dev_name(qmp->dev)); 1478 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); 1479 if (IS_ERR(hw)) 1480 return PTR_ERR(hw); 1481 1482 clk_data->hws[2] = hw; 1483 1484 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); 1485 if (ret) 1486 return ret; 1487 1488 /* 1489 * Roll a devm action because the clock provider can be a child node. 1490 */ 1491 return devm_add_action_or_reset(qmp->dev, qmp_ufs_clk_release_provider, np); 1492 } 1493 1494 static int qmp_ufs_parse_dt_legacy(struct qmp_ufs *qmp, struct device_node *np) 1495 { 1496 struct platform_device *pdev = to_platform_device(qmp->dev); 1497 const struct qmp_phy_cfg *cfg = qmp->cfg; 1498 struct device *dev = qmp->dev; 1499 1500 qmp->serdes = devm_platform_ioremap_resource(pdev, 0); 1501 if (IS_ERR(qmp->serdes)) 1502 return PTR_ERR(qmp->serdes); 1503 1504 /* 1505 * Get memory resources for the PHY: 1506 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. 1507 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5 1508 * For single lane PHYs: pcs_misc (optional) -> 3. 1509 */ 1510 qmp->tx = devm_of_iomap(dev, np, 0, NULL); 1511 if (IS_ERR(qmp->tx)) 1512 return PTR_ERR(qmp->tx); 1513 1514 qmp->rx = devm_of_iomap(dev, np, 1, NULL); 1515 if (IS_ERR(qmp->rx)) 1516 return PTR_ERR(qmp->rx); 1517 1518 qmp->pcs = devm_of_iomap(dev, np, 2, NULL); 1519 if (IS_ERR(qmp->pcs)) 1520 return PTR_ERR(qmp->pcs); 1521 1522 if (cfg->lanes >= 2) { 1523 qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); 1524 if (IS_ERR(qmp->tx2)) 1525 return PTR_ERR(qmp->tx2); 1526 1527 qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); 1528 if (IS_ERR(qmp->rx2)) 1529 return PTR_ERR(qmp->rx2); 1530 1531 qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); 1532 } else { 1533 qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL); 1534 } 1535 1536 if (IS_ERR(qmp->pcs_misc)) 1537 dev_vdbg(dev, "PHY pcs_misc-reg not used\n"); 1538 1539 return 0; 1540 } 1541 1542 static int qmp_ufs_parse_dt(struct qmp_ufs *qmp) 1543 { 1544 struct platform_device *pdev = to_platform_device(qmp->dev); 1545 const struct qmp_phy_cfg *cfg = qmp->cfg; 1546 const struct qmp_ufs_offsets *offs = cfg->offsets; 1547 void __iomem *base; 1548 1549 if (!offs) 1550 return -EINVAL; 1551 1552 base = devm_platform_ioremap_resource(pdev, 0); 1553 if (IS_ERR(base)) 1554 return PTR_ERR(base); 1555 1556 qmp->serdes = base + offs->serdes; 1557 qmp->pcs = base + offs->pcs; 1558 qmp->tx = base + offs->tx; 1559 qmp->rx = base + offs->rx; 1560 1561 if (cfg->lanes >= 2) { 1562 qmp->tx2 = base + offs->tx2; 1563 qmp->rx2 = base + offs->rx2; 1564 } 1565 1566 return 0; 1567 } 1568 1569 static int qmp_ufs_probe(struct platform_device *pdev) 1570 { 1571 struct device *dev = &pdev->dev; 1572 struct phy_provider *phy_provider; 1573 struct device_node *np; 1574 struct qmp_ufs *qmp; 1575 int ret; 1576 1577 qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL); 1578 if (!qmp) 1579 return -ENOMEM; 1580 1581 qmp->dev = dev; 1582 1583 qmp->cfg = of_device_get_match_data(dev); 1584 if (!qmp->cfg) 1585 return -EINVAL; 1586 1587 ret = qmp_ufs_clk_init(qmp); 1588 if (ret) 1589 return ret; 1590 1591 ret = qmp_ufs_vreg_init(qmp); 1592 if (ret) 1593 return ret; 1594 1595 /* Check for legacy binding with child node. */ 1596 np = of_get_next_available_child(dev->of_node, NULL); 1597 if (np) { 1598 ret = qmp_ufs_parse_dt_legacy(qmp, np); 1599 } else { 1600 np = of_node_get(dev->of_node); 1601 ret = qmp_ufs_parse_dt(qmp); 1602 } 1603 if (ret) 1604 goto err_node_put; 1605 1606 ret = qmp_ufs_register_clocks(qmp, np); 1607 if (ret) 1608 goto err_node_put; 1609 1610 qmp->phy = devm_phy_create(dev, np, &qcom_qmp_ufs_phy_ops); 1611 if (IS_ERR(qmp->phy)) { 1612 ret = PTR_ERR(qmp->phy); 1613 dev_err(dev, "failed to create PHY: %d\n", ret); 1614 goto err_node_put; 1615 } 1616 1617 phy_set_drvdata(qmp->phy, qmp); 1618 1619 of_node_put(np); 1620 1621 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 1622 1623 return PTR_ERR_OR_ZERO(phy_provider); 1624 1625 err_node_put: 1626 of_node_put(np); 1627 return ret; 1628 } 1629 1630 static const struct of_device_id qmp_ufs_of_match_table[] = { 1631 { 1632 .compatible = "qcom,msm8996-qmp-ufs-phy", 1633 .data = &msm8996_ufsphy_cfg, 1634 }, { 1635 .compatible = "qcom,msm8998-qmp-ufs-phy", 1636 .data = &sdm845_ufsphy_cfg, 1637 }, { 1638 .compatible = "qcom,sa8775p-qmp-ufs-phy", 1639 .data = &sa8775p_ufsphy_cfg, 1640 }, { 1641 .compatible = "qcom,sc8180x-qmp-ufs-phy", 1642 .data = &sm8150_ufsphy_cfg, 1643 }, { 1644 .compatible = "qcom,sc8280xp-qmp-ufs-phy", 1645 .data = &sc8280xp_ufsphy_cfg, 1646 }, { 1647 .compatible = "qcom,sdm845-qmp-ufs-phy", 1648 .data = &sdm845_ufsphy_cfg, 1649 }, { 1650 .compatible = "qcom,sm6115-qmp-ufs-phy", 1651 .data = &sm6115_ufsphy_cfg, 1652 }, { 1653 .compatible = "qcom,sm6125-qmp-ufs-phy", 1654 .data = &sm6115_ufsphy_cfg, 1655 }, { 1656 .compatible = "qcom,sm6350-qmp-ufs-phy", 1657 .data = &sdm845_ufsphy_cfg, 1658 }, { 1659 .compatible = "qcom,sm7150-qmp-ufs-phy", 1660 .data = &sm7150_ufsphy_cfg, 1661 }, { 1662 .compatible = "qcom,sm8150-qmp-ufs-phy", 1663 .data = &sm8150_ufsphy_cfg, 1664 }, { 1665 .compatible = "qcom,sm8250-qmp-ufs-phy", 1666 .data = &sm8250_ufsphy_cfg, 1667 }, { 1668 .compatible = "qcom,sm8350-qmp-ufs-phy", 1669 .data = &sm8350_ufsphy_cfg, 1670 }, { 1671 .compatible = "qcom,sm8450-qmp-ufs-phy", 1672 .data = &sm8450_ufsphy_cfg, 1673 }, { 1674 .compatible = "qcom,sm8550-qmp-ufs-phy", 1675 .data = &sm8550_ufsphy_cfg, 1676 }, 1677 { }, 1678 }; 1679 MODULE_DEVICE_TABLE(of, qmp_ufs_of_match_table); 1680 1681 static struct platform_driver qmp_ufs_driver = { 1682 .probe = qmp_ufs_probe, 1683 .driver = { 1684 .name = "qcom-qmp-ufs-phy", 1685 .of_match_table = qmp_ufs_of_match_table, 1686 }, 1687 }; 1688 1689 module_platform_driver(qmp_ufs_driver); 1690 1691 MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>"); 1692 MODULE_DESCRIPTION("Qualcomm QMP UFS PHY driver"); 1693 MODULE_LICENSE("GPL v2"); 1694