1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2023, Linaro Limited
7 #include <linux/ethtool.h>
8 #include <linux/module.h>
10 #include <linux/phy/phy.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
14 #define QSERDES_QMP_PLL 0x0
15 #define QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0 (QSERDES_QMP_PLL + 0x1ac)
16 #define QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0 (QSERDES_QMP_PLL + 0x1b0)
17 #define QSERDES_COM_BIN_VCOCAL_HSCLK_SEL (QSERDES_QMP_PLL + 0x1bc)
18 #define QSERDES_COM_CORE_CLK_EN (QSERDES_QMP_PLL + 0x174)
19 #define QSERDES_COM_CORECLK_DIV_MODE0 (QSERDES_QMP_PLL + 0x168)
20 #define QSERDES_COM_CP_CTRL_MODE0 (QSERDES_QMP_PLL + 0x74)
21 #define QSERDES_COM_DEC_START_MODE0 (QSERDES_QMP_PLL + 0xbc)
22 #define QSERDES_COM_DIV_FRAC_START1_MODE0 (QSERDES_QMP_PLL + 0xcc)
23 #define QSERDES_COM_DIV_FRAC_START2_MODE0 (QSERDES_QMP_PLL + 0xd0)
24 #define QSERDES_COM_DIV_FRAC_START3_MODE0 (QSERDES_QMP_PLL + 0xd4)
25 #define QSERDES_COM_HSCLK_HS_SWITCH_SEL (QSERDES_QMP_PLL + 0x15c)
26 #define QSERDES_COM_HSCLK_SEL (QSERDES_QMP_PLL + 0x158)
27 #define QSERDES_COM_LOCK_CMP1_MODE0 (QSERDES_QMP_PLL + 0xac)
28 #define QSERDES_COM_LOCK_CMP2_MODE0 (QSERDES_QMP_PLL + 0xb0)
29 #define QSERDES_COM_PLL_CCTRL_MODE0 (QSERDES_QMP_PLL + 0x84)
30 #define QSERDES_COM_PLL_IVCO (QSERDES_QMP_PLL + 0x58)
31 #define QSERDES_COM_PLL_RCTRL_MODE0 (QSERDES_QMP_PLL + 0x7c)
32 #define QSERDES_COM_SYSCLK_EN_SEL (QSERDES_QMP_PLL + 0x94)
33 #define QSERDES_COM_VCO_TUNE1_MODE0 (QSERDES_QMP_PLL + 0x110)
34 #define QSERDES_COM_VCO_TUNE2_MODE0 (QSERDES_QMP_PLL + 0x114)
35 #define QSERDES_COM_VCO_TUNE_INITVAL2 (QSERDES_QMP_PLL + 0x124)
36 #define QSERDES_COM_C_READY_STATUS (QSERDES_QMP_PLL + 0x178)
37 #define QSERDES_COM_CMN_STATUS (QSERDES_QMP_PLL + 0x140)
39 #define QSERDES_RX 0x600
40 #define QSERDES_RX_UCDR_FO_GAIN (QSERDES_RX + 0x8)
41 #define QSERDES_RX_UCDR_SO_GAIN (QSERDES_RX + 0x14)
42 #define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN (QSERDES_RX + 0x30)
43 #define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE (QSERDES_RX + 0x34)
44 #define QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW (QSERDES_RX + 0x3c)
45 #define QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH (QSERDES_RX + 0x40)
46 #define QSERDES_RX_UCDR_PI_CONTROLS (QSERDES_RX + 0x44)
47 #define QSERDES_RX_UCDR_PI_CTRL2 (QSERDES_RX + 0x48)
48 #define QSERDES_RX_RX_TERM_BW (QSERDES_RX + 0x80)
49 #define QSERDES_RX_VGA_CAL_CNTRL2 (QSERDES_RX + 0xd8)
50 #define QSERDES_RX_GM_CAL (QSERDES_RX + 0xdc)
51 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1 (QSERDES_RX + 0xe8)
52 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 (QSERDES_RX + 0xec)
53 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 (QSERDES_RX + 0xf0)
54 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 (QSERDES_RX + 0xf4)
55 #define QSERDES_RX_RX_IDAC_TSETTLE_LOW (QSERDES_RX + 0xf8)
56 #define QSERDES_RX_RX_IDAC_TSETTLE_HIGH (QSERDES_RX + 0xfc)
57 #define QSERDES_RX_RX_IDAC_MEASURE_TIME (QSERDES_RX + 0x100)
58 #define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 (QSERDES_RX + 0x110)
59 #define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 (QSERDES_RX + 0x114)
60 #define QSERDES_RX_SIGDET_CNTRL (QSERDES_RX + 0x11c)
61 #define QSERDES_RX_SIGDET_DEGLITCH_CNTRL (QSERDES_RX + 0x124)
62 #define QSERDES_RX_RX_BAND (QSERDES_RX + 0x128)
63 #define QSERDES_RX_RX_MODE_00_LOW (QSERDES_RX + 0x15c)
64 #define QSERDES_RX_RX_MODE_00_HIGH (QSERDES_RX + 0x160)
65 #define QSERDES_RX_RX_MODE_00_HIGH2 (QSERDES_RX + 0x164)
66 #define QSERDES_RX_RX_MODE_00_HIGH3 (QSERDES_RX + 0x168)
67 #define QSERDES_RX_RX_MODE_00_HIGH4 (QSERDES_RX + 0x16c)
68 #define QSERDES_RX_RX_MODE_01_LOW (QSERDES_RX + 0x170)
69 #define QSERDES_RX_RX_MODE_01_HIGH (QSERDES_RX + 0x174)
70 #define QSERDES_RX_RX_MODE_01_HIGH2 (QSERDES_RX + 0x178)
71 #define QSERDES_RX_RX_MODE_01_HIGH3 (QSERDES_RX + 0x17c)
72 #define QSERDES_RX_RX_MODE_01_HIGH4 (QSERDES_RX + 0x180)
73 #define QSERDES_RX_RX_MODE_10_LOW (QSERDES_RX + 0x184)
74 #define QSERDES_RX_RX_MODE_10_HIGH (QSERDES_RX + 0x188)
75 #define QSERDES_RX_RX_MODE_10_HIGH2 (QSERDES_RX + 0x18c)
76 #define QSERDES_RX_RX_MODE_10_HIGH3 (QSERDES_RX + 0x190)
77 #define QSERDES_RX_RX_MODE_10_HIGH4 (QSERDES_RX + 0x194)
78 #define QSERDES_RX_DCC_CTRL1 (QSERDES_RX + 0x1a8)
80 #define QSERDES_TX 0x400
81 #define QSERDES_TX_TX_BAND (QSERDES_TX + 0x24)
82 #define QSERDES_TX_SLEW_CNTL (QSERDES_TX + 0x28)
83 #define QSERDES_TX_RES_CODE_LANE_OFFSET_TX (QSERDES_TX + 0x3c)
84 #define QSERDES_TX_RES_CODE_LANE_OFFSET_RX (QSERDES_TX + 0x40)
85 #define QSERDES_TX_LANE_MODE_1 (QSERDES_TX + 0x84)
86 #define QSERDES_TX_LANE_MODE_3 (QSERDES_TX + 0x8c)
87 #define QSERDES_TX_RCV_DETECT_LVL_2 (QSERDES_TX + 0xa4)
88 #define QSERDES_TX_TRAN_DRVR_EMP_EN (QSERDES_TX + 0xc0)
90 #define QSERDES_PCS 0xC00
91 #define QSERDES_PCS_PHY_START (QSERDES_PCS + 0x0)
92 #define QSERDES_PCS_POWER_DOWN_CONTROL (QSERDES_PCS + 0x4)
93 #define QSERDES_PCS_SW_RESET (QSERDES_PCS + 0x8)
94 #define QSERDES_PCS_LINE_RESET_TIME (QSERDES_PCS + 0xc)
95 #define QSERDES_PCS_TX_LARGE_AMP_DRV_LVL (QSERDES_PCS + 0x20)
96 #define QSERDES_PCS_TX_SMALL_AMP_DRV_LVL (QSERDES_PCS + 0x28)
97 #define QSERDES_PCS_TX_MID_TERM_CTRL1 (QSERDES_PCS + 0xd8)
98 #define QSERDES_PCS_TX_MID_TERM_CTRL2 (QSERDES_PCS + 0xdc)
99 #define QSERDES_PCS_SGMII_MISC_CTRL8 (QSERDES_PCS + 0x118)
100 #define QSERDES_PCS_PCS_READY_STATUS (QSERDES_PCS + 0x94)
102 #define QSERDES_COM_C_READY BIT(0)
103 #define QSERDES_PCS_READY BIT(0)
104 #define QSERDES_PCS_SGMIIPHY_READY BIT(7)
105 #define QSERDES_COM_C_PLL_LOCKED BIT(1)
107 struct qcom_dwmac_sgmii_phy_data {
108 struct regmap *regmap;
113 static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap)
115 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01);
116 regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01);
118 regmap_write(regmap, QSERDES_COM_PLL_IVCO, 0x0F);
119 regmap_write(regmap, QSERDES_COM_CP_CTRL_MODE0, 0x06);
120 regmap_write(regmap, QSERDES_COM_PLL_RCTRL_MODE0, 0x16);
121 regmap_write(regmap, QSERDES_COM_PLL_CCTRL_MODE0, 0x36);
122 regmap_write(regmap, QSERDES_COM_SYSCLK_EN_SEL, 0x1A);
123 regmap_write(regmap, QSERDES_COM_LOCK_CMP1_MODE0, 0x0A);
124 regmap_write(regmap, QSERDES_COM_LOCK_CMP2_MODE0, 0x1A);
125 regmap_write(regmap, QSERDES_COM_DEC_START_MODE0, 0x82);
126 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55);
127 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55);
128 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03);
129 regmap_write(regmap, QSERDES_COM_VCO_TUNE1_MODE0, 0x24);
131 regmap_write(regmap, QSERDES_COM_VCO_TUNE2_MODE0, 0x02);
132 regmap_write(regmap, QSERDES_COM_VCO_TUNE_INITVAL2, 0x00);
133 regmap_write(regmap, QSERDES_COM_HSCLK_SEL, 0x04);
134 regmap_write(regmap, QSERDES_COM_HSCLK_HS_SWITCH_SEL, 0x00);
135 regmap_write(regmap, QSERDES_COM_CORECLK_DIV_MODE0, 0x0A);
136 regmap_write(regmap, QSERDES_COM_CORE_CLK_EN, 0x00);
137 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xB9);
138 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1E);
139 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_HSCLK_SEL, 0x11);
141 regmap_write(regmap, QSERDES_TX_TX_BAND, 0x05);
142 regmap_write(regmap, QSERDES_TX_SLEW_CNTL, 0x0A);
143 regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_TX, 0x09);
144 regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_RX, 0x09);
145 regmap_write(regmap, QSERDES_TX_LANE_MODE_1, 0x05);
146 regmap_write(regmap, QSERDES_TX_LANE_MODE_3, 0x00);
147 regmap_write(regmap, QSERDES_TX_RCV_DETECT_LVL_2, 0x12);
148 regmap_write(regmap, QSERDES_TX_TRAN_DRVR_EMP_EN, 0x0C);
150 regmap_write(regmap, QSERDES_RX_UCDR_FO_GAIN, 0x0A);
151 regmap_write(regmap, QSERDES_RX_UCDR_SO_GAIN, 0x06);
152 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A);
153 regmap_write(regmap, QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F);
154 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00);
155 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01);
156 regmap_write(regmap, QSERDES_RX_UCDR_PI_CONTROLS, 0x81);
157 regmap_write(regmap, QSERDES_RX_UCDR_PI_CTRL2, 0x80);
158 regmap_write(regmap, QSERDES_RX_RX_TERM_BW, 0x04);
159 regmap_write(regmap, QSERDES_RX_VGA_CAL_CNTRL2, 0x08);
160 regmap_write(regmap, QSERDES_RX_GM_CAL, 0x0F);
161 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04);
162 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00);
163 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A);
164 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A);
165 regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_LOW, 0x80);
166 regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_HIGH, 0x01);
167 regmap_write(regmap, QSERDES_RX_RX_IDAC_MEASURE_TIME, 0x20);
168 regmap_write(regmap, QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17);
169 regmap_write(regmap, QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00);
170 regmap_write(regmap, QSERDES_RX_SIGDET_CNTRL, 0x0F);
171 regmap_write(regmap, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E);
172 regmap_write(regmap, QSERDES_RX_RX_BAND, 0x05);
173 regmap_write(regmap, QSERDES_RX_RX_MODE_00_LOW, 0xE0);
174 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH, 0xC8);
175 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH2, 0xC8);
176 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH3, 0x09);
177 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH4, 0xB1);
178 regmap_write(regmap, QSERDES_RX_RX_MODE_01_LOW, 0xE0);
179 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH, 0xC8);
180 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH2, 0xC8);
181 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH3, 0x09);
182 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH4, 0xB1);
183 regmap_write(regmap, QSERDES_RX_RX_MODE_10_LOW, 0xE0);
184 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH, 0xC8);
185 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH2, 0xC8);
186 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH3, 0x3B);
187 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH4, 0xB7);
188 regmap_write(regmap, QSERDES_RX_DCC_CTRL1, 0x0C);
190 regmap_write(regmap, QSERDES_PCS_LINE_RESET_TIME, 0x0C);
191 regmap_write(regmap, QSERDES_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F);
192 regmap_write(regmap, QSERDES_PCS_TX_SMALL_AMP_DRV_LVL, 0x03);
193 regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL1, 0x83);
194 regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08);
195 regmap_write(regmap, QSERDES_PCS_SGMII_MISC_CTRL8, 0x0C);
196 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x00);
198 regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01);
201 static void qcom_dwmac_sgmii_phy_init_2p5g(struct regmap *regmap)
203 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01);
204 regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01);
206 regmap_write(regmap, QSERDES_COM_PLL_IVCO, 0x0F);
207 regmap_write(regmap, QSERDES_COM_CP_CTRL_MODE0, 0x06);
208 regmap_write(regmap, QSERDES_COM_PLL_RCTRL_MODE0, 0x16);
209 regmap_write(regmap, QSERDES_COM_PLL_CCTRL_MODE0, 0x36);
210 regmap_write(regmap, QSERDES_COM_SYSCLK_EN_SEL, 0x1A);
211 regmap_write(regmap, QSERDES_COM_LOCK_CMP1_MODE0, 0x1A);
212 regmap_write(regmap, QSERDES_COM_LOCK_CMP2_MODE0, 0x41);
213 regmap_write(regmap, QSERDES_COM_DEC_START_MODE0, 0x7A);
214 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00);
215 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START2_MODE0, 0x20);
216 regmap_write(regmap, QSERDES_COM_DIV_FRAC_START3_MODE0, 0x01);
217 regmap_write(regmap, QSERDES_COM_VCO_TUNE1_MODE0, 0xA1);
219 regmap_write(regmap, QSERDES_COM_VCO_TUNE2_MODE0, 0x02);
220 regmap_write(regmap, QSERDES_COM_VCO_TUNE_INITVAL2, 0x00);
221 regmap_write(regmap, QSERDES_COM_HSCLK_SEL, 0x03);
222 regmap_write(regmap, QSERDES_COM_HSCLK_HS_SWITCH_SEL, 0x00);
223 regmap_write(regmap, QSERDES_COM_CORECLK_DIV_MODE0, 0x05);
224 regmap_write(regmap, QSERDES_COM_CORE_CLK_EN, 0x00);
225 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xCD);
226 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1C);
227 regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_HSCLK_SEL, 0x11);
229 regmap_write(regmap, QSERDES_TX_TX_BAND, 0x04);
230 regmap_write(regmap, QSERDES_TX_SLEW_CNTL, 0x0A);
231 regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_TX, 0x09);
232 regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_RX, 0x02);
233 regmap_write(regmap, QSERDES_TX_LANE_MODE_1, 0x05);
234 regmap_write(regmap, QSERDES_TX_LANE_MODE_3, 0x00);
235 regmap_write(regmap, QSERDES_TX_RCV_DETECT_LVL_2, 0x12);
236 regmap_write(regmap, QSERDES_TX_TRAN_DRVR_EMP_EN, 0x0C);
238 regmap_write(regmap, QSERDES_RX_UCDR_FO_GAIN, 0x0A);
239 regmap_write(regmap, QSERDES_RX_UCDR_SO_GAIN, 0x06);
240 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A);
241 regmap_write(regmap, QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F);
242 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00);
243 regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01);
244 regmap_write(regmap, QSERDES_RX_UCDR_PI_CONTROLS, 0x81);
245 regmap_write(regmap, QSERDES_RX_UCDR_PI_CTRL2, 0x80);
246 regmap_write(regmap, QSERDES_RX_RX_TERM_BW, 0x00);
247 regmap_write(regmap, QSERDES_RX_VGA_CAL_CNTRL2, 0x08);
248 regmap_write(regmap, QSERDES_RX_GM_CAL, 0x0F);
249 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04);
250 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00);
251 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A);
252 regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A);
253 regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_LOW, 0x80);
254 regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_HIGH, 0x01);
255 regmap_write(regmap, QSERDES_RX_RX_IDAC_MEASURE_TIME, 0x20);
256 regmap_write(regmap, QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17);
257 regmap_write(regmap, QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00);
258 regmap_write(regmap, QSERDES_RX_SIGDET_CNTRL, 0x0F);
259 regmap_write(regmap, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E);
260 regmap_write(regmap, QSERDES_RX_RX_BAND, 0x18);
261 regmap_write(regmap, QSERDES_RX_RX_MODE_00_LOW, 0x18);
262 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH, 0xC8);
263 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH2, 0xC8);
264 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH3, 0x0C);
265 regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH4, 0xB8);
266 regmap_write(regmap, QSERDES_RX_RX_MODE_01_LOW, 0xE0);
267 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH, 0xC8);
268 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH2, 0xC8);
269 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH3, 0x09);
270 regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH4, 0xB1);
271 regmap_write(regmap, QSERDES_RX_RX_MODE_10_LOW, 0xE0);
272 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH, 0xC8);
273 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH2, 0xC8);
274 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH3, 0x3B);
275 regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH4, 0xB7);
276 regmap_write(regmap, QSERDES_RX_DCC_CTRL1, 0x0C);
278 regmap_write(regmap, QSERDES_PCS_LINE_RESET_TIME, 0x0C);
279 regmap_write(regmap, QSERDES_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F);
280 regmap_write(regmap, QSERDES_PCS_TX_SMALL_AMP_DRV_LVL, 0x03);
281 regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL1, 0x83);
282 regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08);
283 regmap_write(regmap, QSERDES_PCS_SGMII_MISC_CTRL8, 0x8C);
284 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x00);
286 regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01);
290 qcom_dwmac_sgmii_phy_poll_status(struct regmap *regmap, unsigned int reg,
295 return regmap_read_poll_timeout(regmap, reg, val,
296 val & bit, 1500, 750000);
299 static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
301 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
302 struct device *dev = phy->dev.parent;
304 switch (data->speed) {
308 qcom_dwmac_sgmii_phy_init_1g(data->regmap);
311 qcom_dwmac_sgmii_phy_init_2p5g(data->regmap);
315 if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
316 QSERDES_COM_C_READY_STATUS,
317 QSERDES_COM_C_READY)) {
318 dev_err(dev, "QSERDES_COM_C_READY_STATUS timed-out");
322 if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
323 QSERDES_PCS_PCS_READY_STATUS,
324 QSERDES_PCS_READY)) {
325 dev_err(dev, "PCS_READY timed-out");
329 if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
330 QSERDES_PCS_PCS_READY_STATUS,
331 QSERDES_PCS_SGMIIPHY_READY)) {
332 dev_err(dev, "SGMIIPHY_READY timed-out");
336 if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
337 QSERDES_COM_CMN_STATUS,
338 QSERDES_COM_C_PLL_LOCKED)) {
339 dev_err(dev, "PLL Lock Status timed-out");
346 static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
348 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
350 return clk_prepare_enable(data->refclk);
353 static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
355 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
357 regmap_write(data->regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08);
358 regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x01);
360 regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x00);
361 regmap_write(data->regmap, QSERDES_PCS_PHY_START, 0x01);
363 clk_disable_unprepare(data->refclk);
368 static int qcom_dwmac_sgmii_phy_set_speed(struct phy *phy, int speed)
370 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
372 if (speed != data->speed)
375 return qcom_dwmac_sgmii_phy_calibrate(phy);
378 static const struct phy_ops qcom_dwmac_sgmii_phy_ops = {
379 .power_on = qcom_dwmac_sgmii_phy_power_on,
380 .power_off = qcom_dwmac_sgmii_phy_power_off,
381 .set_speed = qcom_dwmac_sgmii_phy_set_speed,
382 .calibrate = qcom_dwmac_sgmii_phy_calibrate,
383 .owner = THIS_MODULE,
386 static const struct regmap_config qcom_dwmac_sgmii_phy_regmap_cfg = {
390 .use_relaxed_mmio = true,
391 .disable_locking = true,
394 static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
396 struct qcom_dwmac_sgmii_phy_data *data;
397 struct device *dev = &pdev->dev;
398 struct phy_provider *provider;
402 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
406 data->speed = SPEED_10;
408 base = devm_platform_ioremap_resource(pdev, 0);
410 return PTR_ERR(base);
412 data->regmap = devm_regmap_init_mmio(dev, base,
413 &qcom_dwmac_sgmii_phy_regmap_cfg);
414 if (IS_ERR(data->regmap))
415 return PTR_ERR(data->regmap);
417 phy = devm_phy_create(dev, NULL, &qcom_dwmac_sgmii_phy_ops);
421 data->refclk = devm_clk_get(dev, "sgmi_ref");
422 if (IS_ERR(data->refclk))
423 return PTR_ERR(data->refclk);
425 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
426 if (IS_ERR(provider))
427 return PTR_ERR(provider);
429 phy_set_drvdata(phy, data);
434 static const struct of_device_id qcom_dwmac_sgmii_phy_of_match[] = {
435 { .compatible = "qcom,sa8775p-dwmac-sgmii-phy" },
438 MODULE_DEVICE_TABLE(of, qcom_dwmac_sgmii_phy_of_match);
440 static struct platform_driver qcom_dwmac_sgmii_phy_driver = {
441 .probe = qcom_dwmac_sgmii_phy_probe,
443 .name = "qcom-dwmac-sgmii-phy",
444 .of_match_table = qcom_dwmac_sgmii_phy_of_match,
448 module_platform_driver(qcom_dwmac_sgmii_phy_driver);
450 MODULE_DESCRIPTION("Qualcomm DWMAC SGMII PHY driver");
451 MODULE_LICENSE("GPL");