Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2017, The Linux Foundation. All rights reserved.
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 /* QPHY_SW_RESET bit */
0028 #define SW_RESET                BIT(0)
0029 /* QPHY_POWER_DOWN_CONTROL */
0030 #define SW_PWRDN                BIT(0)
0031 #define REFCLK_DRV_DSBL             BIT(1)
0032 /* QPHY_START_CONTROL bits */
0033 #define SERDES_START                BIT(0)
0034 #define PCS_START               BIT(1)
0035 #define PLL_READY_GATE_EN           BIT(3)
0036 /* QPHY_PCS_STATUS bit */
0037 #define PHYSTATUS               BIT(6)
0038 #define PHYSTATUS_4_20              BIT(7)
0039 /* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
0040 #define PCS_READY               BIT(0)
0041 
0042 /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
0043 /* DP PHY soft reset */
0044 #define SW_DPPHY_RESET              BIT(0)
0045 /* mux to select DP PHY reset control, 0:HW control, 1: software reset */
0046 #define SW_DPPHY_RESET_MUX          BIT(1)
0047 /* USB3 PHY soft reset */
0048 #define SW_USB3PHY_RESET            BIT(2)
0049 /* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
0050 #define SW_USB3PHY_RESET_MUX            BIT(3)
0051 
0052 /* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
0053 #define USB3_MODE               BIT(0) /* enables USB3 mode */
0054 #define DP_MODE                 BIT(1) /* enables DP mode */
0055 
0056 /* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
0057 #define ARCVR_DTCT_EN               BIT(0)
0058 #define ALFPS_DTCT_EN               BIT(1)
0059 #define ARCVR_DTCT_EVENT_SEL            BIT(4)
0060 
0061 /* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
0062 #define IRQ_CLEAR               BIT(0)
0063 
0064 /* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
0065 #define RCVR_DETECT             BIT(0)
0066 
0067 /* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
0068 #define CLAMP_EN                BIT(0) /* enables i/o clamp_n */
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 /* Define the assumed distance between lanes for underspecified device trees. */
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      * register part of layout ?
0084      * if yes, then offset gives index in the reg-layout
0085      */
0086     bool in_layout;
0087     /*
0088      * mask of lanes for which this register is written
0089      * for cases when second lane needs different values
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 /* set of registers with offsets different per-PHY */
0117 enum qphy_reg_layout {
0118     /* Common block control registers */
0119     QPHY_COM_SW_RESET,
0120     QPHY_COM_POWER_DOWN_CONTROL,
0121     QPHY_COM_START_CONTROL,
0122     QPHY_COM_PCS_READY_STATUS,
0123     /* PCS registers */
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     /* PCS_MISC registers */
0133     QPHY_PCS_MISC_TYPEC_CTRL,
0134     /* Keep last to ensure regs_layout arrays are properly initialized */
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     /* In PCS_USB */
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     /* FLL settings */
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     /* Lock Det settings */
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     /* Lock Det settings */
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 /* list of regulators */
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 /* struct qmp_phy_cfg - per-PHY initialization config */
0624 struct qmp_phy_cfg {
0625     /* phy-type - PCIE/UFS/USB */
0626     unsigned int type;
0627     /* number of lanes provided by phy */
0628     int nlanes;
0629 
0630     /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
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     /* Init sequence for DP PHY block link rates */
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     /* DP PHY callbacks */
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     /* clock ids to be requested */
0659     const char * const *clk_list;
0660     int num_clks;
0661     /* resets to be requested */
0662     const char * const *reset_list;
0663     int num_resets;
0664     /* regulators to be requested */
0665     const struct qmp_regulator_data *vreg_list;
0666     int num_vregs;
0667 
0668     /* array of registers with different offsets */
0669     const unsigned int *regs;
0670 
0671     unsigned int start_ctrl;
0672     unsigned int pwrdn_ctrl;
0673     /* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
0674     unsigned int phy_status;
0675 
0676     /* true, if PHY needs delay after POWER_DOWN */
0677     bool has_pwrdn_delay;
0678     /* power_down delay in usec */
0679     int pwrdn_delay_min;
0680     int pwrdn_delay_max;
0681 
0682     /* true, if PHY has a separate DP_COM control block */
0683     bool has_phy_dp_com_ctrl;
0684     /* true, if PHY has secondary tx/rx lanes to be configured */
0685     bool is_dual_lane_phy;
0686 
0687     /* Offset from PCS to PCS_USB region */
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  * struct qmp_phy - per-lane phy descriptor
0699  *
0700  * @phy: generic phy
0701  * @cfg: phy specific configuration
0702  * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
0703  * @tx: iomapped memory space for lane's tx
0704  * @rx: iomapped memory space for lane's rx
0705  * @pcs: iomapped memory space for lane's pcs
0706  * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
0707  * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
0708  * @pcs_misc: iomapped memory space for lane's pcs_misc
0709  * @pcs_usb: iomapped memory space for lane's pcs_usb
0710  * @pipe_clk: pipe clock
0711  * @index: lane index
0712  * @qmp: QMP phy to which this lane belongs
0713  * @lane_rst: lane's reset controller
0714  * @mode: current PHY mode
0715  * @dp_aux_cfg: Display port aux config
0716  * @dp_opts: Display port optional config
0717  * @dp_clks: Display port clocks
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  * struct qcom_qmp - structure holding QMP phy block attributes
0748  *
0749  * @dev: device
0750  * @dp_com: iomapped memory space for phy's dp_com control block
0751  *
0752  * @clks: array of clocks required by phy
0753  * @resets: array of resets required by phy
0754  * @vregs: regulator supplies bulk data
0755  *
0756  * @phys: array of per-lane phy descriptors
0757  * @phy_mutex: mutex lock for PHY common block initialization
0758  * @init_count: phy common block initialization count
0759  * @ufs_reset: optional UFS PHY reset handle
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     /* ensure that above write is through */
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     /* ensure that above write is through */
0808     readl(base + offset);
0809 }
0810 
0811 /* list of clocks required by phy */
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 /* the primary usb3 phy on sm8250 doesn't have a ref clock */
0821 static const char * const qmp_v4_sm8250_usbphy_clk_l[] = {
0822     "aux", "ref_clk_src", "com_aux"
0823 };
0824 
0825 /* list of resets */
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             /* Other link rates aren't supported */
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     /* Turn on BIAS current for PHY/PLL */
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     /* TODO: Move check to config check */
1222     if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
1223         return -EINVAL;
1224 
1225     /* Enable MUX to use Cursor values from these registers */
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      * TODO: Assume orientation is CC1 for now and two lanes, need to
1271      * use type-c connector to understand orientation and lanes.
1272      *
1273      * Otherwise val changes to be like below if this code understood
1274      * the orientation of the type-c cable.
1275      *
1276      * if (lane_cnt == 4 || orientation == ORIENTATION_CC2)
1277      *  val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
1278      * if (lane_cnt == 4 || orientation == ORIENTATION_CC1)
1279      *  val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
1280      * if (orientation == ORIENTATION_CC2)
1281      *  writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
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         /* Other link rates aren't supported */
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  * We need to calibrate the aux setting here as many times
1366  * as the caller tries
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     /* Turn on BIAS current for PHY/PLL */
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     /* Program default values before writing proper values */
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         /* Other link rates aren't supported */
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      * At least for 7nm DP PHY this has to be done after enabling link
1514      * clock.
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  * We need to calibrate the aux setting here as many times
1564  * as the caller tries
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     /* turn on regulator supplies */
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         /* override hardware control for reset of qmp phy */
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         /* Default type-c orientation, i.e CC1 */
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         /* bring both QMP USB and QMP DP PHYs PCS block out of reset */
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     /* Tx, Rx, and PCS configurations */
1751     qcom_qmp_phy_combo_configure_lane(tx, cfg->regs,
1752                     cfg->tx_tbl, cfg->tx_tbl_num, 1);
1753 
1754     /* Configuration for other LANE for USB-DP combo PHY */
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     /* Configure special DP tx tunings */
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     /* Configure link rate, swing, etc. */
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         /* Pull PHY out of reset state */
1788         qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1789         /* start SerDes and Phy-Coding-Sublayer */
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         /* Assert DP PHY power down */
1820         writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
1821     } else {
1822         /* PHY reset */
1823         qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1824 
1825         /* stop SerDes and Phy-Coding-Sublayer */
1826         qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
1827 
1828         /* Put PHY into POWER DOWN state: active low */
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     /* Clear any pending interrupts status */
1899     qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
1900     /* Writing 1 followed by 0 clears the interrupt */
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     /* Enable required PHY autonomous mode interrupts */
1907     qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
1908 
1909     /* Enable i/o clamp_n for autonomous mode */
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     /* Disable i/o clamp_n on resume for normal mode */
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     /* Writing 1 followed by 0 clears the interrupt */
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     /* Supported only for USB3 PHY and luckily USB3 is the first phy */
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     /* Supported only for USB3 PHY and luckily USB3 is the first phy */
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  * Register a fixed rate pipe clock.
2067  *
2068  * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
2069  * controls it. The <s>_pipe_clk coming out of the GCC is requested
2070  * by the PHY driver for its operations.
2071  * We register the <s>_pipe_clksrc here. The gcc driver takes care
2072  * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
2073  * Below picture shows this relationship.
2074  *
2075  *         +---------------+
2076  *         |   PHY block   |<<---------------------------------------+
2077  *         |               |                                         |
2078  *         |   +-------+   |                   +-----+               |
2079  *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
2080  *    clk  |   +-------+   |                   +-----+
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     /* controllers using QMP phys use 125MHz pipe clock interface */
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      * Roll a devm action because the clock provider is the child node, but
2115      * the child node is not actually a device.
2116      */
2117     return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
2118 }
2119 
2120 /*
2121  * Display Port PLL driver block diagram for branch clocks
2122  *
2123  *              +------------------------------+
2124  *              |         DP_VCO_CLK           |
2125  *              |                              |
2126  *              |    +-------------------+     |
2127  *              |    |   (DP PLL/VCO)    |     |
2128  *              |    +---------+---------+     |
2129  *              |              v               |
2130  *              |   +----------+-----------+   |
2131  *              |   | hsclk_divsel_clk_src |   |
2132  *              |   +----------+-----------+   |
2133  *              +------------------------------+
2134  *                              |
2135  *          +---------<---------v------------>----------+
2136  *          |                                           |
2137  * +--------v----------------+                          |
2138  * |    dp_phy_pll_link_clk  |                          |
2139  * |     link_clk            |                          |
2140  * +--------+----------------+                          |
2141  *          |                                           |
2142  *          |                                           |
2143  *          v                                           v
2144  * Input to DISPCC block                                |
2145  * for link clk, crypto clk                             |
2146  * and interface clock                                  |
2147  *                                                      |
2148  *                                                      |
2149  *      +--------<------------+-----------------+---<---+
2150  *      |                     |                 |
2151  * +----v---------+  +--------v-----+  +--------v------+
2152  * | vco_divided  |  | vco_divided  |  | vco_divided   |
2153  * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
2154  * |              |  |              |  |               |
2155  * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
2156  * +-------+------+  +-----+--------+  +--------+------+
2157  *         |                 |                  |
2158  *         v---->----------v-------------<------v
2159  *                         |
2160  *              +----------+-----------------+
2161  *              |   dp_phy_pll_vco_div_clk   |
2162  *              +---------+------------------+
2163  *                        |
2164  *                        v
2165  *              Input to DISPCC block
2166  *              for DP pixel clock
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     /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
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      * Roll a devm action because the clock provider is the child node, but
2307      * the child node is not actually a device.
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      * Get memory resources for each phy lane:
2349      * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
2350      * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
2351      * For single lane PHYs: pcs_misc (optional) -> 3.
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      * If this is a dual-lane PHY, then there should be registers for the
2370      * second lane. Some old device trees did not specify this, so fall
2371      * back to old legacy behavior of assuming they can be reached at an
2372      * offset from the first lane.
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             /* In the old version, pcs_misc is at index 3. */
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      * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
2399      * based phys, so they essentially have pipe clock. So,
2400      * we return error in case phy is USB3 or PIPE type.
2401      * Otherwise, we initialize pipe clock to NULL for
2402      * all phys that don't need this.
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     /* Get the specific init parameters of QMP phy */
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; /* Setup clks and regulators */
2491 
2492     /* per PHY serdes; usually located at base address */
2493     usb_serdes = serdes = devm_platform_ioremap_resource(pdev, 0);
2494     if (IS_ERR(serdes))
2495         return PTR_ERR(serdes);
2496 
2497     /* per PHY dp_com; if PHY has dp_com control block */
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     /* Only two serdes for combo PHY */
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     /* do we have a rogue child node ? */
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      * Prevent runtime pm from being ON by default. Users can enable
2543      * it using power/control in sysfs.
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             /* Create per-lane phy */
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             /* Create per-lane phy */
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              * Register the pipe clock provided by phy.
2581              * See function description to see details of this pipe clock.
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");