blob: eef0093e1869b012b09d3c63588d48e71c135128 [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
186static const struct qmp_ufs_init_tbl sm8150_ufsphy_serdes[] = {
187 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
188 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
189 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
190 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
191 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
192 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
193 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
194 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
195 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
196 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
197 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
198 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
199 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
200 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
201 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
202 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
203 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
204 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
205 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
206 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
207 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
208 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
209 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
210 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
211};
212
213static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_b_serdes[] = {
214 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
215};
216
217static const struct qmp_ufs_init_tbl sm8150_ufsphy_tx[] = {
218 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
219 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
220 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
221 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
222 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
223 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
224};
225
226static const struct qmp_ufs_init_tbl sm8150_ufsphy_rx[] = {
227 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
228 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
229 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
230 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
231 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
232 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
233 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
234 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
235 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
236 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
237 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
238 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
239 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
240 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
241 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
242 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
243 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
244 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
245 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
246 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
247 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
248 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
249 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
250 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
251 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
252 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
253 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
254 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
255 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
256 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
257 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
258 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
259 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
260 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
261};
262
263static const struct qmp_ufs_init_tbl sm8150_ufsphy_pcs[] = {
264 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
265 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
266 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
267 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
268 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
269 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
270 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
271};
272
273static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_g4_pcs[] = {
274 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x10),
275 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a),
276};
277
278static const struct qmp_ufs_init_tbl sm8250_ufsphy_hs_g4_tx[] = {
279 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xe5),
280};
281
282static const struct qmp_ufs_init_tbl sm8250_ufsphy_hs_g4_rx[] = {
283 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
284 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
285 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
286 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
287 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
288 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
289 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09),
290 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
291 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
292 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
293 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
294 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
295 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
296 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
297 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
298 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
299 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x2c),
300 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
301 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
302 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
303 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
304};
305
306static const struct qmp_ufs_init_tbl sm8550_ufsphy_serdes[] = {
307 QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
308 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
309 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
310 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
311 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
312 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
313 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
314 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
315 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
316 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
317 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
318 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
319 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
320 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
321 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
322 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
323 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
324 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
325 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
326 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
327};
328
329static const struct qmp_ufs_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
330 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
331};
332
333static const struct qmp_ufs_init_tbl sm8550_ufsphy_tx[] = {
334 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
335 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
336 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
337};
338
339static const struct qmp_ufs_init_tbl sm8550_ufsphy_rx[] = {
340 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
341 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
342
343 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
344 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
345 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
346 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
347
348 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
349 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
350
351 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
352 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
353 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
354 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
355
356};
357
358static const struct qmp_ufs_init_tbl sm8550_ufsphy_pcs[] = {
359 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
360 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
361 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
362 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
363 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
364 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
365 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
366 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
367 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
368 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
369};
370
371static const struct qmp_ufs_init_tbl sm8650_ufsphy_serdes[] = {
372 QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
373 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
374 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
375 QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
376 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
377 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
378 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO_MODE1, 0x1f),
379 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x0a),
380 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17),
381 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
382 QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
383 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
384 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
385 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
386 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
387 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
388 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
389 QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
390 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
391 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
392 QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
393 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
394 QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
395};
396
397static const struct qmp_ufs_init_tbl sm8650_ufsphy_tx[] = {
398 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x01),
399 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
400 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
401};
402
403static const struct qmp_ufs_init_tbl sm8650_ufsphy_rx[] = {
404 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
405 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
406 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
407 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
408 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
409 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
410 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
411 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
412 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
413 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x3e),
414 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
415 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xce),
416 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xce),
417 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2, 0x18),
418 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
419 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4, 0x0f),
420 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
421 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
422 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
423 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
424 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
425 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
426 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
427 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B0, 0x24),
428 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B1, 0x24),
429 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B2, 0x20),
430 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
431 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
432 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_SATURATION, 0x1f),
433 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94),
434 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_TERM_BW_CTRL0, 0xfa),
435 QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
436};
437
438static const struct qmp_ufs_init_tbl sm8650_ufsphy_pcs[] = {
439 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
440 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
441 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PCS_CTRL1, 0xc1),
442 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
443 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68),
444 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S4, 0x0e),
445 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S5, 0x12),
446 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S6, 0x15),
447 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S7, 0x19),
448 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x13),
449 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
450 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
451 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
452 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x05),
453 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x05),
454 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4d),
455 QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
456};
457
Caleb Connollyf2021a22024-10-12 15:22:05 +0200458
459static const struct qmp_ufs_init_tbl sc7280_ufsphy_tx[] = {
460 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
461 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
462 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
463 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
464 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35),
465 QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
466};
467
468static const struct qmp_ufs_init_tbl sc7280_ufsphy_rx[] = {
469 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
470 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
471 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
472 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
473 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
474 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
475 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
476 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
477 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
478 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
479 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
480 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
481 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
482 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
483 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
484 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
485 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
486 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
487 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
488 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x6d),
489 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x6d),
490 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xed),
491 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
492 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3c),
493 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
494 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
495 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
496 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
497 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
498 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
499 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
500 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
501 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
502 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
503 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
504};
505
506static const struct qmp_ufs_init_tbl sc7280_ufsphy_pcs[] = {
507 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
508 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
509 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
510 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
511 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
512 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
513 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
514 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_PLL_CNTL, 0x03),
515 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
516 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
517 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
518 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
519 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
520 QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
521};
522
523static const struct qmp_ufs_init_tbl sc7280_ufsphy_hs_g4_rx[] = {
524 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
525 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
526 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
527 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
528 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
529 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
530 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
531 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
532 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
533 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
534 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
535 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
536 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
537 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
538 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09),
539 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
540 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
541 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
542 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
543 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
544 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
545 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
546 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
547 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
548 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
549 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x2c),
550 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
551 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
552 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
553 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
554 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
555 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
556 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
557 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
558 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
559 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
560 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
561 QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x0f),
562};
563
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +0200564struct qmp_ufs_offsets {
565 u16 serdes;
566 u16 pcs;
567 u16 tx;
568 u16 rx;
569 /* for PHYs with >= 2 lanes */
570 u16 tx2;
571 u16 rx2;
572};
573
574struct qmp_ufs_cfg_tbls {
575 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
576 const struct qmp_ufs_init_tbl *serdes;
577 int serdes_num;
578 const struct qmp_ufs_init_tbl *tx;
579 int tx_num;
580 const struct qmp_ufs_init_tbl *rx;
581 int rx_num;
582 const struct qmp_ufs_init_tbl *pcs;
583 int pcs_num;
584};
585
586/* struct qmp_ufs_cfg - per-PHY initialization config */
587struct qmp_ufs_cfg {
588 int lanes;
589
590 const struct qmp_ufs_offsets *offsets;
591
592 /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
593 const struct qmp_ufs_cfg_tbls tbls;
594 /* Additional sequence for HS Series B */
595 const struct qmp_ufs_cfg_tbls tbls_hs_b;
596 /* Additional sequence for HS G4 */
597 const struct qmp_ufs_cfg_tbls tbls_hs_g4;
598
599 /* clock ids to be requested */
600 const char * const *clk_list;
601 int num_clks;
602 /* regulators to be requested */
603 const char * const *vreg_list;
604 int num_vregs;
605 /* resets to be requested */
606 const char * const *reset_list;
607 int num_resets;
608
609 /* array of registers with different offsets */
610 const unsigned int *regs;
611
612 /* true, if PCS block has no separate SW_RESET register */
613 bool no_pcs_sw_reset;
614};
615
616struct qmp_ufs_priv {
617 struct phy *phy;
618
619 void __iomem *serdes;
620 void __iomem *pcs;
621 void __iomem *pcs_misc;
622 void __iomem *tx;
623 void __iomem *rx;
624 void __iomem *tx2;
625 void __iomem *rx2;
626
627 struct clk *clks;
628 unsigned int clk_count;
629
630 struct reset_ctl *resets;
631 unsigned int reset_count;
632
633 const struct qmp_ufs_cfg *cfg;
634
635 struct udevice *dev;
636
637 u32 mode;
638 u32 submode;
639};
640
641static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
642{
643 u32 reg;
644
645 reg = readl(base + offset);
646 reg |= val;
647 writel(reg, base + offset);
648
649 /* ensure that above write is through */
650 readl(base + offset);
651}
652
653static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
654{
655 u32 reg;
656
657 reg = readl(base + offset);
658 reg &= ~val;
659 writel(reg, base + offset);
660
661 /* ensure that above write is through */
662 readl(base + offset);
663}
664
665/* list of clocks required by phy */
666static const char * const sdm845_ufs_phy_clk_l[] = {
667 "ref", "ref_aux",
668};
669
670/* list of regulators */
671static const char * const qmp_ufs_vreg_l[] = {
672 "vdda-phy", "vdda-pll",
673};
674
675/* list of resets */
676static const char * const qmp_ufs_reset_l[] = {
677 "ufsphy",
678};
679
680static const struct qmp_ufs_offsets qmp_ufs_offsets = {
681 .serdes = 0,
682 .pcs = 0xc00,
683 .tx = 0x400,
684 .rx = 0x600,
685 .tx2 = 0x800,
686 .rx2 = 0xa00,
687};
688
689static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = {
690 .serdes = 0,
691 .pcs = 0x0400,
692 .tx = 0x1000,
693 .rx = 0x1200,
694 .tx2 = 0x1800,
695 .rx2 = 0x1a00,
696};
697
698static const struct qmp_ufs_cfg sdm845_ufsphy_cfg = {
699 .lanes = 2,
700
701 .offsets = &qmp_ufs_offsets,
702
703 .tbls = {
704 .serdes = sdm845_ufsphy_serdes,
705 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_serdes),
706 .tx = sdm845_ufsphy_tx,
707 .tx_num = ARRAY_SIZE(sdm845_ufsphy_tx),
708 .rx = sdm845_ufsphy_rx,
709 .rx_num = ARRAY_SIZE(sdm845_ufsphy_rx),
710 .pcs = sdm845_ufsphy_pcs,
711 .pcs_num = ARRAY_SIZE(sdm845_ufsphy_pcs),
712 },
713 .tbls_hs_b = {
714 .serdes = sdm845_ufsphy_hs_b_serdes,
715 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
716 },
717 .clk_list = sdm845_ufs_phy_clk_l,
718 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
719 .vreg_list = qmp_ufs_vreg_l,
720 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
721 .regs = ufsphy_v3_regs_layout,
722
723 .no_pcs_sw_reset = true,
724};
725
726static const struct qmp_ufs_cfg sm8250_ufsphy_cfg = {
727 .lanes = 2,
728
729 .offsets = &qmp_ufs_offsets,
730
731 .tbls = {
732 .serdes = sm8150_ufsphy_serdes,
733 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
734 .tx = sm8150_ufsphy_tx,
735 .tx_num = ARRAY_SIZE(sm8150_ufsphy_tx),
736 .rx = sm8150_ufsphy_rx,
737 .rx_num = ARRAY_SIZE(sm8150_ufsphy_rx),
738 .pcs = sm8150_ufsphy_pcs,
739 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs),
740 },
741 .tbls_hs_b = {
742 .serdes = sm8150_ufsphy_hs_b_serdes,
743 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
744 },
745 .tbls_hs_g4 = {
746 .tx = sm8250_ufsphy_hs_g4_tx,
747 .tx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
748 .rx = sm8250_ufsphy_hs_g4_rx,
749 .rx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_rx),
750 .pcs = sm8150_ufsphy_hs_g4_pcs,
751 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
752 },
753 .clk_list = sdm845_ufs_phy_clk_l,
754 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
755 .vreg_list = qmp_ufs_vreg_l,
756 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
757 .reset_list = qmp_ufs_reset_l,
758 .num_resets = ARRAY_SIZE(qmp_ufs_reset_l),
759 .regs = ufsphy_v4_regs_layout,
760
761 .no_pcs_sw_reset = false,
762};
763
764static const struct qmp_ufs_cfg sm8550_ufsphy_cfg = {
765 .lanes = 2,
766
767 .offsets = &qmp_ufs_offsets_v6,
768
769 .tbls = {
770 .serdes = sm8550_ufsphy_serdes,
771 .serdes_num = ARRAY_SIZE(sm8550_ufsphy_serdes),
772 .tx = sm8550_ufsphy_tx,
773 .tx_num = ARRAY_SIZE(sm8550_ufsphy_tx),
774 .rx = sm8550_ufsphy_rx,
775 .rx_num = ARRAY_SIZE(sm8550_ufsphy_rx),
776 .pcs = sm8550_ufsphy_pcs,
777 .pcs_num = ARRAY_SIZE(sm8550_ufsphy_pcs),
778 },
779 .tbls_hs_b = {
780 .serdes = sm8550_ufsphy_hs_b_serdes,
781 .serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
782 },
783 .clk_list = sdm845_ufs_phy_clk_l,
784 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
785 .vreg_list = qmp_ufs_vreg_l,
786 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
787 .regs = ufsphy_v6_regs_layout,
788
789 .no_pcs_sw_reset = false,
790};
791
792static const struct qmp_ufs_cfg sm8650_ufsphy_cfg = {
793 .lanes = 2,
794
795 .offsets = &qmp_ufs_offsets_v6,
796
797 .tbls = {
798 .serdes = sm8650_ufsphy_serdes,
799 .serdes_num = ARRAY_SIZE(sm8650_ufsphy_serdes),
800 .tx = sm8650_ufsphy_tx,
801 .tx_num = ARRAY_SIZE(sm8650_ufsphy_tx),
802 .rx = sm8650_ufsphy_rx,
803 .rx_num = ARRAY_SIZE(sm8650_ufsphy_rx),
804 .pcs = sm8650_ufsphy_pcs,
805 .pcs_num = ARRAY_SIZE(sm8650_ufsphy_pcs),
806 },
807 .clk_list = sdm845_ufs_phy_clk_l,
808 .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
809 .vreg_list = qmp_ufs_vreg_l,
810 .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
811 .regs = ufsphy_v6_regs_layout,
812
813 .no_pcs_sw_reset = false,
814};
815
Caleb Connollyf2021a22024-10-12 15:22:05 +0200816
817static const struct qmp_ufs_cfg sc7280_ufsphy_cfg = {
818 .lanes = 2,
819
820 .offsets = &qmp_ufs_offsets,
821
822 .tbls = {
823 .serdes = sm8150_ufsphy_serdes,
824 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
825 .tx = sc7280_ufsphy_tx,
826 .tx_num = ARRAY_SIZE(sc7280_ufsphy_tx),
827 .rx = sc7280_ufsphy_rx,
828 .rx_num = ARRAY_SIZE(sc7280_ufsphy_rx),
829 .pcs = sc7280_ufsphy_pcs,
830 .pcs_num = ARRAY_SIZE(sc7280_ufsphy_pcs),
831 },
832 .tbls_hs_b = {
833 .serdes = sm8150_ufsphy_hs_b_serdes,
834 .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
835 },
836 .tbls_hs_g4 = {
837 .tx = sm8250_ufsphy_hs_g4_tx,
838 .tx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
839 .rx = sc7280_ufsphy_hs_g4_rx,
840 .rx_num = ARRAY_SIZE(sc7280_ufsphy_hs_g4_rx),
841 .pcs = sm8150_ufsphy_hs_g4_pcs,
842 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
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_v4_regs_layout,
849};
850
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +0200851static void qmp_ufs_configure_lane(void __iomem *base,
852 const struct qmp_ufs_init_tbl tbl[],
853 int num,
854 u8 lane_mask)
855{
856 int i;
857 const struct qmp_ufs_init_tbl *t = tbl;
858
859 if (!t)
860 return;
861
862 for (i = 0; i < num; i++, t++) {
863 if (!(t->lane_mask & lane_mask))
864 continue;
865
866 writel(t->val, base + t->offset);
867 }
868}
869
870static void qmp_ufs_configure(void __iomem *base,
871 const struct qmp_ufs_init_tbl tbl[],
872 int num)
873{
874 qmp_ufs_configure_lane(base, tbl, num, 0xff);
875}
876
877static void qmp_ufs_serdes_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)
878{
879 void __iomem *serdes = qmp->serdes;
880
881 qmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num);
882}
883
884static void qmp_ufs_lanes_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)
885{
886 const struct qmp_ufs_cfg *cfg = qmp->cfg;
887 void __iomem *tx = qmp->tx;
888 void __iomem *rx = qmp->rx;
889
890 qmp_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
891 qmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
892
893 if (cfg->lanes >= 2) {
894 qmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2);
895 qmp_ufs_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2);
896 }
897}
898
899static void qmp_ufs_pcs_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)
900{
901 void __iomem *pcs = qmp->pcs;
902
903 qmp_ufs_configure(pcs, tbls->pcs, tbls->pcs_num);
904}
905
906static void qmp_ufs_init_registers(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg *cfg)
907{
908 /* We support 'PHY_MODE_UFS_HS_B' mode & 'UFS_HS_G3' submode for now. */
909 qmp_ufs_serdes_init(qmp, &cfg->tbls);
910 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
911 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
912 qmp_ufs_lanes_init(qmp, &cfg->tbls);
913 qmp_ufs_pcs_init(qmp, &cfg->tbls);
914}
915
916static int qmp_ufs_do_reset(struct qmp_ufs_priv *qmp)
917{
918 int i, ret;
919
920 for (i = 0; i < qmp->reset_count; i++) {
921 ret = reset_assert(&qmp->resets[i]);
922 if (ret)
923 return ret;
924 }
925
926 udelay(10);
927
928 for (i = 0; i < qmp->reset_count; i++) {
929 ret = reset_deassert(&qmp->resets[i]);
930 if (ret)
931 return ret;
932 }
933
934 udelay(50);
935
936 return 0;
937}
938
939static int qmp_ufs_power_on(struct phy *phy)
940{
941 struct qmp_ufs_priv *qmp = dev_get_priv(phy->dev);
942 const struct qmp_ufs_cfg *cfg = qmp->cfg;
943 void __iomem *pcs = qmp->pcs;
944 void __iomem *status;
945 unsigned int val;
946 int ret;
947
948 /* Power down PHY */
949 qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
950
951 qmp_ufs_init_registers(qmp, cfg);
952
953 if (cfg->no_pcs_sw_reset) {
954 ret = qmp_ufs_do_reset(qmp);
955 if (ret) {
956 dev_err(phy->dev, "qmp reset failed\n");
957 return ret;
958 }
959 }
960
961 /* Pull PHY out of reset state */
962 if (!cfg->no_pcs_sw_reset)
963 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
964
965 /* start SerDes */
966 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START);
967
968 status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
969 ret = readl_poll_timeout(status, val, (val & PCS_READY), PHY_INIT_COMPLETE_TIMEOUT);
970 if (ret) {
971 dev_err(phy->dev, "phy initialization timed-out\n");
972 return ret;
973 }
974
975 return 0;
976}
977
978static int qmp_ufs_power_off(struct phy *phy)
979{
980 struct qmp_ufs_priv *qmp = dev_get_priv(phy->dev);
981 const struct qmp_ufs_cfg *cfg = qmp->cfg;
982
983 /* PHY reset */
984 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
985
986 /* stop SerDes and Phy-Coding-Sublayer */
987 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL],
988 SERDES_START | PCS_START);
989
990 /* Put PHY into POWER DOWN state: active low */
991 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
992 SW_PWRDN);
993
994 clk_release_all(qmp->clks, qmp->clk_count);
995
996 return 0;
997}
998
999static int qmp_ufs_vreg_init(struct udevice *dev, struct qmp_ufs_priv *qmp)
1000{
1001 /* TOFIX: Add regulator support, but they should be voted at boot time already */
1002
1003 return 0;
1004}
1005
1006static int qmp_ufs_reset_init(struct udevice *dev, struct qmp_ufs_priv *qmp)
1007{
1008 const struct qmp_ufs_cfg *cfg = qmp->cfg;
1009 int num = cfg->num_resets;
1010 int i, ret;
1011
1012 qmp->reset_count = 0;
1013 qmp->resets = devm_kcalloc(dev, num, sizeof(*qmp->resets), GFP_KERNEL);
1014 if (!qmp->resets)
1015 return -ENOMEM;
1016
1017 for (i = 0; i < num; i++) {
1018 ret = reset_get_by_index(dev, i, &qmp->resets[i]);
1019 if (ret < 0) {
1020 dev_err(dev, "failed to get reset %d\n", i);
1021 goto reset_get_err;
1022 }
1023
1024 ++qmp->reset_count;
1025 }
1026
1027 return 0;
1028
1029reset_get_err:
1030 ret = reset_release_all(qmp->resets, qmp->reset_count);
1031 if (ret)
1032 dev_warn(dev, "failed to disable all resets\n");
1033
1034 return ret;
1035}
1036
1037static int qmp_ufs_clk_init(struct udevice *dev, struct qmp_ufs_priv *qmp)
1038{
1039 const struct qmp_ufs_cfg *cfg = qmp->cfg;
1040 int num = cfg->num_clks;
1041 int i, ret;
1042
1043 qmp->clk_count = 0;
1044 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
1045 if (!qmp->clks)
1046 return -ENOMEM;
1047
1048 for (i = 0; i < num; i++) {
1049 ret = clk_get_by_index(dev, i, &qmp->clks[i]);
1050 if (ret < 0)
1051 goto clk_get_err;
1052
1053 ret = clk_enable(&qmp->clks[i]);
1054 if (ret && ret != -ENOSYS) {
1055 dev_err(dev, "failed to enable clock %d\n", i);
1056 goto clk_get_err;
1057 }
1058
1059 ++qmp->clk_count;
1060 }
1061
1062 return 0;
1063
1064clk_get_err:
1065 ret = clk_release_all(qmp->clks, qmp->clk_count);
1066 if (ret)
1067 dev_warn(dev, "failed to disable all clocks\n");
1068
1069 return ret;
1070}
1071
1072static int qmp_ufs_probe_generic_child(struct udevice *dev,
1073 ofnode child)
1074{
1075 struct qmp_ufs_priv *qmp = dev_get_priv(dev);
1076 const struct qmp_ufs_cfg *cfg = qmp->cfg;
1077 struct resource res;
1078 int ret;
1079
1080 /*
1081 * Get memory resources for the PHY:
1082 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
1083 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
1084 * For single lane PHYs: pcs_misc (optional) -> 3.
1085 */
1086 ret = ofnode_read_resource(child, 0, &res);
1087 if (ret) {
1088 dev_err(dev, "can't get reg property of child %s\n",
1089 ofnode_get_name(child));
1090 return ret;
1091 }
1092
1093 qmp->tx = (void __iomem *)res.start;
1094
1095 ret = ofnode_read_resource(child, 1, &res);
1096 if (ret) {
1097 dev_err(dev, "can't get reg property of child %s\n",
1098 ofnode_get_name(child));
1099 return ret;
1100 }
1101
1102 qmp->rx = (void __iomem *)res.start;
1103
1104 ret = ofnode_read_resource(child, 2, &res);
1105 if (ret) {
1106 dev_err(dev, "can't get reg property of child %s\n",
1107 ofnode_get_name(child));
1108 return ret;
1109 }
1110
1111 qmp->pcs = (void __iomem *)res.start;
1112
1113 if (cfg->lanes >= 2) {
1114 ret = ofnode_read_resource(child, 3, &res);
1115 if (ret) {
1116 dev_err(dev, "can't get reg property of child %s\n",
1117 ofnode_get_name(child));
1118 return ret;
1119 }
1120
1121 qmp->tx2 = (void __iomem *)res.start;
1122
1123 ret = ofnode_read_resource(child, 4, &res);
1124 if (ret) {
1125 dev_err(dev, "can't get reg property of child %s\n",
1126 ofnode_get_name(child));
1127 return ret;
1128 }
1129
1130 qmp->rx2 = (void __iomem *)res.start;
1131
1132 ret = ofnode_read_resource(child, 5, &res);
1133 if (ret)
1134 qmp->pcs_misc = NULL;
1135 } else {
1136 ret = ofnode_read_resource(child, 3, &res);
1137 if (ret)
1138 qmp->pcs_misc = NULL;
1139 }
1140
1141 return 0;
1142}
1143
1144static int qmp_ufs_probe_dt_children(struct udevice *dev)
1145{
1146 int ret;
1147 ofnode child;
1148
1149 ofnode_for_each_subnode(child, dev_ofnode(dev)) {
1150 ret = qmp_ufs_probe_generic_child(dev, child);
1151 if (ret) {
1152 dev_err(dev, "Cannot parse child %s:%d\n",
1153 ofnode_get_name(child), ret);
1154 return ret;
1155 }
1156 }
1157
1158 return 0;
1159}
1160
1161static int qmp_ufs_probe(struct udevice *dev)
1162{
1163 struct qmp_ufs_priv *qmp = dev_get_priv(dev);
1164 int ret;
1165
1166 qmp->serdes = (void __iomem *)dev_read_addr(dev);
1167 if (IS_ERR(qmp->serdes))
1168 return PTR_ERR(qmp->serdes);
1169
1170 qmp->cfg = (const struct qmp_ufs_cfg *)dev_get_driver_data(dev);
1171 if (!qmp->cfg)
1172 return -EINVAL;
1173
1174 ret = qmp_ufs_clk_init(dev, qmp);
1175 if (ret) {
1176 dev_err(dev, "failed to get UFS clks\n");
1177 return ret;
1178 }
1179
1180 ret = qmp_ufs_vreg_init(dev, qmp);
1181 if (ret) {
1182 dev_err(dev, "failed to get UFS voltage regulators\n");
1183 return ret;
1184 }
1185
1186 if (qmp->cfg->no_pcs_sw_reset) {
1187 ret = qmp_ufs_reset_init(dev, qmp);
1188 if (ret) {
1189 dev_err(dev, "failed to get UFS resets\n");
1190 return ret;
1191 }
1192 }
1193
1194 qmp->dev = dev;
1195
1196 if (ofnode_get_child_count(dev_ofnode(dev))) {
1197 ret = qmp_ufs_probe_dt_children(dev);
1198 if (ret) {
1199 dev_err(dev, "failed to get UFS dt regs\n");
1200 return ret;
1201 }
1202 } else {
1203 const struct qmp_ufs_offsets *offs = qmp->cfg->offsets;
1204 struct resource res;
1205
1206 if (!qmp->cfg->offsets) {
1207 dev_err(dev, "missing UFS offsets\n");
1208 return -EINVAL;
1209 }
1210
1211 ret = ofnode_read_resource(dev_ofnode(dev), 0, &res);
1212 if (ret) {
1213 dev_err(dev, "can't get reg property\n");
1214 return ret;
1215 }
1216
1217 qmp->serdes = (void __iomem *)res.start + offs->serdes;
1218 qmp->pcs = (void __iomem *)res.start + offs->pcs;
1219 qmp->tx = (void __iomem *)res.start + offs->tx;
1220 qmp->rx = (void __iomem *)res.start + offs->rx;
1221
1222 if (qmp->cfg->lanes >= 2) {
1223 qmp->tx2 = (void __iomem *)res.start + offs->tx2;
1224 qmp->rx2 = (void __iomem *)res.start + offs->rx2;
1225 }
1226 }
1227
1228 return 0;
1229}
1230
1231static struct phy_ops qmp_ufs_ops = {
1232 .power_on = qmp_ufs_power_on,
1233 .power_off = qmp_ufs_power_off,
1234};
1235
1236static const struct udevice_id qmp_ufs_ids[] = {
1237 { .compatible = "qcom,sdm845-qmp-ufs-phy", .data = (ulong)&sdm845_ufsphy_cfg },
1238 { .compatible = "qcom,sm8250-qmp-ufs-phy", .data = (ulong)&sm8250_ufsphy_cfg },
1239 { .compatible = "qcom,sm8550-qmp-ufs-phy", .data = (ulong)&sm8550_ufsphy_cfg },
1240 { .compatible = "qcom,sm8650-qmp-ufs-phy", .data = (ulong)&sm8650_ufsphy_cfg },
Caleb Connollyf2021a22024-10-12 15:22:05 +02001241 { .compatible = "qcom,sc7280-qmp-ufs-phy", .data = (ulong)&sc7280_ufsphy_cfg, },
Bhupesh Sharmaf0cbbc92024-09-10 11:11:58 +02001242 { }
1243};
1244
1245U_BOOT_DRIVER(qcom_qmp_ufs) = {
1246 .name = "qcom-qmp-ufs",
1247 .id = UCLASS_PHY,
1248 .of_match = qmp_ufs_ids,
1249 .ops = &qmp_ufs_ops,
1250 .probe = qmp_ufs_probe,
1251 .priv_auto = sizeof(struct qmp_ufs_priv),
1252};