Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
   4 */
   5
   6#include <linux/clk.h>
   7#include <linux/clk-provider.h>
   8#include <linux/delay.h>
   9#include <linux/err.h>
  10#include <linux/io.h>
  11#include <linux/iopoll.h>
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/of.h>
  15#include <linux/of_device.h>
  16#include <linux/of_address.h>
  17#include <linux/phy/phy.h>
  18#include <linux/platform_device.h>
  19#include <linux/regulator/consumer.h>
  20#include <linux/reset.h>
  21#include <linux/slab.h>
  22
  23#include "phy-qcom-qmp.h"
  24#include "phy-qcom-qmp-pcs-misc-v3.h"
  25#include "phy-qcom-qmp-pcs-usb-v4.h"
  26#include "phy-qcom-qmp-pcs-usb-v5.h"
  27
  28/* QPHY_SW_RESET bit */
  29#define SW_RESET				BIT(0)
  30/* QPHY_POWER_DOWN_CONTROL */
  31#define SW_PWRDN				BIT(0)
  32/* QPHY_START_CONTROL bits */
  33#define SERDES_START				BIT(0)
  34#define PCS_START				BIT(1)
  35/* QPHY_PCS_STATUS bit */
  36#define PHYSTATUS				BIT(6)
  37
  38/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
  39/* DP PHY soft reset */
  40#define SW_DPPHY_RESET				BIT(0)
  41/* mux to select DP PHY reset control, 0:HW control, 1: software reset */
  42#define SW_DPPHY_RESET_MUX			BIT(1)
  43/* USB3 PHY soft reset */
  44#define SW_USB3PHY_RESET			BIT(2)
  45/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
  46#define SW_USB3PHY_RESET_MUX			BIT(3)
  47
  48/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
  49#define USB3_MODE				BIT(0) /* enables USB3 mode */
  50#define DP_MODE					BIT(1) /* enables DP mode */
  51
  52/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
  53#define ARCVR_DTCT_EN				BIT(0)
  54#define ALFPS_DTCT_EN				BIT(1)
  55#define ARCVR_DTCT_EVENT_SEL			BIT(4)
  56
  57/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
  58#define IRQ_CLEAR				BIT(0)
  59
  60/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
  61#define CLAMP_EN				BIT(0) /* enables i/o clamp_n */
  62
  63#define PHY_INIT_COMPLETE_TIMEOUT		10000
  64
  65struct qmp_phy_init_tbl {
  66	unsigned int offset;
  67	unsigned int val;
  68	/*
  69	 * mask of lanes for which this register is written
  70	 * for cases when second lane needs different values
  71	 */
  72	u8 lane_mask;
  73};
  74
  75#define QMP_PHY_INIT_CFG(o, v)		\
  76	{				\
  77		.offset = o,		\
  78		.val = v,		\
  79		.lane_mask = 0xff,	\
  80	}
  81
  82#define QMP_PHY_INIT_CFG_LANE(o, v, l)	\
  83	{				\
  84		.offset = o,		\
  85		.val = v,		\
  86		.lane_mask = l,		\
  87	}
  88
  89/* set of registers with offsets different per-PHY */
  90enum qphy_reg_layout {
  91	/* PCS registers */
  92	QPHY_SW_RESET,
  93	QPHY_START_CTRL,
  94	QPHY_PCS_STATUS,
  95	QPHY_PCS_AUTONOMOUS_MODE_CTRL,
  96	QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
  97	QPHY_PCS_POWER_DOWN_CONTROL,
  98	/* Keep last to ensure regs_layout arrays are properly initialized */
  99	QPHY_LAYOUT_SIZE
 100};
 101
 102static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
 103	[QPHY_SW_RESET]			= QPHY_V3_PCS_SW_RESET,
 104	[QPHY_START_CTRL]		= QPHY_V3_PCS_START_CONTROL,
 105	[QPHY_PCS_STATUS]		= QPHY_V3_PCS_PCS_STATUS,
 106	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL,
 107	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR,
 108	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V3_PCS_POWER_DOWN_CONTROL,
 109};
 110
 111static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
 112	[QPHY_SW_RESET]			= QPHY_V4_PCS_SW_RESET,
 113	[QPHY_START_CTRL]		= QPHY_V4_PCS_START_CONTROL,
 114	[QPHY_PCS_STATUS]		= QPHY_V4_PCS_PCS_STATUS1,
 115	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V4_PCS_POWER_DOWN_CONTROL,
 116
 117	/* In PCS_USB */
 118	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL,
 119	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
 120};
 121
 122static const unsigned int qmp_v5_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
 123	[QPHY_SW_RESET]			= QPHY_V5_PCS_SW_RESET,
 124	[QPHY_START_CTRL]		= QPHY_V5_PCS_START_CONTROL,
 125	[QPHY_PCS_STATUS]		= QPHY_V5_PCS_PCS_STATUS1,
 126	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V5_PCS_POWER_DOWN_CONTROL,
 127
 128	/* In PCS_USB */
 129	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= QPHY_V5_PCS_USB3_AUTONOMOUS_MODE_CTRL,
 130	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V5_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
 131};
 132
 133static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
 134	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
 135	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
 136	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
 137	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
 138	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
 139	QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
 140	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x16),
 141	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
 142	QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
 143	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
 144	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
 145	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
 146	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
 147	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
 148	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
 149	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
 150	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
 151	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
 152	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
 153	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
 154	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
 155	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
 156	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
 157	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
 158	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
 159	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
 160	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
 161	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
 162	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
 163	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
 164	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
 165	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
 166	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
 167	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
 168	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
 169	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
 170};
 171
 172static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
 173	QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
 174	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
 175	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
 176	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
 177	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
 178};
 179
 180static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
 181	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
 182	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
 183	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
 184	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
 185	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
 186	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
 187	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
 188	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
 189	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
 190};
 191
 192static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
 193	/* FLL settings */
 194	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
 195	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
 196	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
 197	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
 198	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
 199
 200	/* Lock Det settings */
 201	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
 202	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
 203	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
 204	QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
 205
 206	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
 207	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
 208	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
 209	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
 210	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
 211	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
 212	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
 213	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
 214	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
 215	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
 216	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
 217	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
 218	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
 219	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
 220	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
 221	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
 222	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
 223	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
 224	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
 225
 226	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
 227	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
 228	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
 229	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
 230	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
 231	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
 232	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
 233	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
 234	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
 235	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
 236	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 237};
 238
 239static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = {
 240	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
 241	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
 242	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
 243	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
 244	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
 245	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
 246	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
 247	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
 248	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
 249	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
 250	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
 251	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
 252	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
 253	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
 254	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
 255	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
 256	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
 257	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
 258	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
 259	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
 260	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
 261	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
 262	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
 263	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
 264	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
 265	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
 266	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
 267	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
 268	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
 269	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
 270	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
 271	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
 272	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
 273	QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
 274	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
 275	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
 276	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
 277	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
 278	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
 279	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
 280};
 281
 282static const struct qmp_phy_init_tbl sm8150_usb3_tx_tbl[] = {
 283	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x00),
 284	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x00),
 285	QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
 286	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
 287	QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
 288};
 289
 290static const struct qmp_phy_init_tbl sm8150_usb3_rx_tbl[] = {
 291	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
 292	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
 293	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
 294	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
 295	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
 296	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
 297	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
 298	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
 299	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
 300	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
 301	QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
 302	QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0e),
 303	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
 304	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
 305	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
 306	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
 307	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
 308	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
 309	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
 310	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
 311	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
 312	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xbf),
 313	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x3f),
 314	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
 315	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x94),
 316	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
 317	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
 318	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
 319	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
 320	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
 321	QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
 322	QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
 323	QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
 324	QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
 325	QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
 326	QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
 327};
 328
 329static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = {
 330	/* Lock Det settings */
 331	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
 332	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
 333	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
 334
 335	QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
 336	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
 337	QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
 338	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
 339	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
 340	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
 341	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
 342	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
 343};
 344
 345static const struct qmp_phy_init_tbl sm8150_usb3_pcs_usb_tbl[] = {
 346	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
 347	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
 348};
 349
 350static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl[] = {
 351	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x60),
 352	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x60),
 353	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
 354	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
 355	QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
 356	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
 357	QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x40, 1),
 358	QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x54, 2),
 359};
 360
 361static const struct qmp_phy_init_tbl sm8250_usb3_rx_tbl[] = {
 362	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
 363	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
 364	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
 365	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
 366	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
 367	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
 368	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
 369	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
 370	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
 371	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
 372	QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
 373	QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
 374	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
 375	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
 376	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
 377	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
 378	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
 379	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
 380	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
 381	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
 382	QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff, 1),
 383	QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f, 2),
 384	QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f, 1),
 385	QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff, 2),
 386	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x7f),
 387	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
 388	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x97),
 389	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
 390	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
 391	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
 392	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
 393	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
 394	QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
 395	QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
 396	QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
 397	QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
 398	QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
 399	QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
 400};
 401
 402static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {
 403	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
 404	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
 405	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
 406	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
 407	QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
 408	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
 409	QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
 410	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
 411	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
 412	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
 413	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
 414	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
 415};
 416
 417static const struct qmp_phy_init_tbl sm8250_usb3_pcs_usb_tbl[] = {
 418	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
 419	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
 420};
 421
 422static const struct qmp_phy_init_tbl sm8350_usb3_tx_tbl[] = {
 423	QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_TX, 0x00),
 424	QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_RX, 0x00),
 425	QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
 426	QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
 427	QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x35),
 428	QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
 429	QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x7f),
 430	QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_5, 0x3f),
 431	QMP_PHY_INIT_CFG(QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12),
 432	QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
 433};
 434
 435static const struct qmp_phy_init_tbl sm8350_usb3_rx_tbl[] = {
 436	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
 437	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
 438	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
 439	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
 440	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
 441	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
 442	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
 443	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
 444	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
 445	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
 446	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
 447	QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
 448	QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
 449	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
 450	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
 451	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
 452	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
 453	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
 454	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
 455	QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
 456	QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
 457	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbb),
 458	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7b),
 459	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbb),
 460	QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3d, 1),
 461	QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3c, 2),
 462	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
 463	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
 464	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
 465	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xd2),
 466	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x13),
 467	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
 468	QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_EN_TIMER, 0x04),
 469	QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
 470	QMP_PHY_INIT_CFG(QSERDES_V5_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
 471	QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
 472	QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
 473	QMP_PHY_INIT_CFG(QSERDES_V5_RX_VTH_CODE, 0x10),
 474};
 475
 476static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl[] = {
 477	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
 478	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
 479	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
 480	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
 481	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
 482	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
 483	QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
 484	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
 485	QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
 486	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
 487	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
 488	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
 489	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
 490	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
 491};
 492
 493static const struct qmp_phy_init_tbl sm8350_usb3_pcs_usb_tbl[] = {
 494	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
 495	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
 496	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
 497	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
 498};
 499
 500struct qmp_usb_legacy_offsets {
 501	u16 serdes;
 502	u16 pcs;
 503	u16 pcs_usb;
 504	u16 tx;
 505	u16 rx;
 506};
 507
 508/* struct qmp_phy_cfg - per-PHY initialization config */
 509struct qmp_phy_cfg {
 510	int lanes;
 511
 512	const struct qmp_usb_legacy_offsets *offsets;
 513
 514	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
 515	const struct qmp_phy_init_tbl *serdes_tbl;
 516	int serdes_tbl_num;
 517	const struct qmp_phy_init_tbl *tx_tbl;
 518	int tx_tbl_num;
 519	const struct qmp_phy_init_tbl *rx_tbl;
 520	int rx_tbl_num;
 521	const struct qmp_phy_init_tbl *pcs_tbl;
 522	int pcs_tbl_num;
 523	const struct qmp_phy_init_tbl *pcs_usb_tbl;
 524	int pcs_usb_tbl_num;
 525
 526	/* clock ids to be requested */
 527	const char * const *clk_list;
 528	int num_clks;
 529	/* resets to be requested */
 530	const char * const *reset_list;
 531	int num_resets;
 532	/* regulators to be requested */
 533	const char * const *vreg_list;
 534	int num_vregs;
 535
 536	/* array of registers with different offsets */
 537	const unsigned int *regs;
 538
 539	/* Offset from PCS to PCS_USB region */
 540	unsigned int pcs_usb_offset;
 541};
 542
 543struct qmp_usb {
 544	struct device *dev;
 545
 546	const struct qmp_phy_cfg *cfg;
 547
 548	void __iomem *serdes;
 549	void __iomem *pcs;
 550	void __iomem *pcs_misc;
 551	void __iomem *pcs_usb;
 552	void __iomem *tx;
 553	void __iomem *rx;
 554	void __iomem *tx2;
 555	void __iomem *rx2;
 556
 557	void __iomem *dp_com;
 558
 559	struct clk *pipe_clk;
 560	struct clk_bulk_data *clks;
 561	struct reset_control_bulk_data *resets;
 562	struct regulator_bulk_data *vregs;
 563
 564	enum phy_mode mode;
 565
 566	struct phy *phy;
 567
 568	struct clk_fixed_rate pipe_clk_fixed;
 569};
 570
 571static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
 572{
 573	u32 reg;
 574
 575	reg = readl(base + offset);
 576	reg |= val;
 577	writel(reg, base + offset);
 578
 579	/* ensure that above write is through */
 580	readl(base + offset);
 581}
 582
 583static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
 584{
 585	u32 reg;
 586
 587	reg = readl(base + offset);
 588	reg &= ~val;
 589	writel(reg, base + offset);
 590
 591	/* ensure that above write is through */
 592	readl(base + offset);
 593}
 594
 595/* list of clocks required by phy */
 596static const char * const qmp_v3_phy_clk_l[] = {
 597	"aux", "cfg_ahb", "ref", "com_aux",
 598};
 599
 600static const char * const qmp_v4_ref_phy_clk_l[] = {
 601	"aux", "ref_clk_src", "ref", "com_aux",
 602};
 603
 604/* the primary usb3 phy on sm8250 doesn't have a ref clock */
 605static const char * const qmp_v4_sm8250_usbphy_clk_l[] = {
 606	"aux", "ref_clk_src", "com_aux"
 607};
 608
 609/* list of resets */
 610static const char * const msm8996_usb3phy_reset_l[] = {
 611	"phy", "common",
 612};
 613
 614static const char * const sc7180_usb3phy_reset_l[] = {
 615	"phy",
 616};
 617
 618/* list of regulators */
 619static const char * const qmp_phy_vreg_l[] = {
 620	"vdda-phy", "vdda-pll",
 621};
 622
 623static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
 624	.lanes			= 2,
 625
 626	.serdes_tbl		= qmp_v3_usb3_serdes_tbl,
 627	.serdes_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
 628	.tx_tbl			= qmp_v3_usb3_tx_tbl,
 629	.tx_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
 630	.rx_tbl			= qmp_v3_usb3_rx_tbl,
 631	.rx_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
 632	.pcs_tbl		= qmp_v3_usb3_pcs_tbl,
 633	.pcs_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
 634	.clk_list		= qmp_v3_phy_clk_l,
 635	.num_clks		= ARRAY_SIZE(qmp_v3_phy_clk_l),
 636	.reset_list		= msm8996_usb3phy_reset_l,
 637	.num_resets		= ARRAY_SIZE(msm8996_usb3phy_reset_l),
 638	.vreg_list		= qmp_phy_vreg_l,
 639	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 640	.regs			= qmp_v3_usb3phy_regs_layout,
 641};
 642
 643static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
 644	.lanes			= 2,
 645
 646	.serdes_tbl		= qmp_v3_usb3_serdes_tbl,
 647	.serdes_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
 648	.tx_tbl			= qmp_v3_usb3_tx_tbl,
 649	.tx_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
 650	.rx_tbl			= qmp_v3_usb3_rx_tbl,
 651	.rx_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
 652	.pcs_tbl		= qmp_v3_usb3_pcs_tbl,
 653	.pcs_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
 654	.clk_list		= qmp_v3_phy_clk_l,
 655	.num_clks		= ARRAY_SIZE(qmp_v3_phy_clk_l),
 656	.reset_list		= sc7180_usb3phy_reset_l,
 657	.num_resets		= ARRAY_SIZE(sc7180_usb3phy_reset_l),
 658	.vreg_list		= qmp_phy_vreg_l,
 659	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 660	.regs			= qmp_v3_usb3phy_regs_layout,
 661};
 662
 663static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
 664	.lanes			= 2,
 665
 666	.serdes_tbl		= sm8150_usb3_serdes_tbl,
 667	.serdes_tbl_num		= ARRAY_SIZE(sm8150_usb3_serdes_tbl),
 668	.tx_tbl			= sm8150_usb3_tx_tbl,
 669	.tx_tbl_num		= ARRAY_SIZE(sm8150_usb3_tx_tbl),
 670	.rx_tbl			= sm8150_usb3_rx_tbl,
 671	.rx_tbl_num		= ARRAY_SIZE(sm8150_usb3_rx_tbl),
 672	.pcs_tbl		= sm8150_usb3_pcs_tbl,
 673	.pcs_tbl_num		= ARRAY_SIZE(sm8150_usb3_pcs_tbl),
 674	.pcs_usb_tbl		= sm8150_usb3_pcs_usb_tbl,
 675	.pcs_usb_tbl_num	= ARRAY_SIZE(sm8150_usb3_pcs_usb_tbl),
 676	.clk_list		= qmp_v4_ref_phy_clk_l,
 677	.num_clks		= ARRAY_SIZE(qmp_v4_ref_phy_clk_l),
 678	.reset_list		= msm8996_usb3phy_reset_l,
 679	.num_resets		= ARRAY_SIZE(msm8996_usb3phy_reset_l),
 680	.vreg_list		= qmp_phy_vreg_l,
 681	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 682	.regs			= qmp_v4_usb3phy_regs_layout,
 683	.pcs_usb_offset		= 0x300,
 684};
 685
 686static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
 687	.lanes			= 2,
 688
 689	.serdes_tbl		= sm8150_usb3_serdes_tbl,
 690	.serdes_tbl_num		= ARRAY_SIZE(sm8150_usb3_serdes_tbl),
 691	.tx_tbl			= sm8250_usb3_tx_tbl,
 692	.tx_tbl_num		= ARRAY_SIZE(sm8250_usb3_tx_tbl),
 693	.rx_tbl			= sm8250_usb3_rx_tbl,
 694	.rx_tbl_num		= ARRAY_SIZE(sm8250_usb3_rx_tbl),
 695	.pcs_tbl		= sm8250_usb3_pcs_tbl,
 696	.pcs_tbl_num		= ARRAY_SIZE(sm8250_usb3_pcs_tbl),
 697	.pcs_usb_tbl		= sm8250_usb3_pcs_usb_tbl,
 698	.pcs_usb_tbl_num	= ARRAY_SIZE(sm8250_usb3_pcs_usb_tbl),
 699	.clk_list		= qmp_v4_sm8250_usbphy_clk_l,
 700	.num_clks		= ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
 701	.reset_list		= msm8996_usb3phy_reset_l,
 702	.num_resets		= ARRAY_SIZE(msm8996_usb3phy_reset_l),
 703	.vreg_list		= qmp_phy_vreg_l,
 704	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 705	.regs			= qmp_v4_usb3phy_regs_layout,
 706	.pcs_usb_offset		= 0x300,
 707};
 708
 709static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
 710	.lanes			= 2,
 711
 712	.serdes_tbl		= sm8150_usb3_serdes_tbl,
 713	.serdes_tbl_num		= ARRAY_SIZE(sm8150_usb3_serdes_tbl),
 714	.tx_tbl			= sm8350_usb3_tx_tbl,
 715	.tx_tbl_num		= ARRAY_SIZE(sm8350_usb3_tx_tbl),
 716	.rx_tbl			= sm8350_usb3_rx_tbl,
 717	.rx_tbl_num		= ARRAY_SIZE(sm8350_usb3_rx_tbl),
 718	.pcs_tbl		= sm8350_usb3_pcs_tbl,
 719	.pcs_tbl_num		= ARRAY_SIZE(sm8350_usb3_pcs_tbl),
 720	.pcs_usb_tbl		= sm8350_usb3_pcs_usb_tbl,
 721	.pcs_usb_tbl_num	= ARRAY_SIZE(sm8350_usb3_pcs_usb_tbl),
 722	.clk_list		= qmp_v4_sm8250_usbphy_clk_l,
 723	.num_clks		= ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
 724	.reset_list		= msm8996_usb3phy_reset_l,
 725	.num_resets		= ARRAY_SIZE(msm8996_usb3phy_reset_l),
 726	.vreg_list		= qmp_phy_vreg_l,
 727	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 728	.regs			= qmp_v5_usb3phy_regs_layout,
 729	.pcs_usb_offset		= 0x300,
 730};
 731
 732static void qmp_usb_legacy_configure_lane(void __iomem *base,
 733					const struct qmp_phy_init_tbl tbl[],
 734					int num,
 735					u8 lane_mask)
 736{
 737	int i;
 738	const struct qmp_phy_init_tbl *t = tbl;
 739
 740	if (!t)
 741		return;
 742
 743	for (i = 0; i < num; i++, t++) {
 744		if (!(t->lane_mask & lane_mask))
 745			continue;
 746
 747		writel(t->val, base + t->offset);
 748	}
 749}
 750
 751static void qmp_usb_legacy_configure(void __iomem *base,
 752				   const struct qmp_phy_init_tbl tbl[],
 753				   int num)
 754{
 755	qmp_usb_legacy_configure_lane(base, tbl, num, 0xff);
 756}
 757
 758static int qmp_usb_legacy_serdes_init(struct qmp_usb *qmp)
 759{
 760	const struct qmp_phy_cfg *cfg = qmp->cfg;
 761	void __iomem *serdes = qmp->serdes;
 762	const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
 763	int serdes_tbl_num = cfg->serdes_tbl_num;
 764
 765	qmp_usb_legacy_configure(serdes, serdes_tbl, serdes_tbl_num);
 766
 767	return 0;
 768}
 769
 770static void qmp_usb_legacy_init_dp_com(struct phy *phy)
 771{
 772	struct qmp_usb *qmp = phy_get_drvdata(phy);
 773	void __iomem *dp_com = qmp->dp_com;
 774
 775	qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
 776		     SW_PWRDN);
 777	/* override hardware control for reset of qmp phy */
 778	qphy_setbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
 779		     SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
 780		     SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
 781
 782	/* Default type-c orientation, i.e CC1 */
 783	qphy_setbits(dp_com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02);
 784
 785	qphy_setbits(dp_com, QPHY_V3_DP_COM_PHY_MODE_CTRL,
 786		     USB3_MODE | DP_MODE);
 787
 788	/* bring both QMP USB and QMP DP PHYs PCS block out of reset */
 789	qphy_clrbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
 790		     SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
 791		     SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
 792
 793	qphy_clrbits(dp_com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);
 794	qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
 795}
 796
 797static int qmp_usb_legacy_init(struct phy *phy)
 798{
 799	struct qmp_usb *qmp = phy_get_drvdata(phy);
 800	const struct qmp_phy_cfg *cfg = qmp->cfg;
 801	void __iomem *pcs = qmp->pcs;
 802	int ret;
 803
 804	ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
 805	if (ret) {
 806		dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
 807		return ret;
 808	}
 809
 810	ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 811	if (ret) {
 812		dev_err(qmp->dev, "reset assert failed\n");
 813		goto err_disable_regulators;
 814	}
 815
 816	ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
 817	if (ret) {
 818		dev_err(qmp->dev, "reset deassert failed\n");
 819		goto err_disable_regulators;
 820	}
 821
 822	ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
 823	if (ret)
 824		goto err_assert_reset;
 825
 826	qmp_usb_legacy_init_dp_com(phy);
 827
 828	qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
 829
 830	return 0;
 831
 832err_assert_reset:
 833	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 834err_disable_regulators:
 835	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 836
 837	return ret;
 838}
 839
 840static int qmp_usb_legacy_exit(struct phy *phy)
 841{
 842	struct qmp_usb *qmp = phy_get_drvdata(phy);
 843	const struct qmp_phy_cfg *cfg = qmp->cfg;
 844
 845	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 846
 847	clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
 848
 849	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 850
 851	return 0;
 852}
 853
 854static int qmp_usb_legacy_power_on(struct phy *phy)
 855{
 856	struct qmp_usb *qmp = phy_get_drvdata(phy);
 857	const struct qmp_phy_cfg *cfg = qmp->cfg;
 858	void __iomem *tx = qmp->tx;
 859	void __iomem *rx = qmp->rx;
 860	void __iomem *pcs = qmp->pcs;
 861	void __iomem *status;
 862	unsigned int val;
 863	int ret;
 864
 865	qmp_usb_legacy_serdes_init(qmp);
 866
 867	ret = clk_prepare_enable(qmp->pipe_clk);
 868	if (ret) {
 869		dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
 870		return ret;
 871	}
 872
 873	/* Tx, Rx, and PCS configurations */
 874	qmp_usb_legacy_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
 875	qmp_usb_legacy_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
 876
 877	if (cfg->lanes >= 2) {
 878		qmp_usb_legacy_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
 879		qmp_usb_legacy_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
 880	}
 881
 882	qmp_usb_legacy_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
 883
 884	usleep_range(10, 20);
 885
 886	/* Pull PHY out of reset state */
 887	qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
 888
 889	/* start SerDes and Phy-Coding-Sublayer */
 890	qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START);
 891
 892	status = pcs + cfg->regs[QPHY_PCS_STATUS];
 893	ret = readl_poll_timeout(status, val, !(val & PHYSTATUS), 200,
 894				 PHY_INIT_COMPLETE_TIMEOUT);
 895	if (ret) {
 896		dev_err(qmp->dev, "phy initialization timed-out\n");
 897		goto err_disable_pipe_clk;
 898	}
 899
 900	return 0;
 901
 902err_disable_pipe_clk:
 903	clk_disable_unprepare(qmp->pipe_clk);
 904
 905	return ret;
 906}
 907
 908static int qmp_usb_legacy_power_off(struct phy *phy)
 909{
 910	struct qmp_usb *qmp = phy_get_drvdata(phy);
 911	const struct qmp_phy_cfg *cfg = qmp->cfg;
 912
 913	clk_disable_unprepare(qmp->pipe_clk);
 914
 915	/* PHY reset */
 916	qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
 917
 918	/* stop SerDes and Phy-Coding-Sublayer */
 919	qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL],
 920			SERDES_START | PCS_START);
 921
 922	/* Put PHY into POWER DOWN state: active low */
 923	qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
 924			SW_PWRDN);
 925
 926	return 0;
 927}
 928
 929static int qmp_usb_legacy_enable(struct phy *phy)
 930{
 931	int ret;
 932
 933	ret = qmp_usb_legacy_init(phy);
 934	if (ret)
 935		return ret;
 936
 937	ret = qmp_usb_legacy_power_on(phy);
 938	if (ret)
 939		qmp_usb_legacy_exit(phy);
 940
 941	return ret;
 942}
 943
 944static int qmp_usb_legacy_disable(struct phy *phy)
 945{
 946	int ret;
 947
 948	ret = qmp_usb_legacy_power_off(phy);
 949	if (ret)
 950		return ret;
 951	return qmp_usb_legacy_exit(phy);
 952}
 953
 954static int qmp_usb_legacy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 955{
 956	struct qmp_usb *qmp = phy_get_drvdata(phy);
 957
 958	qmp->mode = mode;
 959
 960	return 0;
 961}
 962
 963static const struct phy_ops qmp_usb_legacy_phy_ops = {
 964	.init		= qmp_usb_legacy_enable,
 965	.exit		= qmp_usb_legacy_disable,
 966	.set_mode	= qmp_usb_legacy_set_mode,
 967	.owner		= THIS_MODULE,
 968};
 969
 970static void qmp_usb_legacy_enable_autonomous_mode(struct qmp_usb *qmp)
 971{
 972	const struct qmp_phy_cfg *cfg = qmp->cfg;
 973	void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs;
 974	void __iomem *pcs_misc = qmp->pcs_misc;
 975	u32 intr_mask;
 976
 977	if (qmp->mode == PHY_MODE_USB_HOST_SS ||
 978	    qmp->mode == PHY_MODE_USB_DEVICE_SS)
 979		intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
 980	else
 981		intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
 982
 983	/* Clear any pending interrupts status */
 984	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
 985	/* Writing 1 followed by 0 clears the interrupt */
 986	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
 987
 988	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
 989		     ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
 990
 991	/* Enable required PHY autonomous mode interrupts */
 992	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
 993
 994	/* Enable i/o clamp_n for autonomous mode */
 995	if (pcs_misc)
 996		qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
 997}
 998
 999static void qmp_usb_legacy_disable_autonomous_mode(struct qmp_usb *qmp)
