mtd: fix build with GCC 14
[openwrt/openwrt.git] / target / linux / generic / backport-5.15 / 791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch
1 From a6e68f0f8769f79c67cdcfb6302feecd36197dec Mon Sep 17 00:00:00 2001
2 From: Frank Sae <Frank.Sae@motor-comm.com>
3 Date: Thu, 2 Feb 2023 11:00:35 +0800
4 Subject: [PATCH] net: phy: Add dts support for Motorcomm yt8521 gigabit
5 ethernet phy
6
7 Add dts support for Motorcomm yt8521 gigabit ethernet phy.
8 Add ytphy_rgmii_clk_delay_config function to support dst config for
9 the delay of rgmii clk. This funciont is common for yt8521, yt8531s
10 and yt8531.
11 This patch has been verified on AM335x platform.
12
13 Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
14 Reviewed-by: Andrew Lunn <andrew@lunn.ch>
15 Signed-off-by: David S. Miller <davem@davemloft.net>
16 ---
17 drivers/net/phy/motorcomm.c | 253 ++++++++++++++++++++++++++++--------
18 1 file changed, 199 insertions(+), 54 deletions(-)
19
20 --- a/drivers/net/phy/motorcomm.c
21 +++ b/drivers/net/phy/motorcomm.c
22 @@ -10,6 +10,7 @@
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/phy.h>
26 +#include <linux/of.h>
27
28 #define PHY_ID_YT8511 0x0000010a
29 #define PHY_ID_YT8521 0x0000011a
30 @@ -187,21 +188,9 @@
31 * 1b1 use inverted tx_clk_rgmii.
32 */
33 #define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14)
34 -/* TX Gig-E Delay is bits 3:0, default 0x1
35 - * TX Fast-E Delay is bits 7:4, default 0xf
36 - * RX Delay is bits 13:10, default 0x0
37 - * Delay = 150ps * N
38 - * On = 2250ps, off = 0ps
39 - */
40 #define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10)
41 -#define YT8521_RC1R_RX_DELAY_EN (0xF << 10)
42 -#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10)
43 #define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4)
44 -#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4)
45 -#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4)
46 #define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0)
47 -#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0)
48 -#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0)
49 #define YT8521_RC1R_RGMII_0_000_NS 0
50 #define YT8521_RC1R_RGMII_0_150_NS 1
51 #define YT8521_RC1R_RGMII_0_300_NS 2
52 @@ -274,6 +263,10 @@
53
54 /* Extended Register end */
55
56 +#define YTPHY_DTS_OUTPUT_CLK_DIS 0
57 +#define YTPHY_DTS_OUTPUT_CLK_25M 25000000
58 +#define YTPHY_DTS_OUTPUT_CLK_125M 125000000
59 +
60 struct yt8521_priv {
61 /* combo_advertising is used for case of YT8521 in combo mode,
62 * this means that yt8521 may work in utp or fiber mode which depends
63 @@ -641,6 +634,142 @@ static int yt8521_write_page(struct phy_
64 };
65
66 /**
67 + * struct ytphy_cfg_reg_map - map a config value to a register value
68 + * @cfg: value in device configuration
69 + * @reg: value in the register
70 + */
71 +struct ytphy_cfg_reg_map {
72 + u32 cfg;
73 + u32 reg;
74 +};
75 +
76 +static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = {
77 + /* for tx delay / rx delay with YT8521_CCR_RXC_DLY_EN is not set. */
78 + { 0, YT8521_RC1R_RGMII_0_000_NS },
79 + { 150, YT8521_RC1R_RGMII_0_150_NS },
80 + { 300, YT8521_RC1R_RGMII_0_300_NS },
81 + { 450, YT8521_RC1R_RGMII_0_450_NS },
82 + { 600, YT8521_RC1R_RGMII_0_600_NS },
83 + { 750, YT8521_RC1R_RGMII_0_750_NS },
84 + { 900, YT8521_RC1R_RGMII_0_900_NS },
85 + { 1050, YT8521_RC1R_RGMII_1_050_NS },
86 + { 1200, YT8521_RC1R_RGMII_1_200_NS },
87 + { 1350, YT8521_RC1R_RGMII_1_350_NS },
88 + { 1500, YT8521_RC1R_RGMII_1_500_NS },
89 + { 1650, YT8521_RC1R_RGMII_1_650_NS },
90 + { 1800, YT8521_RC1R_RGMII_1_800_NS },
91 + { 1950, YT8521_RC1R_RGMII_1_950_NS }, /* default tx/rx delay */
92 + { 2100, YT8521_RC1R_RGMII_2_100_NS },
93 + { 2250, YT8521_RC1R_RGMII_2_250_NS },
94 +
95 + /* only for rx delay with YT8521_CCR_RXC_DLY_EN is set. */
96 + { 0 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_000_NS },
97 + { 150 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_150_NS },
98 + { 300 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_300_NS },
99 + { 450 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_450_NS },
100 + { 600 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_600_NS },
101 + { 750 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_750_NS },
102 + { 900 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_900_NS },
103 + { 1050 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_050_NS },
104 + { 1200 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_200_NS },
105 + { 1350 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_350_NS },
106 + { 1500 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_500_NS },
107 + { 1650 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_650_NS },
108 + { 1800 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_800_NS },
109 + { 1950 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_950_NS },
110 + { 2100 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_100_NS },
111 + { 2250 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_250_NS }
112 +};
113 +
114 +static u32 ytphy_get_delay_reg_value(struct phy_device *phydev,
115 + const char *prop_name,
116 + const struct ytphy_cfg_reg_map *tbl,
117 + int tb_size,
118 + u16 *rxc_dly_en,
119 + u32 dflt)
120 +{
121 + struct device_node *node = phydev->mdio.dev.of_node;
122 + int tb_size_half = tb_size / 2;
123 + u32 val;
124 + int i;
125 +
126 + if (of_property_read_u32(node, prop_name, &val))
127 + goto err_dts_val;
128 +
129 + /* when rxc_dly_en is NULL, it is get the delay for tx, only half of
130 + * tb_size is valid.
131 + */
132 + if (!rxc_dly_en)
133 + tb_size = tb_size_half;
134 +
135 + for (i = 0; i < tb_size; i++) {
136 + if (tbl[i].cfg == val) {
137 + if (rxc_dly_en && i < tb_size_half)
138 + *rxc_dly_en = 0;
139 + return tbl[i].reg;
140 + }
141 + }
142 +
143 + phydev_warn(phydev, "Unsupported value %d for %s using default (%u)\n",
144 + val, prop_name, dflt);
145 +
146 +err_dts_val:
147 + /* when rxc_dly_en is not NULL, it is get the delay for rx.
148 + * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps,
149 + * so YT8521_CCR_RXC_DLY_EN should not be set.
150 + */
151 + if (rxc_dly_en)
152 + *rxc_dly_en = 0;
153 +
154 + return dflt;
155 +}
156 +
157 +static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
158 +{
159 + int tb_size = ARRAY_SIZE(ytphy_rgmii_delays);
160 + u16 rxc_dly_en = YT8521_CCR_RXC_DLY_EN;
161 + u32 rx_reg, tx_reg;
162 + u16 mask, val = 0;
163 + int ret;
164 +
165 + rx_reg = ytphy_get_delay_reg_value(phydev, "rx-internal-delay-ps",
166 + ytphy_rgmii_delays, tb_size,
167 + &rxc_dly_en,
168 + YT8521_RC1R_RGMII_1_950_NS);
169 + tx_reg = ytphy_get_delay_reg_value(phydev, "tx-internal-delay-ps",
170 + ytphy_rgmii_delays, tb_size, NULL,
171 + YT8521_RC1R_RGMII_1_950_NS);
172 +
173 + switch (phydev->interface) {
174 + case PHY_INTERFACE_MODE_RGMII:
175 + rxc_dly_en = 0;
176 + break;
177 + case PHY_INTERFACE_MODE_RGMII_RXID:
178 + val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg);
179 + break;
180 + case PHY_INTERFACE_MODE_RGMII_TXID:
181 + rxc_dly_en = 0;
182 + val |= FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
183 + break;
184 + case PHY_INTERFACE_MODE_RGMII_ID:
185 + val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) |
186 + FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
187 + break;
188 + default: /* do not support other modes */
189 + return -EOPNOTSUPP;
190 + }
191 +
192 + ret = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG,
193 + YT8521_CCR_RXC_DLY_EN, rxc_dly_en);
194 + if (ret < 0)
195 + return ret;
196 +
197 + /* Generally, it is not necessary to adjust YT8521_RC1R_FE_TX_DELAY */
198 + mask = YT8521_RC1R_RX_DELAY_MASK | YT8521_RC1R_GE_TX_DELAY_MASK;
199 + return ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, mask, val);
200 +}
201 +
202 +/**
203 * yt8521_probe() - read chip config then set suitable polling_mode
204 * @phydev: a pointer to a &struct phy_device
205 *
206 @@ -648,9 +777,12 @@ static int yt8521_write_page(struct phy_
207 */
208 static int yt8521_probe(struct phy_device *phydev)
209 {
210 + struct device_node *node = phydev->mdio.dev.of_node;
211 struct device *dev = &phydev->mdio.dev;
212 struct yt8521_priv *priv;
213 int chip_config;
214 + u16 mask, val;
215 + u32 freq;
216 int ret;
217
218 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
219 @@ -695,7 +827,45 @@ static int yt8521_probe(struct phy_devic
220 return ret;
221 }
222
223 - return 0;
224 + if (of_property_read_u32(node, "motorcomm,clk-out-frequency-hz", &freq))
225 + freq = YTPHY_DTS_OUTPUT_CLK_DIS;
226 +
227 + if (phydev->drv->phy_id == PHY_ID_YT8521) {
228 + switch (freq) {
229 + case YTPHY_DTS_OUTPUT_CLK_DIS:
230 + mask = YT8521_SCR_SYNCE_ENABLE;
231 + val = 0;
232 + break;
233 + case YTPHY_DTS_OUTPUT_CLK_25M:
234 + mask = YT8521_SCR_SYNCE_ENABLE |
235 + YT8521_SCR_CLK_SRC_MASK |
236 + YT8521_SCR_CLK_FRE_SEL_125M;
237 + val = YT8521_SCR_SYNCE_ENABLE |
238 + FIELD_PREP(YT8521_SCR_CLK_SRC_MASK,
239 + YT8521_SCR_CLK_SRC_REF_25M);
240 + break;
241 + case YTPHY_DTS_OUTPUT_CLK_125M:
242 + mask = YT8521_SCR_SYNCE_ENABLE |
243 + YT8521_SCR_CLK_SRC_MASK |
244 + YT8521_SCR_CLK_FRE_SEL_125M;
245 + val = YT8521_SCR_SYNCE_ENABLE |
246 + YT8521_SCR_CLK_FRE_SEL_125M |
247 + FIELD_PREP(YT8521_SCR_CLK_SRC_MASK,
248 + YT8521_SCR_CLK_SRC_PLL_125M);
249 + break;
250 + default:
251 + phydev_warn(phydev, "Freq err:%u\n", freq);
252 + return -EINVAL;
253 + }
254 + } else if (phydev->drv->phy_id == PHY_ID_YT8531S) {
255 + return 0;
256 + } else {
257 + phydev_warn(phydev, "PHY id err\n");
258 + return -EINVAL;
259 + }
260 +
261 + return ytphy_modify_ext_with_lock(phydev, YTPHY_SYNCE_CFG_REG, mask,
262 + val);
263 }
264
265 /**
266 @@ -1180,61 +1350,36 @@ static int yt8521_resume(struct phy_devi
267 */
268 static int yt8521_config_init(struct phy_device *phydev)
269 {
270 + struct device_node *node = phydev->mdio.dev.of_node;
271 int old_page;
272 int ret = 0;
273 - u16 val;
274
275 old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE);
276 if (old_page < 0)
277 goto err_restore_page;
278
279 - switch (phydev->interface) {
280 - case PHY_INTERFACE_MODE_RGMII:
281 - val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
282 - val |= YT8521_RC1R_RX_DELAY_DIS;
283 - break;
284 - case PHY_INTERFACE_MODE_RGMII_RXID:
285 - val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS;
286 - val |= YT8521_RC1R_RX_DELAY_EN;
287 - break;
288 - case PHY_INTERFACE_MODE_RGMII_TXID:
289 - val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
290 - val |= YT8521_RC1R_RX_DELAY_DIS;
291 - break;
292 - case PHY_INTERFACE_MODE_RGMII_ID:
293 - val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN;
294 - val |= YT8521_RC1R_RX_DELAY_EN;
295 - break;
296 - case PHY_INTERFACE_MODE_SGMII:
297 - break;
298 - default: /* do not support other modes */
299 - ret = -EOPNOTSUPP;
300 - goto err_restore_page;
301 - }
302 -
303 /* set rgmii delay mode */
304 if (phydev->interface != PHY_INTERFACE_MODE_SGMII) {
305 - ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG,
306 - (YT8521_RC1R_RX_DELAY_MASK |
307 - YT8521_RC1R_FE_TX_DELAY_MASK |
308 - YT8521_RC1R_GE_TX_DELAY_MASK),
309 - val);
310 + ret = ytphy_rgmii_clk_delay_config(phydev);
311 if (ret < 0)
312 goto err_restore_page;
313 }
314
315 - /* disable auto sleep */
316 - ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG,
317 - YT8521_ESC1R_SLEEP_SW, 0);
318 - if (ret < 0)
319 - goto err_restore_page;
320 -
321 - /* enable RXC clock when no wire plug */
322 - ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG,
323 - YT8521_CGR_RX_CLK_EN, 0);
324 - if (ret < 0)
325 - goto err_restore_page;
326 + if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) {
327 + /* disable auto sleep */
328 + ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG,
329 + YT8521_ESC1R_SLEEP_SW, 0);
330 + if (ret < 0)
331 + goto err_restore_page;
332 + }
333
334 + if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) {
335 + /* enable RXC clock when no wire plug */
336 + ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG,
337 + YT8521_CGR_RX_CLK_EN, 0);
338 + if (ret < 0)
339 + goto err_restore_page;
340 + }
341 err_restore_page:
342 return phy_restore_page(phydev, old_page, ret);
343 }