hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
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;
....@@ -57,6 +105,7 @@
57105 int (*parse_data)(struct stm32_dwmac *dwmac,
58106 struct device *dev);
59107 u32 syscfg_eth_mask;
108
+ bool clk_rx_enable_in_suspend;
60109 };
61110
62111 static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
....@@ -74,7 +123,8 @@
74123 if (ret)
75124 return ret;
76125
77
- if (!dwmac->dev->power.is_suspended) {
126
+ if (!dwmac->ops->clk_rx_enable_in_suspend ||
127
+ !dwmac->dev->power.is_suspended) {
78128 ret = clk_prepare_enable(dwmac->clk_rx);
79129 if (ret) {
80130 clk_disable_unprepare(dwmac->clk_tx);
....@@ -101,8 +151,7 @@
101151 ret = clk_prepare_enable(dwmac->syscfg_clk);
102152 if (ret)
103153 return ret;
104
-
105
- if (dwmac->int_phyclk) {
154
+ if (dwmac->enable_eth_ck) {
106155 ret = clk_prepare_enable(dwmac->clk_eth_ck);
107156 if (ret) {
108157 clk_disable_unprepare(dwmac->syscfg_clk);
....@@ -111,7 +160,7 @@
111160 }
112161 } else {
113162 clk_disable_unprepare(dwmac->syscfg_clk);
114
- if (dwmac->int_phyclk)
163
+ if (dwmac->enable_eth_ck)
115164 clk_disable_unprepare(dwmac->clk_eth_ck);
116165 }
117166 return ret;
....@@ -120,30 +169,46 @@
120169 static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
121170 {
122171 struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
123
- u32 reg = dwmac->mode_reg;
172
+ u32 reg = dwmac->mode_reg, clk_rate;
124173 int val;
125174
175
+ clk_rate = clk_get_rate(dwmac->clk_eth_ck);
176
+ dwmac->enable_eth_ck = false;
126177 switch (plat_dat->interface) {
127178 case PHY_INTERFACE_MODE_MII:
179
+ if (clk_rate == ETH_CK_F_25M && dwmac->ext_phyclk)
180
+ dwmac->enable_eth_ck = true;
128181 val = SYSCFG_PMCR_ETH_SEL_MII;
129182 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
130183 break;
131184 case PHY_INTERFACE_MODE_GMII:
132185 val = SYSCFG_PMCR_ETH_SEL_GMII;
133
- if (dwmac->int_phyclk)
186
+ if (clk_rate == ETH_CK_F_25M &&
187
+ (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
188
+ dwmac->enable_eth_ck = true;
134189 val |= SYSCFG_PMCR_ETH_CLK_SEL;
190
+ }
135191 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
136192 break;
137193 case PHY_INTERFACE_MODE_RMII:
138194 val = SYSCFG_PMCR_ETH_SEL_RMII;
139
- if (dwmac->int_phyclk)
195
+ if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
196
+ (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
197
+ dwmac->enable_eth_ck = true;
140198 val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
199
+ }
141200 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
142201 break;
143202 case PHY_INTERFACE_MODE_RGMII:
203
+ case PHY_INTERFACE_MODE_RGMII_ID:
204
+ case PHY_INTERFACE_MODE_RGMII_RXID:
205
+ case PHY_INTERFACE_MODE_RGMII_TXID:
144206 val = SYSCFG_PMCR_ETH_SEL_RGMII;
145
- if (dwmac->int_phyclk)
207
+ if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) &&
208
+ (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
209
+ dwmac->enable_eth_ck = true;
146210 val |= SYSCFG_PMCR_ETH_CLK_SEL;
211
+ }
147212 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
148213 break;
149214 default:
....@@ -153,6 +218,11 @@
153218 return -EINVAL;
154219 }
155220
221
+ /* Need to update PMCCLRR (clear register) */
222
+ regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
223
+ dwmac->ops->syscfg_eth_mask);
224
+
225
+ /* Update PMCSETR (set register) */
156226 return regmap_update_bits(dwmac->regmap, reg,
157227 dwmac->ops->syscfg_eth_mask, val);
158228 }
....@@ -180,7 +250,7 @@
180250 }
181251
182252 return regmap_update_bits(dwmac->regmap, reg,
183
- dwmac->ops->syscfg_eth_mask, val);
253
+ dwmac->ops->syscfg_eth_mask, val << 23);
184254 }
185255
186256 static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac)
....@@ -232,35 +302,63 @@
232302 static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
233303 struct device *dev)
234304 {
305
+ struct platform_device *pdev = to_platform_device(dev);
235306 struct device_node *np = dev->of_node;
307
+ int err = 0;
236308
237
- dwmac->int_phyclk = of_property_read_bool(np, "st,int-phyclk");
309
+ /* Ethernet PHY have no crystal */
310
+ dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
238311
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
- }
312
+ /* Gigabit Ethernet 125MHz clock selection. */
313
+ dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel");
314
+
315
+ /* Ethernet 50Mhz RMII clock selection */
316
+ dwmac->eth_ref_clk_sel_reg =
317
+ of_property_read_bool(np, "st,eth-ref-clk-sel");
318
+
319
+ /* Get ETH_CLK clocks */
320
+ dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck");
321
+ if (IS_ERR(dwmac->clk_eth_ck)) {
322
+ dev_info(dev, "No phy clock provided...\n");
323
+ dwmac->clk_eth_ck = NULL;
247324 }
248325
249326 /* Clock used for low power mode */
250327 dwmac->clk_ethstp = devm_clk_get(dev, "ethstp");
251328 if (IS_ERR(dwmac->clk_ethstp)) {
252
- dev_err(dev, "No ETH peripheral clock provided for CStop mode ...\n");
329
+ dev_err(dev,
330
+ "No ETH peripheral clock provided for CStop mode ...\n");
253331 return PTR_ERR(dwmac->clk_ethstp);
254332 }
255333
256
- /* Clock for sysconfig */
334
+ /* Optional Clock for sysconfig */
257335 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
- }
336
+ if (IS_ERR(dwmac->syscfg_clk))
337
+ dwmac->syscfg_clk = NULL;
262338
263
- return 0;
339
+ /* Get IRQ information early to have an ability to ask for deferred
340
+ * probe if needed before we went too far with resource allocation.
341
+ */
342
+ dwmac->irq_pwr_wakeup = platform_get_irq_byname_optional(pdev,
343
+ "stm32_pwr_wakeup");
344
+ if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER)
345
+ return -EPROBE_DEFER;
346
+
347
+ if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) {
348
+ err = device_init_wakeup(&pdev->dev, true);
349
+ if (err) {
350
+ dev_err(&pdev->dev, "Failed to init wake up irq\n");
351
+ return err;
352
+ }
353
+ err = dev_pm_set_dedicated_wake_irq(&pdev->dev,
354
+ dwmac->irq_pwr_wakeup);
355
+ if (err) {
356
+ dev_err(&pdev->dev, "Failed to set wake up irq\n");
357
+ device_init_wakeup(&pdev->dev, false);
358
+ }
359
+ device_set_wakeup_enable(&pdev->dev, false);
360
+ }
361
+ return err;
264362 }
265363
266364 static int stm32_dwmac_probe(struct platform_device *pdev)
....@@ -326,8 +424,14 @@
326424 struct net_device *ndev = platform_get_drvdata(pdev);
327425 struct stmmac_priv *priv = netdev_priv(ndev);
328426 int ret = stmmac_dvr_remove(&pdev->dev);
427
+ struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
329428
330429 stm32_dwmac_clk_disable(priv->plat->bsp_priv);
430
+
431
+ if (dwmac->irq_pwr_wakeup >= 0) {
432
+ dev_pm_clear_wake_irq(&pdev->dev);
433
+ device_init_wakeup(&pdev->dev, false);
434
+ }
331435
332436 return ret;
333437 }
....@@ -342,7 +446,7 @@
342446
343447 clk_disable_unprepare(dwmac->clk_tx);
344448 clk_disable_unprepare(dwmac->syscfg_clk);
345
- if (dwmac->int_phyclk)
449
+ if (dwmac->enable_eth_ck)
346450 clk_disable_unprepare(dwmac->clk_eth_ck);
347451
348452 return ret;
....@@ -413,7 +517,8 @@
413517 .suspend = stm32mp1_suspend,
414518 .resume = stm32mp1_resume,
415519 .parse_data = stm32mp1_parse_data,
416
- .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK
520
+ .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
521
+ .clk_rx_enable_in_suspend = true
417522 };
418523
419524 static const struct of_device_id stm32_dwmac_match[] = {