forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
....@@ -1,10 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU
34 *
45 * Copyright (C) STMicroelectronics SA 2017
56 * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
6
- * License terms: GNU General Public License (GPL), version 2
7
- *
87 */
98
109 #include <linux/clk.h>
....@@ -25,9 +24,29 @@
2524
2625 #define SYSCFG_MCU_ETH_MASK BIT(23)
2726 #define SYSCFG_MP1_ETH_MASK GENMASK(23, 16)
27
+#define SYSCFG_PMCCLRR_OFFSET 0x40
2828
2929 #define SYSCFG_PMCR_ETH_CLK_SEL BIT(16)
3030 #define SYSCFG_PMCR_ETH_REF_CLK_SEL BIT(17)
31
+
32
+/* CLOCK feed to PHY*/
33
+#define ETH_CK_F_25M 25000000
34
+#define ETH_CK_F_50M 50000000
35
+#define ETH_CK_F_125M 125000000
36
+
37
+/* Ethernet PHY interface selection in register SYSCFG Configuration
38
+ *------------------------------------------
39
+ * src |BIT(23)| BIT(22)| BIT(21)|BIT(20)|
40
+ *------------------------------------------
41
+ * MII | 0 | 0 | 0 | 1 |
42
+ *------------------------------------------
43
+ * GMII | 0 | 0 | 0 | 0 |
44
+ *------------------------------------------
45
+ * RGMII | 0 | 0 | 1 | n/a |
46
+ *------------------------------------------
47
+ * RMII | 1 | 0 | 0 | n/a |
48
+ *------------------------------------------
49
+ */
3150 #define SYSCFG_PMCR_ETH_SEL_MII BIT(20)
3251 #define SYSCFG_PMCR_ETH_SEL_RGMII BIT(21)
3352 #define SYSCFG_PMCR_ETH_SEL_RMII BIT(23)
....@@ -35,14 +54,43 @@
3554 #define SYSCFG_MCU_ETH_SEL_MII 0
3655 #define SYSCFG_MCU_ETH_SEL_RMII 1
3756
57
+/* STM32MP1 register definitions
58
+ *
59
+ * Below table summarizes the clock requirement and clock sources for
60
+ * supported phy interface modes.
61
+ * __________________________________________________________________________
62
+ *|PHY_MODE | Normal | PHY wo crystal| PHY wo crystal |No 125Mhz from PHY|
63
+ *| | | 25MHz | 50MHz | |
64
+ * ---------------------------------------------------------------------------
65
+ *| MII | - | eth-ck | n/a | n/a |
66
+ *| | | st,ext-phyclk | | |
67
+ * ---------------------------------------------------------------------------
68
+ *| GMII | - | eth-ck | n/a | n/a |
69
+ *| | | st,ext-phyclk | | |
70
+ * ---------------------------------------------------------------------------
71
+ *| RGMII | - | eth-ck | n/a | eth-ck |
72
+ *| | | st,ext-phyclk | | st,eth-clk-sel or|
73
+ *| | | | | st,ext-phyclk |
74
+ * ---------------------------------------------------------------------------
75
+ *| RMII | - | eth-ck | eth-ck | n/a |
76
+ *| | | st,ext-phyclk | st,eth-ref-clk-sel | |
77
+ *| | | | or st,ext-phyclk | |
78
+ * ---------------------------------------------------------------------------
79
+ *
80
+ */
81
+
3882 struct stm32_dwmac {
3983 struct clk *clk_tx;
4084 struct clk *clk_rx;
4185 struct clk *clk_eth_ck;
4286 struct clk *clk_ethstp;
4387 struct clk *syscfg_clk;
44
- bool int_phyclk; /* Clock from RCC to drive PHY */
45
- u32 mode_reg; /* MAC glue-logic mode register */
88
+ int ext_phyclk;
89
+ int enable_eth_ck;
90
+ int eth_clk_sel_reg;
91
+ int eth_ref_clk_sel_reg;
92
+ int irq_pwr_wakeup;
93
+ u32 mode_reg; /* MAC glue-logic mode register */
4694 struct regmap *regmap;
4795 u32 speed;
4896 const struct stm32_ops *ops;
....@@ -101,8 +149,7 @@
101149 ret = clk_prepare_enable(dwmac->syscfg_clk);
102150 if (ret)
103151 return ret;
104
-
105
- if (dwmac->int_phyclk) {
152
+ if (dwmac->enable_eth_ck) {
106153 ret = clk_prepare_enable(dwmac->clk_eth_ck);
107154 if (ret) {
108155 clk_disable_unprepare(dwmac->syscfg_clk);
....@@ -111,7 +158,7 @@
111158 }
112159 } else {
113160 clk_disable_unprepare(dwmac->syscfg_clk);
114
- if (dwmac->int_phyclk)
161
+ if (dwmac->enable_eth_ck)
115162 clk_disable_unprepare(dwmac->clk_eth_ck);
116163 }
117164 return ret;
....@@ -120,30 +167,46 @@
120167 static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
121168 {
122169 struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
123
- u32 reg = dwmac->mode_reg;
170
+ u32 reg = dwmac->mode_reg, clk_rate;
124171 int val;
125172
173
+ clk_rate = clk_get_rate(dwmac->clk_eth_ck);
174
+ dwmac->enable_eth_ck = false;
126175 switch (plat_dat->interface) {
127176 case PHY_INTERFACE_MODE_MII:
177
+ if (clk_rate == ETH_CK_F_25M && dwmac->ext_phyclk)
178
+ dwmac->enable_eth_ck = true;
128179 val = SYSCFG_PMCR_ETH_SEL_MII;
129180 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
130181 break;
131182 case PHY_INTERFACE_MODE_GMII:
132183 val = SYSCFG_PMCR_ETH_SEL_GMII;
133
- if (dwmac->int_phyclk)
184
+ if (clk_rate == ETH_CK_F_25M &&
185
+ (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
186
+ dwmac->enable_eth_ck = true;
134187 val |= SYSCFG_PMCR_ETH_CLK_SEL;
188
+ }
135189 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
136190 break;
137191 case PHY_INTERFACE_MODE_RMII:
138192 val = SYSCFG_PMCR_ETH_SEL_RMII;
139
- if (dwmac->int_phyclk)
193
+ if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
194
+ (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
195
+ dwmac->enable_eth_ck = true;
140196 val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
197
+ }
141198 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
142199 break;
143200 case PHY_INTERFACE_MODE_RGMII:
201
+ case PHY_INTERFACE_MODE_RGMII_ID:
202
+ case PHY_INTERFACE_MODE_RGMII_RXID:
203
+ case PHY_INTERFACE_MODE_RGMII_TXID:
144204 val = SYSCFG_PMCR_ETH_SEL_RGMII;
145
- if (dwmac->int_phyclk)
205
+ if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) &&
206
+ (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
207
+ dwmac->enable_eth_ck = true;
146208 val |= SYSCFG_PMCR_ETH_CLK_SEL;
209
+ }
147210 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
148211 break;
149212 default:
....@@ -153,6 +216,11 @@
153216 return -EINVAL;
154217 }
155218
219
+ /* Need to update PMCCLRR (clear register) */
220
+ regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
221
+ dwmac->ops->syscfg_eth_mask);
222
+
223
+ /* Update PMCSETR (set register) */
156224 return regmap_update_bits(dwmac->regmap, reg,
157225 dwmac->ops->syscfg_eth_mask, val);
158226 }
....@@ -180,7 +248,7 @@
180248 }
181249
182250 return regmap_update_bits(dwmac->regmap, reg,
183
- dwmac->ops->syscfg_eth_mask, val);
251
+ dwmac->ops->syscfg_eth_mask, val << 23);
184252 }
185253
186254 static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac)
....@@ -232,35 +300,63 @@
232300 static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
233301 struct device *dev)
234302 {
303
+ struct platform_device *pdev = to_platform_device(dev);
235304 struct device_node *np = dev->of_node;
305
+ int err = 0;
236306
237
- dwmac->int_phyclk = of_property_read_bool(np, "st,int-phyclk");
307
+ /* Ethernet PHY have no crystal */
308
+ dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
238309
239
- /* Check if internal clk from RCC selected */
240
- if (dwmac->int_phyclk) {
241
- /* Get ETH_CLK clocks */
242
- dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck");
243
- if (IS_ERR(dwmac->clk_eth_ck)) {
244
- dev_err(dev, "No ETH CK clock provided...\n");
245
- return PTR_ERR(dwmac->clk_eth_ck);
246
- }
310
+ /* Gigabit Ethernet 125MHz clock selection. */
311
+ dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel");
312
+
313
+ /* Ethernet 50Mhz RMII clock selection */
314
+ dwmac->eth_ref_clk_sel_reg =
315
+ of_property_read_bool(np, "st,eth-ref-clk-sel");
316
+
317
+ /* Get ETH_CLK clocks */
318
+ dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck");
319
+ if (IS_ERR(dwmac->clk_eth_ck)) {
320
+ dev_info(dev, "No phy clock provided...\n");
321
+ dwmac->clk_eth_ck = NULL;
247322 }
248323
249324 /* Clock used for low power mode */
250325 dwmac->clk_ethstp = devm_clk_get(dev, "ethstp");
251326 if (IS_ERR(dwmac->clk_ethstp)) {
252
- dev_err(dev, "No ETH peripheral clock provided for CStop mode ...\n");
327
+ dev_err(dev,
328
+ "No ETH peripheral clock provided for CStop mode ...\n");
253329 return PTR_ERR(dwmac->clk_ethstp);
254330 }
255331
256
- /* Clock for sysconfig */
332
+ /* Optional Clock for sysconfig */
257333 dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk");
258
- if (IS_ERR(dwmac->syscfg_clk)) {
259
- dev_err(dev, "No syscfg clock provided...\n");
260
- return PTR_ERR(dwmac->syscfg_clk);
261
- }
334
+ if (IS_ERR(dwmac->syscfg_clk))
335
+ dwmac->syscfg_clk = NULL;
262336
263
- return 0;
337
+ /* Get IRQ information early to have an ability to ask for deferred
338
+ * probe if needed before we went too far with resource allocation.
339
+ */
340
+ dwmac->irq_pwr_wakeup = platform_get_irq_byname_optional(pdev,
341
+ "stm32_pwr_wakeup");
342
+ if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER)
343
+ return -EPROBE_DEFER;
344
+
345
+ if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) {
346
+ err = device_init_wakeup(&pdev->dev, true);
347
+ if (err) {
348
+ dev_err(&pdev->dev, "Failed to init wake up irq\n");
349
+ return err;
350
+ }
351
+ err = dev_pm_set_dedicated_wake_irq(&pdev->dev,
352
+ dwmac->irq_pwr_wakeup);
353
+ if (err) {
354
+ dev_err(&pdev->dev, "Failed to set wake up irq\n");
355
+ device_init_wakeup(&pdev->dev, false);
356
+ }
357
+ device_set_wakeup_enable(&pdev->dev, false);
358
+ }
359
+ return err;
264360 }
265361
266362 static int stm32_dwmac_probe(struct platform_device *pdev)
....@@ -326,8 +422,14 @@
326422 struct net_device *ndev = platform_get_drvdata(pdev);
327423 struct stmmac_priv *priv = netdev_priv(ndev);
328424 int ret = stmmac_dvr_remove(&pdev->dev);
425
+ struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
329426
330427 stm32_dwmac_clk_disable(priv->plat->bsp_priv);
428
+
429
+ if (dwmac->irq_pwr_wakeup >= 0) {
430
+ dev_pm_clear_wake_irq(&pdev->dev);
431
+ device_init_wakeup(&pdev->dev, false);
432
+ }
331433
332434 return ret;
333435 }
....@@ -342,7 +444,7 @@
342444
343445 clk_disable_unprepare(dwmac->clk_tx);
344446 clk_disable_unprepare(dwmac->syscfg_clk);
345
- if (dwmac->int_phyclk)
447
+ if (dwmac->enable_eth_ck)
346448 clk_disable_unprepare(dwmac->clk_eth_ck);
347449
348450 return ret;