blob: a2c763c8791e99584496f6773793a9a7c9eabbb7 [file] [log] [blame]
Yanhong Wang1d6c3412023-06-15 17:36:42 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Motorcomm 8531 PHY driver.
4 *
5 * Copyright (C) 2023 StarFive Technology Co., Ltd.
6 */
7
8#include <config.h>
Tom Riniabb9a042024-05-18 20:20:43 -06009#include <common.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
16#define PHY_ID_MASK GENMASK(31, 0)
17
18/* Extended Register's Address Offset Register */
19#define YTPHY_PAGE_SELECT 0x1E
20
21/* Extended Register's Data Register */
22#define YTPHY_PAGE_DATA 0x1F
23
24#define YTPHY_SYNCE_CFG_REG 0xA012
25
Lukasz Tekieli3282aee2024-01-28 20:22:47 +010026#define YT8531_PAD_DRIVE_STRENGTH_CFG_REG 0xA010
27#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13)
28#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */
29#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */
30#define YT8531_RGMII_RX_DS_DEFAULT 0x3
31
Yanhong Wang1d6c3412023-06-15 17:36:42 +080032#define YTPHY_DTS_OUTPUT_CLK_DIS 0
33#define YTPHY_DTS_OUTPUT_CLK_25M 25000000
34#define YTPHY_DTS_OUTPUT_CLK_125M 125000000
35
Nicolas Frattarolif08686a2023-08-05 12:35:01 +020036#define YT8511_EXT_CLK_GATE 0x0c
37#define YT8511_EXT_DELAY_DRIVE 0x0d
38#define YT8511_EXT_SLEEP_CTRL 0x27
39
40/* 2b00 25m from pll
41 * 2b01 25m from xtl *default*
42 * 2b10 62.m from pll
43 * 2b11 125m from pll
44 */
45#define YT8511_CLK_125M (BIT(2) | BIT(1))
46#define YT8511_PLLON_SLP BIT(14)
47
48/* RX Delay enabled = 1.8ns 1000T, 8ns 10/100T */
49#define YT8511_DELAY_RX BIT(0)
50
51/* TX Gig-E Delay is bits 7:4, default 0x5
52 * TX Fast-E Delay is bits 15:12, default 0xf
53 * Delay = 150ps * N - 250ps
54 * On = 2000ps, off = 50ps
55 */
56#define YT8511_DELAY_GE_TX_EN (0xf << 4)
57#define YT8511_DELAY_GE_TX_DIS (0x2 << 4)
58#define YT8511_DELAY_FE_TX_EN (0xf << 12)
59#define YT8511_DELAY_FE_TX_DIS (0x2 << 12)
60
Yanhong Wang1d6c3412023-06-15 17:36:42 +080061#define YT8531_SCR_SYNCE_ENABLE BIT(6)
62/* 1b0 output 25m clock *default*
63 * 1b1 output 125m clock
64 */
65#define YT8531_SCR_CLK_FRE_SEL_125M BIT(4)
66#define YT8531_SCR_CLK_SRC_MASK GENMASK(3, 1)
67#define YT8531_SCR_CLK_SRC_PLL_125M 0
68#define YT8531_SCR_CLK_SRC_UTP_RX 1
69#define YT8531_SCR_CLK_SRC_SDS_RX 2
70#define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3
71#define YT8531_SCR_CLK_SRC_REF_25M 4
72#define YT8531_SCR_CLK_SRC_SSC_25M 5
73
74/* 1b0 use original tx_clk_rgmii *default*
75 * 1b1 use inverted tx_clk_rgmii.
76 */
77#define YT8531_RC1R_TX_CLK_SEL_INVERTED BIT(14)
78#define YT8531_RC1R_RX_DELAY_MASK GENMASK(13, 10)
79#define YT8531_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4)
80#define YT8531_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0)
81#define YT8531_RC1R_RGMII_0_000_NS 0
82#define YT8531_RC1R_RGMII_0_150_NS 1
83#define YT8531_RC1R_RGMII_0_300_NS 2
84#define YT8531_RC1R_RGMII_0_450_NS 3
85#define YT8531_RC1R_RGMII_0_600_NS 4
86#define YT8531_RC1R_RGMII_0_750_NS 5
87#define YT8531_RC1R_RGMII_0_900_NS 6
88#define YT8531_RC1R_RGMII_1_050_NS 7
89#define YT8531_RC1R_RGMII_1_200_NS 8
90#define YT8531_RC1R_RGMII_1_350_NS 9
91#define YT8531_RC1R_RGMII_1_500_NS 10
92#define YT8531_RC1R_RGMII_1_650_NS 11
93#define YT8531_RC1R_RGMII_1_800_NS 12
94#define YT8531_RC1R_RGMII_1_950_NS 13
95#define YT8531_RC1R_RGMII_2_100_NS 14
96#define YT8531_RC1R_RGMII_2_250_NS 15
97
98/* Phy gmii clock gating Register */
99#define YT8531_CLOCK_GATING_REG 0xC
100#define YT8531_CGR_RX_CLK_EN BIT(12)
101
102/* Specific Status Register */
103#define YTPHY_SPECIFIC_STATUS_REG 0x11
104#define YTPHY_DUPLEX_MASK BIT(13)
105#define YTPHY_DUPLEX_SHIFT 13
106#define YTPHY_SPEED_MODE_MASK GENMASK(15, 14)
107#define YTPHY_SPEED_MODE_SHIFT 14
108
109#define YT8531_EXTREG_SLEEP_CONTROL1_REG 0x27
110#define YT8531_ESC1R_SLEEP_SW BIT(15)
111#define YT8531_ESC1R_PLLON_SLP BIT(14)
112
113#define YT8531_RGMII_CONFIG1_REG 0xA003
114
115#define YT8531_CHIP_CONFIG_REG 0xA001
116#define YT8531_CCR_SW_RST BIT(15)
117/* 1b0 disable 1.9ns rxc clock delay *default*
118 * 1b1 enable 1.9ns rxc clock delay
119 */
120#define YT8531_CCR_RXC_DLY_EN BIT(8)
121#define YT8531_CCR_RXC_DLY_1_900_NS 1900
122
Lukasz Tekieli3282aee2024-01-28 20:22:47 +0100123#define YT8531_CCR_CFG_LDO_MASK GENMASK(5, 4)
124#define YT8531_CCR_CFG_LDO_3V3 0x0
125#define YT8531_CCR_CFG_LDO_1V8 0x2
126
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800127/* bits in struct ytphy_plat_priv->flag */
128#define TX_CLK_ADJ_ENABLED BIT(0)
129#define AUTO_SLEEP_DISABLED BIT(1)
130#define KEEP_PLL_ENABLED BIT(2)
131#define TX_CLK_10_INVERTED BIT(3)
132#define TX_CLK_100_INVERTED BIT(4)
133#define TX_CLK_1000_INVERTED BIT(5)
134
135struct ytphy_plat_priv {
136 u32 rx_delay_ps;
137 u32 tx_delay_ps;
138 u32 clk_out_frequency;
139 u32 flag;
140};
141
142/**
143 * struct ytphy_cfg_reg_map - map a config value to a register value
144 * @cfg: value in device configuration
145 * @reg: value in the register
146 */
147struct ytphy_cfg_reg_map {
148 u32 cfg;
149 u32 reg;
150};
151
152static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = {
153 /* for tx delay / rx delay with YT8531_CCR_RXC_DLY_EN is not set. */
154 { 0, YT8531_RC1R_RGMII_0_000_NS },
155 { 150, YT8531_RC1R_RGMII_0_150_NS },
156 { 300, YT8531_RC1R_RGMII_0_300_NS },
157 { 450, YT8531_RC1R_RGMII_0_450_NS },
158 { 600, YT8531_RC1R_RGMII_0_600_NS },
159 { 750, YT8531_RC1R_RGMII_0_750_NS },
160 { 900, YT8531_RC1R_RGMII_0_900_NS },
161 { 1050, YT8531_RC1R_RGMII_1_050_NS },
162 { 1200, YT8531_RC1R_RGMII_1_200_NS },
163 { 1350, YT8531_RC1R_RGMII_1_350_NS },
164 { 1500, YT8531_RC1R_RGMII_1_500_NS },
165 { 1650, YT8531_RC1R_RGMII_1_650_NS },
166 { 1800, YT8531_RC1R_RGMII_1_800_NS },
167 { 1950, YT8531_RC1R_RGMII_1_950_NS }, /* default tx/rx delay */
168 { 2100, YT8531_RC1R_RGMII_2_100_NS },
169 { 2250, YT8531_RC1R_RGMII_2_250_NS },
170
171 /* only for rx delay with YT8531_CCR_RXC_DLY_EN is set. */
172 { 0 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_000_NS },
173 { 150 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_150_NS },
174 { 300 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_300_NS },
175 { 450 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_450_NS },
176 { 600 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_600_NS },
177 { 750 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_750_NS },
178 { 900 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_900_NS },
179 { 1050 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_050_NS },
180 { 1200 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_200_NS },
181 { 1350 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_350_NS },
182 { 1500 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_500_NS },
183 { 1650 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_650_NS },
184 { 1800 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_800_NS },
185 { 1950 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_950_NS },
186 { 2100 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_2_100_NS },
187 { 2250 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_2_250_NS }
188};
189
190static u32 ytphy_get_delay_reg_value(struct phy_device *phydev,
191 u32 val,
192 u16 *rxc_dly_en)
193{
194 int tb_size = ARRAY_SIZE(ytphy_rgmii_delays);
195 int tb_size_half = tb_size / 2;
196 int i;
197
198 /* when rxc_dly_en is NULL, it is get the delay for tx, only half of
199 * tb_size is valid.
200 */
201 if (!rxc_dly_en)
202 tb_size = tb_size_half;
203
204 for (i = 0; i < tb_size; i++) {
205 if (ytphy_rgmii_delays[i].cfg == val) {
206 if (rxc_dly_en && i < tb_size_half)
207 *rxc_dly_en = 0;
208 return ytphy_rgmii_delays[i].reg;
209 }
210 }
211
212 pr_warn("Unsupported value %d, using default (%u)\n",
213 val, YT8531_RC1R_RGMII_1_950_NS);
214
215 /* when rxc_dly_en is not NULL, it is get the delay for rx.
216 * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps,
217 * so YT8531_CCR_RXC_DLY_EN should not be set.
218 */
219 if (rxc_dly_en)
220 *rxc_dly_en = 0;
221
222 return YT8531_RC1R_RGMII_1_950_NS;
223}
224
225static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask,
226 u16 set)
227{
228 int ret;
229
230 ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
231 if (ret < 0)
232 return ret;
233
234 return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set);
235}
236
Lukasz Tekieli3282aee2024-01-28 20:22:47 +0100237static int ytphy_read_ext(struct phy_device *phydev, u16 regnum)
238{
239 int ret;
240
241 ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
242 if (ret < 0)
243 return ret;
244
245 return phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA);
246}
247
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800248static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
249{
250 struct ytphy_plat_priv *priv = phydev->priv;
251 u16 rxc_dly_en = YT8531_CCR_RXC_DLY_EN;
252 u32 rx_reg, tx_reg;
253 u16 mask, val = 0;
254 int ret;
255
256 rx_reg = ytphy_get_delay_reg_value(phydev, priv->rx_delay_ps,
257 &rxc_dly_en);
258 tx_reg = ytphy_get_delay_reg_value(phydev, priv->tx_delay_ps,
259 NULL);
260
261 switch (phydev->interface) {
262 case PHY_INTERFACE_MODE_RGMII:
263 rxc_dly_en = 0;
264 break;
265 case PHY_INTERFACE_MODE_RGMII_RXID:
266 val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg);
267 break;
268 case PHY_INTERFACE_MODE_RGMII_TXID:
269 rxc_dly_en = 0;
270 val |= FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
271 break;
272 case PHY_INTERFACE_MODE_RGMII_ID:
273 val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg) |
274 FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
275 break;
276 default: /* do not support other modes */
277 return -EOPNOTSUPP;
278 }
279
280 ret = ytphy_modify_ext(phydev, YT8531_CHIP_CONFIG_REG,
281 YT8531_CCR_RXC_DLY_EN, rxc_dly_en);
282 if (ret < 0)
283 return ret;
284
285 /* Generally, it is not necessary to adjust YT8531_RC1R_FE_TX_DELAY */
286 mask = YT8531_RC1R_RX_DELAY_MASK | YT8531_RC1R_GE_TX_DELAY_MASK;
287 return ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG, mask, val);
288}
289
290static int yt8531_parse_status(struct phy_device *phydev)
291{
292 int val;
293 int speed, speed_mode;
294
295 val = phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_SPECIFIC_STATUS_REG);
296 if (val < 0)
297 return val;
298
299 speed_mode = (val & YTPHY_SPEED_MODE_MASK) >> YTPHY_SPEED_MODE_SHIFT;
300 switch (speed_mode) {
301 case 2:
302 speed = SPEED_1000;
303 break;
304 case 1:
305 speed = SPEED_100;
306 break;
307 default:
308 speed = SPEED_10;
309 break;
310 }
311
312 phydev->speed = speed;
313 phydev->duplex = (val & YTPHY_DUPLEX_MASK) >> YTPHY_DUPLEX_SHIFT;
314
315 return 0;
316}
317
318static int yt8531_startup(struct phy_device *phydev)
319{
320 struct ytphy_plat_priv *priv = phydev->priv;
321 u16 val = 0;
322 int ret;
323
324 ret = genphy_update_link(phydev);
325 if (ret)
326 return ret;
327
328 ret = yt8531_parse_status(phydev);
329 if (ret)
330 return ret;
331
332 if (phydev->speed < 0)
333 return -EINVAL;
334
335 if (!(priv->flag & TX_CLK_ADJ_ENABLED))
336 return 0;
337
338 switch (phydev->speed) {
339 case SPEED_1000:
340 if (priv->flag & TX_CLK_1000_INVERTED)
341 val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
342 break;
343 case SPEED_100:
344 if (priv->flag & TX_CLK_100_INVERTED)
345 val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
346 break;
347 case SPEED_10:
348 if (priv->flag & TX_CLK_10_INVERTED)
349 val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
350 break;
351 default:
352 printf("UNKNOWN SPEED\n");
353 return -EINVAL;
354 }
355
356 ret = ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG,
357 YT8531_RC1R_TX_CLK_SEL_INVERTED, val);
358 if (ret < 0)
359 pr_warn("Modify TX_CLK_SEL err:%d\n", ret);
360
361 return 0;
362}
363
364static void ytphy_dt_parse(struct phy_device *phydev)
365{
366 struct ytphy_plat_priv *priv = phydev->priv;
367
368 priv->clk_out_frequency = ofnode_read_u32_default(phydev->node,
369 "motorcomm,clk-out-frequency-hz",
370 YTPHY_DTS_OUTPUT_CLK_DIS);
371 priv->rx_delay_ps = ofnode_read_u32_default(phydev->node,
372 "rx-internal-delay-ps",
373 YT8531_RC1R_RGMII_1_950_NS);
374 priv->tx_delay_ps = ofnode_read_u32_default(phydev->node,
375 "tx-internal-delay-ps",
376 YT8531_RC1R_RGMII_1_950_NS);
377
378 if (ofnode_read_bool(phydev->node, "motorcomm,auto-sleep-disabled"))
379 priv->flag |= AUTO_SLEEP_DISABLED;
380
381 if (ofnode_read_bool(phydev->node, "motorcomm,keep-pll-enabled"))
382 priv->flag |= KEEP_PLL_ENABLED;
383
384 if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-adj-enabled"))
385 priv->flag |= TX_CLK_ADJ_ENABLED;
386
387 if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-10-inverted"))
388 priv->flag |= TX_CLK_10_INVERTED;
389
390 if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-100-inverted"))
391 priv->flag |= TX_CLK_100_INVERTED;
392
393 if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-1000-inverted"))
394 priv->flag |= TX_CLK_1000_INVERTED;
395}
396
Nicolas Frattarolif08686a2023-08-05 12:35:01 +0200397static int yt8511_config(struct phy_device *phydev)
398{
399 u32 ge, fe;
400 int ret;
401
402 ret = genphy_config_aneg(phydev);
403 if (ret < 0)
404 return ret;
405
406 switch (phydev->interface) {
407 case PHY_INTERFACE_MODE_RGMII:
408 ge = YT8511_DELAY_GE_TX_DIS;
409 fe = YT8511_DELAY_FE_TX_DIS;
410 break;
411 case PHY_INTERFACE_MODE_RGMII_RXID:
412 ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_DIS;
413 fe = YT8511_DELAY_FE_TX_DIS;
414 break;
415 case PHY_INTERFACE_MODE_RGMII_TXID:
416 ge = YT8511_DELAY_GE_TX_EN;
417 fe = YT8511_DELAY_FE_TX_EN;
418 break;
419 case PHY_INTERFACE_MODE_RGMII_ID:
420 ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN;
421 fe = YT8511_DELAY_FE_TX_EN;
422 break;
423 default: /* do not support other modes */
424 return -EOPNOTSUPP;
425 }
426
427 ret = ytphy_modify_ext(phydev, YT8511_EXT_CLK_GATE,
428 (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge);
429 if (ret < 0)
430 return ret;
431 /* set clock mode to 125m */
432 ret = ytphy_modify_ext(phydev, YT8511_EXT_CLK_GATE,
433 YT8511_CLK_125M, YT8511_CLK_125M);
434 if (ret < 0)
435 return ret;
436 ret = ytphy_modify_ext(phydev, YT8511_EXT_DELAY_DRIVE,
437 YT8511_DELAY_FE_TX_EN, fe);
438 if (ret < 0)
439 return ret;
440 /* sleep control, disable PLL in sleep for now */
441 ret = ytphy_modify_ext(phydev, YT8511_EXT_SLEEP_CTRL, YT8511_PLLON_SLP,
442 0);
443 if (ret < 0)
444 return ret;
445
446 return 0;
447}
448
Lukasz Tekieli3282aee2024-01-28 20:22:47 +0100449/**
450 * struct ytphy_ldo_vol_map - map a current value to a register value
451 * @vol: ldo voltage
452 * @ds: value in the register
453 * @cur: value in device configuration
454 */
455struct ytphy_ldo_vol_map {
456 u32 vol;
457 u32 ds;
458 u32 cur;
459};
460
461static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = {
462 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 0, .cur = 1200},
463 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 1, .cur = 2100},
464 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 2, .cur = 2700},
465 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 3, .cur = 2910},
466 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 4, .cur = 3110},
467 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 5, .cur = 3600},
468 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 6, .cur = 3970},
469 {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 7, .cur = 4350},
470 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 0, .cur = 3070},
471 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 1, .cur = 4080},
472 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 2, .cur = 4370},
473 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 3, .cur = 4680},
474 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 4, .cur = 5020},
475 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 5, .cur = 5450},
476 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 6, .cur = 5740},
477 {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 7, .cur = 6140},
478};
479
480static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
481{
482 u32 val;
483
484 val = ytphy_read_ext(phydev, YT8531_CHIP_CONFIG_REG);
485 val = FIELD_GET(YT8531_CCR_CFG_LDO_MASK, val);
486
487 return val <= YT8531_CCR_CFG_LDO_1V8 ? val : YT8531_CCR_CFG_LDO_1V8;
488}
489
490static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur)
491{
492 u32 vol;
493 int i;
494
495 vol = yt8531_get_ldo_vol(phydev);
496 for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) {
497 if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur)
498 return yt8531_ldo_vol[i].ds;
499 }
500
501 return -EINVAL;
502}
503
504static int yt8531_set_ds(struct phy_device *phydev)
505{
506 u32 ds_field_low, ds_field_hi, val;
507 int ret, ds;
508
509 /* set rgmii rx clk driver strength */
510 if (!ofnode_read_u32(phydev->node, "motorcomm,rx-clk-drv-microamp", &val)) {
511 ds = yt8531_get_ds_map(phydev, val);
512 if (ds < 0) {
513 pr_warn("No matching current value was found.");
514 return -EINVAL;
515 }
516 } else {
517 ds = YT8531_RGMII_RX_DS_DEFAULT;
518 }
519
520 ret = ytphy_modify_ext(phydev,
521 YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
522 YT8531_RGMII_RXC_DS_MASK,
523 FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
524 if (ret < 0)
525 return ret;
526
527 /* set rgmii rx data driver strength */
528 if (!ofnode_read_u32(phydev->node, "motorcomm,rx-data-drv-microamp", &val)) {
529 ds = yt8531_get_ds_map(phydev, val);
530 if (ds < 0) {
531 pr_warn("No matching current value was found.");
532 return -EINVAL;
533 }
534 } else {
535 ds = YT8531_RGMII_RX_DS_DEFAULT;
536 }
537
538 ds_field_hi = FIELD_GET(BIT(2), ds);
539 ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi);
540
541 ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
542 ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
543
544 ret = ytphy_modify_ext(phydev,
545 YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
546 YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
547 ds_field_low | ds_field_hi);
548 if (ret < 0)
549 return ret;
550
551 return 0;
552}
553
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800554static int yt8531_config(struct phy_device *phydev)
555{
556 struct ytphy_plat_priv *priv = phydev->priv;
557 u16 mask, val;
558 int ret;
559
560 ret = genphy_config_aneg(phydev);
561 if (ret < 0)
562 return ret;
563
564 ytphy_dt_parse(phydev);
565 switch (priv->clk_out_frequency) {
566 case YTPHY_DTS_OUTPUT_CLK_DIS:
567 mask = YT8531_SCR_SYNCE_ENABLE;
568 val = 0;
569 break;
570 case YTPHY_DTS_OUTPUT_CLK_25M:
571 mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
572 YT8531_SCR_CLK_FRE_SEL_125M;
573 val = YT8531_SCR_SYNCE_ENABLE |
574 FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
575 YT8531_SCR_CLK_SRC_REF_25M);
576 break;
577 case YTPHY_DTS_OUTPUT_CLK_125M:
578 mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
579 YT8531_SCR_CLK_FRE_SEL_125M;
580 val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M |
581 FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
582 YT8531_SCR_CLK_SRC_PLL_125M);
583 break;
584 default:
585 pr_warn("Freq err:%u\n", priv->clk_out_frequency);
586 return -EINVAL;
587 }
588
589 ret = ytphy_modify_ext(phydev, YTPHY_SYNCE_CFG_REG, mask,
590 val);
591 if (ret < 0)
592 return ret;
593
594 ret = ytphy_rgmii_clk_delay_config(phydev);
595 if (ret < 0)
596 return ret;
597
598 if (priv->flag & AUTO_SLEEP_DISABLED) {
599 /* disable auto sleep */
600 ret = ytphy_modify_ext(phydev,
601 YT8531_EXTREG_SLEEP_CONTROL1_REG,
602 YT8531_ESC1R_SLEEP_SW, 0);
603 if (ret < 0)
604 return ret;
605 }
606
607 if (priv->flag & KEEP_PLL_ENABLED) {
608 /* enable RXC clock when no wire plug */
609 ret = ytphy_modify_ext(phydev,
610 YT8531_CLOCK_GATING_REG,
611 YT8531_CGR_RX_CLK_EN, 0);
612 if (ret < 0)
613 return ret;
614 }
615
Lukasz Tekieli3282aee2024-01-28 20:22:47 +0100616 ret = yt8531_set_ds(phydev);
617 if (ret < 0)
618 return ret;
619
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800620 return 0;
621}
622
623static int yt8531_probe(struct phy_device *phydev)
624{
625 struct ytphy_plat_priv *priv;
626
627 priv = calloc(1, sizeof(struct ytphy_plat_priv));
628 if (!priv)
629 return -ENOMEM;
630
631 phydev->priv = priv;
632
633 return 0;
634}
635
Nicolas Frattarolif08686a2023-08-05 12:35:01 +0200636U_BOOT_PHY_DRIVER(motorcomm8511) = {
637 .name = "YT8511 Gigabit Ethernet",
638 .uid = PHY_ID_YT8511,
639 .mask = PHY_ID_MASK,
640 .features = PHY_GBIT_FEATURES,
641 .config = &yt8511_config,
642 .startup = &genphy_startup,
643 .shutdown = &genphy_shutdown,
644};
645
Yanhong Wang1d6c3412023-06-15 17:36:42 +0800646U_BOOT_PHY_DRIVER(motorcomm8531) = {
647 .name = "YT8531 Gigabit Ethernet",
648 .uid = PHY_ID_YT8531,
649 .mask = PHY_ID_MASK,
650 .features = PHY_GBIT_FEATURES,
651 .probe = &yt8531_probe,
652 .config = &yt8531_config,
653 .startup = &yt8531_startup,
654 .shutdown = &genphy_shutdown,
655};