0001
0002
0003
0004
0005
0006 #include <linux/clk.h>
0007 #include <linux/clk-provider.h>
0008 #include <linux/delay.h>
0009 #include <linux/err.h>
0010 #include <linux/io.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/of_device.h>
0016 #include <linux/of_address.h>
0017 #include <linux/phy/phy.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/regulator/consumer.h>
0020 #include <linux/reset.h>
0021 #include <linux/slab.h>
0022
0023 #include <dt-bindings/phy/phy.h>
0024
0025 #include "phy-qcom-qmp.h"
0026
0027
0028 #define SW_RESET BIT(0)
0029
0030 #define SW_PWRDN BIT(0)
0031 #define REFCLK_DRV_DSBL BIT(1)
0032
0033 #define SERDES_START BIT(0)
0034 #define PCS_START BIT(1)
0035 #define PLL_READY_GATE_EN BIT(3)
0036
0037 #define PHYSTATUS BIT(6)
0038 #define PHYSTATUS_4_20 BIT(7)
0039
0040 #define PCS_READY BIT(0)
0041
0042
0043
0044 #define SW_DPPHY_RESET BIT(0)
0045
0046 #define SW_DPPHY_RESET_MUX BIT(1)
0047
0048 #define SW_USB3PHY_RESET BIT(2)
0049
0050 #define SW_USB3PHY_RESET_MUX BIT(3)
0051
0052
0053 #define USB3_MODE BIT(0)
0054 #define DP_MODE BIT(1)
0055
0056
0057 #define ARCVR_DTCT_EN BIT(0)
0058 #define ALFPS_DTCT_EN BIT(1)
0059 #define ARCVR_DTCT_EVENT_SEL BIT(4)
0060
0061
0062 #define IRQ_CLEAR BIT(0)
0063
0064
0065 #define RCVR_DETECT BIT(0)
0066
0067
0068 #define CLAMP_EN BIT(0)
0069
0070 #define PHY_INIT_COMPLETE_TIMEOUT 10000
0071 #define POWER_DOWN_DELAY_US_MIN 10
0072 #define POWER_DOWN_DELAY_US_MAX 11
0073
0074 #define MAX_PROP_NAME 32
0075
0076
0077 #define QMP_PHY_LEGACY_LANE_STRIDE 0x400
0078
0079 struct qmp_phy_init_tbl {
0080 unsigned int offset;
0081 unsigned int val;
0082
0083
0084
0085
0086 bool in_layout;
0087
0088
0089
0090
0091 u8 lane_mask;
0092 };
0093
0094 #define QMP_PHY_INIT_CFG(o, v) \
0095 { \
0096 .offset = o, \
0097 .val = v, \
0098 .lane_mask = 0xff, \
0099 }
0100
0101 #define QMP_PHY_INIT_CFG_L(o, v) \
0102 { \
0103 .offset = o, \
0104 .val = v, \
0105 .in_layout = true, \
0106 .lane_mask = 0xff, \
0107 }
0108
0109 #define QMP_PHY_INIT_CFG_LANE(o, v, l) \
0110 { \
0111 .offset = o, \
0112 .val = v, \
0113 .lane_mask = l, \
0114 }
0115
0116
0117 enum qphy_reg_layout {
0118
0119 QPHY_COM_SW_RESET,
0120 QPHY_COM_POWER_DOWN_CONTROL,
0121 QPHY_COM_START_CONTROL,
0122 QPHY_COM_PCS_READY_STATUS,
0123
0124 QPHY_SW_RESET,
0125 QPHY_START_CTRL,
0126 QPHY_PCS_READY_STATUS,
0127 QPHY_PCS_STATUS,
0128 QPHY_PCS_AUTONOMOUS_MODE_CTRL,
0129 QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
0130 QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
0131 QPHY_PCS_POWER_DOWN_CONTROL,
0132
0133 QPHY_PCS_MISC_TYPEC_CTRL,
0134
0135 QPHY_LAYOUT_SIZE
0136 };
0137
0138 static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
0139 [QPHY_SW_RESET] = 0x00,
0140 [QPHY_START_CTRL] = 0x08,
0141 [QPHY_PCS_STATUS] = 0x174,
0142 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
0143 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0dc,
0144 [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
0145 };
0146
0147 static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
0148 [QPHY_SW_RESET] = 0x00,
0149 [QPHY_START_CTRL] = 0x44,
0150 [QPHY_PCS_STATUS] = 0x14,
0151 [QPHY_PCS_POWER_DOWN_CONTROL] = 0x40,
0152
0153
0154 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x008,
0155 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x014,
0156 };
0157
0158 static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
0159 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
0160 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
0161 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
0162 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
0163 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
0164 QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
0165 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x16),
0166 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
0167 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
0168 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
0169 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
0170 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
0171 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
0172 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
0173 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
0174 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
0175 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
0176 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
0177 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
0178 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
0179 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
0180 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
0181 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
0182 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
0183 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
0184 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
0185 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
0186 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
0187 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
0188 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
0189 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
0190 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
0191 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
0192 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
0193 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
0194 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
0195 };
0196
0197 static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
0198 QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
0199 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
0200 QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
0201 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
0202 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
0203 };
0204
0205 static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl[] = {
0206 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
0207 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x37),
0208 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
0209 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x0e),
0210 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
0211 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
0212 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x02),
0213 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x00),
0214 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
0215 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
0216 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
0217 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
0218 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
0219 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
0220 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
0221 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x3f),
0222 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x1f),
0223 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
0224 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
0225 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
0226 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
0227 };
0228
0229 static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_rbr[] = {
0230 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x0c),
0231 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
0232 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
0233 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
0234 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x6f),
0235 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x08),
0236 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
0237 };
0238
0239 static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr[] = {
0240 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x04),
0241 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
0242 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
0243 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
0244 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x0f),
0245 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0e),
0246 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
0247 };
0248
0249 static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr2[] = {
0250 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
0251 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x8c),
0252 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x00),
0253 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x0a),
0254 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x1f),
0255 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x1c),
0256 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
0257 };
0258
0259 static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr3[] = {
0260 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x03),
0261 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
0262 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
0263 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
0264 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x2f),
0265 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x2a),
0266 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x08),
0267 };
0268
0269 static const struct qmp_phy_init_tbl qmp_v3_dp_tx_tbl[] = {
0270 QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a),
0271 QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40),
0272 QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
0273 QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d),
0274 QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f),
0275 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03),
0276 QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03),
0277 QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
0278 QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00),
0279 QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4),
0280 QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_POL_INV, 0x0a),
0281 QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x38),
0282 QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x20),
0283 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
0284 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
0285 };
0286
0287 static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
0288 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
0289 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
0290 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
0291 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
0292 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
0293 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
0294 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
0295 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
0296 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
0297 };
0298
0299 static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
0300
0301 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
0302 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
0303 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
0304 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
0305 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
0306
0307
0308 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
0309 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
0310 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
0311 QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
0312
0313 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
0314 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
0315 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
0316 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
0317 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
0318 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
0319 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
0320 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
0321 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
0322 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
0323 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
0324 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
0325 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
0326 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
0327 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
0328 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
0329 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
0330 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
0331 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
0332
0333 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
0334 QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
0335 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
0336 QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
0337 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
0338 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
0339 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
0340 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
0341 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
0342 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
0343 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
0344 };
0345
0346 static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = {
0347 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
0348 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
0349 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
0350 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
0351 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
0352 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
0353 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
0354 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
0355 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
0356 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
0357 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
0358 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
0359 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
0360 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
0361 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
0362 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
0363 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
0364 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
0365 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
0366 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
0367 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
0368 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
0369 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
0370 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
0371 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
0372 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
0373 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
0374 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
0375 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
0376 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
0377 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
0378 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
0379 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
0380 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
0381 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
0382 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
0383 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
0384 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
0385 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
0386 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
0387 };
0388
0389 static const struct qmp_phy_init_tbl sm8150_usb3_tx_tbl[] = {
0390 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x00),
0391 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x00),
0392 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
0393 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
0394 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
0395 };
0396
0397 static const struct qmp_phy_init_tbl sm8150_usb3_rx_tbl[] = {
0398 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
0399 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
0400 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
0401 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
0402 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
0403 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
0404 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
0405 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
0406 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
0407 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
0408 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
0409 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0e),
0410 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
0411 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
0412 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
0413 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
0414 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
0415 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
0416 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
0417 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
0418 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
0419 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xbf),
0420 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x3f),
0421 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
0422 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x94),
0423 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
0424 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
0425 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
0426 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
0427 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
0428 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
0429 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
0430 QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
0431 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
0432 QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
0433 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
0434 };
0435
0436 static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = {
0437
0438 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
0439 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
0440 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
0441
0442 QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
0443 QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
0444 QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
0445 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
0446 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
0447 QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
0448 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
0449 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
0450 };
0451
0452 static const struct qmp_phy_init_tbl sm8150_usb3_pcs_usb_tbl[] = {
0453 QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
0454 QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
0455 };
0456
0457 static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl[] = {
0458 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x60),
0459 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x60),
0460 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
0461 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
0462 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
0463 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
0464 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x40, 1),
0465 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x54, 2),
0466 };
0467
0468 static const struct qmp_phy_init_tbl sm8250_usb3_rx_tbl[] = {
0469 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
0470 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
0471 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
0472 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
0473 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
0474 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
0475 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
0476 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
0477 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
0478 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
0479 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
0480 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
0481 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
0482 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
0483 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
0484 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
0485 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
0486 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
0487 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
0488 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
0489 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff, 1),
0490 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f, 2),
0491 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f, 1),
0492 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff, 2),
0493 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x7f),
0494 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
0495 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x97),
0496 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
0497 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
0498 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
0499 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
0500 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
0501 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
0502 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
0503 QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
0504 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
0505 QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
0506 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
0507 };
0508
0509 static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {
0510 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
0511 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
0512 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
0513 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
0514 QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
0515 QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
0516 QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
0517 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
0518 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
0519 QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
0520 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
0521 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
0522 };
0523
0524 static const struct qmp_phy_init_tbl sm8250_usb3_pcs_usb_tbl[] = {
0525 QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
0526 QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
0527 };
0528
0529 static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl[] = {
0530 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
0531 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x3b),
0532 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02),
0533 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x0c),
0534 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06),
0535 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x30),
0536 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
0537 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
0538 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
0539 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
0540 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x02),
0541 QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
0542 QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
0543 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x00),
0544 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x00),
0545 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0a),
0546 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x0a),
0547 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_CTRL, 0x00),
0548 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x17),
0549 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x1f),
0550 };
0551
0552 static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_rbr[] = {
0553 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x05),
0554 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
0555 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
0556 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
0557 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x6f),
0558 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x08),
0559 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
0560 };
0561
0562 static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr[] = {
0563 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x03),
0564 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
0565 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
0566 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
0567 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0f),
0568 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0e),
0569 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
0570 };
0571
0572 static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr2[] = {
0573 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
0574 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x8c),
0575 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x00),
0576 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x0a),
0577 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x1f),
0578 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1c),
0579 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
0580 };
0581
0582 static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr3[] = {
0583 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x00),
0584 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
0585 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
0586 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
0587 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x2f),
0588 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x2a),
0589 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
0590 };
0591
0592 static const struct qmp_phy_init_tbl qmp_v4_dp_tx_tbl[] = {
0593 QMP_PHY_INIT_CFG(QSERDES_V4_TX_VMODE_CTRL1, 0x40),
0594 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
0595 QMP_PHY_INIT_CFG(QSERDES_V4_TX_INTERFACE_SELECT, 0x3b),
0596 QMP_PHY_INIT_CFG(QSERDES_V4_TX_CLKBUF_ENABLE, 0x0f),
0597 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RESET_TSYNC_EN, 0x03),
0598 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0f),
0599 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
0600 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_INTERFACE_MODE, 0x00),
0601 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
0602 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x11),
0603 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_BAND, 0x4),
0604 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_POL_INV, 0x0a),
0605 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_DRV_LVL, 0x2a),
0606 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_EMP_POST1_LVL, 0x20),
0607 };
0608
0609
0610
0611 struct qmp_regulator_data {
0612 const char *name;
0613 unsigned int enable_load;
0614 };
0615
0616 static struct qmp_regulator_data qmp_phy_vreg_l[] = {
0617 { .name = "vdda-phy", .enable_load = 21800 },
0618 { .name = "vdda-pll", .enable_load = 36000 },
0619 };
0620
0621 struct qmp_phy;
0622
0623
0624 struct qmp_phy_cfg {
0625
0626 unsigned int type;
0627
0628 int nlanes;
0629
0630
0631 const struct qmp_phy_init_tbl *serdes_tbl;
0632 int serdes_tbl_num;
0633 const struct qmp_phy_init_tbl *tx_tbl;
0634 int tx_tbl_num;
0635 const struct qmp_phy_init_tbl *rx_tbl;
0636 int rx_tbl_num;
0637 const struct qmp_phy_init_tbl *pcs_tbl;
0638 int pcs_tbl_num;
0639 const struct qmp_phy_init_tbl *pcs_usb_tbl;
0640 int pcs_usb_tbl_num;
0641
0642
0643 const struct qmp_phy_init_tbl *serdes_tbl_rbr;
0644 int serdes_tbl_rbr_num;
0645 const struct qmp_phy_init_tbl *serdes_tbl_hbr;
0646 int serdes_tbl_hbr_num;
0647 const struct qmp_phy_init_tbl *serdes_tbl_hbr2;
0648 int serdes_tbl_hbr2_num;
0649 const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
0650 int serdes_tbl_hbr3_num;
0651
0652
0653 int (*configure_dp_phy)(struct qmp_phy *qphy);
0654 void (*configure_dp_tx)(struct qmp_phy *qphy);
0655 int (*calibrate_dp_phy)(struct qmp_phy *qphy);
0656 void (*dp_aux_init)(struct qmp_phy *qphy);
0657
0658
0659 const char * const *clk_list;
0660 int num_clks;
0661
0662 const char * const *reset_list;
0663 int num_resets;
0664
0665 const struct qmp_regulator_data *vreg_list;
0666 int num_vregs;
0667
0668
0669 const unsigned int *regs;
0670
0671 unsigned int start_ctrl;
0672 unsigned int pwrdn_ctrl;
0673
0674 unsigned int phy_status;
0675
0676
0677 bool has_pwrdn_delay;
0678
0679 int pwrdn_delay_min;
0680 int pwrdn_delay_max;
0681
0682
0683 bool has_phy_dp_com_ctrl;
0684
0685 bool is_dual_lane_phy;
0686
0687
0688 unsigned int pcs_usb_offset;
0689
0690 };
0691
0692 struct qmp_phy_combo_cfg {
0693 const struct qmp_phy_cfg *usb_cfg;
0694 const struct qmp_phy_cfg *dp_cfg;
0695 };
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719 struct qmp_phy {
0720 struct phy *phy;
0721 const struct qmp_phy_cfg *cfg;
0722 void __iomem *serdes;
0723 void __iomem *tx;
0724 void __iomem *rx;
0725 void __iomem *pcs;
0726 void __iomem *tx2;
0727 void __iomem *rx2;
0728 void __iomem *pcs_misc;
0729 void __iomem *pcs_usb;
0730 struct clk *pipe_clk;
0731 unsigned int index;
0732 struct qcom_qmp *qmp;
0733 struct reset_control *lane_rst;
0734 enum phy_mode mode;
0735 unsigned int dp_aux_cfg;
0736 struct phy_configure_opts_dp dp_opts;
0737 struct qmp_phy_dp_clks *dp_clks;
0738 };
0739
0740 struct qmp_phy_dp_clks {
0741 struct qmp_phy *qphy;
0742 struct clk_hw dp_link_hw;
0743 struct clk_hw dp_pixel_hw;
0744 };
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761 struct qcom_qmp {
0762 struct device *dev;
0763 void __iomem *dp_com;
0764
0765 struct clk_bulk_data *clks;
0766 struct reset_control_bulk_data *resets;
0767 struct regulator_bulk_data *vregs;
0768
0769 struct qmp_phy **phys;
0770
0771 struct mutex phy_mutex;
0772 int init_count;
0773
0774 struct reset_control *ufs_reset;
0775 };
0776
0777 static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy);
0778 static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy);
0779 static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy);
0780 static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy);
0781
0782 static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy);
0783 static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy);
0784 static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy);
0785 static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy);
0786
0787 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
0788 {
0789 u32 reg;
0790
0791 reg = readl(base + offset);
0792 reg |= val;
0793 writel(reg, base + offset);
0794
0795
0796 readl(base + offset);
0797 }
0798
0799 static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
0800 {
0801 u32 reg;
0802
0803 reg = readl(base + offset);
0804 reg &= ~val;
0805 writel(reg, base + offset);
0806
0807
0808 readl(base + offset);
0809 }
0810
0811
0812 static const char * const qmp_v3_phy_clk_l[] = {
0813 "aux", "cfg_ahb", "ref", "com_aux",
0814 };
0815
0816 static const char * const qmp_v4_phy_clk_l[] = {
0817 "aux", "ref_clk_src", "ref", "com_aux",
0818 };
0819
0820
0821 static const char * const qmp_v4_sm8250_usbphy_clk_l[] = {
0822 "aux", "ref_clk_src", "com_aux"
0823 };
0824
0825
0826 static const char * const msm8996_usb3phy_reset_l[] = {
0827 "phy", "common",
0828 };
0829
0830 static const char * const sc7180_usb3phy_reset_l[] = {
0831 "phy",
0832 };
0833
0834 static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
0835 .type = PHY_TYPE_USB3,
0836 .nlanes = 1,
0837
0838 .serdes_tbl = qmp_v3_usb3_serdes_tbl,
0839 .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
0840 .tx_tbl = qmp_v3_usb3_tx_tbl,
0841 .tx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
0842 .rx_tbl = qmp_v3_usb3_rx_tbl,
0843 .rx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
0844 .pcs_tbl = qmp_v3_usb3_pcs_tbl,
0845 .pcs_tbl_num = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
0846 .clk_list = qmp_v3_phy_clk_l,
0847 .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l),
0848 .reset_list = sc7180_usb3phy_reset_l,
0849 .num_resets = ARRAY_SIZE(sc7180_usb3phy_reset_l),
0850 .vreg_list = qmp_phy_vreg_l,
0851 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
0852 .regs = qmp_v3_usb3phy_regs_layout,
0853
0854 .start_ctrl = SERDES_START | PCS_START,
0855 .pwrdn_ctrl = SW_PWRDN,
0856 .phy_status = PHYSTATUS,
0857
0858 .has_pwrdn_delay = true,
0859 .pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
0860 .pwrdn_delay_max = POWER_DOWN_DELAY_US_MAX,
0861
0862 .has_phy_dp_com_ctrl = true,
0863 .is_dual_lane_phy = true,
0864 };
0865
0866 static const struct qmp_phy_cfg sc7180_dpphy_cfg = {
0867 .type = PHY_TYPE_DP,
0868 .nlanes = 1,
0869
0870 .serdes_tbl = qmp_v3_dp_serdes_tbl,
0871 .serdes_tbl_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl),
0872 .tx_tbl = qmp_v3_dp_tx_tbl,
0873 .tx_tbl_num = ARRAY_SIZE(qmp_v3_dp_tx_tbl),
0874
0875 .serdes_tbl_rbr = qmp_v3_dp_serdes_tbl_rbr,
0876 .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_rbr),
0877 .serdes_tbl_hbr = qmp_v3_dp_serdes_tbl_hbr,
0878 .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr),
0879 .serdes_tbl_hbr2 = qmp_v3_dp_serdes_tbl_hbr2,
0880 .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr2),
0881 .serdes_tbl_hbr3 = qmp_v3_dp_serdes_tbl_hbr3,
0882 .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr3),
0883
0884 .clk_list = qmp_v3_phy_clk_l,
0885 .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l),
0886 .reset_list = sc7180_usb3phy_reset_l,
0887 .num_resets = ARRAY_SIZE(sc7180_usb3phy_reset_l),
0888 .vreg_list = qmp_phy_vreg_l,
0889 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
0890 .regs = qmp_v3_usb3phy_regs_layout,
0891
0892 .has_phy_dp_com_ctrl = true,
0893 .is_dual_lane_phy = true,
0894
0895 .dp_aux_init = qcom_qmp_v3_phy_dp_aux_init,
0896 .configure_dp_tx = qcom_qmp_v3_phy_configure_dp_tx,
0897 .configure_dp_phy = qcom_qmp_v3_phy_configure_dp_phy,
0898 .calibrate_dp_phy = qcom_qmp_v3_dp_phy_calibrate,
0899 };
0900
0901 static const struct qmp_phy_combo_cfg sc7180_usb3dpphy_cfg = {
0902 .usb_cfg = &sc7180_usb3phy_cfg,
0903 .dp_cfg = &sc7180_dpphy_cfg,
0904 };
0905
0906 static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
0907 .type = PHY_TYPE_USB3,
0908 .nlanes = 1,
0909
0910 .serdes_tbl = sm8150_usb3_serdes_tbl,
0911 .serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
0912 .tx_tbl = sm8150_usb3_tx_tbl,
0913 .tx_tbl_num = ARRAY_SIZE(sm8150_usb3_tx_tbl),
0914 .rx_tbl = sm8150_usb3_rx_tbl,
0915 .rx_tbl_num = ARRAY_SIZE(sm8150_usb3_rx_tbl),
0916 .pcs_tbl = sm8150_usb3_pcs_tbl,
0917 .pcs_tbl_num = ARRAY_SIZE(sm8150_usb3_pcs_tbl),
0918 .pcs_usb_tbl = sm8150_usb3_pcs_usb_tbl,
0919 .pcs_usb_tbl_num = ARRAY_SIZE(sm8150_usb3_pcs_usb_tbl),
0920 .clk_list = qmp_v4_phy_clk_l,
0921 .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
0922 .reset_list = msm8996_usb3phy_reset_l,
0923 .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
0924 .vreg_list = qmp_phy_vreg_l,
0925 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
0926 .regs = qmp_v4_usb3phy_regs_layout,
0927 .pcs_usb_offset = 0x300,
0928
0929 .start_ctrl = SERDES_START | PCS_START,
0930 .pwrdn_ctrl = SW_PWRDN,
0931 .phy_status = PHYSTATUS,
0932
0933
0934 .has_pwrdn_delay = true,
0935 .pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
0936 .pwrdn_delay_max = POWER_DOWN_DELAY_US_MAX,
0937
0938 .has_phy_dp_com_ctrl = true,
0939 .is_dual_lane_phy = true,
0940 };
0941
0942 static const struct qmp_phy_cfg sc8180x_dpphy_cfg = {
0943 .type = PHY_TYPE_DP,
0944 .nlanes = 1,
0945
0946 .serdes_tbl = qmp_v4_dp_serdes_tbl,
0947 .serdes_tbl_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
0948 .tx_tbl = qmp_v4_dp_tx_tbl,
0949 .tx_tbl_num = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
0950
0951 .serdes_tbl_rbr = qmp_v4_dp_serdes_tbl_rbr,
0952 .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
0953 .serdes_tbl_hbr = qmp_v4_dp_serdes_tbl_hbr,
0954 .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
0955 .serdes_tbl_hbr2 = qmp_v4_dp_serdes_tbl_hbr2,
0956 .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
0957 .serdes_tbl_hbr3 = qmp_v4_dp_serdes_tbl_hbr3,
0958 .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
0959
0960 .clk_list = qmp_v3_phy_clk_l,
0961 .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l),
0962 .reset_list = sc7180_usb3phy_reset_l,
0963 .num_resets = ARRAY_SIZE(sc7180_usb3phy_reset_l),
0964 .vreg_list = qmp_phy_vreg_l,
0965 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
0966 .regs = qmp_v3_usb3phy_regs_layout,
0967
0968 .has_phy_dp_com_ctrl = true,
0969 .is_dual_lane_phy = true,
0970
0971 .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
0972 .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
0973 .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
0974 .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
0975 };
0976
0977 static const struct qmp_phy_combo_cfg sc8180x_usb3dpphy_cfg = {
0978 .usb_cfg = &sm8150_usb3phy_cfg,
0979 .dp_cfg = &sc8180x_dpphy_cfg,
0980 };
0981
0982 static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
0983 .type = PHY_TYPE_USB3,
0984 .nlanes = 1,
0985
0986 .serdes_tbl = sm8150_usb3_serdes_tbl,
0987 .serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
0988 .tx_tbl = sm8250_usb3_tx_tbl,
0989 .tx_tbl_num = ARRAY_SIZE(sm8250_usb3_tx_tbl),
0990 .rx_tbl = sm8250_usb3_rx_tbl,
0991 .rx_tbl_num = ARRAY_SIZE(sm8250_usb3_rx_tbl),
0992 .pcs_tbl = sm8250_usb3_pcs_tbl,
0993 .pcs_tbl_num = ARRAY_SIZE(sm8250_usb3_pcs_tbl),
0994 .pcs_usb_tbl = sm8250_usb3_pcs_usb_tbl,
0995 .pcs_usb_tbl_num = ARRAY_SIZE(sm8250_usb3_pcs_usb_tbl),
0996 .clk_list = qmp_v4_sm8250_usbphy_clk_l,
0997 .num_clks = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
0998 .reset_list = msm8996_usb3phy_reset_l,
0999 .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
1000 .vreg_list = qmp_phy_vreg_l,
1001 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
1002 .regs = qmp_v4_usb3phy_regs_layout,
1003 .pcs_usb_offset = 0x300,
1004
1005 .start_ctrl = SERDES_START | PCS_START,
1006 .pwrdn_ctrl = SW_PWRDN,
1007 .phy_status = PHYSTATUS,
1008
1009 .has_pwrdn_delay = true,
1010 .pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
1011 .pwrdn_delay_max = POWER_DOWN_DELAY_US_MAX,
1012
1013 .has_phy_dp_com_ctrl = true,
1014 .is_dual_lane_phy = true,
1015 };
1016
1017 static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
1018 .type = PHY_TYPE_DP,
1019 .nlanes = 1,
1020
1021 .serdes_tbl = qmp_v4_dp_serdes_tbl,
1022 .serdes_tbl_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
1023 .tx_tbl = qmp_v4_dp_tx_tbl,
1024 .tx_tbl_num = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
1025
1026 .serdes_tbl_rbr = qmp_v4_dp_serdes_tbl_rbr,
1027 .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
1028 .serdes_tbl_hbr = qmp_v4_dp_serdes_tbl_hbr,
1029 .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
1030 .serdes_tbl_hbr2 = qmp_v4_dp_serdes_tbl_hbr2,
1031 .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
1032 .serdes_tbl_hbr3 = qmp_v4_dp_serdes_tbl_hbr3,
1033 .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
1034
1035 .clk_list = qmp_v4_phy_clk_l,
1036 .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
1037 .reset_list = msm8996_usb3phy_reset_l,
1038 .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
1039 .vreg_list = qmp_phy_vreg_l,
1040 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
1041 .regs = qmp_v4_usb3phy_regs_layout,
1042
1043 .has_phy_dp_com_ctrl = true,
1044 .is_dual_lane_phy = true,
1045
1046 .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
1047 .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
1048 .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
1049 .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
1050 };
1051
1052 static const struct qmp_phy_combo_cfg sm8250_usb3dpphy_cfg = {
1053 .usb_cfg = &sm8250_usb3phy_cfg,
1054 .dp_cfg = &sm8250_dpphy_cfg,
1055 };
1056
1057 static void qcom_qmp_phy_combo_configure_lane(void __iomem *base,
1058 const unsigned int *regs,
1059 const struct qmp_phy_init_tbl tbl[],
1060 int num,
1061 u8 lane_mask)
1062 {
1063 int i;
1064 const struct qmp_phy_init_tbl *t = tbl;
1065
1066 if (!t)
1067 return;
1068
1069 for (i = 0; i < num; i++, t++) {
1070 if (!(t->lane_mask & lane_mask))
1071 continue;
1072
1073 if (t->in_layout)
1074 writel(t->val, base + regs[t->offset]);
1075 else
1076 writel(t->val, base + t->offset);
1077 }
1078 }
1079
1080 static void qcom_qmp_phy_combo_configure(void __iomem *base,
1081 const unsigned int *regs,
1082 const struct qmp_phy_init_tbl tbl[],
1083 int num)
1084 {
1085 qcom_qmp_phy_combo_configure_lane(base, regs, tbl, num, 0xff);
1086 }
1087
1088 static int qcom_qmp_phy_combo_serdes_init(struct qmp_phy *qphy)
1089 {
1090 const struct qmp_phy_cfg *cfg = qphy->cfg;
1091 void __iomem *serdes = qphy->serdes;
1092 const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
1093 const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
1094 int serdes_tbl_num = cfg->serdes_tbl_num;
1095
1096 qcom_qmp_phy_combo_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
1097
1098 if (cfg->type == PHY_TYPE_DP) {
1099 switch (dp_opts->link_rate) {
1100 case 1620:
1101 qcom_qmp_phy_combo_configure(serdes, cfg->regs,
1102 cfg->serdes_tbl_rbr,
1103 cfg->serdes_tbl_rbr_num);
1104 break;
1105 case 2700:
1106 qcom_qmp_phy_combo_configure(serdes, cfg->regs,
1107 cfg->serdes_tbl_hbr,
1108 cfg->serdes_tbl_hbr_num);
1109 break;
1110 case 5400:
1111 qcom_qmp_phy_combo_configure(serdes, cfg->regs,
1112 cfg->serdes_tbl_hbr2,
1113 cfg->serdes_tbl_hbr2_num);
1114 break;
1115 case 8100:
1116 qcom_qmp_phy_combo_configure(serdes, cfg->regs,
1117 cfg->serdes_tbl_hbr3,
1118 cfg->serdes_tbl_hbr3_num);
1119 break;
1120 default:
1121
1122 return -EINVAL;
1123 }
1124 }
1125
1126 return 0;
1127 }
1128
1129 static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
1130 {
1131 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
1132 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
1133 qphy->pcs + QSERDES_DP_PHY_PD_CTL);
1134
1135
1136 writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
1137 QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
1138 qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
1139
1140 writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
1141
1142 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
1143 DP_PHY_PD_CTL_LANE_0_1_PWRDN |
1144 DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
1145 DP_PHY_PD_CTL_DP_CLAMP_EN,
1146 qphy->pcs + QSERDES_DP_PHY_PD_CTL);
1147
1148 writel(QSERDES_V3_COM_BIAS_EN |
1149 QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
1150 QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
1151 QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
1152 qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
1153
1154 writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
1155 writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
1156 writel(0x24, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
1157 writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
1158 writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
1159 writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
1160 writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
1161 writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
1162 writel(0xbb, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
1163 writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
1164 qphy->dp_aux_cfg = 0;
1165
1166 writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
1167 PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
1168 PHY_AUX_REQ_ERR_MASK,
1169 qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
1170 }
1171
1172 static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = {
1173 { 0x00, 0x0c, 0x15, 0x1a },
1174 { 0x02, 0x0e, 0x16, 0xff },
1175 { 0x02, 0x11, 0xff, 0xff },
1176 { 0x04, 0xff, 0xff, 0xff }
1177 };
1178
1179 static const u8 qmp_dp_v3_voltage_swing_hbr3_hbr2[4][4] = {
1180 { 0x02, 0x12, 0x16, 0x1a },
1181 { 0x09, 0x19, 0x1f, 0xff },
1182 { 0x10, 0x1f, 0xff, 0xff },
1183 { 0x1f, 0xff, 0xff, 0xff }
1184 };
1185
1186 static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
1187 { 0x00, 0x0c, 0x14, 0x19 },
1188 { 0x00, 0x0b, 0x12, 0xff },
1189 { 0x00, 0x0b, 0xff, 0xff },
1190 { 0x04, 0xff, 0xff, 0xff }
1191 };
1192
1193 static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
1194 { 0x08, 0x0f, 0x16, 0x1f },
1195 { 0x11, 0x1e, 0x1f, 0xff },
1196 { 0x19, 0x1f, 0xff, 0xff },
1197 { 0x1f, 0xff, 0xff, 0xff }
1198 };
1199
1200 static int qcom_qmp_phy_combo_configure_dp_swing(struct qmp_phy *qphy,
1201 unsigned int drv_lvl_reg, unsigned int emp_post_reg)
1202 {
1203 const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
1204 unsigned int v_level = 0, p_level = 0;
1205 u8 voltage_swing_cfg, pre_emphasis_cfg;
1206 int i;
1207
1208 for (i = 0; i < dp_opts->lanes; i++) {
1209 v_level = max(v_level, dp_opts->voltage[i]);
1210 p_level = max(p_level, dp_opts->pre[i]);
1211 }
1212
1213 if (dp_opts->link_rate <= 2700) {
1214 voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
1215 pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
1216 } else {
1217 voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];
1218 pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];
1219 }
1220
1221
1222 if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
1223 return -EINVAL;
1224
1225
1226 voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
1227 pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
1228
1229 writel(voltage_swing_cfg, qphy->tx + drv_lvl_reg);
1230 writel(pre_emphasis_cfg, qphy->tx + emp_post_reg);
1231 writel(voltage_swing_cfg, qphy->tx2 + drv_lvl_reg);
1232 writel(pre_emphasis_cfg, qphy->tx2 + emp_post_reg);
1233
1234 return 0;
1235 }
1236
1237 static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
1238 {
1239 const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
1240 u32 bias_en, drvr_en;
1241
1242 if (qcom_qmp_phy_combo_configure_dp_swing(qphy,
1243 QSERDES_V3_TX_TX_DRV_LVL,
1244 QSERDES_V3_TX_TX_EMP_POST1_LVL) < 0)
1245 return;
1246
1247 if (dp_opts->lanes == 1) {
1248 bias_en = 0x3e;
1249 drvr_en = 0x13;
1250 } else {
1251 bias_en = 0x3f;
1252 drvr_en = 0x10;
1253 }
1254
1255 writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
1256 writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
1257 writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
1258 writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
1259 }
1260
1261 static bool qcom_qmp_phy_combo_configure_dp_mode(struct qmp_phy *qphy)
1262 {
1263 u32 val;
1264 bool reverse = false;
1265
1266 val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
1267 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283 val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
1284 writel(val, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
1285
1286 writel(0x5c, qphy->pcs + QSERDES_DP_PHY_MODE);
1287
1288 return reverse;
1289 }
1290
1291 static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy)
1292 {
1293 const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
1294 const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
1295 u32 phy_vco_div, status;
1296 unsigned long pixel_freq;
1297
1298 qcom_qmp_phy_combo_configure_dp_mode(qphy);
1299
1300 writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
1301 writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
1302
1303 switch (dp_opts->link_rate) {
1304 case 1620:
1305 phy_vco_div = 0x1;
1306 pixel_freq = 1620000000UL / 2;
1307 break;
1308 case 2700:
1309 phy_vco_div = 0x1;
1310 pixel_freq = 2700000000UL / 2;
1311 break;
1312 case 5400:
1313 phy_vco_div = 0x2;
1314 pixel_freq = 5400000000UL / 4;
1315 break;
1316 case 8100:
1317 phy_vco_div = 0x0;
1318 pixel_freq = 8100000000UL / 6;
1319 break;
1320 default:
1321
1322 return -EINVAL;
1323 }
1324 writel(phy_vco_div, qphy->pcs + QSERDES_V3_DP_PHY_VCO_DIV);
1325
1326 clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
1327 clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
1328
1329 writel(0x04, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
1330 writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
1331 writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
1332 writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
1333 writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
1334
1335 writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL);
1336
1337 if (readl_poll_timeout(qphy->serdes + QSERDES_V3_COM_C_READY_STATUS,
1338 status,
1339 ((status & BIT(0)) > 0),
1340 500,
1341 10000))
1342 return -ETIMEDOUT;
1343
1344 writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
1345
1346 if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
1347 status,
1348 ((status & BIT(1)) > 0),
1349 500,
1350 10000))
1351 return -ETIMEDOUT;
1352
1353 writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
1354 udelay(2000);
1355 writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
1356
1357 return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
1358 status,
1359 ((status & BIT(1)) > 0),
1360 500,
1361 10000);
1362 }
1363
1364
1365
1366
1367
1368 static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)
1369 {
1370 static const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d };
1371 u8 val;
1372
1373 qphy->dp_aux_cfg++;
1374 qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
1375 val = cfg1_settings[qphy->dp_aux_cfg];
1376
1377 writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
1378
1379 return 0;
1380 }
1381
1382 static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)
1383 {
1384 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
1385 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
1386 qphy->pcs + QSERDES_DP_PHY_PD_CTL);
1387
1388
1389 writel(0x17, qphy->serdes + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
1390
1391 writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
1392 writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
1393 writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
1394 writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
1395 writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
1396 writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
1397 writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
1398 writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
1399 writel(0xb7, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
1400 writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
1401 qphy->dp_aux_cfg = 0;
1402
1403 writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
1404 PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
1405 PHY_AUX_REQ_ERR_MASK,
1406 qphy->pcs + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
1407 }
1408
1409 static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy)
1410 {
1411
1412 writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
1413 writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
1414
1415 writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
1416 writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
1417
1418 qcom_qmp_phy_combo_configure_dp_swing(qphy,
1419 QSERDES_V4_TX_TX_DRV_LVL,
1420 QSERDES_V4_TX_TX_EMP_POST1_LVL);
1421 }
1422
1423 static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
1424 {
1425 const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
1426 const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
1427 u32 phy_vco_div, status;
1428 unsigned long pixel_freq;
1429 u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
1430 bool reverse;
1431
1432 writel(0x0f, qphy->pcs + QSERDES_V4_DP_PHY_CFG_1);
1433
1434 reverse = qcom_qmp_phy_combo_configure_dp_mode(qphy);
1435
1436 writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
1437 writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
1438
1439 writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL);
1440 writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL);
1441
1442 switch (dp_opts->link_rate) {
1443 case 1620:
1444 phy_vco_div = 0x1;
1445 pixel_freq = 1620000000UL / 2;
1446 break;
1447 case 2700:
1448 phy_vco_div = 0x1;
1449 pixel_freq = 2700000000UL / 2;
1450 break;
1451 case 5400:
1452 phy_vco_div = 0x2;
1453 pixel_freq = 5400000000UL / 4;
1454 break;
1455 case 8100:
1456 phy_vco_div = 0x0;
1457 pixel_freq = 8100000000UL / 6;
1458 break;
1459 default:
1460
1461 return -EINVAL;
1462 }
1463 writel(phy_vco_div, qphy->pcs + QSERDES_V4_DP_PHY_VCO_DIV);
1464
1465 clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
1466 clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
1467
1468 writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
1469 writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
1470 writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
1471 writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
1472
1473 writel(0x20, qphy->serdes + QSERDES_V4_COM_RESETSM_CNTRL);
1474
1475 if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_C_READY_STATUS,
1476 status,
1477 ((status & BIT(0)) > 0),
1478 500,
1479 10000))
1480 return -ETIMEDOUT;
1481
1482 if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
1483 status,
1484 ((status & BIT(0)) > 0),
1485 500,
1486 10000))
1487 return -ETIMEDOUT;
1488
1489 if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
1490 status,
1491 ((status & BIT(1)) > 0),
1492 500,
1493 10000))
1494 return -ETIMEDOUT;
1495
1496 writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
1497
1498 if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
1499 status,
1500 ((status & BIT(0)) > 0),
1501 500,
1502 10000))
1503 return -ETIMEDOUT;
1504
1505 if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
1506 status,
1507 ((status & BIT(1)) > 0),
1508 500,
1509 10000))
1510 return -ETIMEDOUT;
1511
1512
1513
1514
1515
1516
1517 if (dp_opts->lanes == 1) {
1518 bias0_en = reverse ? 0x3e : 0x15;
1519 bias1_en = reverse ? 0x15 : 0x3e;
1520 drvr0_en = reverse ? 0x13 : 0x10;
1521 drvr1_en = reverse ? 0x10 : 0x13;
1522 } else if (dp_opts->lanes == 2) {
1523 bias0_en = reverse ? 0x3f : 0x15;
1524 bias1_en = reverse ? 0x15 : 0x3f;
1525 drvr0_en = 0x10;
1526 drvr1_en = 0x10;
1527 } else {
1528 bias0_en = 0x3f;
1529 bias1_en = 0x3f;
1530 drvr0_en = 0x10;
1531 drvr1_en = 0x10;
1532 }
1533
1534 writel(drvr0_en, qphy->tx + QSERDES_V4_TX_HIGHZ_DRVR_EN);
1535 writel(bias0_en, qphy->tx + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
1536 writel(drvr1_en, qphy->tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);
1537 writel(bias1_en, qphy->tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
1538
1539 writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
1540 udelay(2000);
1541 writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
1542
1543 if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
1544 status,
1545 ((status & BIT(1)) > 0),
1546 500,
1547 10000))
1548 return -ETIMEDOUT;
1549
1550 writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);
1551 writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);
1552
1553 writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
1554 writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
1555
1556 writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
1557 writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
1558
1559 return 0;
1560 }
1561
1562
1563
1564
1565
1566 static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy)
1567 {
1568 static const u8 cfg1_settings[] = { 0x20, 0x13, 0x23, 0x1d };
1569 u8 val;
1570
1571 qphy->dp_aux_cfg++;
1572 qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
1573 val = cfg1_settings[qphy->dp_aux_cfg];
1574
1575 writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
1576
1577 return 0;
1578 }
1579
1580 static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
1581 {
1582 const struct phy_configure_opts_dp *dp_opts = &opts->dp;
1583 struct qmp_phy *qphy = phy_get_drvdata(phy);
1584 const struct qmp_phy_cfg *cfg = qphy->cfg;
1585
1586 memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
1587 if (qphy->dp_opts.set_voltages) {
1588 cfg->configure_dp_tx(qphy);
1589 qphy->dp_opts.set_voltages = 0;
1590 }
1591
1592 return 0;
1593 }
1594
1595 static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
1596 {
1597 struct qmp_phy *qphy = phy_get_drvdata(phy);
1598 const struct qmp_phy_cfg *cfg = qphy->cfg;
1599
1600 if (cfg->calibrate_dp_phy)
1601 return cfg->calibrate_dp_phy(qphy);
1602
1603 return 0;
1604 }
1605
1606 static int qcom_qmp_phy_combo_com_init(struct qmp_phy *qphy)
1607 {
1608 struct qcom_qmp *qmp = qphy->qmp;
1609 const struct qmp_phy_cfg *cfg = qphy->cfg;
1610 void __iomem *pcs = qphy->pcs;
1611 void __iomem *dp_com = qmp->dp_com;
1612 int ret;
1613
1614 mutex_lock(&qmp->phy_mutex);
1615 if (qmp->init_count++) {
1616 mutex_unlock(&qmp->phy_mutex);
1617 return 0;
1618 }
1619
1620
1621 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
1622 if (ret) {
1623 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
1624 goto err_unlock;
1625 }
1626
1627 ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
1628 if (ret) {
1629 dev_err(qmp->dev, "reset assert failed\n");
1630 goto err_disable_regulators;
1631 }
1632
1633 ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
1634 if (ret) {
1635 dev_err(qmp->dev, "reset deassert failed\n");
1636 goto err_disable_regulators;
1637 }
1638
1639 ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
1640 if (ret)
1641 goto err_assert_reset;
1642
1643 if (cfg->has_phy_dp_com_ctrl) {
1644 qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
1645 SW_PWRDN);
1646
1647 qphy_setbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
1648 SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
1649 SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
1650
1651
1652 qphy_setbits(dp_com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02);
1653
1654 qphy_setbits(dp_com, QPHY_V3_DP_COM_PHY_MODE_CTRL,
1655 USB3_MODE | DP_MODE);
1656
1657
1658 qphy_clrbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
1659 SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
1660 SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
1661
1662 qphy_clrbits(dp_com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);
1663 qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
1664 }
1665
1666 if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
1667 qphy_setbits(pcs,
1668 cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
1669 cfg->pwrdn_ctrl);
1670 else
1671 qphy_setbits(pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
1672 cfg->pwrdn_ctrl);
1673
1674 mutex_unlock(&qmp->phy_mutex);
1675
1676 return 0;
1677
1678 err_assert_reset:
1679 reset_control_bulk_assert(cfg->num_resets, qmp->resets);
1680 err_disable_regulators:
1681 regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
1682 err_unlock:
1683 mutex_unlock(&qmp->phy_mutex);
1684
1685 return ret;
1686 }
1687
1688 static int qcom_qmp_phy_combo_com_exit(struct qmp_phy *qphy)
1689 {
1690 struct qcom_qmp *qmp = qphy->qmp;
1691 const struct qmp_phy_cfg *cfg = qphy->cfg;
1692
1693 mutex_lock(&qmp->phy_mutex);
1694 if (--qmp->init_count) {
1695 mutex_unlock(&qmp->phy_mutex);
1696 return 0;
1697 }
1698
1699 reset_control_assert(qmp->ufs_reset);
1700
1701 reset_control_bulk_assert(cfg->num_resets, qmp->resets);
1702
1703 clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
1704
1705 regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
1706
1707 mutex_unlock(&qmp->phy_mutex);
1708
1709 return 0;
1710 }
1711
1712 static int qcom_qmp_phy_combo_init(struct phy *phy)
1713 {
1714 struct qmp_phy *qphy = phy_get_drvdata(phy);
1715 struct qcom_qmp *qmp = qphy->qmp;
1716 const struct qmp_phy_cfg *cfg = qphy->cfg;
1717 int ret;
1718 dev_vdbg(qmp->dev, "Initializing QMP phy\n");
1719
1720 ret = qcom_qmp_phy_combo_com_init(qphy);
1721 if (ret)
1722 return ret;
1723
1724 if (cfg->type == PHY_TYPE_DP)
1725 cfg->dp_aux_init(qphy);
1726
1727 return 0;
1728 }
1729
1730 static int qcom_qmp_phy_combo_power_on(struct phy *phy)
1731 {
1732 struct qmp_phy *qphy = phy_get_drvdata(phy);
1733 struct qcom_qmp *qmp = qphy->qmp;
1734 const struct qmp_phy_cfg *cfg = qphy->cfg;
1735 void __iomem *tx = qphy->tx;
1736 void __iomem *rx = qphy->rx;
1737 void __iomem *pcs = qphy->pcs;
1738 void __iomem *status;
1739 unsigned int mask, val, ready;
1740 int ret;
1741
1742 qcom_qmp_phy_combo_serdes_init(qphy);
1743
1744 ret = clk_prepare_enable(qphy->pipe_clk);
1745 if (ret) {
1746 dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
1747 return ret;
1748 }
1749
1750
1751 qcom_qmp_phy_combo_configure_lane(tx, cfg->regs,
1752 cfg->tx_tbl, cfg->tx_tbl_num, 1);
1753
1754
1755 if (cfg->is_dual_lane_phy) {
1756 qcom_qmp_phy_combo_configure_lane(qphy->tx2, cfg->regs,
1757 cfg->tx_tbl, cfg->tx_tbl_num, 2);
1758 }
1759
1760
1761 if (cfg->type == PHY_TYPE_DP)
1762 cfg->configure_dp_tx(qphy);
1763
1764 qcom_qmp_phy_combo_configure_lane(rx, cfg->regs,
1765 cfg->rx_tbl, cfg->rx_tbl_num, 1);
1766
1767 if (cfg->is_dual_lane_phy) {
1768 qcom_qmp_phy_combo_configure_lane(qphy->rx2, cfg->regs,
1769 cfg->rx_tbl, cfg->rx_tbl_num, 2);
1770 }
1771
1772
1773 if (cfg->type == PHY_TYPE_DP) {
1774 cfg->configure_dp_phy(qphy);
1775 } else {
1776 qcom_qmp_phy_combo_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
1777 }
1778
1779 ret = reset_control_deassert(qmp->ufs_reset);
1780 if (ret)
1781 goto err_disable_pipe_clk;
1782
1783 if (cfg->has_pwrdn_delay)
1784 usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
1785
1786 if (cfg->type != PHY_TYPE_DP) {
1787
1788 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1789
1790 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
1791
1792 status = pcs + cfg->regs[QPHY_PCS_STATUS];
1793 mask = cfg->phy_status;
1794 ready = 0;
1795
1796 ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
1797 PHY_INIT_COMPLETE_TIMEOUT);
1798 if (ret) {
1799 dev_err(qmp->dev, "phy initialization timed-out\n");
1800 goto err_disable_pipe_clk;
1801 }
1802 }
1803 return 0;
1804
1805 err_disable_pipe_clk:
1806 clk_disable_unprepare(qphy->pipe_clk);
1807
1808 return ret;
1809 }
1810
1811 static int qcom_qmp_phy_combo_power_off(struct phy *phy)
1812 {
1813 struct qmp_phy *qphy = phy_get_drvdata(phy);
1814 const struct qmp_phy_cfg *cfg = qphy->cfg;
1815
1816 clk_disable_unprepare(qphy->pipe_clk);
1817
1818 if (cfg->type == PHY_TYPE_DP) {
1819
1820 writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
1821 } else {
1822
1823 qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1824
1825
1826 qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
1827
1828
1829 if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
1830 qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
1831 cfg->pwrdn_ctrl);
1832 } else {
1833 qphy_clrbits(qphy->pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
1834 cfg->pwrdn_ctrl);
1835 }
1836 }
1837
1838 return 0;
1839 }
1840
1841 static int qcom_qmp_phy_combo_exit(struct phy *phy)
1842 {
1843 struct qmp_phy *qphy = phy_get_drvdata(phy);
1844
1845 qcom_qmp_phy_combo_com_exit(qphy);
1846
1847 return 0;
1848 }
1849
1850 static int qcom_qmp_phy_combo_enable(struct phy *phy)
1851 {
1852 int ret;
1853
1854 ret = qcom_qmp_phy_combo_init(phy);
1855 if (ret)
1856 return ret;
1857
1858 ret = qcom_qmp_phy_combo_power_on(phy);
1859 if (ret)
1860 qcom_qmp_phy_combo_exit(phy);
1861
1862 return ret;
1863 }
1864
1865 static int qcom_qmp_phy_combo_disable(struct phy *phy)
1866 {
1867 int ret;
1868
1869 ret = qcom_qmp_phy_combo_power_off(phy);
1870 if (ret)
1871 return ret;
1872 return qcom_qmp_phy_combo_exit(phy);
1873 }
1874
1875 static int qcom_qmp_phy_combo_set_mode(struct phy *phy,
1876 enum phy_mode mode, int submode)
1877 {
1878 struct qmp_phy *qphy = phy_get_drvdata(phy);
1879
1880 qphy->mode = mode;
1881
1882 return 0;
1883 }
1884
1885 static void qcom_qmp_phy_combo_enable_autonomous_mode(struct qmp_phy *qphy)
1886 {
1887 const struct qmp_phy_cfg *cfg = qphy->cfg;
1888 void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs;
1889 void __iomem *pcs_misc = qphy->pcs_misc;
1890 u32 intr_mask;
1891
1892 if (qphy->mode == PHY_MODE_USB_HOST_SS ||
1893 qphy->mode == PHY_MODE_USB_DEVICE_SS)
1894 intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
1895 else
1896 intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
1897
1898
1899 qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
1900
1901 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
1902
1903 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
1904 ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
1905
1906
1907 qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
1908
1909
1910 if (pcs_misc)
1911 qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
1912 }
1913
1914 static void qcom_qmp_phy_combo_disable_autonomous_mode(struct qmp_phy *qphy)
1915 {
1916 const struct qmp_phy_cfg *cfg = qphy->cfg;
1917 void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs_usb;
1918 void __iomem *pcs_misc = qphy->pcs_misc;
1919
1920
1921 if (pcs_misc)
1922 qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
1923
1924 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
1925 ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
1926
1927 qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
1928
1929 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
1930 }
1931
1932 static int __maybe_unused qcom_qmp_phy_combo_runtime_suspend(struct device *dev)
1933 {
1934 struct qcom_qmp *qmp = dev_get_drvdata(dev);
1935 struct qmp_phy *qphy = qmp->phys[0];
1936 const struct qmp_phy_cfg *cfg = qphy->cfg;
1937
1938 dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qphy->mode);
1939
1940
1941 if (cfg->type != PHY_TYPE_USB3)
1942 return 0;
1943
1944 if (!qmp->init_count) {
1945 dev_vdbg(dev, "PHY not initialized, bailing out\n");
1946 return 0;
1947 }
1948
1949 qcom_qmp_phy_combo_enable_autonomous_mode(qphy);
1950
1951 clk_disable_unprepare(qphy->pipe_clk);
1952 clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
1953
1954 return 0;
1955 }
1956
1957 static int __maybe_unused qcom_qmp_phy_combo_runtime_resume(struct device *dev)
1958 {
1959 struct qcom_qmp *qmp = dev_get_drvdata(dev);
1960 struct qmp_phy *qphy = qmp->phys[0];
1961 const struct qmp_phy_cfg *cfg = qphy->cfg;
1962 int ret = 0;
1963
1964 dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qphy->mode);
1965
1966
1967 if (cfg->type != PHY_TYPE_USB3)
1968 return 0;
1969
1970 if (!qmp->init_count) {
1971 dev_vdbg(dev, "PHY not initialized, bailing out\n");
1972 return 0;
1973 }
1974
1975 ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
1976 if (ret)
1977 return ret;
1978
1979 ret = clk_prepare_enable(qphy->pipe_clk);
1980 if (ret) {
1981 dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
1982 clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
1983 return ret;
1984 }
1985
1986 qcom_qmp_phy_combo_disable_autonomous_mode(qphy);
1987
1988 return 0;
1989 }
1990
1991 static int qcom_qmp_phy_combo_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
1992 {
1993 struct qcom_qmp *qmp = dev_get_drvdata(dev);
1994 int num = cfg->num_vregs;
1995 int ret, i;
1996
1997 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
1998 if (!qmp->vregs)
1999 return -ENOMEM;
2000
2001 for (i = 0; i < num; i++)
2002 qmp->vregs[i].supply = cfg->vreg_list[i].name;
2003
2004 ret = devm_regulator_bulk_get(dev, num, qmp->vregs);
2005 if (ret) {
2006 dev_err(dev, "failed at devm_regulator_bulk_get\n");
2007 return ret;
2008 }
2009
2010 for (i = 0; i < num; i++) {
2011 ret = regulator_set_load(qmp->vregs[i].consumer,
2012 cfg->vreg_list[i].enable_load);
2013 if (ret) {
2014 dev_err(dev, "failed to set load at %s\n",
2015 qmp->vregs[i].supply);
2016 return ret;
2017 }
2018 }
2019
2020 return 0;
2021 }
2022
2023 static int qcom_qmp_phy_combo_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg)
2024 {
2025 struct qcom_qmp *qmp = dev_get_drvdata(dev);
2026 int i;
2027 int ret;
2028
2029 qmp->resets = devm_kcalloc(dev, cfg->num_resets,
2030 sizeof(*qmp->resets), GFP_KERNEL);
2031 if (!qmp->resets)
2032 return -ENOMEM;
2033
2034 for (i = 0; i < cfg->num_resets; i++)
2035 qmp->resets[i].id = cfg->reset_list[i];
2036
2037 ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
2038 if (ret)
2039 return dev_err_probe(dev, ret, "failed to get resets\n");
2040
2041 return 0;
2042 }
2043
2044 static int qcom_qmp_phy_combo_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
2045 {
2046 struct qcom_qmp *qmp = dev_get_drvdata(dev);
2047 int num = cfg->num_clks;
2048 int i;
2049
2050 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
2051 if (!qmp->clks)
2052 return -ENOMEM;
2053
2054 for (i = 0; i < num; i++)
2055 qmp->clks[i].id = cfg->clk_list[i];
2056
2057 return devm_clk_bulk_get(dev, num, qmp->clks);
2058 }
2059
2060 static void phy_clk_release_provider(void *res)
2061 {
2062 of_clk_del_provider(res);
2063 }
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083 static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
2084 {
2085 struct clk_fixed_rate *fixed;
2086 struct clk_init_data init = { };
2087 int ret;
2088
2089 ret = of_property_read_string(np, "clock-output-names", &init.name);
2090 if (ret) {
2091 dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
2092 return ret;
2093 }
2094
2095 fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
2096 if (!fixed)
2097 return -ENOMEM;
2098
2099 init.ops = &clk_fixed_rate_ops;
2100
2101
2102 fixed->fixed_rate = 125000000;
2103 fixed->hw.init = &init;
2104
2105 ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
2106 if (ret)
2107 return ret;
2108
2109 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
2110 if (ret)
2111 return ret;
2112
2113
2114
2115
2116
2117 return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
2118 }
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169 static int qcom_qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
2170 struct clk_rate_request *req)
2171 {
2172 switch (req->rate) {
2173 case 1620000000UL / 2:
2174 case 2700000000UL / 2:
2175
2176 return 0;
2177 default:
2178 return -EINVAL;
2179 }
2180 }
2181
2182 static unsigned long
2183 qcom_qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
2184 {
2185 const struct qmp_phy_dp_clks *dp_clks;
2186 const struct qmp_phy *qphy;
2187 const struct phy_configure_opts_dp *dp_opts;
2188
2189 dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_pixel_hw);
2190 qphy = dp_clks->qphy;
2191 dp_opts = &qphy->dp_opts;
2192
2193 switch (dp_opts->link_rate) {
2194 case 1620:
2195 return 1620000000UL / 2;
2196 case 2700:
2197 return 2700000000UL / 2;
2198 case 5400:
2199 return 5400000000UL / 4;
2200 case 8100:
2201 return 8100000000UL / 6;
2202 default:
2203 return 0;
2204 }
2205 }
2206
2207 static const struct clk_ops qcom_qmp_dp_pixel_clk_ops = {
2208 .determine_rate = qcom_qmp_dp_pixel_clk_determine_rate,
2209 .recalc_rate = qcom_qmp_dp_pixel_clk_recalc_rate,
2210 };
2211
2212 static int qcom_qmp_dp_link_clk_determine_rate(struct clk_hw *hw,
2213 struct clk_rate_request *req)
2214 {
2215 switch (req->rate) {
2216 case 162000000:
2217 case 270000000:
2218 case 540000000:
2219 case 810000000:
2220 return 0;
2221 default:
2222 return -EINVAL;
2223 }
2224 }
2225
2226 static unsigned long
2227 qcom_qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
2228 {
2229 const struct qmp_phy_dp_clks *dp_clks;
2230 const struct qmp_phy *qphy;
2231 const struct phy_configure_opts_dp *dp_opts;
2232
2233 dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_link_hw);
2234 qphy = dp_clks->qphy;
2235 dp_opts = &qphy->dp_opts;
2236
2237 switch (dp_opts->link_rate) {
2238 case 1620:
2239 case 2700:
2240 case 5400:
2241 case 8100:
2242 return dp_opts->link_rate * 100000;
2243 default:
2244 return 0;
2245 }
2246 }
2247
2248 static const struct clk_ops qcom_qmp_dp_link_clk_ops = {
2249 .determine_rate = qcom_qmp_dp_link_clk_determine_rate,
2250 .recalc_rate = qcom_qmp_dp_link_clk_recalc_rate,
2251 };
2252
2253 static struct clk_hw *
2254 qcom_qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
2255 {
2256 struct qmp_phy_dp_clks *dp_clks = data;
2257 unsigned int idx = clkspec->args[0];
2258
2259 if (idx >= 2) {
2260 pr_err("%s: invalid index %u\n", __func__, idx);
2261 return ERR_PTR(-EINVAL);
2262 }
2263
2264 if (idx == 0)
2265 return &dp_clks->dp_link_hw;
2266
2267 return &dp_clks->dp_pixel_hw;
2268 }
2269
2270 static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
2271 struct device_node *np)
2272 {
2273 struct clk_init_data init = { };
2274 struct qmp_phy_dp_clks *dp_clks;
2275 char name[64];
2276 int ret;
2277
2278 dp_clks = devm_kzalloc(qmp->dev, sizeof(*dp_clks), GFP_KERNEL);
2279 if (!dp_clks)
2280 return -ENOMEM;
2281
2282 dp_clks->qphy = qphy;
2283 qphy->dp_clks = dp_clks;
2284
2285 snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
2286 init.ops = &qcom_qmp_dp_link_clk_ops;
2287 init.name = name;
2288 dp_clks->dp_link_hw.init = &init;
2289 ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_link_hw);
2290 if (ret)
2291 return ret;
2292
2293 snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
2294 init.ops = &qcom_qmp_dp_pixel_clk_ops;
2295 init.name = name;
2296 dp_clks->dp_pixel_hw.init = &init;
2297 ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_pixel_hw);
2298 if (ret)
2299 return ret;
2300
2301 ret = of_clk_add_hw_provider(np, qcom_qmp_dp_clks_hw_get, dp_clks);
2302 if (ret)
2303 return ret;
2304
2305
2306
2307
2308
2309 return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
2310 }
2311
2312 static const struct phy_ops qcom_qmp_phy_combo_usb_ops = {
2313 .init = qcom_qmp_phy_combo_enable,
2314 .exit = qcom_qmp_phy_combo_disable,
2315 .set_mode = qcom_qmp_phy_combo_set_mode,
2316 .owner = THIS_MODULE,
2317 };
2318
2319 static const struct phy_ops qcom_qmp_phy_combo_dp_ops = {
2320 .init = qcom_qmp_phy_combo_init,
2321 .configure = qcom_qmp_dp_phy_configure,
2322 .power_on = qcom_qmp_phy_combo_power_on,
2323 .calibrate = qcom_qmp_dp_phy_calibrate,
2324 .power_off = qcom_qmp_phy_combo_power_off,
2325 .exit = qcom_qmp_phy_combo_exit,
2326 .set_mode = qcom_qmp_phy_combo_set_mode,
2327 .owner = THIS_MODULE,
2328 };
2329
2330 static
2331 int qcom_qmp_phy_combo_create(struct device *dev, struct device_node *np, int id,
2332 void __iomem *serdes, const struct qmp_phy_cfg *cfg)
2333 {
2334 struct qcom_qmp *qmp = dev_get_drvdata(dev);
2335 struct phy *generic_phy;
2336 struct qmp_phy *qphy;
2337 const struct phy_ops *ops;
2338 char prop_name[MAX_PROP_NAME];
2339 int ret;
2340
2341 qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
2342 if (!qphy)
2343 return -ENOMEM;
2344
2345 qphy->cfg = cfg;
2346 qphy->serdes = serdes;
2347
2348
2349
2350
2351
2352
2353 qphy->tx = of_iomap(np, 0);
2354 if (!qphy->tx)
2355 return -ENOMEM;
2356
2357 qphy->rx = of_iomap(np, 1);
2358 if (!qphy->rx)
2359 return -ENOMEM;
2360
2361 qphy->pcs = of_iomap(np, 2);
2362 if (!qphy->pcs)
2363 return -ENOMEM;
2364
2365 if (cfg->pcs_usb_offset)
2366 qphy->pcs_usb = qphy->pcs + cfg->pcs_usb_offset;
2367
2368
2369
2370
2371
2372
2373
2374 if (cfg->is_dual_lane_phy) {
2375 qphy->tx2 = of_iomap(np, 3);
2376 qphy->rx2 = of_iomap(np, 4);
2377 if (!qphy->tx2 || !qphy->rx2) {
2378 dev_warn(dev,
2379 "Underspecified device tree, falling back to legacy register regions\n");
2380
2381
2382 qphy->pcs_misc = qphy->tx2;
2383 qphy->tx2 = qphy->tx + QMP_PHY_LEGACY_LANE_STRIDE;
2384 qphy->rx2 = qphy->rx + QMP_PHY_LEGACY_LANE_STRIDE;
2385
2386 } else {
2387 qphy->pcs_misc = of_iomap(np, 5);
2388 }
2389
2390 } else {
2391 qphy->pcs_misc = of_iomap(np, 3);
2392 }
2393
2394 if (!qphy->pcs_misc)
2395 dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
2396
2397
2398
2399
2400
2401
2402
2403
2404 snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
2405 qphy->pipe_clk = devm_get_clk_from_child(dev, np, prop_name);
2406 if (IS_ERR(qphy->pipe_clk)) {
2407 if (cfg->type == PHY_TYPE_USB3) {
2408 ret = PTR_ERR(qphy->pipe_clk);
2409 if (ret != -EPROBE_DEFER)
2410 dev_err(dev,
2411 "failed to get lane%d pipe_clk, %d\n",
2412 id, ret);
2413 return ret;
2414 }
2415 qphy->pipe_clk = NULL;
2416 }
2417
2418 if (cfg->type == PHY_TYPE_DP)
2419 ops = &qcom_qmp_phy_combo_dp_ops;
2420 else
2421 ops = &qcom_qmp_phy_combo_usb_ops;
2422
2423 generic_phy = devm_phy_create(dev, np, ops);
2424 if (IS_ERR(generic_phy)) {
2425 ret = PTR_ERR(generic_phy);
2426 dev_err(dev, "failed to create qphy %d\n", ret);
2427 return ret;
2428 }
2429
2430 qphy->phy = generic_phy;
2431 qphy->index = id;
2432 qphy->qmp = qmp;
2433 qmp->phys[id] = qphy;
2434 phy_set_drvdata(generic_phy, qphy);
2435
2436 return 0;
2437 }
2438
2439 static const struct of_device_id qcom_qmp_combo_phy_of_match_table[] = {
2440 {
2441 .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
2442 .data = &sc7180_usb3dpphy_cfg,
2443 },
2444 {
2445 .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
2446 .data = &sm8250_usb3dpphy_cfg,
2447 },
2448 {
2449 .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
2450 .data = &sc8180x_usb3dpphy_cfg,
2451 },
2452 { }
2453 };
2454 MODULE_DEVICE_TABLE(of, qcom_qmp_combo_phy_of_match_table);
2455
2456 static const struct dev_pm_ops qcom_qmp_phy_combo_pm_ops = {
2457 SET_RUNTIME_PM_OPS(qcom_qmp_phy_combo_runtime_suspend,
2458 qcom_qmp_phy_combo_runtime_resume, NULL)
2459 };
2460
2461 static int qcom_qmp_phy_combo_probe(struct platform_device *pdev)
2462 {
2463 struct qcom_qmp *qmp;
2464 struct device *dev = &pdev->dev;
2465 struct device_node *child;
2466 struct phy_provider *phy_provider;
2467 void __iomem *serdes;
2468 void __iomem *usb_serdes;
2469 void __iomem *dp_serdes = NULL;
2470 const struct qmp_phy_combo_cfg *combo_cfg = NULL;
2471 const struct qmp_phy_cfg *cfg = NULL;
2472 const struct qmp_phy_cfg *usb_cfg = NULL;
2473 const struct qmp_phy_cfg *dp_cfg = NULL;
2474 int num, id, expected_phys;
2475 int ret;
2476
2477 qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
2478 if (!qmp)
2479 return -ENOMEM;
2480
2481 qmp->dev = dev;
2482 dev_set_drvdata(dev, qmp);
2483
2484
2485 combo_cfg = of_device_get_match_data(dev);
2486 if (!combo_cfg)
2487 return -EINVAL;
2488
2489 usb_cfg = combo_cfg->usb_cfg;
2490 cfg = usb_cfg;
2491
2492
2493 usb_serdes = serdes = devm_platform_ioremap_resource(pdev, 0);
2494 if (IS_ERR(serdes))
2495 return PTR_ERR(serdes);
2496
2497
2498 if (cfg->has_phy_dp_com_ctrl) {
2499 qmp->dp_com = devm_platform_ioremap_resource(pdev, 1);
2500 if (IS_ERR(qmp->dp_com))
2501 return PTR_ERR(qmp->dp_com);
2502 }
2503
2504
2505 dp_serdes = devm_platform_ioremap_resource(pdev, 2);
2506 if (IS_ERR(dp_serdes))
2507 return PTR_ERR(dp_serdes);
2508
2509 dp_cfg = combo_cfg->dp_cfg;
2510 expected_phys = 2;
2511
2512 mutex_init(&qmp->phy_mutex);
2513
2514 ret = qcom_qmp_phy_combo_clk_init(dev, cfg);
2515 if (ret)
2516 return ret;
2517
2518 ret = qcom_qmp_phy_combo_reset_init(dev, cfg);
2519 if (ret)
2520 return ret;
2521
2522 ret = qcom_qmp_phy_combo_vreg_init(dev, cfg);
2523 if (ret) {
2524 if (ret != -EPROBE_DEFER)
2525 dev_err(dev, "failed to get regulator supplies: %d\n",
2526 ret);
2527 return ret;
2528 }
2529
2530 num = of_get_available_child_count(dev->of_node);
2531
2532 if (num > expected_phys)
2533 return -EINVAL;
2534
2535 qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
2536 if (!qmp->phys)
2537 return -ENOMEM;
2538
2539 pm_runtime_set_active(dev);
2540 pm_runtime_enable(dev);
2541
2542
2543
2544
2545 pm_runtime_forbid(dev);
2546
2547 id = 0;
2548 for_each_available_child_of_node(dev->of_node, child) {
2549 if (of_node_name_eq(child, "dp-phy")) {
2550 cfg = dp_cfg;
2551 serdes = dp_serdes;
2552
2553
2554 ret = qcom_qmp_phy_combo_create(dev, child, id, serdes, cfg);
2555 if (ret) {
2556 dev_err(dev, "failed to create lane%d phy, %d\n",
2557 id, ret);
2558 goto err_node_put;
2559 }
2560
2561 ret = phy_dp_clks_register(qmp, qmp->phys[id], child);
2562 if (ret) {
2563 dev_err(qmp->dev,
2564 "failed to register DP clock source\n");
2565 goto err_node_put;
2566 }
2567 } else if (of_node_name_eq(child, "usb3-phy")) {
2568 cfg = usb_cfg;
2569 serdes = usb_serdes;
2570
2571
2572 ret = qcom_qmp_phy_combo_create(dev, child, id, serdes, cfg);
2573 if (ret) {
2574 dev_err(dev, "failed to create lane%d phy, %d\n",
2575 id, ret);
2576 goto err_node_put;
2577 }
2578
2579
2580
2581
2582
2583 ret = phy_pipe_clk_register(qmp, child);
2584 if (ret) {
2585 dev_err(qmp->dev,
2586 "failed to register pipe clock source\n");
2587 goto err_node_put;
2588 }
2589 }
2590
2591 id++;
2592 }
2593
2594 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
2595 if (!IS_ERR(phy_provider))
2596 dev_info(dev, "Registered Qcom-QMP phy\n");
2597 else
2598 pm_runtime_disable(dev);
2599
2600 return PTR_ERR_OR_ZERO(phy_provider);
2601
2602 err_node_put:
2603 pm_runtime_disable(dev);
2604 of_node_put(child);
2605 return ret;
2606 }
2607
2608 static struct platform_driver qcom_qmp_phy_combo_driver = {
2609 .probe = qcom_qmp_phy_combo_probe,
2610 .driver = {
2611 .name = "qcom-qmp-combo-phy",
2612 .pm = &qcom_qmp_phy_combo_pm_ops,
2613 .of_match_table = qcom_qmp_combo_phy_of_match_table,
2614 },
2615 };
2616
2617 module_platform_driver(qcom_qmp_phy_combo_driver);
2618
2619 MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
2620 MODULE_DESCRIPTION("Qualcomm QMP USB+DP combo PHY driver");
2621 MODULE_LICENSE("GPL v2");