Linux Audio

Check our new training course

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