blob: e1630e1c2299ed96ddc17d87b606c1015f389d17 [file] [log] [blame]
Yanhong Wang1d6c3412023-06-15 17:36:42 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
Frank Sae985eb732024-11-23 23:38:44 -08003 * Motorcomm YT8511/YT8531/YT8531S/YT8821/YT8521S PHY driver.
Yanhong Wang1d6c3412023-06-15 17:36:42 +08004 *
5 * Copyright (C) 2023 StarFive Technology Co., Ltd.
Frank Saea34b2bb2024-11-23 23:38:43 -08006 * Copyright (C) 2024 Motorcomm Electronic Technology Co., Ltd.
Yanhong Wang1d6c3412023-06-15 17:36:42 +08007 */
8
9#include <config.h>
Yanhong Wang1d6c3412023-06-15 17:36:42 +080010#include <malloc.h>
11#include <phy.h>
12#include <linux/bitfield.h>
13
Nicolas Frattarolif08686a2023-08-05 12:35:01 +020014#define PHY_ID_YT8511 0x0000010a
Yanhong Wang1d6c3412023-06-15 17:36:42 +080015#define PHY_ID_YT8531 0x4f51e91b
Frank Sae63f2cad2024-09-12 05:02:25 -070016#define PHY_ID_YT8821 0x4f51ea19
Frank Saea34b2bb2024-11-23 23:38:43 -080017#define PHY_ID_YT8531S 0x4f51e91a
Frank Sae985eb732024-11-23 23:38:44 -080018#define PHY_ID_YT8521S 0x0000011a
Yanhong Wang1d6c3412023-06-15 17:36:42 +080019#define PHY_ID_MASK GENMASK(31, 0)
20
21/* Extended Register's Address Offset Register */
22#define YTPHY_PAGE_SELECT 0x1E
23
24/* Extended Register's Data Register */
25#define YTPHY_PAGE_DATA 0x1F
26
27#define YTPHY_SYNCE_CFG_REG 0xA012
28
Lukasz Tekieli3282aee2024-01-28 20:22:47 +010029#define YT8531_PAD_DRIVE_STRENGTH_CFG_REG 0xA010
30#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13)
31#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */
32#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */
33#define YT8531_RGMII_RX_DS_DEFAULT 0x3
34
Yanhong Wang1d6c3412023-06-15 17:36:42 +080035#define YTPHY_DTS_OUTPUT_CLK_DIS 0
36#define YTPHY_DTS_OUTPUT_CLK_25M 25000000
37#define YTPHY_DTS_OUTPUT_CLK_125M 125000000
38
Frank Sae985eb732024-11-23 23:38:44 -080039#define YT8521S_SCR_SYNCE_ENABLE BIT(5)
40/* 1b0 output 25m clock *default*
41 * 1b1 output 125m clock
42 */
43#define YT8521S_SCR_CLK_FRE_SEL_125M BIT(3)
44#define YT8521S_SCR_CLK_SRC_MASK GENMASK(2, 1)
45#define YT8521S_SCR_CLK_SRC_PLL_125M 0
46#define YT8521S_SCR_CLK_SRC_UTP_RX 1
47#define YT8521S_SCR_CLK_SRC_SDS_RX 2
48#define YT8521S_SCR_CLK_SRC_REF_25M 3
49
Nicolas Frattarolif08686a2023-08-05 12:35:01 +020050#define YT8511_EXT_CLK_GATE 0x0c
51#define YT8511_EXT_DELAY_DRIVE 0x0d
52#define YT8511_EXT_SLEEP_CTRL 0x27
53
54/* 2b00 25m from pll
55 * 2b01 25m from xtl *default*
56 * 2b10 62.m from pll
57 * 2b11 125m from pll
58 */
59#define YT8511_CLK_125M (BIT(2) | BIT(1))
60#define YT8511_PLLON_SLP BIT(14)
61
62/* RX Delay enabled = 1.8ns 1000T, 8ns 10/100T */
63#define YT8511_DELAY_RX BIT(0)
64
65/* TX Gig-E Delay is bits 7:4, default 0x5
66 * TX Fast-E Delay is bits 15:12, default 0xf
67 * Delay = 150ps * N - 250ps
68 * On = 2000ps, off = 50ps
69 */
70#define YT8511_DELAY_GE_TX_EN (0xf << 4)
71#define YT8511_DELAY_GE_TX_DIS (0x2 << 4)
72#define YT8511_DELAY_FE_TX_EN (0xf << 12)
73#define YT8511_DELAY_FE_TX_DIS (0x2 << 12)
74
Yanhong Wang1d6c3412023-06-15 17:36:42 +080075#define YT8531_SCR_SYNCE_ENABLE BIT(6)
76/* 1b0 output 25m clock *default*
77 * 1b1 output 125m clock
78 */
79#define YT8531_SCR_CLK_FRE_SEL_125M BIT(4)
80#define YT8531_SCR_CLK_SRC_MASK GENMASK(3, 1)
81#define YT8531_SCR_CLK_SRC_PLL_125M 0
82#define YT8531_SCR_CLK_SRC_UTP_RX 1
83#define YT8531_SCR_CLK_SRC_SDS_RX 2
84#define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3
85#define YT8531_SCR_CLK_SRC_REF_25M 4
86#define YT8531_SCR_CLK_SRC_SSC_25M 5
87
88/* 1b0 use original tx_clk_rgmii *default*
89 * 1b1 use inverted tx_clk_rgmii.
90 */
91#define YT8531_RC1R_TX_CLK_SEL_INVERTED BIT(14)
92#define YT8531_RC1R_RX_DELAY_MASK GENMASK(13, 10)
93#define YT8531_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4)
94#define YT8531_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0)
95#define YT8531_RC1R_RGMII_0_000_NS 0
96#define YT8531_RC1R_RGMII_0_150_NS 1
97#define YT8531_RC1R_RGMII_0_300_NS 2
98#define YT8531_RC1R_RGMII_0_450_NS 3
99#define YT8531_RC1R_RGMII_0_600_NS 4
100#define YT8531_RC1R_RGMII_0_750_NS 5
101#define YT8531_RC1R_RGMII_0_900_NS 6
102#define YT8531_RC1R_RGMII_1_050_NS 7
103#define YT8531_RC1R_RGMII_1_200_NS 8
104#define YT8531_RC1R_RGMII_1_350_NS 9
105#define YT8531_RC1R_RGMII_1_500_NS 10
106#define YT8531_RC1R_RGMII_1_650_NS 11
107#define YT8531_RC1R_RGMII_1_800_NS 12
108#define YT8531_RC1R_RGMII_1_950_NS 13
109#define YT8531_RC1R_RGMII_2_100_NS 14
110#define YT8531_RC1R_RGMII_2_250_NS 15
111
112/* Phy gmii clock gating Register */
113#define YT8531_CLOCK_GATING_REG 0xC
114#define YT8531_CGR_RX_CLK_EN BIT(12)
115
116/* Specific Status Register */
117#define YTPHY_SPECIFIC_STATUS_REG 0x11
118#define YTPHY_DUPLEX_MASK BIT(13)
119#define YTPHY_DUPLEX_SHIFT 13
Frank Sae8e896f22024-09-12 05:02:24 -0700120#define YTPHY_SPEED_MASK ((0x3 << 14) | BIT(9))
121#define YTPHY_SPEED_10M ((0x0 << 14))
122#define YTPHY_SPEED_100M ((0x1 << 14))
123#define YTPHY_SPEED_1000M ((0x2 << 14))
Frank Sae63f2cad2024-09-12 05:02:25 -0700124#define YTPHY_SPEED_10G ((0x3 << 14))
125#define YTPHY_SPEED_2500M ((0x0 << 14) | BIT(9))
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800126
127#define YT8531_EXTREG_SLEEP_CONTROL1_REG 0x27
128#define YT8531_ESC1R_SLEEP_SW BIT(15)
129#define YT8531_ESC1R_PLLON_SLP BIT(14)
130
131#define YT8531_RGMII_CONFIG1_REG 0xA003
132
133#define YT8531_CHIP_CONFIG_REG 0xA001
134#define YT8531_CCR_SW_RST BIT(15)
135/* 1b0 disable 1.9ns rxc clock delay *default*
136 * 1b1 enable 1.9ns rxc clock delay
137 */
138#define YT8531_CCR_RXC_DLY_EN BIT(8)
139#define YT8531_CCR_RXC_DLY_1_900_NS 1900
140
Lukasz Tekieli3282aee2024-01-28 20:22:47 +0100141#define YT8531_CCR_CFG_LDO_MASK GENMASK(5, 4)
142#define YT8531_CCR_CFG_LDO_3V3 0x0
143#define YT8531_CCR_CFG_LDO_1V8 0x2
144
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800145/* bits in struct ytphy_plat_priv->flag */
146#define TX_CLK_ADJ_ENABLED BIT(0)
147#define AUTO_SLEEP_DISABLED BIT(1)
148#define KEEP_PLL_ENABLED BIT(2)
149#define TX_CLK_10_INVERTED BIT(3)
150#define TX_CLK_100_INVERTED BIT(4)
151#define TX_CLK_1000_INVERTED BIT(5)
152
Frank Sae63f2cad2024-09-12 05:02:25 -0700153#define YT8821_SDS_EXT_CSR_CTRL_REG 0x23
154#define YT8821_SDS_EXT_CSR_VCO_LDO_EN BIT(15)
155#define YT8821_SDS_EXT_CSR_VCO_BIAS_LPF_EN BIT(8)
156
157#define YT8821_UTP_EXT_PI_CTRL_REG 0x56
158#define YT8821_UTP_EXT_PI_RST_N_FIFO BIT(5)
159#define YT8821_UTP_EXT_PI_TX_CLK_SEL_AFE BIT(4)
160#define YT8821_UTP_EXT_PI_RX_CLK_3_SEL_AFE BIT(3)
161#define YT8821_UTP_EXT_PI_RX_CLK_2_SEL_AFE BIT(2)
162#define YT8821_UTP_EXT_PI_RX_CLK_1_SEL_AFE BIT(1)
163#define YT8821_UTP_EXT_PI_RX_CLK_0_SEL_AFE BIT(0)
164
165#define YT8821_UTP_EXT_VCT_CFG6_CTRL_REG 0x97
166#define YT8821_UTP_EXT_FECHO_AMP_TH_HUGE GENMASK(15, 8)
167
168#define YT8821_UTP_EXT_ECHO_CTRL_REG 0x336
169#define YT8821_UTP_EXT_TRACE_LNG_GAIN_THR_1000 GENMASK(14, 8)
170
171#define YT8821_UTP_EXT_GAIN_CTRL_REG 0x340
172#define YT8821_UTP_EXT_TRACE_MED_GAIN_THR_1000 GENMASK(6, 0)
173
174#define YT8821_UTP_EXT_RPDN_CTRL_REG 0x34E
175#define YT8821_UTP_EXT_RPDN_BP_FFE_LNG_2500 BIT(15)
176#define YT8821_UTP_EXT_RPDN_BP_FFE_SHT_2500 BIT(7)
177#define YT8821_UTP_EXT_RPDN_IPR_SHT_2500 GENMASK(6, 0)
178
179#define YT8821_UTP_EXT_TH_20DB_2500_CTRL_REG 0x36A
180#define YT8821_UTP_EXT_TH_20DB_2500 GENMASK(15, 0)
181
182#define YT8821_UTP_EXT_TRACE_CTRL_REG 0x372
183#define YT8821_UTP_EXT_TRACE_LNG_GAIN_THE_2500 GENMASK(14, 8)
184#define YT8821_UTP_EXT_TRACE_MED_GAIN_THE_2500 GENMASK(6, 0)
185
186#define YT8821_UTP_EXT_ALPHA_IPR_CTRL_REG 0x374
187#define YT8821_UTP_EXT_ALPHA_SHT_2500 GENMASK(14, 8)
188#define YT8821_UTP_EXT_IPR_LNG_2500 GENMASK(6, 0)
189
190#define YT8821_UTP_EXT_PLL_CTRL_REG 0x450
191#define YT8821_UTP_EXT_PLL_SPARE_CFG GENMASK(7, 0)
192
193#define YT8821_UTP_EXT_DAC_IMID_CH_2_3_CTRL_REG 0x466
194#define YT8821_UTP_EXT_DAC_IMID_CH_3_10_ORG GENMASK(14, 8)
195#define YT8821_UTP_EXT_DAC_IMID_CH_2_10_ORG GENMASK(6, 0)
196
197#define YT8821_UTP_EXT_DAC_IMID_CH_0_1_CTRL_REG 0x467
198#define YT8821_UTP_EXT_DAC_IMID_CH_1_10_ORG GENMASK(14, 8)
199#define YT8821_UTP_EXT_DAC_IMID_CH_0_10_ORG GENMASK(6, 0)
200
201#define YT8821_UTP_EXT_DAC_IMSB_CH_2_3_CTRL_REG 0x468
202#define YT8821_UTP_EXT_DAC_IMSB_CH_3_10_ORG GENMASK(14, 8)
203#define YT8821_UTP_EXT_DAC_IMSB_CH_2_10_ORG GENMASK(6, 0)
204
205#define YT8821_UTP_EXT_DAC_IMSB_CH_0_1_CTRL_REG 0x469
206#define YT8821_UTP_EXT_DAC_IMSB_CH_1_10_ORG GENMASK(14, 8)
207#define YT8821_UTP_EXT_DAC_IMSB_CH_0_10_ORG GENMASK(6, 0)
208
209#define YT8821_UTP_EXT_MU_COARSE_FR_CTRL_REG 0x4B3
210#define YT8821_UTP_EXT_MU_COARSE_FR_F_FFE GENMASK(14, 12)
211#define YT8821_UTP_EXT_MU_COARSE_FR_F_FBE GENMASK(10, 8)
212
213#define YT8821_UTP_EXT_MU_FINE_FR_CTRL_REG 0x4B5
214#define YT8821_UTP_EXT_MU_FINE_FR_F_FFE GENMASK(14, 12)
215#define YT8821_UTP_EXT_MU_FINE_FR_F_FBE GENMASK(10, 8)
216
217#define YT8821_UTP_EXT_VGA_LPF1_CAP_CTRL_REG 0x4D2
218#define YT8821_UTP_EXT_VGA_LPF1_CAP_OTHER GENMASK(7, 4)
219#define YT8821_UTP_EXT_VGA_LPF1_CAP_2500 GENMASK(3, 0)
220
221#define YT8821_UTP_EXT_VGA_LPF2_CAP_CTRL_REG 0x4D3
222#define YT8821_UTP_EXT_VGA_LPF2_CAP_OTHER GENMASK(7, 4)
223#define YT8821_UTP_EXT_VGA_LPF2_CAP_2500 GENMASK(3, 0)
224
225#define YT8821_UTP_EXT_TXGE_NFR_FR_THP_CTRL_REG 0x660
226#define YT8821_UTP_EXT_NFR_TX_ABILITY BIT(3)
227
228#define YT8821_CHIP_MODE_FORCE_BX2500 1
229
230/* chip config register */
231#define YTPHY_CCR_MODE_SEL_MASK GENMASK(2, 0)
232
233#define YTPHY_REG_SPACE_SELECT_REG 0xA000
234#define YTPHY_RSSR_SPACE_MASK BIT(1)
235#define YTPHY_RSSR_FIBER_SPACE (0x1 << 1)
236#define YTPHY_RSSR_UTP_SPACE (0x0 << 1)
237
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800238struct ytphy_plat_priv {
239 u32 rx_delay_ps;
240 u32 tx_delay_ps;
241 u32 clk_out_frequency;
242 u32 flag;
243};
244
245/**
246 * struct ytphy_cfg_reg_map - map a config value to a register value
247 * @cfg: value in device configuration
248 * @reg: value in the register
249 */
250struct ytphy_cfg_reg_map {
251 u32 cfg;
252 u32 reg;
253};
254
255static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = {
256 /* for tx delay / rx delay with YT8531_CCR_RXC_DLY_EN is not set. */
257 { 0, YT8531_RC1R_RGMII_0_000_NS },
258 { 150, YT8531_RC1R_RGMII_0_150_NS },
259 { 300, YT8531_RC1R_RGMII_0_300_NS },
260 { 450, YT8531_RC1R_RGMII_0_450_NS },
261 { 600, YT8531_RC1R_RGMII_0_600_NS },
262 { 750, YT8531_RC1R_RGMII_0_750_NS },
263 { 900, YT8531_RC1R_RGMII_0_900_NS },
264 { 1050, YT8531_RC1R_RGMII_1_050_NS },
265 { 1200, YT8531_RC1R_RGMII_1_200_NS },
266 { 1350, YT8531_RC1R_RGMII_1_350_NS },
267 { 1500, YT8531_RC1R_RGMII_1_500_NS },
268 { 1650, YT8531_RC1R_RGMII_1_650_NS },
269 { 1800, YT8531_RC1R_RGMII_1_800_NS },
270 { 1950, YT8531_RC1R_RGMII_1_950_NS }, /* default tx/rx delay */
271 { 2100, YT8531_RC1R_RGMII_2_100_NS },
272 { 2250, YT8531_RC1R_RGMII_2_250_NS },
273
274 /* only for rx delay with YT8531_CCR_RXC_DLY_EN is set. */
275 { 0 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_000_NS },
276 { 150 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_150_NS },
277 { 300 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_300_NS },
278 { 450 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_450_NS },
279 { 600 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_600_NS },
280 { 750 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_750_NS },
281 { 900 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_900_NS },
282 { 1050 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_050_NS },
283 { 1200 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_200_NS },
284 { 1350 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_350_NS },
285 { 1500 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_500_NS },
286 { 1650 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_650_NS },
287 { 1800 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_800_NS },
288 { 1950 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_950_NS },
289 { 2100 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_2_100_NS },
290 { 2250 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_2_250_NS }
291};
292
293static u32 ytphy_get_delay_reg_value(struct phy_device *phydev,
294 u32 val,
295 u16 *rxc_dly_en)
296{
297 int tb_size = ARRAY_SIZE(ytphy_rgmii_delays);
298 int tb_size_half = tb_size / 2;
299 int i;
300
301 /* when rxc_dly_en is NULL, it is get the delay for tx, only half of
302 * tb_size is valid.
303 */
304 if (!rxc_dly_en)
305 tb_size = tb_size_half;
306
307 for (i = 0; i < tb_size; i++) {
308 if (ytphy_rgmii_delays[i].cfg == val) {
309 if (rxc_dly_en && i < tb_size_half)
310 *rxc_dly_en = 0;
311 return ytphy_rgmii_delays[i].reg;
312 }
313 }
314
315 pr_warn("Unsupported value %d, using default (%u)\n",
316 val, YT8531_RC1R_RGMII_1_950_NS);
317
318 /* when rxc_dly_en is not NULL, it is get the delay for rx.
319 * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps,
320 * so YT8531_CCR_RXC_DLY_EN should not be set.
321 */
322 if (rxc_dly_en)
323 *rxc_dly_en = 0;
324
325 return YT8531_RC1R_RGMII_1_950_NS;
326}
327
328static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask,
329 u16 set)
330{
331 int ret;
332
333 ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
334 if (ret < 0)
335 return ret;
336
337 return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set);
338}
339
Lukasz Tekieli3282aee2024-01-28 20:22:47 +0100340static int ytphy_read_ext(struct phy_device *phydev, u16 regnum)
341{
342 int ret;
343
344 ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
345 if (ret < 0)
346 return ret;
347
348 return phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA);
349}
350
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800351static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
352{
353 struct ytphy_plat_priv *priv = phydev->priv;
354 u16 rxc_dly_en = YT8531_CCR_RXC_DLY_EN;
355 u32 rx_reg, tx_reg;
356 u16 mask, val = 0;
357 int ret;
358
359 rx_reg = ytphy_get_delay_reg_value(phydev, priv->rx_delay_ps,
360 &rxc_dly_en);
361 tx_reg = ytphy_get_delay_reg_value(phydev, priv->tx_delay_ps,
362 NULL);
363
364 switch (phydev->interface) {
365 case PHY_INTERFACE_MODE_RGMII:
366 rxc_dly_en = 0;
367 break;
368 case PHY_INTERFACE_MODE_RGMII_RXID:
369 val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg);
370 break;
371 case PHY_INTERFACE_MODE_RGMII_TXID:
372 rxc_dly_en = 0;
373 val |= FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
374 break;
375 case PHY_INTERFACE_MODE_RGMII_ID:
376 val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg) |
377 FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
378 break;
379 default: /* do not support other modes */
380 return -EOPNOTSUPP;
381 }
382
383 ret = ytphy_modify_ext(phydev, YT8531_CHIP_CONFIG_REG,
384 YT8531_CCR_RXC_DLY_EN, rxc_dly_en);
385 if (ret < 0)
386 return ret;
387
388 /* Generally, it is not necessary to adjust YT8531_RC1R_FE_TX_DELAY */
389 mask = YT8531_RC1R_RX_DELAY_MASK | YT8531_RC1R_GE_TX_DELAY_MASK;
390 return ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG, mask, val);
391}
392
393static int yt8531_parse_status(struct phy_device *phydev)
394{
395 int val;
396 int speed, speed_mode;
397
398 val = phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_SPECIFIC_STATUS_REG);
399 if (val < 0)
400 return val;
401
Frank Sae8e896f22024-09-12 05:02:24 -0700402 speed_mode = (val & YTPHY_SPEED_MASK);
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800403 switch (speed_mode) {
Frank Sae8e896f22024-09-12 05:02:24 -0700404 case YTPHY_SPEED_1000M:
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800405 speed = SPEED_1000;
406 break;
Frank Sae8e896f22024-09-12 05:02:24 -0700407 case YTPHY_SPEED_100M:
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800408 speed = SPEED_100;
409 break;
Frank Sae8e896f22024-09-12 05:02:24 -0700410 case YTPHY_SPEED_10M:
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800411 speed = SPEED_10;
412 break;
413 }
414
415 phydev->speed = speed;
416 phydev->duplex = (val & YTPHY_DUPLEX_MASK) >> YTPHY_DUPLEX_SHIFT;
417
418 return 0;
419}
420
421static int yt8531_startup(struct phy_device *phydev)
422{
423 struct ytphy_plat_priv *priv = phydev->priv;
424 u16 val = 0;
425 int ret;
426
427 ret = genphy_update_link(phydev);
428 if (ret)
429 return ret;
430
431 ret = yt8531_parse_status(phydev);
432 if (ret)
433 return ret;
434
435 if (phydev->speed < 0)
436 return -EINVAL;
437
438 if (!(priv->flag & TX_CLK_ADJ_ENABLED))
439 return 0;
440
441 switch (phydev->speed) {
442 case SPEED_1000:
443 if (priv->flag & TX_CLK_1000_INVERTED)
444 val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
445 break;
446 case SPEED_100:
447 if (priv->flag & TX_CLK_100_INVERTED)
448 val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
449 break;
450 case SPEED_10:
451 if (priv->flag & TX_CLK_10_INVERTED)
452 val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
453 break;
454 default:
455 printf("UNKNOWN SPEED\n");
456 return -EINVAL;
457 }
458
459 ret = ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG,
460 YT8531_RC1R_TX_CLK_SEL_INVERTED, val);
461 if (ret < 0)
462 pr_warn("Modify TX_CLK_SEL err:%d\n", ret);
463
464 return 0;
465}
466
467static void ytphy_dt_parse(struct phy_device *phydev)
468{
469 struct ytphy_plat_priv *priv = phydev->priv;
470
471 priv->clk_out_frequency = ofnode_read_u32_default(phydev->node,
472 "motorcomm,clk-out-frequency-hz",
473 YTPHY_DTS_OUTPUT_CLK_DIS);
474 priv->rx_delay_ps = ofnode_read_u32_default(phydev->node,
475 "rx-internal-delay-ps",
476 YT8531_RC1R_RGMII_1_950_NS);
477 priv->tx_delay_ps = ofnode_read_u32_default(phydev->node,
478 "tx-internal-delay-ps",
479 YT8531_RC1R_RGMII_1_950_NS);
480
481 if (ofnode_read_bool(phydev->node, "motorcomm,auto-sleep-disabled"))
482 priv->flag |= AUTO_SLEEP_DISABLED;
483
484 if (ofnode_read_bool(phydev->node, "motorcomm,keep-pll-enabled"))
485 priv->flag |= KEEP_PLL_ENABLED;
486
487 if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-adj-enabled"))
488 priv->flag |= TX_CLK_ADJ_ENABLED;
489
490 if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-10-inverted"))
491 priv->flag |= TX_CLK_10_INVERTED;
492
493 if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-100-inverted"))
494 priv->flag |= TX_CLK_100_INVERTED;
495
496 if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-1000-inverted"))
497 priv->flag |= TX_CLK_1000_INVERTED;
498}
499
Nicolas Frattarolif08686a2023-08-05 12:35:01 +0200500static int yt8511_config(struct phy_device *phydev)
501{
502 u32 ge, fe;
503 int ret;
504
505 ret = genphy_config_aneg(phydev);
506 if (ret < 0)
507 return ret;
508
509 switch (phydev->interface) {
510 case PHY_INTERFACE_MODE_RGMII:
511 ge = YT8511_DELAY_GE_TX_DIS;
512 fe = YT8511_DELAY_FE_TX_DIS;
513 break;
514 case PHY_INTERFACE_MODE_RGMII_RXID:
515 ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_DIS;
516 fe = YT8511_DELAY_FE_TX_DIS;
517 break;
518 case PHY_INTERFACE_MODE_RGMII_TXID:
519 ge = YT8511_DELAY_GE_TX_EN;
520 fe = YT8511_DELAY_FE_TX_EN;
521 break;
522 case PHY_INTERFACE_MODE_RGMII_ID:
523 ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN;
524 fe = YT8511_DELAY_FE_TX_EN;
525 break;
526 default: /* do not support other modes */
527 return -EOPNOTSUPP;
528 }
529
530 ret = ytphy_modify_ext(phydev, YT8511_EXT_CLK_GATE,
531 (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge);
532 if (ret < 0)
533 return ret;
534 /* set clock mode to 125m */
535 ret = ytphy_modify_ext(phydev, YT8511_EXT_CLK_GATE,
536 YT8511_CLK_125M, YT8511_CLK_125M);
537 if (ret < 0)
538 return ret;
539 ret = ytphy_modify_ext(phydev, YT8511_EXT_DELAY_DRIVE,
540 YT8511_DELAY_FE_TX_EN, fe);
541 if (ret < 0)
542 return ret;
543 /* sleep control, disable PLL in sleep for now */
544 ret = ytphy_modify_ext(phydev, YT8511_EXT_SLEEP_CTRL, YT8511_PLLON_SLP,
545 0);
546 if (ret < 0)
547 return ret;
548
549 return 0;
550}
551
Lukasz Tekieli3282aee2024-01-28 20:22:47 +0100552/**
553 * struct ytphy_ldo_vol_map - map a current value to a register value
554 * @vol: ldo voltage
555 * @ds: value in the register
556 * @cur: value in device configuration
557 */
558struct ytphy_ldo_vol_map {
559 u32 vol;
560 u32 ds;
561 u32 cur;
562};
563
564static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = {
565 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 0, .cur = 1200},
566 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 1, .cur = 2100},
567 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 2, .cur = 2700},
568 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 3, .cur = 2910},
569 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 4, .cur = 3110},
570 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 5, .cur = 3600},
571 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 6, .cur = 3970},
572 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 7, .cur = 4350},
573 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 0, .cur = 3070},
574 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 1, .cur = 4080},
575 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 2, .cur = 4370},
576 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 3, .cur = 4680},
577 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 4, .cur = 5020},
578 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 5, .cur = 5450},
579 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 6, .cur = 5740},
580 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 7, .cur = 6140},
581};
582
583static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
584{
585 u32 val;
586
587 val = ytphy_read_ext(phydev, YT8531_CHIP_CONFIG_REG);
588 val = FIELD_GET(YT8531_CCR_CFG_LDO_MASK, val);
589
590 return val <= YT8531_CCR_CFG_LDO_1V8 ? val : YT8531_CCR_CFG_LDO_1V8;
591}
592
593static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur)
594{
595 u32 vol;
596 int i;
597
598 vol = yt8531_get_ldo_vol(phydev);
599 for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) {
600 if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur)
601 return yt8531_ldo_vol[i].ds;
602 }
603
604 return -EINVAL;
605}
606
607static int yt8531_set_ds(struct phy_device *phydev)
608{
609 u32 ds_field_low, ds_field_hi, val;
610 int ret, ds;
611
612 /* set rgmii rx clk driver strength */
613 if (!ofnode_read_u32(phydev->node, "motorcomm,rx-clk-drv-microamp", &val)) {
614 ds = yt8531_get_ds_map(phydev, val);
615 if (ds < 0) {
616 pr_warn("No matching current value was found.");
617 return -EINVAL;
618 }
619 } else {
620 ds = YT8531_RGMII_RX_DS_DEFAULT;
621 }
622
623 ret = ytphy_modify_ext(phydev,
624 YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
625 YT8531_RGMII_RXC_DS_MASK,
626 FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
627 if (ret < 0)
628 return ret;
629
630 /* set rgmii rx data driver strength */
631 if (!ofnode_read_u32(phydev->node, "motorcomm,rx-data-drv-microamp", &val)) {
632 ds = yt8531_get_ds_map(phydev, val);
633 if (ds < 0) {
634 pr_warn("No matching current value was found.");
635 return -EINVAL;
636 }
637 } else {
638 ds = YT8531_RGMII_RX_DS_DEFAULT;
639 }
640
641 ds_field_hi = FIELD_GET(BIT(2), ds);
642 ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi);
643
644 ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
645 ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
646
647 ret = ytphy_modify_ext(phydev,
648 YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
649 YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
650 ds_field_low | ds_field_hi);
651 if (ret < 0)
652 return ret;
653
654 return 0;
655}
656
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800657static int yt8531_config(struct phy_device *phydev)
658{
659 struct ytphy_plat_priv *priv = phydev->priv;
660 u16 mask, val;
661 int ret;
662
663 ret = genphy_config_aneg(phydev);
664 if (ret < 0)
665 return ret;
666
667 ytphy_dt_parse(phydev);
668 switch (priv->clk_out_frequency) {
669 case YTPHY_DTS_OUTPUT_CLK_DIS:
670 mask = YT8531_SCR_SYNCE_ENABLE;
671 val = 0;
672 break;
673 case YTPHY_DTS_OUTPUT_CLK_25M:
674 mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
675 YT8531_SCR_CLK_FRE_SEL_125M;
676 val = YT8531_SCR_SYNCE_ENABLE |
677 FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
678 YT8531_SCR_CLK_SRC_REF_25M);
679 break;
680 case YTPHY_DTS_OUTPUT_CLK_125M:
681 mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
682 YT8531_SCR_CLK_FRE_SEL_125M;
683 val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M |
684 FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
685 YT8531_SCR_CLK_SRC_PLL_125M);
686 break;
687 default:
688 pr_warn("Freq err:%u\n", priv->clk_out_frequency);
689 return -EINVAL;
690 }
691
692 ret = ytphy_modify_ext(phydev, YTPHY_SYNCE_CFG_REG, mask,
693 val);
694 if (ret < 0)
695 return ret;
696
697 ret = ytphy_rgmii_clk_delay_config(phydev);
698 if (ret < 0)
699 return ret;
700
701 if (priv->flag & AUTO_SLEEP_DISABLED) {
702 /* disable auto sleep */
703 ret = ytphy_modify_ext(phydev,
704 YT8531_EXTREG_SLEEP_CONTROL1_REG,
705 YT8531_ESC1R_SLEEP_SW, 0);
706 if (ret < 0)
707 return ret;
708 }
709
710 if (priv->flag & KEEP_PLL_ENABLED) {
711 /* enable RXC clock when no wire plug */
712 ret = ytphy_modify_ext(phydev,
713 YT8531_CLOCK_GATING_REG,
714 YT8531_CGR_RX_CLK_EN, 0);
715 if (ret < 0)
716 return ret;
717 }
718
Lukasz Tekieli3282aee2024-01-28 20:22:47 +0100719 ret = yt8531_set_ds(phydev);
720 if (ret < 0)
721 return ret;
722
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800723 return 0;
724}
725
726static int yt8531_probe(struct phy_device *phydev)
727{
728 struct ytphy_plat_priv *priv;
729
730 priv = calloc(1, sizeof(struct ytphy_plat_priv));
731 if (!priv)
732 return -ENOMEM;
733
734 phydev->priv = priv;
735
736 return 0;
737}
738
Frank Sae63f2cad2024-09-12 05:02:25 -0700739static int ytphy_save_page(struct phy_device *phydev)
740{
741 int old_page;
742
743 old_page = ytphy_read_ext(phydev, YTPHY_REG_SPACE_SELECT_REG);
744 if (old_page < 0)
745 return old_page;
746
747 if ((old_page & YTPHY_RSSR_SPACE_MASK) == YTPHY_RSSR_FIBER_SPACE)
748 return YTPHY_RSSR_FIBER_SPACE;
749
750 return YTPHY_RSSR_UTP_SPACE;
751};
752
753static int ytphy_restore_page(struct phy_device *phydev, int page,
754 int ret)
755{
756 int mask = YTPHY_RSSR_SPACE_MASK;
757 int set;
758 int r;
759
760 if ((page & YTPHY_RSSR_SPACE_MASK) == YTPHY_RSSR_FIBER_SPACE)
761 set = YTPHY_RSSR_FIBER_SPACE;
762 else
763 set = YTPHY_RSSR_UTP_SPACE;
764
765 r = ytphy_modify_ext(phydev, YTPHY_REG_SPACE_SELECT_REG, mask,
766 set);
767 if (ret >= 0 && r < 0)
768 ret = r;
769
770 return ret;
771};
772
773static int ytphy_write_ext(struct phy_device *phydev, u16 regnum,
774 u16 val)
775{
776 int ret;
777
778 ret = phy_write(phydev, MDIO_DEVAD_NONE,
779 YTPHY_PAGE_SELECT, regnum);
780 if (ret < 0)
781 return ret;
782
783 return phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, val);
784}
785
786static int yt8821_probe(struct phy_device *phydev)
787{
788 phydev->advertising = PHY_GBIT_FEATURES |
789 SUPPORTED_2500baseX_Full |
790 SUPPORTED_Pause |
791 SUPPORTED_Asym_Pause;
792 phydev->supported = phydev->advertising;
793
794 return 0;
795}
796
797static int yt8821_serdes_init(struct phy_device *phydev)
798{
799 int old_page;
800 u16 mask;
801 u16 set;
802 int ret;
803
804 old_page = ytphy_save_page(phydev);
805 if (old_page < 0)
806 return old_page;
807
808 ret = ytphy_modify_ext(phydev, YTPHY_REG_SPACE_SELECT_REG,
809 YTPHY_RSSR_SPACE_MASK,
810 YTPHY_RSSR_FIBER_SPACE);
811 if (ret < 0)
812 goto err_restore_page;
813
814 ret = phy_modify(phydev, MDIO_DEVAD_NONE, MII_BMCR,
815 BMCR_ANENABLE, 0);
816 if (ret < 0)
817 goto err_restore_page;
818
819 mask = YT8821_SDS_EXT_CSR_VCO_LDO_EN |
820 YT8821_SDS_EXT_CSR_VCO_BIAS_LPF_EN;
821 set = YT8821_SDS_EXT_CSR_VCO_LDO_EN;
822 ret = ytphy_modify_ext(phydev, YT8821_SDS_EXT_CSR_CTRL_REG, mask,
823 set);
824
825err_restore_page:
826 return ytphy_restore_page(phydev, old_page, ret);
827}
828
829static int yt8821_utp_init(struct phy_device *phydev)
830{
831 int old_page;
832 u16 mask;
833 u16 save;
834 u16 set;
835 int ret;
836
837 old_page = ytphy_save_page(phydev);
838 if (old_page < 0)
839 return old_page;
840
841 ret = ytphy_modify_ext(phydev, YTPHY_REG_SPACE_SELECT_REG,
842 YTPHY_RSSR_SPACE_MASK,
843 YTPHY_RSSR_UTP_SPACE);
844 if (ret < 0)
845 goto err_restore_page;
846
847 mask = YT8821_UTP_EXT_RPDN_BP_FFE_LNG_2500 |
848 YT8821_UTP_EXT_RPDN_BP_FFE_SHT_2500 |
849 YT8821_UTP_EXT_RPDN_IPR_SHT_2500;
850 set = YT8821_UTP_EXT_RPDN_BP_FFE_LNG_2500 |
851 YT8821_UTP_EXT_RPDN_BP_FFE_SHT_2500;
852 ret = ytphy_modify_ext(phydev, YT8821_UTP_EXT_RPDN_CTRL_REG,
853 mask, set);
854 if (ret < 0)
855 goto err_restore_page;
856
857 mask = YT8821_UTP_EXT_VGA_LPF1_CAP_OTHER |
858 YT8821_UTP_EXT_VGA_LPF1_CAP_2500;
859 ret = ytphy_modify_ext(phydev,
860 YT8821_UTP_EXT_VGA_LPF1_CAP_CTRL_REG,
861 mask, 0);
862 if (ret < 0)
863 goto err_restore_page;
864
865 mask = YT8821_UTP_EXT_VGA_LPF2_CAP_OTHER |
866 YT8821_UTP_EXT_VGA_LPF2_CAP_2500;
867 ret = ytphy_modify_ext(phydev,
868 YT8821_UTP_EXT_VGA_LPF2_CAP_CTRL_REG,
869 mask, 0);
870 if (ret < 0)
871 goto err_restore_page;
872
873 mask = YT8821_UTP_EXT_TRACE_LNG_GAIN_THE_2500 |
874 YT8821_UTP_EXT_TRACE_MED_GAIN_THE_2500;
875 set = FIELD_PREP(YT8821_UTP_EXT_TRACE_LNG_GAIN_THE_2500, 0x5a) |
876 FIELD_PREP(YT8821_UTP_EXT_TRACE_MED_GAIN_THE_2500, 0x3c);
877 ret = ytphy_modify_ext(phydev, YT8821_UTP_EXT_TRACE_CTRL_REG,
878 mask, set);
879 if (ret < 0)
880 goto err_restore_page;
881
882 mask = YT8821_UTP_EXT_IPR_LNG_2500;
883 set = FIELD_PREP(YT8821_UTP_EXT_IPR_LNG_2500, 0x6c);
884 ret = ytphy_modify_ext(phydev,
885 YT8821_UTP_EXT_ALPHA_IPR_CTRL_REG,
886 mask, set);
887 if (ret < 0)
888 goto err_restore_page;
889
890 mask = YT8821_UTP_EXT_TRACE_LNG_GAIN_THR_1000;
891 set = FIELD_PREP(YT8821_UTP_EXT_TRACE_LNG_GAIN_THR_1000, 0x2a);
892 ret = ytphy_modify_ext(phydev, YT8821_UTP_EXT_ECHO_CTRL_REG,
893 mask, set);
894 if (ret < 0)
895 goto err_restore_page;
896
897 mask = YT8821_UTP_EXT_TRACE_MED_GAIN_THR_1000;
898 set = FIELD_PREP(YT8821_UTP_EXT_TRACE_MED_GAIN_THR_1000, 0x22);
899 ret = ytphy_modify_ext(phydev, YT8821_UTP_EXT_GAIN_CTRL_REG,
900 mask, set);
901 if (ret < 0)
902 goto err_restore_page;
903
904 mask = YT8821_UTP_EXT_TH_20DB_2500;
905 set = FIELD_PREP(YT8821_UTP_EXT_TH_20DB_2500, 0x8000);
906 ret = ytphy_modify_ext(phydev,
907 YT8821_UTP_EXT_TH_20DB_2500_CTRL_REG,
908 mask, set);
909 if (ret < 0)
910 goto err_restore_page;
911
912 mask = YT8821_UTP_EXT_MU_COARSE_FR_F_FFE |
913 YT8821_UTP_EXT_MU_COARSE_FR_F_FBE;
914 set = FIELD_PREP(YT8821_UTP_EXT_MU_COARSE_FR_F_FFE, 0x7) |
915 FIELD_PREP(YT8821_UTP_EXT_MU_COARSE_FR_F_FBE, 0x7);
916 ret = ytphy_modify_ext(phydev,
917 YT8821_UTP_EXT_MU_COARSE_FR_CTRL_REG,
918 mask, set);
919 if (ret < 0)
920 goto err_restore_page;
921
922 mask = YT8821_UTP_EXT_MU_FINE_FR_F_FFE |
923 YT8821_UTP_EXT_MU_FINE_FR_F_FBE;
924 set = FIELD_PREP(YT8821_UTP_EXT_MU_FINE_FR_F_FFE, 0x2) |
925 FIELD_PREP(YT8821_UTP_EXT_MU_FINE_FR_F_FBE, 0x2);
926 ret = ytphy_modify_ext(phydev,
927 YT8821_UTP_EXT_MU_FINE_FR_CTRL_REG,
928 mask, set);
929 if (ret < 0)
930 goto err_restore_page;
931
932 /* save YT8821_UTP_EXT_PI_CTRL_REG's val for use later */
933 ret = ytphy_read_ext(phydev, YT8821_UTP_EXT_PI_CTRL_REG);
934 if (ret < 0)
935 goto err_restore_page;
936
937 save = ret;
938
939 mask = YT8821_UTP_EXT_PI_TX_CLK_SEL_AFE |
940 YT8821_UTP_EXT_PI_RX_CLK_3_SEL_AFE |
941 YT8821_UTP_EXT_PI_RX_CLK_2_SEL_AFE |
942 YT8821_UTP_EXT_PI_RX_CLK_1_SEL_AFE |
943 YT8821_UTP_EXT_PI_RX_CLK_0_SEL_AFE;
944 ret = ytphy_modify_ext(phydev, YT8821_UTP_EXT_PI_CTRL_REG,
945 mask, 0);
946 if (ret < 0)
947 goto err_restore_page;
948
949 /* restore YT8821_UTP_EXT_PI_CTRL_REG's val */
950 ret = ytphy_write_ext(phydev, YT8821_UTP_EXT_PI_CTRL_REG, save);
951 if (ret < 0)
952 goto err_restore_page;
953
954 mask = YT8821_UTP_EXT_FECHO_AMP_TH_HUGE;
955 set = FIELD_PREP(YT8821_UTP_EXT_FECHO_AMP_TH_HUGE, 0x38);
956 ret = ytphy_modify_ext(phydev, YT8821_UTP_EXT_VCT_CFG6_CTRL_REG,
957 mask, set);
958 if (ret < 0)
959 goto err_restore_page;
960
961 mask = YT8821_UTP_EXT_NFR_TX_ABILITY;
962 set = YT8821_UTP_EXT_NFR_TX_ABILITY;
963 ret = ytphy_modify_ext(phydev,
964 YT8821_UTP_EXT_TXGE_NFR_FR_THP_CTRL_REG,
965 mask, set);
966 if (ret < 0)
967 goto err_restore_page;
968
969 mask = YT8821_UTP_EXT_PLL_SPARE_CFG;
970 set = FIELD_PREP(YT8821_UTP_EXT_PLL_SPARE_CFG, 0xe9);
971 ret = ytphy_modify_ext(phydev, YT8821_UTP_EXT_PLL_CTRL_REG,
972 mask, set);
973 if (ret < 0)
974 goto err_restore_page;
975
976 mask = YT8821_UTP_EXT_DAC_IMID_CH_3_10_ORG |
977 YT8821_UTP_EXT_DAC_IMID_CH_2_10_ORG;
978 set = FIELD_PREP(YT8821_UTP_EXT_DAC_IMID_CH_3_10_ORG, 0x64) |
979 FIELD_PREP(YT8821_UTP_EXT_DAC_IMID_CH_2_10_ORG, 0x64);
980 ret = ytphy_modify_ext(phydev,
981 YT8821_UTP_EXT_DAC_IMID_CH_2_3_CTRL_REG,
982 mask, set);
983 if (ret < 0)
984 goto err_restore_page;
985
986 mask = YT8821_UTP_EXT_DAC_IMID_CH_1_10_ORG |
987 YT8821_UTP_EXT_DAC_IMID_CH_0_10_ORG;
988 set = FIELD_PREP(YT8821_UTP_EXT_DAC_IMID_CH_1_10_ORG, 0x64) |
989 FIELD_PREP(YT8821_UTP_EXT_DAC_IMID_CH_0_10_ORG, 0x64);
990 ret = ytphy_modify_ext(phydev,
991 YT8821_UTP_EXT_DAC_IMID_CH_0_1_CTRL_REG,
992 mask, set);
993 if (ret < 0)
994 goto err_restore_page;
995
996 mask = YT8821_UTP_EXT_DAC_IMSB_CH_3_10_ORG |
997 YT8821_UTP_EXT_DAC_IMSB_CH_2_10_ORG;
998 set = FIELD_PREP(YT8821_UTP_EXT_DAC_IMSB_CH_3_10_ORG, 0x64) |
999 FIELD_PREP(YT8821_UTP_EXT_DAC_IMSB_CH_2_10_ORG, 0x64);
1000 ret = ytphy_modify_ext(phydev,
1001 YT8821_UTP_EXT_DAC_IMSB_CH_2_3_CTRL_REG,
1002 mask, set);
1003 if (ret < 0)
1004 goto err_restore_page;
1005
1006 mask = YT8821_UTP_EXT_DAC_IMSB_CH_1_10_ORG |
1007 YT8821_UTP_EXT_DAC_IMSB_CH_0_10_ORG;
1008 set = FIELD_PREP(YT8821_UTP_EXT_DAC_IMSB_CH_1_10_ORG, 0x64) |
1009 FIELD_PREP(YT8821_UTP_EXT_DAC_IMSB_CH_0_10_ORG, 0x64);
1010 ret = ytphy_modify_ext(phydev,
1011 YT8821_UTP_EXT_DAC_IMSB_CH_0_1_CTRL_REG,
1012 mask, set);
1013
1014err_restore_page:
1015 return ytphy_restore_page(phydev, old_page, ret);
1016}
1017
1018static int yt8821_auto_sleep_config(struct phy_device *phydev,
1019 bool enable)
1020{
1021 int old_page;
1022 int ret;
1023
1024 old_page = ytphy_save_page(phydev);
1025 if (old_page < 0)
1026 return old_page;
1027
1028 ret = ytphy_modify_ext(phydev, YTPHY_REG_SPACE_SELECT_REG,
1029 YTPHY_RSSR_SPACE_MASK,
1030 YTPHY_RSSR_UTP_SPACE);
1031 if (ret < 0)
1032 goto err_restore_page;
1033
1034 ret = ytphy_modify_ext(phydev,
1035 YT8531_EXTREG_SLEEP_CONTROL1_REG,
1036 YT8531_ESC1R_SLEEP_SW,
1037 enable ? 1 : 0);
1038
1039err_restore_page:
1040 return ytphy_restore_page(phydev, old_page, ret);
1041}
1042
1043static int yt8821_soft_reset(struct phy_device *phydev)
1044{
1045 return ytphy_modify_ext(phydev, YT8531_CHIP_CONFIG_REG,
1046 YT8531_CCR_SW_RST, 0);
1047}
1048
1049static int yt8821_config(struct phy_device *phydev)
1050{
1051 u8 mode = YT8821_CHIP_MODE_FORCE_BX2500;
1052 int ret;
1053 u16 set;
1054
1055 set = FIELD_PREP(YTPHY_CCR_MODE_SEL_MASK, mode);
1056 ret = ytphy_modify_ext(phydev,
1057 YT8531_CHIP_CONFIG_REG,
1058 YTPHY_CCR_MODE_SEL_MASK,
1059 set);
1060 if (ret < 0)
1061 return ret;
1062
1063 ret = yt8821_serdes_init(phydev);
1064 if (ret < 0)
1065 return ret;
1066
1067 ret = yt8821_utp_init(phydev);
1068 if (ret < 0)
1069 return ret;
1070
1071 ret = yt8821_auto_sleep_config(phydev, false);
1072 if (ret < 0)
1073 return ret;
1074
1075 return yt8821_soft_reset(phydev);
1076}
1077
1078static void yt8821_parse_status(struct phy_device *phydev, int val)
1079{
1080 int speed_mode;
1081 int speed;
1082
1083 speed_mode = val & YTPHY_SPEED_MASK;
1084 switch (speed_mode) {
1085 case YTPHY_SPEED_2500M:
1086 speed = SPEED_2500;
1087 break;
1088 case YTPHY_SPEED_1000M:
1089 speed = SPEED_1000;
1090 break;
1091 case YTPHY_SPEED_100M:
1092 speed = SPEED_100;
1093 break;
1094 case YTPHY_SPEED_10M:
1095 speed = SPEED_10;
1096 break;
1097 }
1098
1099 phydev->speed = speed;
1100 phydev->duplex = FIELD_GET(YTPHY_DUPLEX_MASK, val);
1101}
1102
1103static int yt8821_startup(struct phy_device *phydev)
1104{
1105 u16 val;
1106 int ret;
1107
1108 ret = ytphy_modify_ext(phydev, YTPHY_REG_SPACE_SELECT_REG,
1109 YTPHY_RSSR_SPACE_MASK,
1110 YTPHY_RSSR_UTP_SPACE);
1111 if (ret)
1112 return ret;
1113
1114 ret = genphy_update_link(phydev);
1115 if (ret)
1116 return ret;
1117
1118 ret = phy_read(phydev, MDIO_DEVAD_NONE,
1119 YTPHY_SPECIFIC_STATUS_REG);
1120 if (ret < 0)
1121 return ret;
1122
1123 val = ret;
1124
1125 if (phydev->link)
1126 yt8821_parse_status(phydev, val);
1127
1128 return 0;
1129}
1130
Frank Sae985eb732024-11-23 23:38:44 -08001131static int yt8521s_config(struct phy_device *phydev)
1132{
1133 struct ytphy_plat_priv *priv = phydev->priv;
1134 u16 mask, val;
1135 int ret;
1136
1137 ret = genphy_config_aneg(phydev);
1138 if (ret < 0)
1139 return ret;
1140
1141 ytphy_dt_parse(phydev);
1142 switch (priv->clk_out_frequency) {
1143 case YTPHY_DTS_OUTPUT_CLK_DIS:
1144 mask = YT8521S_SCR_SYNCE_ENABLE;
1145 val = 0;
1146 break;
1147 case YTPHY_DTS_OUTPUT_CLK_25M:
1148 mask = YT8521S_SCR_SYNCE_ENABLE | YT8521S_SCR_CLK_SRC_MASK |
1149 YT8521S_SCR_CLK_FRE_SEL_125M;
1150 val = YT8521S_SCR_SYNCE_ENABLE |
1151 FIELD_PREP(YT8521S_SCR_CLK_SRC_MASK,
1152 YT8521S_SCR_CLK_SRC_REF_25M);
1153 break;
1154 case YTPHY_DTS_OUTPUT_CLK_125M:
1155 mask = YT8521S_SCR_SYNCE_ENABLE | YT8521S_SCR_CLK_SRC_MASK |
1156 YT8521S_SCR_CLK_FRE_SEL_125M;
1157 val = YT8521S_SCR_SYNCE_ENABLE | YT8521S_SCR_CLK_FRE_SEL_125M |
1158 FIELD_PREP(YT8521S_SCR_CLK_SRC_MASK,
1159 YT8521S_SCR_CLK_SRC_PLL_125M);
1160 break;
1161 default:
1162 pr_warn("Freq err:%u\n", priv->clk_out_frequency);
1163 return -EINVAL;
1164 }
1165
1166 ret = ytphy_modify_ext(phydev, YTPHY_SYNCE_CFG_REG, mask,
1167 val);
1168 if (ret < 0)
1169 return ret;
1170
1171 ret = ytphy_rgmii_clk_delay_config(phydev);
1172 if (ret < 0)
1173 return ret;
1174
1175 if (priv->flag & AUTO_SLEEP_DISABLED) {
1176 /* disable auto sleep */
1177 ret = ytphy_modify_ext(phydev,
1178 YT8531_EXTREG_SLEEP_CONTROL1_REG,
1179 YT8531_ESC1R_SLEEP_SW, 0);
1180 if (ret < 0)
1181 return ret;
1182 }
1183
1184 if (priv->flag & KEEP_PLL_ENABLED) {
1185 /* enable RXC clock when no wire plug */
1186 ret = ytphy_modify_ext(phydev,
1187 YT8531_CLOCK_GATING_REG,
1188 YT8531_CGR_RX_CLK_EN, 0);
1189 if (ret < 0)
1190 return ret;
1191 }
1192
1193 return 0;
1194}
1195
Frank Saea34b2bb2024-11-23 23:38:43 -08001196static int yt8531s_config(struct phy_device *phydev)
1197{
1198 struct ytphy_plat_priv *priv = phydev->priv;
1199 u16 mask, val;
1200 int ret;
1201
1202 ret = genphy_config_aneg(phydev);
1203 if (ret < 0)
1204 return ret;
1205
1206 ytphy_dt_parse(phydev);
1207 switch (priv->clk_out_frequency) {
1208 case YTPHY_DTS_OUTPUT_CLK_DIS:
1209 mask = YT8531_SCR_SYNCE_ENABLE;
1210 val = 0;
1211 break;
1212 case YTPHY_DTS_OUTPUT_CLK_25M:
1213 mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
1214 YT8531_SCR_CLK_FRE_SEL_125M;
1215 val = YT8531_SCR_SYNCE_ENABLE |
1216 FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
1217 YT8531_SCR_CLK_SRC_REF_25M);
1218 break;
1219 case YTPHY_DTS_OUTPUT_CLK_125M:
1220 mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
1221 YT8531_SCR_CLK_FRE_SEL_125M;
1222 val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M |
1223 FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
1224 YT8531_SCR_CLK_SRC_PLL_125M);
1225 break;
1226 default:
1227 pr_warn("Freq err:%u\n", priv->clk_out_frequency);
1228 return -EINVAL;
1229 }
1230
1231 ret = ytphy_modify_ext(phydev, YTPHY_SYNCE_CFG_REG, mask,
1232 val);
1233 if (ret < 0)
1234 return ret;
1235
1236 ret = ytphy_rgmii_clk_delay_config(phydev);
1237 if (ret < 0)
1238 return ret;
1239
1240 if (priv->flag & AUTO_SLEEP_DISABLED) {
1241 /* disable auto sleep */
1242 ret = ytphy_modify_ext(phydev,
1243 YT8531_EXTREG_SLEEP_CONTROL1_REG,
1244 YT8531_ESC1R_SLEEP_SW, 0);
1245 if (ret < 0)
1246 return ret;
1247 }
1248
1249 if (priv->flag & KEEP_PLL_ENABLED) {
1250 /* enable RXC clock when no wire plug */
1251 ret = ytphy_modify_ext(phydev,
1252 YT8531_CLOCK_GATING_REG,
1253 YT8531_CGR_RX_CLK_EN, 0);
1254 if (ret < 0)
1255 return ret;
1256 }
1257
1258 return 0;
1259}
1260
1261static int yt8531s_startup(struct phy_device *phydev)
1262{
1263 int ret;
1264
1265 ret = genphy_update_link(phydev);
1266 if (ret)
1267 return ret;
1268
1269 ret = yt8531_parse_status(phydev);
1270 if (ret)
1271 return ret;
1272
1273 return 0;
1274}
1275
Nicolas Frattarolif08686a2023-08-05 12:35:01 +02001276U_BOOT_PHY_DRIVER(motorcomm8511) = {
1277 .name = "YT8511 Gigabit Ethernet",
1278 .uid = PHY_ID_YT8511,
1279 .mask = PHY_ID_MASK,
1280 .features = PHY_GBIT_FEATURES,
1281 .config = &yt8511_config,
1282 .startup = &genphy_startup,
1283 .shutdown = &genphy_shutdown,
1284};
1285
Yanhong Wang1d6c3412023-06-15 17:36:42 +08001286U_BOOT_PHY_DRIVER(motorcomm8531) = {
1287 .name = "YT8531 Gigabit Ethernet",
1288 .uid = PHY_ID_YT8531,
1289 .mask = PHY_ID_MASK,
1290 .features = PHY_GBIT_FEATURES,
1291 .probe = &yt8531_probe,
1292 .config = &yt8531_config,
1293 .startup = &yt8531_startup,
1294 .shutdown = &genphy_shutdown,
1295};
Frank Sae63f2cad2024-09-12 05:02:25 -07001296
1297U_BOOT_PHY_DRIVER(motorcomm8821) = {
1298 .name = "YT8821 2.5G Ethernet",
1299 .uid = PHY_ID_YT8821,
1300 .mask = PHY_ID_MASK,
1301 .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_AN),
1302 .probe = &yt8821_probe,
1303 .config = &yt8821_config,
1304 .startup = &yt8821_startup,
1305 .shutdown = &genphy_shutdown,
1306};
Frank Saea34b2bb2024-11-23 23:38:43 -08001307
1308U_BOOT_PHY_DRIVER(motorcomm8531S) = {
1309 .name = "YT8531S Gigabit Ethernet Transceiver",
1310 .uid = PHY_ID_YT8531S,
1311 .mask = PHY_ID_MASK,
1312 .features = PHY_GBIT_FEATURES,
1313 .probe = &yt8531_probe,
1314 .config = &yt8531s_config,
1315 .startup = &yt8531s_startup,
1316 .shutdown = &genphy_shutdown,
1317};
Frank Sae985eb732024-11-23 23:38:44 -08001318
1319U_BOOT_PHY_DRIVER(motorcomm8521S) = {
1320 .name = "YT8521S Gigabit Ethernet Transceiver",
1321 .uid = PHY_ID_YT8521S,
1322 .mask = PHY_ID_MASK,
1323 .features = PHY_GBIT_FEATURES,
1324 .probe = &yt8531_probe,
1325 .config = &yt8521s_config,
1326 .startup = &yt8531s_startup,
1327 .shutdown = &genphy_shutdown,
1328};