1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2023, Linaro Limited
4 */
5
6 #include <linux/clk.h>
7 #include <linux/ethtool.h>
8 #include <linux/module.h>
9 #include <linux/of.h>
10 #include <linux/phy/phy.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
13
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)
38
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)
79
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)
89
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)
101
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)
106
107 struct qcom_dwmac_sgmii_phy_data {
108 struct regmap *regmap;
109 struct clk *refclk;
110 int speed;
111 };
112
qcom_dwmac_sgmii_phy_init_1g(struct regmap * regmap)113 static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap)
114 {
115 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01);
116 regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01);
117
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);
130
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);
140
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);
149
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);
189
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);
197
198 regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01);
199 }
200
qcom_dwmac_sgmii_phy_init_2p5g(struct regmap * regmap)201 static void qcom_dwmac_sgmii_phy_init_2p5g(struct regmap *regmap)
202 {
203 regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01);
204 regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01);
205
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);
218
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);
228
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);
237
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);
277
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);
285
286 regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01);
287 }
288
289 static inline int
qcom_dwmac_sgmii_phy_poll_status(struct regmap * regmap,unsigned int reg,unsigned int bit)290 qcom_dwmac_sgmii_phy_poll_status(struct regmap *regmap, unsigned int reg,
291 unsigned int bit)
292 {
293 unsigned int val;
294
295 return regmap_read_poll_timeout(regmap, reg, val,
296 val & bit, 1500, 750000);
297 }
298
qcom_dwmac_sgmii_phy_calibrate(struct phy * phy)299 static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
300 {
301 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
302 struct device *dev = phy->dev.parent;
303
304 switch (data->speed) {
305 case SPEED_10:
306 case SPEED_100:
307 case SPEED_1000:
308 qcom_dwmac_sgmii_phy_init_1g(data->regmap);
309 break;
310 case SPEED_2500:
311 qcom_dwmac_sgmii_phy_init_2p5g(data->regmap);
312 break;
313 }
314
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");
319 return -ETIMEDOUT;
320 }
321
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");
326 return -ETIMEDOUT;
327 }
328
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");
333 return -ETIMEDOUT;
334 }
335
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");
340 return -ETIMEDOUT;
341 }
342
343 return 0;
344 }
345
qcom_dwmac_sgmii_phy_power_on(struct phy * phy)346 static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
347 {
348 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
349
350 return clk_prepare_enable(data->refclk);
351 }
352
qcom_dwmac_sgmii_phy_power_off(struct phy * phy)353 static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
354 {
355 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
356
357 regmap_write(data->regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08);
358 regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x01);
359 udelay(100);
360 regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x00);
361 regmap_write(data->regmap, QSERDES_PCS_PHY_START, 0x01);
362
363 clk_disable_unprepare(data->refclk);
364
365 return 0;
366 }
367
qcom_dwmac_sgmii_phy_set_speed(struct phy * phy,int speed)368 static int qcom_dwmac_sgmii_phy_set_speed(struct phy *phy, int speed)
369 {
370 struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
371
372 if (speed != data->speed)
373 data->speed = speed;
374
375 return qcom_dwmac_sgmii_phy_calibrate(phy);
376 }
377
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,
384 };
385
386 static const struct regmap_config qcom_dwmac_sgmii_phy_regmap_cfg = {
387 .reg_bits = 32,
388 .val_bits = 32,
389 .reg_stride = 4,
390 .use_relaxed_mmio = true,
391 .disable_locking = true,
392 };
393
qcom_dwmac_sgmii_phy_probe(struct platform_device * pdev)394 static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
395 {
396 struct qcom_dwmac_sgmii_phy_data *data;
397 struct device *dev = &pdev->dev;
398 struct phy_provider *provider;
399 void __iomem *base;
400 struct phy *phy;
401
402 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
403 if (!data)
404 return -ENOMEM;
405
406 data->speed = SPEED_10;
407
408 base = devm_platform_ioremap_resource(pdev, 0);
409 if (IS_ERR(base))
410 return PTR_ERR(base);
411
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);
416
417 phy = devm_phy_create(dev, NULL, &qcom_dwmac_sgmii_phy_ops);
418 if (IS_ERR(phy))
419 return PTR_ERR(phy);
420
421 data->refclk = devm_clk_get(dev, "sgmi_ref");
422 if (IS_ERR(data->refclk))
423 return PTR_ERR(data->refclk);
424
425 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
426 if (IS_ERR(provider))
427 return PTR_ERR(provider);
428
429 phy_set_drvdata(phy, data);
430
431 return 0;
432 }
433
434 static const struct of_device_id qcom_dwmac_sgmii_phy_of_match[] = {
435 { .compatible = "qcom,sa8775p-dwmac-sgmii-phy" },
436 { },
437 };
438 MODULE_DEVICE_TABLE(of, qcom_dwmac_sgmii_phy_of_match);
439
440 static struct platform_driver qcom_dwmac_sgmii_phy_driver = {
441 .probe = qcom_dwmac_sgmii_phy_probe,
442 .driver = {
443 .name = "qcom-dwmac-sgmii-phy",
444 .of_match_table = qcom_dwmac_sgmii_phy_of_match,
445 }
446 };
447
448 module_platform_driver(qcom_dwmac_sgmii_phy_driver);
449
450 MODULE_DESCRIPTION("Qualcomm DWMAC SGMII PHY driver");
451 MODULE_LICENSE("GPL");
452