Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
   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
  25/* QPHY_SW_RESET bit */
  26#define SW_RESET				BIT(0)
  27/* QPHY_POWER_DOWN_CONTROL */
  28#define SW_PWRDN				BIT(0)
  29/* QPHY_START_CONTROL bits */
  30#define SERDES_START				BIT(0)
  31#define PCS_START				BIT(1)
  32/* QPHY_PCS_READY_STATUS bit */
  33#define PCS_READY				BIT(0)
  34
  35#define PHY_INIT_COMPLETE_TIMEOUT		10000
  36
  37struct qmp_phy_init_tbl {
  38	unsigned int offset;
  39	unsigned int val;
  40	/*
  41	 * mask of lanes for which this register is written
  42	 * for cases when second lane needs different values
  43	 */
  44	u8 lane_mask;
  45};
  46
  47#define QMP_PHY_INIT_CFG(o, v)		\
  48	{				\
  49		.offset = o,		\
  50		.val = v,		\
  51		.lane_mask = 0xff,	\
  52	}
  53
  54#define QMP_PHY_INIT_CFG_LANE(o, v, l)	\
  55	{				\
  56		.offset = o,		\
  57		.val = v,		\
  58		.lane_mask = l,		\
  59	}
  60
  61/* set of registers with offsets different per-PHY */
  62enum qphy_reg_layout {
  63	/* PCS registers */
  64	QPHY_SW_RESET,
  65	QPHY_START_CTRL,
  66	QPHY_PCS_READY_STATUS,
  67	QPHY_PCS_POWER_DOWN_CONTROL,
  68	/* Keep last to ensure regs_layout arrays are properly initialized */
  69	QPHY_LAYOUT_SIZE
  70};
  71
  72static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
  73	[QPHY_START_CTRL]		= 0x00,
  74	[QPHY_PCS_READY_STATUS]		= 0x168,
  75	[QPHY_PCS_POWER_DOWN_CONTROL]	= 0x04,
  76};
  77
  78static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
  79	[QPHY_START_CTRL]		= 0x00,
  80	[QPHY_PCS_READY_STATUS]		= 0x160,
  81	[QPHY_PCS_POWER_DOWN_CONTROL]	= 0x04,
  82};
  83
  84static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
  85	[QPHY_START_CTRL]		= 0x00,
  86	[QPHY_PCS_READY_STATUS]		= 0x168,
  87	[QPHY_PCS_POWER_DOWN_CONTROL]	= 0x04,
  88};
  89
  90static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
  91	[QPHY_START_CTRL]		= QPHY_V4_PCS_UFS_PHY_START,
  92	[QPHY_PCS_READY_STATUS]		= QPHY_V4_PCS_UFS_READY_STATUS,
  93	[QPHY_SW_RESET]			= QPHY_V4_PCS_UFS_SW_RESET,
  94	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL,
  95};
  96
  97static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
  98	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
  99	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
 100	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
 101	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
 102	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
 103	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
 104	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
 105	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
 106	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
 107	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
 108	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
 109	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
 110	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
 111	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
 112	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
 113	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
 114	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
 115	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
 116	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
 117	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
 118	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
 119	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
 120	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
 121	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
 122	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
 123	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
 124	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
 125	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
 126	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
 127	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
 128	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
 129	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
 130	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
 131	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
 132	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
 133	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
 134	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
 135	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
 136	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
 137	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
 138	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
 139	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
 140	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
 141	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
 142	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
 143	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
 144};
 145
 146static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
 147	QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
 148	QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
 149};
 150
 151static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
 152	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
 153	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
 154	QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
 155	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
 156	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
 157	QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
 158	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
 159	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
 160	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
 161	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
 162	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
 163};
 164
 165static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
 166	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
 167	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
 168	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
 169	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
 170	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
 171	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
 172	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
 173	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
 174	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
 175	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
 176	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
 177	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
 178	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
 179	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
 180	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
 181	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
 182	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
 183	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
 184	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
 185	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
 186	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
 187	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
 188	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
 189	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
 190	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
 191	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
 192	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
 193	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
 194	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
 195	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
 196	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
 197	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
 198	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
 199	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
 200	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
 201	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
 202	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
 203	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
 204	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
 205	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
 206	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
 207	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
 208	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
 209	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
 210	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
 211	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
 212	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
 213	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
 214	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
 215	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
 216
 217	/* Rate B */
 218	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
 219};
 220
 221static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
 222	QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
 223	QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
 224};
 225
 226static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
 227	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
 228	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
 229	QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
 230	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
 231	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
 232	QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
 233	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
 234	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
 235	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
 236	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
 237	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
 238	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
 239	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
 240	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
 241	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
 242};
 243
 244static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
 245	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_PWM_GEAR_BAND, 0x15),
 246	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SIGDET_CTRL2, 0x6d),
 247	QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_DRV_LVL, 0x0f),
 248	QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
 249	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
 250	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SYM_RESYNC_CTRL, 0x03),
 251	QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
 252	QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
 253	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
 254};
 255
 256static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
 257	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
 258	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
 259	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
 260	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
 261	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
 262	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
 263	QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
 264	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
 265	QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
 266	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
 267	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
 268	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
 269	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
 270	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
 271	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
 272	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
 273	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
 274	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
 275	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
 276	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
 277	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
 278	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
 279	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
 280	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
 281	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
 282	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
 283	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
 284	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
 285	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
 286	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
 287	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
 288	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
 289	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
 290	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
 291	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
 292	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
 293
 294	/* Rate B */
 295	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
 296};
 297
 298static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
 299	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
 300	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
 301	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
 302};
 303
 304static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
 305	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
 306	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
 307	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
 308	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
 309	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
 310	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
 311	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
 312	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
 313	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
 314	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
 315	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
 316	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
 317	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
 318	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
 319	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
 320	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
 321};
 322
 323static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
 324	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e),
 325	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
 326	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
 327	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
 328	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
 329	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f),
 330	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a),
 331	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
 332};
 333
 334static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
 335	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
 336	QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
 337	QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
 338	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
 339	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
 340	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
 341	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
 342	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
 343	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
 344	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
 345	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
 346	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
 347	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
 348	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
 349	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
 350	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
 351	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
 352	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
 353	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
 354	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
 355	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
 356	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
 357	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
 358	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
 359
 360	/* Rate B */
 361	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
 362};
 363
 364static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
 365	QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
 366	QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
 367	QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
 368	QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
 369	QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
 370	QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
 371};
 372
 373static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
 374	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
 375	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
 376	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
 377	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
 378	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
 379	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
 380	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
 381	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
 382	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
 383	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
 384	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
 385	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
 386	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
 387	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
 388	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
 389	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
 390	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
 391	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
 392	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
 393	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
 394	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
 395	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
 396	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
 397	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
 398	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
 399	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
 400	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
 401	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
 402	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
 403	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
 404	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
 405	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
 406	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
 407	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
 408
 409};
 410
 411static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
 412	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
 413	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
 414	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
 415	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
 416	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
 417	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
 418	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
 419};
 420
 421static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
 422	QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
 423	QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
 424	QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
 425	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
 426	QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
 427	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
 428	QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
 429	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
 430	QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
 431	QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
 432	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
 433	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
 434	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
 435	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
 436	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
 437	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
 438	QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
 439	QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
 440	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
 441	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
 442	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
 443	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
 444	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
 445	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
 446
 447	/* Rate B */
 448	QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
 449};
 450
 451static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
 452	QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
 453	QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
 454	QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
 455	QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
 456	QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
 457	QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
 458	QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
 459	QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
 460	QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
 461};
 462
 463static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
 464	QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
 465	QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
 466	QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
 467	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
 468	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
 469	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
 470	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
 471	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
 472	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
 473	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
 474	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
 475	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
 476	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
 477	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
 478	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
 479	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
 480	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
 481	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
 482	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
 483	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
 484	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
 485	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
 486	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
 487	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
 488	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
 489	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
 490	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
 491	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
 492	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
 493	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
 494	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
 495	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
 496	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
 497	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
 498	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
 499	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
 500	QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
 501};
 502
 503static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
 504	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
 505	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
 506	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
 507	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
 508	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
 509	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
 510	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
 511	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
 512	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
 513	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
 514	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
 515	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
 516	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
 517	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
 518	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
 519};
 520
 521struct qmp_ufs_offsets {
 522	u16 serdes;
 523	u16 pcs;
 524	u16 tx;
 525	u16 rx;
 526	u16 tx2;
 527	u16 rx2;
 528};
 529
 530/* struct qmp_phy_cfg - per-PHY initialization config */
 531struct qmp_phy_cfg {
 532	int lanes;
 533
 534	const struct qmp_ufs_offsets *offsets;
 535
 536	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
 537	const struct qmp_phy_init_tbl *serdes_tbl;
 538	int serdes_tbl_num;
 539	const struct qmp_phy_init_tbl *tx_tbl;
 540	int tx_tbl_num;
 541	const struct qmp_phy_init_tbl *rx_tbl;
 542	int rx_tbl_num;
 543	const struct qmp_phy_init_tbl *pcs_tbl;
 544	int pcs_tbl_num;
 545
 546	/* clock ids to be requested */
 547	const char * const *clk_list;
 548	int num_clks;
 549	/* regulators to be requested */
 550	const char * const *vreg_list;
 551	int num_vregs;
 552
 553	/* array of registers with different offsets */
 554	const unsigned int *regs;
 555
 556	/* true, if PCS block has no separate SW_RESET register */
 557	bool no_pcs_sw_reset;
 558};
 559
 560struct qmp_ufs {
 561	struct device *dev;
 562
 563	const struct qmp_phy_cfg *cfg;
 564
 565	void __iomem *serdes;
 566	void __iomem *pcs;
 567	void __iomem *pcs_misc;
 568	void __iomem *tx;
 569	void __iomem *rx;
 570	void __iomem *tx2;
 571	void __iomem *rx2;
 572
 573	struct clk_bulk_data *clks;
 574	struct regulator_bulk_data *vregs;
 575	struct reset_control *ufs_reset;
 576
 577	struct phy *phy;
 578};
 579
 580static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
 581{
 582	u32 reg;
 583
 584	reg = readl(base + offset);
 585	reg |= val;
 586	writel(reg, base + offset);
 587
 588	/* ensure that above write is through */
 589	readl(base + offset);
 590}
 591
 592static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
 593{
 594	u32 reg;
 595
 596	reg = readl(base + offset);
 597	reg &= ~val;
 598	writel(reg, base + offset);
 599
 600	/* ensure that above write is through */
 601	readl(base + offset);
 602}
 603
 604/* list of clocks required by phy */
 605static const char * const msm8996_ufs_phy_clk_l[] = {
 606	"ref",
 607};
 608
 609/* the primary usb3 phy on sm8250 doesn't have a ref clock */
 610static const char * const sm8450_ufs_phy_clk_l[] = {
 611	"qref", "ref", "ref_aux",
 612};
 613
 614static const char * const sdm845_ufs_phy_clk_l[] = {
 615	"ref", "ref_aux",
 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_ufs_offsets qmp_ufs_offsets_v5 = {
 624	.serdes		= 0,
 625	.pcs		= 0xc00,
 626	.tx		= 0x400,
 627	.rx		= 0x600,
 628	.tx2		= 0x800,
 629	.rx2		= 0xa00,
 630};
 631
 632static const struct qmp_phy_cfg msm8996_ufs_cfg = {
 633	.lanes			= 1,
 634
 635	.serdes_tbl		= msm8996_ufs_serdes_tbl,
 636	.serdes_tbl_num		= ARRAY_SIZE(msm8996_ufs_serdes_tbl),
 637	.tx_tbl			= msm8996_ufs_tx_tbl,
 638	.tx_tbl_num		= ARRAY_SIZE(msm8996_ufs_tx_tbl),
 639	.rx_tbl			= msm8996_ufs_rx_tbl,
 640	.rx_tbl_num		= ARRAY_SIZE(msm8996_ufs_rx_tbl),
 641
 642	.clk_list		= msm8996_ufs_phy_clk_l,
 643	.num_clks		= ARRAY_SIZE(msm8996_ufs_phy_clk_l),
 644
 645	.vreg_list		= qmp_phy_vreg_l,
 646	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 647
 648	.regs			= msm8996_ufsphy_regs_layout,
 649
 650	.no_pcs_sw_reset	= true,
 651};
 652
 653static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {
 654	.lanes			= 2,
 655
 656	.offsets		= &qmp_ufs_offsets_v5,
 657
 658	.serdes_tbl		= sm8350_ufsphy_serdes_tbl,
 659	.serdes_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
 660	.tx_tbl			= sm8350_ufsphy_tx_tbl,
 661	.tx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
 662	.rx_tbl			= sm8350_ufsphy_rx_tbl,
 663	.rx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
 664	.pcs_tbl		= sm8350_ufsphy_pcs_tbl,
 665	.pcs_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
 666	.clk_list		= sdm845_ufs_phy_clk_l,
 667	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
 668	.vreg_list		= qmp_phy_vreg_l,
 669	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 670	.regs			= sm8150_ufsphy_regs_layout,
 671};
 672
 673static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
 674	.lanes			= 2,
 675
 676	.serdes_tbl		= sdm845_ufsphy_serdes_tbl,
 677	.serdes_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
 678	.tx_tbl			= sdm845_ufsphy_tx_tbl,
 679	.tx_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
 680	.rx_tbl			= sdm845_ufsphy_rx_tbl,
 681	.rx_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
 682	.pcs_tbl		= sdm845_ufsphy_pcs_tbl,
 683	.pcs_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
 684	.clk_list		= sdm845_ufs_phy_clk_l,
 685	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
 686	.vreg_list		= qmp_phy_vreg_l,
 687	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 688	.regs			= sdm845_ufsphy_regs_layout,
 689
 690	.no_pcs_sw_reset	= true,
 691};
 692
 693static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
 694	.lanes			= 1,
 695
 696	.serdes_tbl		= sm6115_ufsphy_serdes_tbl,
 697	.serdes_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
 698	.tx_tbl			= sm6115_ufsphy_tx_tbl,
 699	.tx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
 700	.rx_tbl			= sm6115_ufsphy_rx_tbl,
 701	.rx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
 702	.pcs_tbl		= sm6115_ufsphy_pcs_tbl,
 703	.pcs_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
 704	.clk_list		= sdm845_ufs_phy_clk_l,
 705	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
 706	.vreg_list		= qmp_phy_vreg_l,
 707	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 708	.regs			= sm6115_ufsphy_regs_layout,
 709
 710	.no_pcs_sw_reset	= true,
 711};
 712
 713static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
 714	.lanes			= 2,
 715
 716	.serdes_tbl		= sm8150_ufsphy_serdes_tbl,
 717	.serdes_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
 718	.tx_tbl			= sm8150_ufsphy_tx_tbl,
 719	.tx_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
 720	.rx_tbl			= sm8150_ufsphy_rx_tbl,
 721	.rx_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
 722	.pcs_tbl		= sm8150_ufsphy_pcs_tbl,
 723	.pcs_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
 724	.clk_list		= sdm845_ufs_phy_clk_l,
 725	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
 726	.vreg_list		= qmp_phy_vreg_l,
 727	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 728	.regs			= sm8150_ufsphy_regs_layout,
 729};
 730
 731static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
 732	.lanes			= 2,
 733
 734	.serdes_tbl		= sm8350_ufsphy_serdes_tbl,
 735	.serdes_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
 736	.tx_tbl			= sm8350_ufsphy_tx_tbl,
 737	.tx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
 738	.rx_tbl			= sm8350_ufsphy_rx_tbl,
 739	.rx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
 740	.pcs_tbl		= sm8350_ufsphy_pcs_tbl,
 741	.pcs_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
 742	.clk_list		= sdm845_ufs_phy_clk_l,
 743	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
 744	.vreg_list		= qmp_phy_vreg_l,
 745	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 746	.regs			= sm8150_ufsphy_regs_layout,
 747};
 748
 749static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
 750	.lanes			= 2,
 751
 752	.serdes_tbl		= sm8350_ufsphy_serdes_tbl,
 753	.serdes_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
 754	.tx_tbl			= sm8350_ufsphy_tx_tbl,
 755	.tx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
 756	.rx_tbl			= sm8350_ufsphy_rx_tbl,
 757	.rx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
 758	.pcs_tbl		= sm8350_ufsphy_pcs_tbl,
 759	.pcs_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
 760	.clk_list		= sm8450_ufs_phy_clk_l,
 761	.num_clks		= ARRAY_SIZE(sm8450_ufs_phy_clk_l),
 762	.vreg_list		= qmp_phy_vreg_l,
 763	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 764	.regs			= sm8150_ufsphy_regs_layout,
 765};
 766
 767static void qmp_ufs_configure_lane(void __iomem *base,
 768					const struct qmp_phy_init_tbl tbl[],
 769					int num,
 770					u8 lane_mask)
 771{
 772	int i;
 773	const struct qmp_phy_init_tbl *t = tbl;
 774
 775	if (!t)
 776		return;
 777
 778	for (i = 0; i < num; i++, t++) {
 779		if (!(t->lane_mask & lane_mask))
 780			continue;
 781
 782		writel(t->val, base + t->offset);
 783	}
 784}
 785
 786static void qmp_ufs_configure(void __iomem *base,
 787				   const struct qmp_phy_init_tbl tbl[],
 788				   int num)
 789{
 790	qmp_ufs_configure_lane(base, tbl, num, 0xff);
 791}
 792
 793static int qmp_ufs_serdes_init(struct qmp_ufs *qmp)
 794{
 795	const struct qmp_phy_cfg *cfg = qmp->cfg;
 796	void __iomem *serdes = qmp->serdes;
 797	const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
 798	int serdes_tbl_num = cfg->serdes_tbl_num;
 799
 800	qmp_ufs_configure(serdes, serdes_tbl, serdes_tbl_num);
 801
 802	return 0;
 803}
 804
 805static int qmp_ufs_com_init(struct qmp_ufs *qmp)
 806{
 807	const struct qmp_phy_cfg *cfg = qmp->cfg;
 808	void __iomem *pcs = qmp->pcs;
 809	int ret;
 810
 811	ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
 812	if (ret) {
 813		dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
 814		return ret;
 815	}
 816
 817	ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
 818	if (ret)
 819		goto err_disable_regulators;
 820
 821	qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
 822
 823	return 0;
 824
 825err_disable_regulators:
 826	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 827
 828	return ret;
 829}
 830
 831static int qmp_ufs_com_exit(struct qmp_ufs *qmp)
 832{
 833	const struct qmp_phy_cfg *cfg = qmp->cfg;
 834
 835	reset_control_assert(qmp->ufs_reset);
 836
 837	clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
 838
 839	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 840
 841	return 0;
 842}
 843
 844static int qmp_ufs_init(struct phy *phy)
 845{
 846	struct qmp_ufs *qmp = phy_get_drvdata(phy);
 847	const struct qmp_phy_cfg *cfg = qmp->cfg;
 848	int ret;
 849	dev_vdbg(qmp->dev, "Initializing QMP phy\n");
 850
 851	if (cfg->no_pcs_sw_reset) {
 852		/*
 853		 * Get UFS reset, which is delayed until now to avoid a
 854		 * circular dependency where UFS needs its PHY, but the PHY
 855		 * needs this UFS reset.
 856		 */
 857		if (!qmp->ufs_reset) {
 858			qmp->ufs_reset =
 859				devm_reset_control_get_exclusive(qmp->dev,
 860								 "ufsphy");
 861
 862			if (IS_ERR(qmp->ufs_reset)) {
 863				ret = PTR_ERR(qmp->ufs_reset);
 864				dev_err(qmp->dev,
 865					"failed to get UFS reset: %d\n",
 866					ret);
 867
 868				qmp->ufs_reset = NULL;
 869				return ret;
 870			}
 871		}
 872
 873		ret = reset_control_assert(qmp->ufs_reset);
 874		if (ret)
 875			return ret;
 876	}
 877
 878	ret = qmp_ufs_com_init(qmp);
 879	if (ret)
 880		return ret;
 881
 882	return 0;
 883}
 884
 885static int qmp_ufs_power_on(struct phy *phy)
 886{
 887	struct qmp_ufs *qmp = phy_get_drvdata(phy);
 888	const struct qmp_phy_cfg *cfg = qmp->cfg;
 889	void __iomem *tx = qmp->tx;
 890	void __iomem *rx = qmp->rx;
 891	void __iomem *pcs = qmp->pcs;
 892	void __iomem *status;
 893	unsigned int val;
 894	int ret;
 895
 896	qmp_ufs_serdes_init(qmp);
 897
 898	/* Tx, Rx, and PCS configurations */
 899	qmp_ufs_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
 900	qmp_ufs_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
 901
 902	if (cfg->lanes >= 2) {
 903		qmp_ufs_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
 904		qmp_ufs_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
 905	}
 906
 907	qmp_ufs_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
 908
 909	ret = reset_control_deassert(qmp->ufs_reset);
 910	if (ret)
 911		return ret;
 912
 913	/* Pull PHY out of reset state */
 914	if (!cfg->no_pcs_sw_reset)
 915		qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
 916
 917	/* start SerDes */
 918	qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START);
 919
 920	status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
 921	ret = readl_poll_timeout(status, val, (val & PCS_READY), 200,
 922				 PHY_INIT_COMPLETE_TIMEOUT);
 923	if (ret) {
 924		dev_err(qmp->dev, "phy initialization timed-out\n");
 925		return ret;
 926	}
 927
 928	return 0;
 929}
 930
 931static int qmp_ufs_power_off(struct phy *phy)
 932{
 933	struct qmp_ufs *qmp = phy_get_drvdata(phy);
 934	const struct qmp_phy_cfg *cfg = qmp->cfg;
 935
 936	/* PHY reset */
 937	if (!cfg->no_pcs_sw_reset)
 938		qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
 939
 940	/* stop SerDes */
 941	qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START);
 942
 943	/* Put PHY into POWER DOWN state: active low */
 944	qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
 945			SW_PWRDN);
 946
 947	return 0;
 948}
 949
 950static int qmp_ufs_exit(struct phy *phy)
 951{
 952	struct qmp_ufs *qmp = phy_get_drvdata(phy);
 953
 954	qmp_ufs_com_exit(qmp);
 955
 956	return 0;
 957}
 958
 959static int qmp_ufs_enable(struct phy *phy)
 960{
 961	int ret;
 962
 963	ret = qmp_ufs_init(phy);
 964	if (ret)
 965		return ret;
 966
 967	ret = qmp_ufs_power_on(phy);
 968	if (ret)
 969		qmp_ufs_exit(phy);
 970
 971	return ret;
 972}
 973
 974static int qmp_ufs_disable(struct phy *phy)
 975{
 976	int ret;
 977
 978	ret = qmp_ufs_power_off(phy);
 979	if (ret)
 980		return ret;
 981	return qmp_ufs_exit(phy);
 982}
 983
 984static const struct phy_ops qcom_qmp_ufs_phy_ops = {
 985	.power_on	= qmp_ufs_enable,
 986	.power_off	= qmp_ufs_disable,
 987	.owner		= THIS_MODULE,
 988};
 989
 990static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
 991{
 992	const struct qmp_phy_cfg *cfg = qmp->cfg;
 993	struct device *dev = qmp->dev;
 994	int num = cfg->num_vregs;
 995	int i;
 996
 997	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
 998	if (!qmp->vregs)
 999		return -ENOMEM;
1000
1001	for (i = 0; i < num; i++)
1002		qmp->vregs[i].supply = cfg->vreg_list[i];
1003
1004	return devm_regulator_bulk_get(dev, num, qmp->vregs);
1005}
1006
1007static int qmp_ufs_clk_init(struct qmp_ufs *qmp)
1008{
1009	const struct qmp_phy_cfg *cfg = qmp->cfg;
1010	struct device *dev = qmp->dev;
1011	int num = cfg->num_clks;
1012	int i;
1013
1014	qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
1015	if (!qmp->clks)
1016		return -ENOMEM;
1017
1018	for (i = 0; i < num; i++)
1019		qmp->clks[i].id = cfg->clk_list[i];
1020
1021	return devm_clk_bulk_get(dev, num, qmp->clks);
1022}
1023
1024static int qmp_ufs_parse_dt_legacy(struct qmp_ufs *qmp, struct device_node *np)
1025{
1026	struct platform_device *pdev = to_platform_device(qmp->dev);
1027	const struct qmp_phy_cfg *cfg = qmp->cfg;
1028	struct device *dev = qmp->dev;
1029
1030	qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
1031	if (IS_ERR(qmp->serdes))
1032		return PTR_ERR(qmp->serdes);
1033
1034	/*
1035	 * Get memory resources for the PHY:
1036	 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
1037	 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
1038	 * For single lane PHYs: pcs_misc (optional) -> 3.
1039	 */
1040	qmp->tx = devm_of_iomap(dev, np, 0, NULL);
1041	if (IS_ERR(qmp->tx))
1042		return PTR_ERR(qmp->tx);
1043
1044	qmp->rx = devm_of_iomap(dev, np, 1, NULL);
1045	if (IS_ERR(qmp->rx))
1046		return PTR_ERR(qmp->rx);
1047
1048	qmp->pcs = devm_of_iomap(dev, np, 2, NULL);
1049	if (IS_ERR(qmp->pcs))
1050		return PTR_ERR(qmp->pcs);
1051
1052	if (cfg->lanes >= 2) {
1053		qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
1054		if (IS_ERR(qmp->tx2))
1055			return PTR_ERR(qmp->tx2);
1056
1057		qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
1058		if (IS_ERR(qmp->rx2))
1059			return PTR_ERR(qmp->rx2);
1060
1061		qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
1062	} else {
1063		qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
1064	}
1065
1066	if (IS_ERR(qmp->pcs_misc))
1067		dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
1068
1069	return 0;
1070}
1071
1072static int qmp_ufs_parse_dt(struct qmp_ufs *qmp)
1073{
1074	struct platform_device *pdev = to_platform_device(qmp->dev);
1075	const struct qmp_phy_cfg *cfg = qmp->cfg;
1076	const struct qmp_ufs_offsets *offs = cfg->offsets;
1077	void __iomem *base;
1078
1079	if (!offs)
1080		return -EINVAL;
1081
1082	base = devm_platform_ioremap_resource(pdev, 0);
1083	if (IS_ERR(base))
1084		return PTR_ERR(base);
1085
1086	qmp->serdes = base + offs->serdes;
1087	qmp->pcs = base + offs->pcs;
1088	qmp->tx = base + offs->tx;
1089	qmp->rx = base + offs->rx;
1090
1091	if (cfg->lanes >= 2) {
1092		qmp->tx2 = base + offs->tx2;
1093		qmp->rx2 = base + offs->rx2;
1094	}
1095
1096	return 0;
1097}
1098
1099static int qmp_ufs_probe(struct platform_device *pdev)
1100{
1101	struct device *dev = &pdev->dev;
1102	struct phy_provider *phy_provider;
1103	struct device_node *np;
1104	struct qmp_ufs *qmp;
1105	int ret;
1106
1107	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
1108	if (!qmp)
1109		return -ENOMEM;
1110
1111	qmp->dev = dev;
1112
1113	qmp->cfg = of_device_get_match_data(dev);
1114	if (!qmp->cfg)
1115		return -EINVAL;
1116
1117	ret = qmp_ufs_clk_init(qmp);
1118	if (ret)
1119		return ret;
1120
1121	ret = qmp_ufs_vreg_init(qmp);
1122	if (ret)
1123		return ret;
1124
1125	/* Check for legacy binding with child node. */
1126	np = of_get_next_available_child(dev->of_node, NULL);
1127	if (np) {
1128		ret = qmp_ufs_parse_dt_legacy(qmp, np);
1129	} else {
1130		np = of_node_get(dev->of_node);
1131		ret = qmp_ufs_parse_dt(qmp);
1132	}
1133	if (ret)
1134		goto err_node_put;
1135
1136	qmp->phy = devm_phy_create(dev, np, &qcom_qmp_ufs_phy_ops);
1137	if (IS_ERR(qmp->phy)) {
1138		ret = PTR_ERR(qmp->phy);
1139		dev_err(dev, "failed to create PHY: %d\n", ret);
1140		goto err_node_put;
1141	}
1142
1143	phy_set_drvdata(qmp->phy, qmp);
1144
1145	of_node_put(np);
1146
1147	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1148
1149	return PTR_ERR_OR_ZERO(phy_provider);
1150
1151err_node_put:
1152	of_node_put(np);
1153	return ret;
1154}
1155
1156static const struct of_device_id qmp_ufs_of_match_table[] = {
1157	{
1158		.compatible = "qcom,msm8996-qmp-ufs-phy",
1159		.data = &msm8996_ufs_cfg,
1160	}, {
1161		.compatible = "qcom,msm8998-qmp-ufs-phy",
1162		.data = &sdm845_ufsphy_cfg,
1163	}, {
1164		.compatible = "qcom,sc8180x-qmp-ufs-phy",
1165		.data = &sm8150_ufsphy_cfg,
1166	}, {
1167		.compatible = "qcom,sc8280xp-qmp-ufs-phy",
1168		.data = &sc8280xp_ufsphy_cfg,
1169	}, {
1170		.compatible = "qcom,sdm845-qmp-ufs-phy",
1171		.data = &sdm845_ufsphy_cfg,
1172	}, {
1173		.compatible = "qcom,sm6115-qmp-ufs-phy",
1174		.data = &sm6115_ufsphy_cfg,
1175	}, {
1176		.compatible = "qcom,sm6350-qmp-ufs-phy",
1177		.data = &sdm845_ufsphy_cfg,
1178	}, {
1179		.compatible = "qcom,sm8150-qmp-ufs-phy",
1180		.data = &sm8150_ufsphy_cfg,
1181	}, {
1182		.compatible = "qcom,sm8250-qmp-ufs-phy",
1183		.data = &sm8150_ufsphy_cfg,
1184	}, {
1185		.compatible = "qcom,sm8350-qmp-ufs-phy",
1186		.data = &sm8350_ufsphy_cfg,
1187	}, {
1188		.compatible = "qcom,sm8450-qmp-ufs-phy",
1189		.data = &sm8450_ufsphy_cfg,
1190	},
1191	{ },
1192};
1193MODULE_DEVICE_TABLE(of, qmp_ufs_of_match_table);
1194
1195static struct platform_driver qmp_ufs_driver = {
1196	.probe		= qmp_ufs_probe,
1197	.driver = {
1198		.name	= "qcom-qmp-ufs-phy",
1199		.of_match_table = qmp_ufs_of_match_table,
1200	},
1201};
1202
1203module_platform_driver(qmp_ufs_driver);
1204
1205MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
1206MODULE_DESCRIPTION("Qualcomm QMP UFS PHY driver");
1207MODULE_LICENSE("GPL v2");