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