1000{
1001	const struct qmp_phy_cfg *cfg = qmp->cfg;
1002	void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs;
1003	void __iomem *pcs_misc = qmp->pcs_misc;
1004
1005	/* Disable i/o clamp_n on resume for normal mode */
1006	if (pcs_misc)
1007		qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
1008
1009	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
1010		     ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
1011
1012	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
1013	/* Writing 1 followed by 0 clears the interrupt */
1014	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
1015}
1016
1017static int __maybe_unused qmp_usb_legacy_runtime_suspend(struct device *dev)
1018{
1019	struct qmp_usb *qmp = dev_get_drvdata(dev);
1020	const struct qmp_phy_cfg *cfg = qmp->cfg;
1021
1022	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
1023
1024	if (!qmp->phy->init_count) {
1025		dev_vdbg(dev, "PHY not initialized, bailing out\n");
1026		return 0;
1027	}
1028
1029	qmp_usb_legacy_enable_autonomous_mode(qmp);
1030
1031	clk_disable_unprepare(qmp->pipe_clk);
1032	clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
1033
1034	return 0;
1035}
1036
1037static int __maybe_unused qmp_usb_legacy_runtime_resume(struct device *dev)
1038{
1039	struct qmp_usb *qmp = dev_get_drvdata(dev);
1040	const struct qmp_phy_cfg *cfg = qmp->cfg;
1041	int ret = 0;
1042
1043	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
1044
1045	if (!qmp->phy->init_count) {
1046		dev_vdbg(dev, "PHY not initialized, bailing out\n");
1047		return 0;
1048	}
1049
1050	ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
1051	if (ret)
1052		return ret;
1053
1054	ret = clk_prepare_enable(qmp->pipe_clk);
1055	if (ret) {
1056		dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
1057		clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
1058		return ret;
1059	}
1060
1061	qmp_usb_legacy_disable_autonomous_mode(qmp);
1062
1063	return 0;
1064}
1065
1066static const struct dev_pm_ops qmp_usb_legacy_pm_ops = {
1067	SET_RUNTIME_PM_OPS(qmp_usb_legacy_runtime_suspend,
1068			   qmp_usb_legacy_runtime_resume, NULL)
1069};
1070
1071static int qmp_usb_legacy_vreg_init(struct qmp_usb *qmp)
1072{
1073	const struct qmp_phy_cfg *cfg = qmp->cfg;
1074	struct device *dev = qmp->dev;
1075	int num = cfg->num_vregs;
1076	int i;
1077
1078	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
1079	if (!qmp->vregs)
1080		return -ENOMEM;
1081
1082	for (i = 0; i < num; i++)
1083		qmp->vregs[i].supply = cfg->vreg_list[i];
1084
1085	return devm_regulator_bulk_get(dev, num, qmp->vregs);
1086}
1087
1088static int qmp_usb_legacy_reset_init(struct qmp_usb *qmp)
1089{
1090	const struct qmp_phy_cfg *cfg = qmp->cfg;
1091	struct device *dev = qmp->dev;
1092	int i;
1093	int ret;
1094
1095	qmp->resets = devm_kcalloc(dev, cfg->num_resets,
1096				   sizeof(*qmp->resets), GFP_KERNEL);
1097	if (!qmp->resets)
1098		return -ENOMEM;
1099
1100	for (i = 0; i < cfg->num_resets; i++)
1101		qmp->resets[i].id = cfg->reset_list[i];
1102
1103	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
1104	if (ret)
1105		return dev_err_probe(dev, ret, "failed to get resets\n");
1106
1107	return 0;
1108}
1109
1110static int qmp_usb_legacy_clk_init(struct qmp_usb *qmp)
1111{
1112	const struct qmp_phy_cfg *cfg = qmp->cfg;
1113	struct device *dev = qmp->dev;
1114	int num = cfg->num_clks;
1115	int i;
1116
1117	qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
1118	if (!qmp->clks)
1119		return -ENOMEM;
1120
1121	for (i = 0; i < num; i++)
1122		qmp->clks[i].id = cfg->clk_list[i];
1123
1124	return devm_clk_bulk_get(dev, num, qmp->clks);
1125}
1126
1127static void phy_clk_release_provider(void *res)
1128{
1129	of_clk_del_provider(res);
1130}
1131
1132/*
1133 * Register a fixed rate pipe clock.
1134 *
1135 * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
1136 * controls it. The <s>_pipe_clk coming out of the GCC is requested
1137 * by the PHY driver for its operations.
1138 * We register the <s>_pipe_clksrc here. The gcc driver takes care
1139 * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
1140 * Below picture shows this relationship.
1141 *
1142 *         +---------------+
1143 *         |   PHY block   |<<---------------------------------------+
1144 *         |               |                                         |
1145 *         |   +-------+   |                   +-----+               |
1146 *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
1147 *    clk  |   +-------+   |                   +-----+
1148 *         +---------------+
1149 */
1150static int phy_pipe_clk_register(struct qmp_usb *qmp, struct device_node *np)
1151{
1152	struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
1153	struct clk_init_data init = { };
1154	int ret;
1155
1156	ret = of_property_read_string(np, "clock-output-names", &init.name);
1157	if (ret) {
1158		dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
1159		return ret;
1160	}
1161
1162	init.ops = &clk_fixed_rate_ops;
1163
1164	/* controllers using QMP phys use 125MHz pipe clock interface */
1165	fixed->fixed_rate = 125000000;
1166	fixed->hw.init = &init;
1167
1168	ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
1169	if (ret)
1170		return ret;
1171
1172	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
1173	if (ret)
1174		return ret;
1175
1176	/*
1177	 * Roll a devm action because the clock provider is the child node, but
1178	 * the child node is not actually a device.
1179	 */
1180	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
1181}
1182
1183static void __iomem *qmp_usb_legacy_iomap(struct device *dev, struct device_node *np,
1184					int index, bool exclusive)
1185{
1186	struct resource res;
1187
1188	if (!exclusive) {
1189		if (of_address_to_resource(np, index, &res))
1190			return IOMEM_ERR_PTR(-EINVAL);
1191
1192		return devm_ioremap(dev, res.start, resource_size(&res));
1193	}
1194
1195	return devm_of_iomap(dev, np, index, NULL);
1196}
1197
1198static int qmp_usb_legacy_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np)
1199{
1200	struct platform_device *pdev = to_platform_device(qmp->dev);
1201	const struct qmp_phy_cfg *cfg = qmp->cfg;
1202	struct device *dev = qmp->dev;
1203	bool exclusive = true;
1204
1205	qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
1206	if (IS_ERR(qmp->serdes))
1207		return PTR_ERR(qmp->serdes);
1208
1209	qmp->dp_com = devm_platform_ioremap_resource(pdev, 1);
1210	if (IS_ERR(qmp->dp_com))
1211		return PTR_ERR(qmp->dp_com);
1212
1213	/*
1214	 * Get memory resources for the PHY:
1215	 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
1216	 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
1217	 * For single lane PHYs: pcs_misc (optional) -> 3.
1218	 */
1219	qmp->tx = devm_of_iomap(dev, np, 0, NULL);
1220	if (IS_ERR(qmp->tx))
1221		return PTR_ERR(qmp->tx);
1222
1223	qmp->rx = devm_of_iomap(dev, np, 1, NULL);
1224	if (IS_ERR(qmp->rx))
1225		return PTR_ERR(qmp->rx);
1226
1227	qmp->pcs = qmp_usb_legacy_iomap(dev, np, 2, exclusive);
1228	if (IS_ERR(qmp->pcs))
1229		return PTR_ERR(qmp->pcs);
1230
1231	if (cfg->pcs_usb_offset)
1232		qmp->pcs_usb = qmp->pcs + cfg->pcs_usb_offset;
1233
1234	if (cfg->lanes >= 2) {
1235		qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
1236		if (IS_ERR(qmp->tx2))
1237			return PTR_ERR(qmp->tx2);
1238
1239		qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
1240		if (IS_ERR(qmp->rx2))
1241			return PTR_ERR(qmp->rx2);
1242
1243		qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
1244	} else {
1245		qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
1246	}
1247
1248	if (IS_ERR(qmp->pcs_misc)) {
1249		dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
1250		qmp->pcs_misc = NULL;
1251	}
1252
1253	qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL);
1254	if (IS_ERR(qmp->pipe_clk)) {
1255		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
1256				     "failed to get pipe clock\n");
1257	}
1258
1259	return 0;
1260}
1261
1262static int qmp_usb_legacy_parse_dt(struct qmp_usb *qmp)
1263{
1264	struct platform_device *pdev = to_platform_device(qmp->dev);
1265	const struct qmp_phy_cfg *cfg = qmp->cfg;
1266	const struct qmp_usb_legacy_offsets *offs = cfg->offsets;
1267	struct device *dev = qmp->dev;
1268	void __iomem *base;
1269
1270	if (!offs)
1271		return -EINVAL;
1272
1273	base = devm_platform_ioremap_resource(pdev, 0);
1274	if (IS_ERR(base))
1275		return PTR_ERR(base);
1276
1277	qmp->serdes = base + offs->serdes;
1278	qmp->pcs = base + offs->pcs;
1279	qmp->pcs_usb = base + offs->pcs_usb;
1280	qmp->tx = base + offs->tx;
1281	qmp->rx = base + offs->rx;
1282
1283	qmp->pipe_clk = devm_clk_get(dev, "pipe");
1284	if (IS_ERR(qmp->pipe_clk)) {
1285		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
1286				     "failed to get pipe clock\n");
1287	}
1288
1289	return 0;
1290}
1291
1292static int qmp_usb_legacy_probe(struct platform_device *pdev)
1293{
1294	struct device *dev = &pdev->dev;
1295	struct phy_provider *phy_provider;
1296	struct device_node *np;
1297	struct qmp_usb *qmp;
1298	int ret;
1299
1300	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
1301	if (!qmp)
1302		return -ENOMEM;
1303
1304	qmp->dev = dev;
1305
1306	qmp->cfg = of_device_get_match_data(dev);
1307	if (!qmp->cfg)
1308		return -EINVAL;
1309
1310	ret = qmp_usb_legacy_clk_init(qmp);
1311	if (ret)
1312		return ret;
1313
1314	ret = qmp_usb_legacy_reset_init(qmp);
1315	if (ret)
1316		return ret;
1317
1318	ret = qmp_usb_legacy_vreg_init(qmp);
1319	if (ret)
1320		return ret;
1321
1322	/* Check for legacy binding with child node. */
1323	np = of_get_next_available_child(dev->of_node, NULL);
1324	if (np) {
1325		ret = qmp_usb_legacy_parse_dt_legacy(qmp, np);
1326	} else {
1327		np = of_node_get(dev->of_node);
1328		ret = qmp_usb_legacy_parse_dt(qmp);
1329	}
1330	if (ret)
1331		goto err_node_put;
1332
1333	pm_runtime_set_active(dev);
1334	ret = devm_pm_runtime_enable(dev);
1335	if (ret)
1336		goto err_node_put;
1337	/*
1338	 * Prevent runtime pm from being ON by default. Users can enable
1339	 * it using power/control in sysfs.
1340	 */
1341	pm_runtime_forbid(dev);
1342
1343	ret = phy_pipe_clk_register(qmp, np);
1344	if (ret)
1345		goto err_node_put;
1346
1347	qmp->phy = devm_phy_create(dev, np, &qmp_usb_legacy_phy_ops);
1348	if (IS_ERR(qmp->phy)) {
1349		ret = PTR_ERR(qmp->phy);
1350		dev_err(dev, "failed to create PHY: %d\n", ret);
1351		goto err_node_put;
1352	}
1353
1354	phy_set_drvdata(qmp->phy, qmp);
1355
1356	of_node_put(np);
1357
1358	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1359
1360	return PTR_ERR_OR_ZERO(phy_provider);
1361
1362err_node_put:
1363	of_node_put(np);
1364	return ret;
1365}
1366
1367static const struct of_device_id qmp_usb_legacy_of_match_table[] = {
1368	{
1369		.compatible = "qcom,sc7180-qmp-usb3-phy",
1370		.data = &sc7180_usb3phy_cfg,
1371	}, {
1372		.compatible = "qcom,sc8180x-qmp-usb3-phy",
1373		.data = &sm8150_usb3phy_cfg,
1374	}, {
1375		.compatible = "qcom,sdm845-qmp-usb3-phy",
1376		.data = &qmp_v3_usb3phy_cfg,
1377	}, {
1378		.compatible = "qcom,sm8150-qmp-usb3-phy",
1379		.data = &sm8150_usb3phy_cfg,
1380	}, {
1381		.compatible = "qcom,sm8250-qmp-usb3-phy",
1382		.data = &sm8250_usb3phy_cfg,
1383	}, {
1384		.compatible = "qcom,sm8350-qmp-usb3-phy",
1385		.data = &sm8350_usb3phy_cfg,
1386	}, {
1387		.compatible = "qcom,sm8450-qmp-usb3-phy",
1388		.data = &sm8350_usb3phy_cfg,
1389	},
1390	{ },
1391};
1392MODULE_DEVICE_TABLE(of, qmp_usb_legacy_of_match_table);
1393
1394static struct platform_driver qmp_usb_legacy_driver = {
1395	.probe		= qmp_usb_legacy_probe,
1396	.driver = {
1397		.name	= "qcom-qmp-usb-legacy-phy",
1398		.pm	= &qmp_usb_legacy_pm_ops,
1399		.of_match_table = qmp_usb_legacy_of_match_table,
1400	},
1401};
1402
1403module_platform_driver(qmp_usb_legacy_driver);
1404
1405MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
1406MODULE_DESCRIPTION("Qualcomm QMP legacy USB+DP PHY driver");
1407MODULE_LICENSE("GPL v2");