blob: 5c90d60e7d10fc3653e2dfa3fbaad77bda8a13cf [file] [log] [blame]
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +02001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2023-2024 Linaro Limited
5 * Authors:
6 * - Bhupesh Sharma <bhupesh.sharma@linaro.org>
7 * - Neil Armstrong <neil.armstrong@linaro.org>
8 *
9 * Based on Linux driver
10 */
11
12#include <clk.h>
13#include <clk-uclass.h>
14#include <dm.h>
15#include <dm/device_compat.h>
16#include <dm/devres.h>
17#include <generic-phy.h>
18#include <malloc.h>
19#include <reset.h>
20
21#include <asm/io.h>
22#include <linux/bitops.h>
23#include <linux/clk-provider.h>
24#include <linux/delay.h>
25#include <linux/iopoll.h>
26#include <linux/ioport.h>
27
28#include "phy-qcom-qmp.h"
29#include "phy-qcom-qmp-pcs-ufs-v2.h"
30#include "phy-qcom-qmp-pcs-ufs-v3.h"
31#include "phy-qcom-qmp-pcs-ufs-v4.h"
32#include "phy-qcom-qmp-pcs-ufs-v5.h"
33#include "phy-qcom-qmp-pcs-ufs-v6.h"
34
35#include "phy-qcom-qmp-qserdes-com-v4.h"
36#include "phy-qcom-qmp-qserdes-com-v6.h"
37#include "phy-qcom-qmp-qserdes-txrx-v4.h"
38#include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h"
39
40/* QPHY_SW_RESET bit */
41#define SW_RESET BIT(0)
42/* QPHY_POWER_DOWN_CONTROL */
43#define SW_PWRDN BIT(0)
44/* QPHY_START_CONTROL bits */
45#define SERDES_START BIT(0)
46#define PCS_START BIT(1)
47/* QPHY_PCS_READY_STATUS bit */
48#define PCS_READY BIT(0)
49
50#define PHY_INIT_COMPLETE_TIMEOUT (200 * 10000)
51
52struct qmp_ufs_init_tbl {
53 unsigned int offset;
54 unsigned int val;
55 /*
56 * mask of lanes for which this register is written
57 * for cases when second lane needs different values
58 */
59 u8 lane_mask;
60};
61
62#define QMP_PHY_INIT_CFG(o, v) \
63 { \
64 .offset = o, \
65 .val = v, \
66 .lane_mask = 0xff, \
67 }
68
69#define QMP_PHY_INIT_CFG_LANE(o, v, l) \
70 { \
71 .offset = o, \
72 .val = v, \
73 .lane_mask = l, \
74 }
75
76/* set of registers with offsets different per-PHY */
77enum qphy_reg_layout {
78 /* PCS registers */
79 QPHY_SW_RESET,
80 QPHY_START_CTRL,
81 QPHY_PCS_READY_STATUS,
82 QPHY_PCS_POWER_DOWN_CONTROL,
83 /* Keep last to ensure regs_layout arrays are properly initialized */
84 QPHY_LAYOUT_SIZE
85};
86
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +020087static const unsigned int ufsphy_v3_regs_layout[QPHY_LAYOUT_SIZE] = {
88 [QPHY_START_CTRL] = QPHY_V3_PCS_UFS_PHY_START,
89 [QPHY_PCS_READY_STATUS] = QPHY_V3_PCS_UFS_READY_STATUS,
90 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_UFS_POWER_DOWN_CONTROL,
91};
92
93static const unsigned int ufsphy_v4_regs_layout[QPHY_LAYOUT_SIZE] = {
94 [QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START,
95 [QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS,
96 [QPHY_SW_RESET] = QPHY_V4_PCS_UFS_SW_RESET,
97 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL,
98};
99
100static const unsigned int ufsphy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
101 [QPHY_START_CTRL] = QPHY_V6_PCS_UFS_PHY_START,
102 [QPHY_PCS_READY_STATUS] = QPHY_V6_PCS_UFS_READY_STATUS,
103 [QPHY_SW_RESET] = QPHY_V6_PCS_UFS_SW_RESET,
104 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL,
105};
106
107static const struct qmp_ufs_init_tbl sdm845_ufsphy_serdes[] = {
108 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
109 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
110 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
111 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
112 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
113 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
114 QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
115 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
116 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
117 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
118 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
119 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
120 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
121 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
122 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
123 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
124 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
125 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
126 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
127 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
128 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
129 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
130 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
131 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
132 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
133 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
134 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
135 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
136 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
137 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
138 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
139 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
140 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
141 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
142 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
143 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
144};
145
146static const struct qmp_ufs_init_tbl sdm845_ufsphy_hs_b_serdes[] = {
147 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
148};
149
150static const struct qmp_ufs_init_tbl sdm845_ufsphy_tx[] = {
151 QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
152 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
153 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
154};
155
156static const struct qmp_ufs_init_tbl sdm845_ufsphy_rx[] = {
157 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
158 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
159 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
160 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
161 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
162 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
163 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
164 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
165 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
166 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
167 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
168 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
169 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
170 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
171 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
172 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
173};
174
175static const struct qmp_ufs_init_tbl sdm845_ufsphy_pcs[] = {
176 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e),
177 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
178 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
179 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
180 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
181 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f),
182 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a),
183 QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
184};
185
Julius Lehmann425a9122024-10-02 20:52:17 +0200186static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_g4_tx[] = {
187 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x75),
188};
189
190static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_g4_rx[] = {
191 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
192 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
193 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
194 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
195 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
196 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
197 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
198 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
199 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
200 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
201 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
202 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x6c),
203 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
204 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
205 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
206 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
207};
208
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +0200209static const struct qmp_ufs_init_tbl sm8150_ufsphy_serdes[] = {
210 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
211 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
212 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
213 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
214 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
215 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
216 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
217 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
218 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
219 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
220 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
221 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
222 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
223 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
224 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
225 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
226 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
227 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
228 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
229 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
230 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
231 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
232 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
233 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
234};
235
236static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_b_serdes[] = {
237 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
238};
239
240static const struct qmp_ufs_init_tbl sm8150_ufsphy_tx[] = {
241 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
242 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
243 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
244 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
245 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
246 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
247};
248
249static const struct qmp_ufs_init_tbl sm8150_ufsphy_rx[] = {
250 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
251 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
252 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
253 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
254 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
255 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
256 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
257 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
258 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
259 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
260 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
261 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
262 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
263 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
264 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
265 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
266 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
267 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
268 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
269 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
270 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
271 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
272 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
273 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
274 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
275 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
276 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
277 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
278 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
279 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
280 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
281 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
282 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
283 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
284};
285
286static const struct qmp_ufs_init_tbl sm8150_ufsphy_pcs[] = {
287 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
288 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
289 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
290 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
291 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
292 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
293 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
294};
295
296static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_g4_pcs[] = {
297 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x10),
298 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a),
299};
300
301static const struct qmp_ufs_init_tbl sm8250_ufsphy_hs_g4_tx[] = {
302 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xe5),
303};
304
305static const struct qmp_ufs_init_tbl sm8250_ufsphy_hs_g4_rx[] = {
306 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
307 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
308 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
309 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
310 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
311 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
312 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09),
313 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
314 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
315 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
316 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
317 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
318 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
319 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
320 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
321 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
322 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x2c),
323 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
324 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
325 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
326 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
327};
328
329static const struct qmp_ufs_init_tbl sm8550_ufsphy_serdes[] = {
330 QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
331 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
332 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
333 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
334 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
335 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
336 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
337 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
338 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
339 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
340 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
341 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
342 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
343 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
344 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
345 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
346 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
347 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
348 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
349 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
350};
351
352static const struct qmp_ufs_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
353 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
354};
355
356static const struct qmp_ufs_init_tbl sm8550_ufsphy_tx[] = {
357 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
358 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
359 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
360};
361
362static const struct qmp_ufs_init_tbl sm8550_ufsphy_rx[] = {
363 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
364 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
365
366 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
367 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
368 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
369 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
370
371 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
372 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
373
374 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
375 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
376 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
377 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
378
379};
380
381static const struct qmp_ufs_init_tbl sm8550_ufsphy_pcs[] = {
382 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
383 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
384 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
385 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
386 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
387 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
388 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
389 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
390 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
391 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
392};
393
394static const struct qmp_ufs_init_tbl sm8650_ufsphy_serdes[] = {
395 QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
396 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
397 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
398 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
399 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
400 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
401 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO_MODE1, 0x1f),
402 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x0a),
403 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17),
404 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
405 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
406 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
407 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
408 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
409 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
410 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
411 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
412 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
413 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
414 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
415 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
416 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
417 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
418};
419
420static const struct qmp_ufs_init_tbl sm8650_ufsphy_tx[] = {
421 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x01),
422 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
423 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
424};
425
426static const struct qmp_ufs_init_tbl sm8650_ufsphy_rx[] = {
427 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
428 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
429 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
430 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
431 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
432 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
433 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
434 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
435 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
436 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x3e),
437 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
438 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xce),
439 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xce),
440 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2, 0x18),
441 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
442 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4, 0x0f),
443 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
444 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
445 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
446 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
447 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
448 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
449 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
450 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B0, 0x24),
451 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B1, 0x24),
452 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B2, 0x20),
453 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
454 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
455 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_SATURATION, 0x1f),
456 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94),
457 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_TERM_BW_CTRL0, 0xfa),
458 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
459};
460
461static const struct qmp_ufs_init_tbl sm8650_ufsphy_pcs[] = {
462 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
463 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
464 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PCS_CTRL1, 0xc1),
465 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
466 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68),
467 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S4, 0x0e),
468 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S5, 0x12),
469 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S6, 0x15),
470 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S7, 0x19),
471 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x13),
472 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
473 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
474 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
475 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x05),
476 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x05),
477 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4d),
478 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
479};
480
Caleb Connollyf2021a22024-10-12 15:22:05 +0200481
482static const struct qmp_ufs_init_tbl sc7280_ufsphy_tx[] = {
483 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
484 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
485 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
486 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
487 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35),
488 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
489};
490
491static const struct qmp_ufs_init_tbl sc7280_ufsphy_rx[] = {
492 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
493 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
494 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
495 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
496 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
497 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
498 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
499 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
500 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
501 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
502 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
503 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
504 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
505 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
506 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
507 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
508 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
509 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
510 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
511 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x6d),
512 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x6d),
513 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xed),
514 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
515 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3c),
516 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
517 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
518 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
519 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
520 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
521 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
522 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
523 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
524 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
525 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
526 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
527};
528
529static const struct qmp_ufs_init_tbl sc7280_ufsphy_pcs[] = {
530 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
531 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
532 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
533 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
534 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
535 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
536 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
537 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_PLL_CNTL, 0x03),
538 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
539 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
540 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
541 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
542 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
543 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
544};
545
546static const struct qmp_ufs_init_tbl sc7280_ufsphy_hs_g4_rx[] = {
547 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
548 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
549 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
550 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
551 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
552 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
553 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
554 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
555 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
556 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
557 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
558 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
559 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
560 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
561 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09),
562 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
563 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
564 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
565 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
566 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
567 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
568 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
569 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
570 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
571 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
572 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x2c),
573 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
574 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
575 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
576 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
577 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
578 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
579 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
580 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
581 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
582 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
583 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
584 QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x0f),
585};
586
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +0200587struct qmp_ufs_offsets {
588 u16 serdes;
589 u16 pcs;
590 u16 tx;
591 u16 rx;
592 /* for PHYs with >= 2 lanes */
593 u16 tx2;
594 u16 rx2;
595};
596
597struct qmp_ufs_cfg_tbls {
598 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
599 const struct qmp_ufs_init_tbl *serdes;
600 int serdes_num;
601 const struct qmp_ufs_init_tbl *tx;
602 int tx_num;
603 const struct qmp_ufs_init_tbl *rx;
604 int rx_num;
605 const struct qmp_ufs_init_tbl *pcs;
606 int pcs_num;
607};
608
609/* struct qmp_ufs_cfg - per-PHY initialization config */
610struct qmp_ufs_cfg {
611 int lanes;
612
613 const struct qmp_ufs_offsets *offsets;
614
615 /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
616 const struct qmp_ufs_cfg_tbls tbls;
617 /* Additional sequence for HS Series B */
618 const struct qmp_ufs_cfg_tbls tbls_hs_b;
619 /* Additional sequence for HS G4 */
620 const struct qmp_ufs_cfg_tbls tbls_hs_g4;
621
622 /* clock ids to be requested */
623 const char * const *clk_list;
624 int num_clks;
625 /* regulators to be requested */
626 const char * const *vreg_list;
627 int num_vregs;
628 /* resets to be requested */
629 const char * const *reset_list;
630 int num_resets;
631
632 /* array of registers with different offsets */
633 const unsigned int *regs;
634
635 /* true, if PCS block has no separate SW_RESET register */
636 bool no_pcs_sw_reset;
637};
638
639struct qmp_ufs_priv {
640 struct phy *phy;
641
642 void __iomem *serdes;
643 void __iomem *pcs;
644 void __iomem *pcs_misc;
645 void __iomem *tx;
646 void __iomem *rx;
647 void __iomem *tx2;
648 void __iomem *rx2;
649
650 struct clk *clks;
651 unsigned int clk_count;
652
653 struct reset_ctl *resets;
654 unsigned int reset_count;
655
656 const struct qmp_ufs_cfg *cfg;
657
658 struct udevice *dev;
659
660 u32 mode;
661 u32 submode;
662};
663
664static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
665{
666 u32 reg;
667
668 reg = readl(base + offset);
669 reg |= val;
670 writel(reg, base + offset);
671
672 /* ensure that above write is through */
673 readl(base + offset);
674}
675
676static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
677{
678 u32 reg;
679
680 reg = readl(base + offset);
681 reg &= ~val;
682 writel(reg, base + offset);
683
684 /* ensure that above write is through */
685 readl(base + offset);
686}
687
688/* list of clocks required by phy */
689static const char * const sdm845_ufs_phy_clk_l[] = {
690 "ref", "ref_aux",
691};
692
693/* list of regulators */
694static const char * const qmp_ufs_vreg_l[] = {
695 "vdda-phy", "vdda-pll",
696};
697
698/* list of resets */
699static const char * const qmp_ufs_reset_l[] = {
700 "ufsphy",
701};
702
703static const struct qmp_ufs_offsets qmp_ufs_offsets = {
704 .serdes = 0,
705 .pcs = 0xc00,
706 .tx = 0x400,
707 .rx = 0x600,
708 .tx2 = 0x800,
709 .rx2 = 0xa00,
710};
711
712static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = {
713 .serdes = 0,
714 .pcs = 0x0400,
715 .tx = 0x1000,
716 .rx = 0x1200,
717 .tx2 = 0x1800,
718 .rx2 = 0x1a00,
719};
720
721static const struct qmp_ufs_cfg sdm845_ufsphy_cfg = {
722 .lanes = 2,
723
724 .offsets = &qmp_ufs_offsets,
725
726 .tbls = {
727 .serdes = sdm845_ufsphy_serdes,
728 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_serdes),
729 .tx = sdm845_ufsphy_tx,
730 .tx_num = ARRAY_SIZE(sdm845_ufsphy_tx),
731 .rx = sdm845_ufsphy_rx,
732 .rx_num = ARRAY_SIZE(sdm845_ufsphy_rx),
733 .pcs = sdm845_ufsphy_pcs,
734 .pcs_num = ARRAY_SIZE(sdm845_ufsphy_pcs),
735 },
736 .tbls_hs_b = {
737 .serdes = sdm845_ufsphy_hs_b_serdes,
738 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
739 },
740 .clk_list = sdm845_ufs_phy_clk_l,
741 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
742 .vreg_list = qmp_ufs_vreg_l,
743 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
744 .regs = ufsphy_v3_regs_layout,
745
746 .no_pcs_sw_reset = true,
747};
748
Julius Lehmann425a9122024-10-02 20:52:17 +0200749static const struct qmp_ufs_cfg sm8150_ufsphy_cfg = {
750 .lanes = 2,
751
752 .offsets = &qmp_ufs_offsets,
753
754 .tbls = {
755 .serdes = sm8150_ufsphy_serdes,
756 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
757 .tx = sm8150_ufsphy_tx,
758 .tx_num = ARRAY_SIZE(sm8150_ufsphy_tx),
759 .rx = sm8150_ufsphy_rx,
760 .rx_num = ARRAY_SIZE(sm8150_ufsphy_rx),
761 .pcs = sm8150_ufsphy_pcs,
762 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs),
763 },
764 .tbls_hs_b = {
765 .serdes = sm8150_ufsphy_hs_b_serdes,
766 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
767 },
768 .tbls_hs_g4 = {
769 .tx = sm8150_ufsphy_hs_g4_tx,
770 .tx_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_tx),
771 .rx = sm8150_ufsphy_hs_g4_rx,
772 .rx_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_rx),
773 .pcs = sm8150_ufsphy_hs_g4_pcs,
774 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
775 },
776 .clk_list = sdm845_ufs_phy_clk_l,
777 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
778 .vreg_list = qmp_ufs_vreg_l,
779 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
780 .reset_list = qmp_ufs_reset_l,
781 .num_resets = ARRAY_SIZE(qmp_ufs_reset_l),
782 .regs = ufsphy_v4_regs_layout,
783
784 .no_pcs_sw_reset = false,
785};
786
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +0200787static const struct qmp_ufs_cfg sm8250_ufsphy_cfg = {
788 .lanes = 2,
789
790 .offsets = &qmp_ufs_offsets,
791
792 .tbls = {
793 .serdes = sm8150_ufsphy_serdes,
794 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
795 .tx = sm8150_ufsphy_tx,
796 .tx_num = ARRAY_SIZE(sm8150_ufsphy_tx),
797 .rx = sm8150_ufsphy_rx,
798 .rx_num = ARRAY_SIZE(sm8150_ufsphy_rx),
799 .pcs = sm8150_ufsphy_pcs,
800 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs),
801 },
802 .tbls_hs_b = {
803 .serdes = sm8150_ufsphy_hs_b_serdes,
804 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
805 },
806 .tbls_hs_g4 = {
807 .tx = sm8250_ufsphy_hs_g4_tx,
808 .tx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
809 .rx = sm8250_ufsphy_hs_g4_rx,
810 .rx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_rx),
811 .pcs = sm8150_ufsphy_hs_g4_pcs,
812 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
813 },
814 .clk_list = sdm845_ufs_phy_clk_l,
815 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
816 .vreg_list = qmp_ufs_vreg_l,
817 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
818 .reset_list = qmp_ufs_reset_l,
819 .num_resets = ARRAY_SIZE(qmp_ufs_reset_l),
820 .regs = ufsphy_v4_regs_layout,
821
822 .no_pcs_sw_reset = false,
823};
824
825static const struct qmp_ufs_cfg sm8550_ufsphy_cfg = {
826 .lanes = 2,
827
828 .offsets = &qmp_ufs_offsets_v6,
829
830 .tbls = {
831 .serdes = sm8550_ufsphy_serdes,
832 .serdes_num = ARRAY_SIZE(sm8550_ufsphy_serdes),
833 .tx = sm8550_ufsphy_tx,
834 .tx_num = ARRAY_SIZE(sm8550_ufsphy_tx),
835 .rx = sm8550_ufsphy_rx,
836 .rx_num = ARRAY_SIZE(sm8550_ufsphy_rx),
837 .pcs = sm8550_ufsphy_pcs,
838 .pcs_num = ARRAY_SIZE(sm8550_ufsphy_pcs),
839 },
840 .tbls_hs_b = {
841 .serdes = sm8550_ufsphy_hs_b_serdes,
842 .serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
843 },
844 .clk_list = sdm845_ufs_phy_clk_l,
845 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
846 .vreg_list = qmp_ufs_vreg_l,
847 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
848 .regs = ufsphy_v6_regs_layout,
849
850 .no_pcs_sw_reset = false,
851};
852
853static const struct qmp_ufs_cfg sm8650_ufsphy_cfg = {
854 .lanes = 2,
855
856 .offsets = &qmp_ufs_offsets_v6,
857
858 .tbls = {
859 .serdes = sm8650_ufsphy_serdes,
860 .serdes_num = ARRAY_SIZE(sm8650_ufsphy_serdes),
861 .tx = sm8650_ufsphy_tx,
862 .tx_num = ARRAY_SIZE(sm8650_ufsphy_tx),
863 .rx = sm8650_ufsphy_rx,
864 .rx_num = ARRAY_SIZE(sm8650_ufsphy_rx),
865 .pcs = sm8650_ufsphy_pcs,
866 .pcs_num = ARRAY_SIZE(sm8650_ufsphy_pcs),
867 },
868 .clk_list = sdm845_ufs_phy_clk_l,
869 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
870 .vreg_list = qmp_ufs_vreg_l,
871 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
872 .regs = ufsphy_v6_regs_layout,
873
874 .no_pcs_sw_reset = false,
875};
876
Caleb Connollyf2021a22024-10-12 15:22:05 +0200877
878static const struct qmp_ufs_cfg sc7280_ufsphy_cfg = {
879 .lanes = 2,
880
881 .offsets = &qmp_ufs_offsets,
882
883 .tbls = {
884 .serdes = sm8150_ufsphy_serdes,
885 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
886 .tx = sc7280_ufsphy_tx,
887 .tx_num = ARRAY_SIZE(sc7280_ufsphy_tx),
888 .rx = sc7280_ufsphy_rx,
889 .rx_num = ARRAY_SIZE(sc7280_ufsphy_rx),
890 .pcs = sc7280_ufsphy_pcs,
891 .pcs_num = ARRAY_SIZE(sc7280_ufsphy_pcs),
892 },
893 .tbls_hs_b = {
894 .serdes = sm8150_ufsphy_hs_b_serdes,
895 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
896 },
897 .tbls_hs_g4 = {
898 .tx = sm8250_ufsphy_hs_g4_tx,
899 .tx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
900 .rx = sc7280_ufsphy_hs_g4_rx,
901 .rx_num = ARRAY_SIZE(sc7280_ufsphy_hs_g4_rx),
902 .pcs = sm8150_ufsphy_hs_g4_pcs,
903 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
904 },
905 .clk_list = sdm845_ufs_phy_clk_l,
906 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
907 .vreg_list = qmp_ufs_vreg_l,
908 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
909 .regs = ufsphy_v4_regs_layout,
910};
911
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +0200912static void qmp_ufs_configure_lane(void __iomem *base,
913 const struct qmp_ufs_init_tbl tbl[],
914 int num,
915 u8 lane_mask)
916{
917 int i;
918 const struct qmp_ufs_init_tbl *t = tbl;
919
920 if (!t)
921 return;
922
923 for (i = 0; i < num; i++, t++) {
924 if (!(t->lane_mask & lane_mask))
925 continue;
926
927 writel(t->val, base + t->offset);
928 }
929}
930
931static void qmp_ufs_configure(void __iomem *base,
932 const struct qmp_ufs_init_tbl tbl[],
933 int num)
934{
935 qmp_ufs_configure_lane(base, tbl, num, 0xff);
936}
937
938static void qmp_ufs_serdes_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)
939{
940 void __iomem *serdes = qmp->serdes;
941
942 qmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num);
943}
944
945static void qmp_ufs_lanes_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)
946{
947 const struct qmp_ufs_cfg *cfg = qmp->cfg;
948 void __iomem *tx = qmp->tx;
949 void __iomem *rx = qmp->rx;
950
951 qmp_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
952 qmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
953
954 if (cfg->lanes >= 2) {
955 qmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2);
956 qmp_ufs_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2);
957 }
958}
959
960static void qmp_ufs_pcs_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)
961{
962 void __iomem *pcs = qmp->pcs;
963
964 qmp_ufs_configure(pcs, tbls->pcs, tbls->pcs_num);
965}
966
967static void qmp_ufs_init_registers(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg *cfg)
968{
969 /* We support 'PHY_MODE_UFS_HS_B' mode & 'UFS_HS_G3' submode for now. */
970 qmp_ufs_serdes_init(qmp, &cfg->tbls);
971 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
972 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
973 qmp_ufs_lanes_init(qmp, &cfg->tbls);
974 qmp_ufs_pcs_init(qmp, &cfg->tbls);
975}
976
977static int qmp_ufs_do_reset(struct qmp_ufs_priv *qmp)
978{
979 int i, ret;
980
981 for (i = 0; i < qmp->reset_count; i++) {
982 ret = reset_assert(&qmp->resets[i]);
983 if (ret)
984 return ret;
985 }
986
987 udelay(10);
988
989 for (i = 0; i < qmp->reset_count; i++) {
990 ret = reset_deassert(&qmp->resets[i]);
991 if (ret)
992 return ret;
993 }
994
995 udelay(50);
996
997 return 0;
998}
999
1000static int qmp_ufs_power_on(struct phy *phy)
1001{
1002 struct qmp_ufs_priv *qmp = dev_get_priv(phy->dev);
1003 const struct qmp_ufs_cfg *cfg = qmp->cfg;
1004 void __iomem *pcs = qmp->pcs;
1005 void __iomem *status;
1006 unsigned int val;
1007 int ret;
1008
1009 /* Power down PHY */
1010 qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
1011
1012 qmp_ufs_init_registers(qmp, cfg);
1013
1014 if (cfg->no_pcs_sw_reset) {
1015 ret = qmp_ufs_do_reset(qmp);
1016 if (ret) {
1017 dev_err(phy->dev, "qmp reset failed\n");
1018 return ret;
1019 }
1020 }
1021
1022 /* Pull PHY out of reset state */
1023 if (!cfg->no_pcs_sw_reset)
1024 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1025
1026 /* start SerDes */
1027 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START);
1028
1029 status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
1030 ret = readl_poll_timeout(status, val, (val & PCS_READY), PHY_INIT_COMPLETE_TIMEOUT);
1031 if (ret) {
1032 dev_err(phy->dev, "phy initialization timed-out\n");
1033 return ret;
1034 }
1035
1036 return 0;
1037}
1038
1039static int qmp_ufs_power_off(struct phy *phy)
1040{
1041 struct qmp_ufs_priv *qmp = dev_get_priv(phy->dev);
1042 const struct qmp_ufs_cfg *cfg = qmp->cfg;
1043
1044 /* PHY reset */
1045 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1046
1047 /* stop SerDes and Phy-Coding-Sublayer */
1048 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL],
1049 SERDES_START | PCS_START);
1050
1051 /* Put PHY into POWER DOWN state: active low */
1052 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
1053 SW_PWRDN);
1054
1055 clk_release_all(qmp->clks, qmp->clk_count);
1056
1057 return 0;
1058}
1059
1060static int qmp_ufs_vreg_init(struct udevice *dev, struct qmp_ufs_priv *qmp)
1061{
1062 /* TOFIX: Add regulator support, but they should be voted at boot time already */
1063
1064 return 0;
1065}
1066
1067static int qmp_ufs_reset_init(struct udevice *dev, struct qmp_ufs_priv *qmp)
1068{
1069 const struct qmp_ufs_cfg *cfg = qmp->cfg;
1070 int num = cfg->num_resets;
1071 int i, ret;
1072
1073 qmp->reset_count = 0;
1074 qmp->resets = devm_kcalloc(dev, num, sizeof(*qmp->resets), GFP_KERNEL);
1075 if (!qmp->resets)
1076 return -ENOMEM;
1077
1078 for (i = 0; i < num; i++) {
1079 ret = reset_get_by_index(dev, i, &qmp->resets[i]);
1080 if (ret < 0) {
1081 dev_err(dev, "failed to get reset %d\n", i);
1082 goto reset_get_err;
1083 }
1084
1085 ++qmp->reset_count;
1086 }
1087
1088 return 0;
1089
1090reset_get_err:
1091 ret = reset_release_all(qmp->resets, qmp->reset_count);
1092 if (ret)
1093 dev_warn(dev, "failed to disable all resets\n");
1094
1095 return ret;
1096}
1097
1098static int qmp_ufs_clk_init(struct udevice *dev, struct qmp_ufs_priv *qmp)
1099{
1100 const struct qmp_ufs_cfg *cfg = qmp->cfg;
1101 int num = cfg->num_clks;
1102 int i, ret;
1103
1104 qmp->clk_count = 0;
1105 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
1106 if (!qmp->clks)
1107 return -ENOMEM;
1108
1109 for (i = 0; i < num; i++) {
1110 ret = clk_get_by_index(dev, i, &qmp->clks[i]);
1111 if (ret < 0)
1112 goto clk_get_err;
1113
1114 ret = clk_enable(&qmp->clks[i]);
1115 if (ret && ret != -ENOSYS) {
1116 dev_err(dev, "failed to enable clock %d\n", i);
1117 goto clk_get_err;
1118 }
1119
1120 ++qmp->clk_count;
1121 }
1122
1123 return 0;
1124
1125clk_get_err:
1126 ret = clk_release_all(qmp->clks, qmp->clk_count);
1127 if (ret)
1128 dev_warn(dev, "failed to disable all clocks\n");
1129
1130 return ret;
1131}
1132
1133static int qmp_ufs_probe_generic_child(struct udevice *dev,
1134 ofnode child)
1135{
1136 struct qmp_ufs_priv *qmp = dev_get_priv(dev);
1137 const struct qmp_ufs_cfg *cfg = qmp->cfg;
1138 struct resource res;
1139 int ret;
1140
1141 /*
1142 * Get memory resources for the PHY:
1143 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
1144 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
1145 * For single lane PHYs: pcs_misc (optional) -> 3.
1146 */
1147 ret = ofnode_read_resource(child, 0, &res);
1148 if (ret) {
1149 dev_err(dev, "can't get reg property of child %s\n",
1150 ofnode_get_name(child));
1151 return ret;
1152 }
1153
1154 qmp->tx = (void __iomem *)res.start;
1155
1156 ret = ofnode_read_resource(child, 1, &res);
1157 if (ret) {
1158 dev_err(dev, "can't get reg property of child %s\n",
1159 ofnode_get_name(child));
1160 return ret;
1161 }
1162
1163 qmp->rx = (void __iomem *)res.start;
1164
1165 ret = ofnode_read_resource(child, 2, &res);
1166 if (ret) {
1167 dev_err(dev, "can't get reg property of child %s\n",
1168 ofnode_get_name(child));
1169 return ret;
1170 }
1171
1172 qmp->pcs = (void __iomem *)res.start;
1173
1174 if (cfg->lanes >= 2) {
1175 ret = ofnode_read_resource(child, 3, &res);
1176 if (ret) {
1177 dev_err(dev, "can't get reg property of child %s\n",
1178 ofnode_get_name(child));
1179 return ret;
1180 }
1181
1182 qmp->tx2 = (void __iomem *)res.start;
1183
1184 ret = ofnode_read_resource(child, 4, &res);
1185 if (ret) {
1186 dev_err(dev, "can't get reg property of child %s\n",
1187 ofnode_get_name(child));
1188 return ret;
1189 }
1190
1191 qmp->rx2 = (void __iomem *)res.start;
1192
1193 ret = ofnode_read_resource(child, 5, &res);
1194 if (ret)
1195 qmp->pcs_misc = NULL;
1196 } else {
1197 ret = ofnode_read_resource(child, 3, &res);
1198 if (ret)
1199 qmp->pcs_misc = NULL;
1200 }
1201
1202 return 0;
1203}
1204
1205static int qmp_ufs_probe_dt_children(struct udevice *dev)
1206{
1207 int ret;
1208 ofnode child;
1209
1210 ofnode_for_each_subnode(child, dev_ofnode(dev)) {
1211 ret = qmp_ufs_probe_generic_child(dev, child);
1212 if (ret) {
1213 dev_err(dev, "Cannot parse child %s:%d\n",
1214 ofnode_get_name(child), ret);
1215 return ret;
1216 }
1217 }
1218
1219 return 0;
1220}
1221
1222static int qmp_ufs_probe(struct udevice *dev)
1223{
1224 struct qmp_ufs_priv *qmp = dev_get_priv(dev);
1225 int ret;
1226
1227 qmp->serdes = (void __iomem *)dev_read_addr(dev);
1228 if (IS_ERR(qmp->serdes))
1229 return PTR_ERR(qmp->serdes);
1230
1231 qmp->cfg = (const struct qmp_ufs_cfg *)dev_get_driver_data(dev);
1232 if (!qmp->cfg)
1233 return -EINVAL;
1234
1235 ret = qmp_ufs_clk_init(dev, qmp);
1236 if (ret) {
1237 dev_err(dev, "failed to get UFS clks\n");
1238 return ret;
1239 }
1240
1241 ret = qmp_ufs_vreg_init(dev, qmp);
1242 if (ret) {
1243 dev_err(dev, "failed to get UFS voltage regulators\n");
1244 return ret;
1245 }
1246
1247 if (qmp->cfg->no_pcs_sw_reset) {
1248 ret = qmp_ufs_reset_init(dev, qmp);
1249 if (ret) {
1250 dev_err(dev, "failed to get UFS resets\n");
1251 return ret;
1252 }
1253 }
1254
1255 qmp->dev = dev;
1256
1257 if (ofnode_get_child_count(dev_ofnode(dev))) {
1258 ret = qmp_ufs_probe_dt_children(dev);
1259 if (ret) {
1260 dev_err(dev, "failed to get UFS dt regs\n");
1261 return ret;
1262 }
1263 } else {
1264 const struct qmp_ufs_offsets *offs = qmp->cfg->offsets;
1265 struct resource res;
1266
1267 if (!qmp->cfg->offsets) {
1268 dev_err(dev, "missing UFS offsets\n");
1269 return -EINVAL;
1270 }
1271
1272 ret = ofnode_read_resource(dev_ofnode(dev), 0, &res);
1273 if (ret) {
1274 dev_err(dev, "can't get reg property\n");
1275 return ret;
1276 }
1277
1278 qmp->serdes = (void __iomem *)res.start + offs->serdes;
1279 qmp->pcs = (void __iomem *)res.start + offs->pcs;
1280 qmp->tx = (void __iomem *)res.start + offs->tx;
1281 qmp->rx = (void __iomem *)res.start + offs->rx;
1282
1283 if (qmp->cfg->lanes >= 2) {
1284 qmp->tx2 = (void __iomem *)res.start + offs->tx2;
1285 qmp->rx2 = (void __iomem *)res.start + offs->rx2;
1286 }
1287 }
1288
1289 return 0;
1290}
1291
1292static struct phy_ops qmp_ufs_ops = {
1293 .power_on = qmp_ufs_power_on,
1294 .power_off = qmp_ufs_power_off,
1295};
1296
1297static const struct udevice_id qmp_ufs_ids[] = {
1298 { .compatible = "qcom,sdm845-qmp-ufs-phy", .data = (ulong)&sdm845_ufsphy_cfg },
Julius Lehmann425a9122024-10-02 20:52:17 +02001299 { .compatible = "qcom,sm8150-qmp-ufs-phy", .data = (ulong)&sm8150_ufsphy_cfg },
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +02001300 { .compatible = "qcom,sm8250-qmp-ufs-phy", .data = (ulong)&sm8250_ufsphy_cfg },
1301 { .compatible = "qcom,sm8550-qmp-ufs-phy", .data = (ulong)&sm8550_ufsphy_cfg },
1302 { .compatible = "qcom,sm8650-qmp-ufs-phy", .data = (ulong)&sm8650_ufsphy_cfg },
Caleb Connollyf2021a22024-10-12 15:22:05 +02001303 { .compatible = "qcom,sc7280-qmp-ufs-phy", .data = (ulong)&sc7280_ufsphy_cfg, },
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +02001304 { }
1305};
1306
1307U_BOOT_DRIVER(qcom_qmp_ufs) = {
1308 .name = "qcom-qmp-ufs",
1309 .id = UCLASS_PHY,
1310 .of_match = qmp_ufs_ids,
1311 .ops = &qmp_ufs_ops,
1312 .probe = qmp_ufs_probe,
1313 .priv_auto = sizeof(struct qmp_ufs_priv),
1314};