1 // SPDX-License-Identifier: GPL-2.0-only
3 * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU
5 * Copyright (C) STMicroelectronics SA 2017
6 * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
10 #include <linux/kernel.h>
11 #include <linux/mfd/syscon.h>
12 #include <linux/module.h>
14 #include <linux/of_device.h>
15 #include <linux/of_net.h>
16 #include <linux/phy.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_wakeirq.h>
19 #include <linux/regmap.h>
20 #include <linux/slab.h>
21 #include <linux/stmmac.h>
23 #include "stmmac_platform.h"
25 #define SYSCFG_MCU_ETH_MASK BIT(23)
26 #define SYSCFG_MP1_ETH_MASK GENMASK(23, 16)
27 #define SYSCFG_PMCCLRR_OFFSET 0x40
29 #define SYSCFG_PMCR_ETH_CLK_SEL BIT(16)
30 #define SYSCFG_PMCR_ETH_REF_CLK_SEL BIT(17)
32 /* Ethernet PHY interface selection in register SYSCFG Configuration
33 *------------------------------------------
34 * src |BIT(23)| BIT(22)| BIT(21)|BIT(20)|
35 *------------------------------------------
36 * MII | 0 | 0 | 0 | 1 |
37 *------------------------------------------
38 * GMII | 0 | 0 | 0 | 0 |
39 *------------------------------------------
40 * RGMII | 0 | 0 | 1 | n/a |
41 *------------------------------------------
42 * RMII | 1 | 0 | 0 | n/a |
43 *------------------------------------------
45 #define SYSCFG_PMCR_ETH_SEL_MII BIT(20)
46 #define SYSCFG_PMCR_ETH_SEL_RGMII BIT(21)
47 #define SYSCFG_PMCR_ETH_SEL_RMII BIT(23)
48 #define SYSCFG_PMCR_ETH_SEL_GMII 0
49 #define SYSCFG_MCU_ETH_SEL_MII 0
50 #define SYSCFG_MCU_ETH_SEL_RMII 1
52 /* STM32MP1 register definitions
54 * Below table summarizes the clock requirement and clock sources for
55 * supported phy interface modes.
56 * __________________________________________________________________________
57 *|PHY_MODE | Normal | PHY wo crystal| PHY wo crystal |No 125Mhz from PHY|
58 *| | | 25MHz | 50MHz | |
59 * ---------------------------------------------------------------------------
60 *| MII | - | eth-ck | n/a | n/a |
62 * ---------------------------------------------------------------------------
63 *| GMII | - | eth-ck | n/a | n/a |
65 * ---------------------------------------------------------------------------
66 *| RGMII | - | eth-ck | n/a | eth-ck (no pin) |
67 *| | | | | st,eth-clk-sel |
68 * ---------------------------------------------------------------------------
69 *| RMII | - | eth-ck | eth-ck | n/a |
70 *| | | | st,eth-ref-clk-sel | |
71 * ---------------------------------------------------------------------------
73 * BIT(17) : set this bit in RMII mode when you have PHY without crystal 50MHz
74 * BIT(16) : set this bit in GMII/RGMII PHY when you do not want use 125Mhz
76 *-----------------------------------------------------
77 * src | BIT(17) | BIT(16) |
78 *-----------------------------------------------------
80 *-----------------------------------------------------
81 * GMII | n/a | st,eth-clk-sel |
82 *-----------------------------------------------------
83 * RGMII | n/a | st,eth-clk-sel |
84 *-----------------------------------------------------
85 * RMII | st,eth-ref-clk-sel | n/a |
86 *-----------------------------------------------------
93 struct clk
*clk_eth_ck
;
94 struct clk
*clk_ethstp
;
95 struct clk
*syscfg_clk
;
97 int eth_ref_clk_sel_reg
;
99 u32 mode_reg
; /* MAC glue-logic mode register */
100 struct regmap
*regmap
;
102 const struct stm32_ops
*ops
;
107 int (*set_mode
)(struct plat_stmmacenet_data
*plat_dat
);
108 int (*clk_prepare
)(struct stm32_dwmac
*dwmac
, bool prepare
);
109 int (*suspend
)(struct stm32_dwmac
*dwmac
);
110 void (*resume
)(struct stm32_dwmac
*dwmac
);
111 int (*parse_data
)(struct stm32_dwmac
*dwmac
,
116 static int stm32_dwmac_init(struct plat_stmmacenet_data
*plat_dat
)
118 struct stm32_dwmac
*dwmac
= plat_dat
->bsp_priv
;
121 if (dwmac
->ops
->set_mode
) {
122 ret
= dwmac
->ops
->set_mode(plat_dat
);
127 ret
= clk_prepare_enable(dwmac
->clk_tx
);
131 if (!dwmac
->dev
->power
.is_suspended
) {
132 ret
= clk_prepare_enable(dwmac
->clk_rx
);
134 clk_disable_unprepare(dwmac
->clk_tx
);
139 if (dwmac
->ops
->clk_prepare
) {
140 ret
= dwmac
->ops
->clk_prepare(dwmac
, true);
142 clk_disable_unprepare(dwmac
->clk_rx
);
143 clk_disable_unprepare(dwmac
->clk_tx
);
150 static int stm32mp1_clk_prepare(struct stm32_dwmac
*dwmac
, bool prepare
)
155 ret
= clk_prepare_enable(dwmac
->syscfg_clk
);
158 ret
= clk_prepare_enable(dwmac
->clk_eth_ck
);
160 clk_disable_unprepare(dwmac
->syscfg_clk
);
164 clk_disable_unprepare(dwmac
->syscfg_clk
);
165 clk_disable_unprepare(dwmac
->clk_eth_ck
);
170 static int stm32mp1_set_mode(struct plat_stmmacenet_data
*plat_dat
)
172 struct stm32_dwmac
*dwmac
= plat_dat
->bsp_priv
;
173 u32 reg
= dwmac
->mode_reg
;
176 switch (plat_dat
->interface
) {
177 case PHY_INTERFACE_MODE_MII
:
178 val
= SYSCFG_PMCR_ETH_SEL_MII
;
179 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
181 case PHY_INTERFACE_MODE_GMII
:
182 val
= SYSCFG_PMCR_ETH_SEL_GMII
;
183 if (dwmac
->eth_clk_sel_reg
)
184 val
|= SYSCFG_PMCR_ETH_CLK_SEL
;
185 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
187 case PHY_INTERFACE_MODE_RMII
:
188 val
= SYSCFG_PMCR_ETH_SEL_RMII
;
189 if (dwmac
->eth_ref_clk_sel_reg
)
190 val
|= SYSCFG_PMCR_ETH_REF_CLK_SEL
;
191 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
193 case PHY_INTERFACE_MODE_RGMII
:
194 case PHY_INTERFACE_MODE_RGMII_ID
:
195 case PHY_INTERFACE_MODE_RGMII_RXID
:
196 case PHY_INTERFACE_MODE_RGMII_TXID
:
197 val
= SYSCFG_PMCR_ETH_SEL_RGMII
;
198 if (dwmac
->eth_clk_sel_reg
)
199 val
|= SYSCFG_PMCR_ETH_CLK_SEL
;
200 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
203 pr_debug("SYSCFG init : Do not manage %d interface\n",
204 plat_dat
->interface
);
205 /* Do not manage others interfaces */
209 /* Need to update PMCCLRR (clear register) */
210 regmap_write(dwmac
->regmap
, reg
+ SYSCFG_PMCCLRR_OFFSET
,
211 dwmac
->ops
->syscfg_eth_mask
);
213 /* Update PMCSETR (set register) */
214 return regmap_update_bits(dwmac
->regmap
, reg
,
215 dwmac
->ops
->syscfg_eth_mask
, val
);
218 static int stm32mcu_set_mode(struct plat_stmmacenet_data
*plat_dat
)
220 struct stm32_dwmac
*dwmac
= plat_dat
->bsp_priv
;
221 u32 reg
= dwmac
->mode_reg
;
224 switch (plat_dat
->interface
) {
225 case PHY_INTERFACE_MODE_MII
:
226 val
= SYSCFG_MCU_ETH_SEL_MII
;
227 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
229 case PHY_INTERFACE_MODE_RMII
:
230 val
= SYSCFG_MCU_ETH_SEL_RMII
;
231 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
234 pr_debug("SYSCFG init : Do not manage %d interface\n",
235 plat_dat
->interface
);
236 /* Do not manage others interfaces */
240 return regmap_update_bits(dwmac
->regmap
, reg
,
241 dwmac
->ops
->syscfg_eth_mask
, val
<< 23);
244 static void stm32_dwmac_clk_disable(struct stm32_dwmac
*dwmac
)
246 clk_disable_unprepare(dwmac
->clk_tx
);
247 clk_disable_unprepare(dwmac
->clk_rx
);
249 if (dwmac
->ops
->clk_prepare
)
250 dwmac
->ops
->clk_prepare(dwmac
, false);
253 static int stm32_dwmac_parse_data(struct stm32_dwmac
*dwmac
,
256 struct device_node
*np
= dev
->of_node
;
259 /* Get TX/RX clocks */
260 dwmac
->clk_tx
= devm_clk_get(dev
, "mac-clk-tx");
261 if (IS_ERR(dwmac
->clk_tx
)) {
262 dev_err(dev
, "No ETH Tx clock provided...\n");
263 return PTR_ERR(dwmac
->clk_tx
);
266 dwmac
->clk_rx
= devm_clk_get(dev
, "mac-clk-rx");
267 if (IS_ERR(dwmac
->clk_rx
)) {
268 dev_err(dev
, "No ETH Rx clock provided...\n");
269 return PTR_ERR(dwmac
->clk_rx
);
272 if (dwmac
->ops
->parse_data
) {
273 err
= dwmac
->ops
->parse_data(dwmac
, dev
);
278 /* Get mode register */
279 dwmac
->regmap
= syscon_regmap_lookup_by_phandle(np
, "st,syscon");
280 if (IS_ERR(dwmac
->regmap
))
281 return PTR_ERR(dwmac
->regmap
);
283 err
= of_property_read_u32_index(np
, "st,syscon", 1, &dwmac
->mode_reg
);
285 dev_err(dev
, "Can't get sysconfig mode offset (%d)\n", err
);
290 static int stm32mp1_parse_data(struct stm32_dwmac
*dwmac
,
293 struct platform_device
*pdev
= to_platform_device(dev
);
294 struct device_node
*np
= dev
->of_node
;
297 /* Gigabit Ethernet 125MHz clock selection. */
298 dwmac
->eth_clk_sel_reg
= of_property_read_bool(np
, "st,eth-clk-sel");
300 /* Ethernet 50Mhz RMII clock selection */
301 dwmac
->eth_ref_clk_sel_reg
=
302 of_property_read_bool(np
, "st,eth-ref-clk-sel");
304 /* Get ETH_CLK clocks */
305 dwmac
->clk_eth_ck
= devm_clk_get(dev
, "eth-ck");
306 if (IS_ERR(dwmac
->clk_eth_ck
)) {
307 dev_warn(dev
, "No phy clock provided...\n");
308 dwmac
->clk_eth_ck
= NULL
;
311 /* Clock used for low power mode */
312 dwmac
->clk_ethstp
= devm_clk_get(dev
, "ethstp");
313 if (IS_ERR(dwmac
->clk_ethstp
)) {
315 "No ETH peripheral clock provided for CStop mode ...\n");
316 return PTR_ERR(dwmac
->clk_ethstp
);
319 /* Optional Clock for sysconfig */
320 dwmac
->syscfg_clk
= devm_clk_get(dev
, "syscfg-clk");
321 if (IS_ERR(dwmac
->syscfg_clk
))
322 dwmac
->syscfg_clk
= NULL
;
324 /* Get IRQ information early to have an ability to ask for deferred
325 * probe if needed before we went too far with resource allocation.
327 dwmac
->irq_pwr_wakeup
= platform_get_irq_byname(pdev
,
329 if (dwmac
->irq_pwr_wakeup
== -EPROBE_DEFER
)
330 return -EPROBE_DEFER
;
332 if (!dwmac
->clk_eth_ck
&& dwmac
->irq_pwr_wakeup
>= 0) {
333 err
= device_init_wakeup(&pdev
->dev
, true);
335 dev_err(&pdev
->dev
, "Failed to init wake up irq\n");
338 err
= dev_pm_set_dedicated_wake_irq(&pdev
->dev
,
339 dwmac
->irq_pwr_wakeup
);
341 dev_err(&pdev
->dev
, "Failed to set wake up irq\n");
342 device_init_wakeup(&pdev
->dev
, false);
344 device_set_wakeup_enable(&pdev
->dev
, false);
349 static int stm32_dwmac_probe(struct platform_device
*pdev
)
351 struct plat_stmmacenet_data
*plat_dat
;
352 struct stmmac_resources stmmac_res
;
353 struct stm32_dwmac
*dwmac
;
354 const struct stm32_ops
*data
;
357 ret
= stmmac_get_platform_resources(pdev
, &stmmac_res
);
361 plat_dat
= stmmac_probe_config_dt(pdev
, &stmmac_res
.mac
);
362 if (IS_ERR(plat_dat
))
363 return PTR_ERR(plat_dat
);
365 dwmac
= devm_kzalloc(&pdev
->dev
, sizeof(*dwmac
), GFP_KERNEL
);
368 goto err_remove_config_dt
;
371 data
= of_device_get_match_data(&pdev
->dev
);
373 dev_err(&pdev
->dev
, "no of match data provided\n");
375 goto err_remove_config_dt
;
379 dwmac
->dev
= &pdev
->dev
;
381 ret
= stm32_dwmac_parse_data(dwmac
, &pdev
->dev
);
383 dev_err(&pdev
->dev
, "Unable to parse OF data\n");
384 goto err_remove_config_dt
;
387 plat_dat
->bsp_priv
= dwmac
;
389 ret
= stm32_dwmac_init(plat_dat
);
391 goto err_remove_config_dt
;
393 ret
= stmmac_dvr_probe(&pdev
->dev
, plat_dat
, &stmmac_res
);
395 goto err_clk_disable
;
400 stm32_dwmac_clk_disable(dwmac
);
401 err_remove_config_dt
:
402 stmmac_remove_config_dt(pdev
, plat_dat
);
407 static int stm32_dwmac_remove(struct platform_device
*pdev
)
409 struct net_device
*ndev
= platform_get_drvdata(pdev
);
410 struct stmmac_priv
*priv
= netdev_priv(ndev
);
411 int ret
= stmmac_dvr_remove(&pdev
->dev
);
412 struct stm32_dwmac
*dwmac
= priv
->plat
->bsp_priv
;
414 stm32_dwmac_clk_disable(priv
->plat
->bsp_priv
);
416 if (dwmac
->irq_pwr_wakeup
>= 0) {
417 dev_pm_clear_wake_irq(&pdev
->dev
);
418 device_init_wakeup(&pdev
->dev
, false);
424 static int stm32mp1_suspend(struct stm32_dwmac
*dwmac
)
428 ret
= clk_prepare_enable(dwmac
->clk_ethstp
);
432 clk_disable_unprepare(dwmac
->clk_tx
);
433 clk_disable_unprepare(dwmac
->syscfg_clk
);
434 clk_disable_unprepare(dwmac
->clk_eth_ck
);
439 static void stm32mp1_resume(struct stm32_dwmac
*dwmac
)
441 clk_disable_unprepare(dwmac
->clk_ethstp
);
444 static int stm32mcu_suspend(struct stm32_dwmac
*dwmac
)
446 clk_disable_unprepare(dwmac
->clk_tx
);
447 clk_disable_unprepare(dwmac
->clk_rx
);
452 #ifdef CONFIG_PM_SLEEP
453 static int stm32_dwmac_suspend(struct device
*dev
)
455 struct net_device
*ndev
= dev_get_drvdata(dev
);
456 struct stmmac_priv
*priv
= netdev_priv(ndev
);
457 struct stm32_dwmac
*dwmac
= priv
->plat
->bsp_priv
;
461 ret
= stmmac_suspend(dev
);
463 if (dwmac
->ops
->suspend
)
464 ret
= dwmac
->ops
->suspend(dwmac
);
469 static int stm32_dwmac_resume(struct device
*dev
)
471 struct net_device
*ndev
= dev_get_drvdata(dev
);
472 struct stmmac_priv
*priv
= netdev_priv(ndev
);
473 struct stm32_dwmac
*dwmac
= priv
->plat
->bsp_priv
;
476 if (dwmac
->ops
->resume
)
477 dwmac
->ops
->resume(dwmac
);
479 ret
= stm32_dwmac_init(priv
->plat
);
483 ret
= stmmac_resume(dev
);
487 #endif /* CONFIG_PM_SLEEP */
489 static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops
,
490 stm32_dwmac_suspend
, stm32_dwmac_resume
);
492 static struct stm32_ops stm32mcu_dwmac_data
= {
493 .set_mode
= stm32mcu_set_mode
,
494 .suspend
= stm32mcu_suspend
,
495 .syscfg_eth_mask
= SYSCFG_MCU_ETH_MASK
498 static struct stm32_ops stm32mp1_dwmac_data
= {
499 .set_mode
= stm32mp1_set_mode
,
500 .clk_prepare
= stm32mp1_clk_prepare
,
501 .suspend
= stm32mp1_suspend
,
502 .resume
= stm32mp1_resume
,
503 .parse_data
= stm32mp1_parse_data
,
504 .syscfg_eth_mask
= SYSCFG_MP1_ETH_MASK
507 static const struct of_device_id stm32_dwmac_match
[] = {
508 { .compatible
= "st,stm32-dwmac", .data
= &stm32mcu_dwmac_data
},
509 { .compatible
= "st,stm32mp1-dwmac", .data
= &stm32mp1_dwmac_data
},
512 MODULE_DEVICE_TABLE(of
, stm32_dwmac_match
);
514 static struct platform_driver stm32_dwmac_driver
= {
515 .probe
= stm32_dwmac_probe
,
516 .remove
= stm32_dwmac_remove
,
518 .name
= "stm32-dwmac",
519 .pm
= &stm32_dwmac_pm_ops
,
520 .of_match_table
= stm32_dwmac_match
,
523 module_platform_driver(stm32_dwmac_driver
);
525 MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@gmail.com>");
526 MODULE_AUTHOR("Christophe Roullier <christophe.roullier@st.com>");
527 MODULE_DESCRIPTION("STMicroelectronics STM32 DWMAC Specific Glue layer");
528 MODULE_LICENSE("GPL v2");