2 * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU
4 * Copyright (C) STMicroelectronics SA 2017
5 * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
6 * License terms: GNU General Public License (GPL), version 2
10 #include <linux/clk.h>
11 #include <linux/kernel.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/module.h>
15 #include <linux/of_device.h>
16 #include <linux/of_net.h>
17 #include <linux/phy.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_wakeirq.h>
20 #include <linux/regmap.h>
21 #include <linux/slab.h>
22 #include <linux/stmmac.h>
24 #include "stmmac_platform.h"
26 #define SYSCFG_MCU_ETH_MASK BIT(23)
27 #define SYSCFG_MP1_ETH_MASK GENMASK(23, 16)
28 #define SYSCFG_PMCCLRR_OFFSET 0x40
30 #define SYSCFG_PMCR_ETH_CLK_SEL BIT(16)
31 #define SYSCFG_PMCR_ETH_REF_CLK_SEL BIT(17)
33 /* Ethernet PHY interface selection in register SYSCFG Configuration
34 *------------------------------------------
35 * src |BIT(23)| BIT(22)| BIT(21)|BIT(20)|
36 *------------------------------------------
37 * MII | 0 | 0 | 0 | 1 |
38 *------------------------------------------
39 * GMII | 0 | 0 | 0 | 0 |
40 *------------------------------------------
41 * RGMII | 0 | 0 | 1 | n/a |
42 *------------------------------------------
43 * RMII | 1 | 0 | 0 | n/a |
44 *------------------------------------------
46 #define SYSCFG_PMCR_ETH_SEL_MII BIT(20)
47 #define SYSCFG_PMCR_ETH_SEL_RGMII BIT(21)
48 #define SYSCFG_PMCR_ETH_SEL_RMII BIT(23)
49 #define SYSCFG_PMCR_ETH_SEL_GMII 0
50 #define SYSCFG_MCU_ETH_SEL_MII 0
51 #define SYSCFG_MCU_ETH_SEL_RMII 1
53 /* STM32MP1 register definitions
55 * Below table summarizes the clock requirement and clock sources for
56 * supported phy interface modes.
57 * __________________________________________________________________________
58 *|PHY_MODE | Normal | PHY wo crystal| PHY wo crystal |No 125Mhz from PHY|
59 *| | | 25MHz | 50MHz | |
60 * ---------------------------------------------------------------------------
61 *| MII | - | eth-ck | n/a | n/a |
63 * ---------------------------------------------------------------------------
64 *| GMII | - | eth-ck | n/a | n/a |
66 * ---------------------------------------------------------------------------
67 *| RGMII | - | eth-ck | n/a | eth-ck (no pin) |
68 *| | | | | st,eth-clk-sel |
69 * ---------------------------------------------------------------------------
70 *| RMII | - | eth-ck | eth-ck | n/a |
71 *| | | | st,eth-ref-clk-sel | |
72 * ---------------------------------------------------------------------------
74 * BIT(17) : set this bit in RMII mode when you have PHY without crystal 50MHz
75 * BIT(16) : set this bit in GMII/RGMII PHY when you do not want use 125Mhz
77 *-----------------------------------------------------
78 * src | BIT(17) | BIT(16) |
79 *-----------------------------------------------------
81 *-----------------------------------------------------
82 * GMII | n/a | st,eth-clk-sel |
83 *-----------------------------------------------------
84 * RGMII | n/a | st,eth-clk-sel |
85 *-----------------------------------------------------
86 * RMII | st,eth-ref-clk-sel | n/a |
87 *-----------------------------------------------------
94 struct clk *clk_eth_ck;
95 struct clk *clk_ethstp;
96 struct clk *syscfg_clk;
98 int eth_ref_clk_sel_reg;
100 u32 mode_reg; /* MAC glue-logic mode register */
101 struct regmap *regmap;
103 const struct stm32_ops *ops;
108 int (*set_mode)(struct plat_stmmacenet_data *plat_dat);
109 int (*clk_prepare)(struct stm32_dwmac *dwmac, bool prepare);
110 int (*suspend)(struct stm32_dwmac *dwmac);
111 void (*resume)(struct stm32_dwmac *dwmac);
112 int (*parse_data)(struct stm32_dwmac *dwmac,
117 static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
119 struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
122 if (dwmac->ops->set_mode) {
123 ret = dwmac->ops->set_mode(plat_dat);
128 ret = clk_prepare_enable(dwmac->clk_tx);
132 if (!dwmac->dev->power.is_suspended) {
133 ret = clk_prepare_enable(dwmac->clk_rx);
135 clk_disable_unprepare(dwmac->clk_tx);
140 if (dwmac->ops->clk_prepare) {
141 ret = dwmac->ops->clk_prepare(dwmac, true);
143 clk_disable_unprepare(dwmac->clk_rx);
144 clk_disable_unprepare(dwmac->clk_tx);
151 static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare)
156 ret = clk_prepare_enable(dwmac->syscfg_clk);
160 if (dwmac->clk_eth_ck) {
161 ret = clk_prepare_enable(dwmac->clk_eth_ck);
163 clk_disable_unprepare(dwmac->syscfg_clk);
168 clk_disable_unprepare(dwmac->syscfg_clk);
169 if (dwmac->clk_eth_ck)
170 clk_disable_unprepare(dwmac->clk_eth_ck);
175 static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
177 struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
178 u32 reg = dwmac->mode_reg;
181 switch (plat_dat->interface) {
182 case PHY_INTERFACE_MODE_MII:
183 val = SYSCFG_PMCR_ETH_SEL_MII;
184 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
186 case PHY_INTERFACE_MODE_GMII:
187 val = SYSCFG_PMCR_ETH_SEL_GMII;
188 if (dwmac->eth_clk_sel_reg)
189 val |= SYSCFG_PMCR_ETH_CLK_SEL;
190 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
192 case PHY_INTERFACE_MODE_RMII:
193 val = SYSCFG_PMCR_ETH_SEL_RMII;
194 if (dwmac->eth_ref_clk_sel_reg)
195 val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
196 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
198 case PHY_INTERFACE_MODE_RGMII:
199 case PHY_INTERFACE_MODE_RGMII_ID:
200 case PHY_INTERFACE_MODE_RGMII_RXID:
201 case PHY_INTERFACE_MODE_RGMII_TXID:
202 val = SYSCFG_PMCR_ETH_SEL_RGMII;
203 if (dwmac->eth_clk_sel_reg)
204 val |= SYSCFG_PMCR_ETH_CLK_SEL;
205 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
208 pr_debug("SYSCFG init : Do not manage %d interface\n",
209 plat_dat->interface);
210 /* Do not manage others interfaces */
214 /* Need to update PMCCLRR (clear register) */
215 ret = regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
216 dwmac->ops->syscfg_eth_mask);
218 /* Update PMCSETR (set register) */
219 return regmap_update_bits(dwmac->regmap, reg,
220 dwmac->ops->syscfg_eth_mask, val);
223 static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
225 struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
226 u32 reg = dwmac->mode_reg;
229 switch (plat_dat->interface) {
230 case PHY_INTERFACE_MODE_MII:
231 val = SYSCFG_MCU_ETH_SEL_MII;
232 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
234 case PHY_INTERFACE_MODE_RMII:
235 val = SYSCFG_MCU_ETH_SEL_RMII;
236 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
239 pr_debug("SYSCFG init : Do not manage %d interface\n",
240 plat_dat->interface);
241 /* Do not manage others interfaces */
245 return regmap_update_bits(dwmac->regmap, reg,
246 dwmac->ops->syscfg_eth_mask, val << 23);
249 static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac)
251 clk_disable_unprepare(dwmac->clk_tx);
252 clk_disable_unprepare(dwmac->clk_rx);
254 if (dwmac->ops->clk_prepare)
255 dwmac->ops->clk_prepare(dwmac, false);
258 static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
261 struct device_node *np = dev->of_node;
264 /* Get TX/RX clocks */
265 dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx");
266 if (IS_ERR(dwmac->clk_tx)) {
267 dev_err(dev, "No ETH Tx clock provided...\n");
268 return PTR_ERR(dwmac->clk_tx);
271 dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx");
272 if (IS_ERR(dwmac->clk_rx)) {
273 dev_err(dev, "No ETH Rx clock provided...\n");
274 return PTR_ERR(dwmac->clk_rx);
277 if (dwmac->ops->parse_data) {
278 err = dwmac->ops->parse_data(dwmac, dev);
283 /* Get mode register */
284 dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon");
285 if (IS_ERR(dwmac->regmap))
286 return PTR_ERR(dwmac->regmap);
288 err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg);
290 dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);
295 static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
298 struct platform_device *pdev = to_platform_device(dev);
299 struct device_node *np = dev->of_node;
302 /* Gigabit Ethernet 125MHz clock selection. */
303 dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel");
305 /* Ethernet 50Mhz RMII clock selection */
306 dwmac->eth_ref_clk_sel_reg =
307 of_property_read_bool(np, "st,eth-ref-clk-sel");
309 /* Get ETH_CLK clocks */
310 dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck");
311 if (IS_ERR(dwmac->clk_eth_ck)) {
312 dev_warn(dev, "No phy clock provided...\n");
313 dwmac->clk_eth_ck = NULL;
316 /* Clock used for low power mode */
317 dwmac->clk_ethstp = devm_clk_get(dev, "ethstp");
318 if (IS_ERR(dwmac->clk_ethstp)) {
320 "No ETH peripheral clock provided for CStop mode ...\n");
321 return PTR_ERR(dwmac->clk_ethstp);
324 /* Clock for sysconfig */
325 dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk");
326 if (IS_ERR(dwmac->syscfg_clk)) {
327 dev_err(dev, "No syscfg clock provided...\n");
328 return PTR_ERR(dwmac->syscfg_clk);
331 /* Get IRQ information early to have an ability to ask for deferred
332 * probe if needed before we went too far with resource allocation.
334 dwmac->irq_pwr_wakeup = platform_get_irq_byname(pdev,
336 if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) {
337 err = device_init_wakeup(&pdev->dev, true);
339 dev_err(&pdev->dev, "Failed to init wake up irq\n");
342 err = dev_pm_set_dedicated_wake_irq(&pdev->dev,
343 dwmac->irq_pwr_wakeup);
345 dev_err(&pdev->dev, "Failed to set wake up irq\n");
346 device_init_wakeup(&pdev->dev, false);
348 device_set_wakeup_enable(&pdev->dev, false);
353 static int stm32_dwmac_probe(struct platform_device *pdev)
355 struct plat_stmmacenet_data *plat_dat;
356 struct stmmac_resources stmmac_res;
357 struct stm32_dwmac *dwmac;
358 const struct stm32_ops *data;
361 ret = stmmac_get_platform_resources(pdev, &stmmac_res);
365 plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
366 if (IS_ERR(plat_dat))
367 return PTR_ERR(plat_dat);
369 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
372 goto err_remove_config_dt;
375 data = of_device_get_match_data(&pdev->dev);
377 dev_err(&pdev->dev, "no of match data provided\n");
379 goto err_remove_config_dt;
383 dwmac->dev = &pdev->dev;
385 ret = stm32_dwmac_parse_data(dwmac, &pdev->dev);
387 dev_err(&pdev->dev, "Unable to parse OF data\n");
388 goto err_remove_config_dt;
391 plat_dat->bsp_priv = dwmac;
393 ret = stm32_dwmac_init(plat_dat);
395 goto err_remove_config_dt;
397 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
399 goto err_clk_disable;
404 stm32_dwmac_clk_disable(dwmac);
405 err_remove_config_dt:
406 stmmac_remove_config_dt(pdev, plat_dat);
411 static int stm32_dwmac_remove(struct platform_device *pdev)
413 struct net_device *ndev = platform_get_drvdata(pdev);
414 struct stmmac_priv *priv = netdev_priv(ndev);
415 int ret = stmmac_dvr_remove(&pdev->dev);
416 struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
418 stm32_dwmac_clk_disable(priv->plat->bsp_priv);
420 if (dwmac->irq_pwr_wakeup >= 0) {
421 dev_pm_clear_wake_irq(&pdev->dev);
422 device_init_wakeup(&pdev->dev, false);
428 static int stm32mp1_suspend(struct stm32_dwmac *dwmac)
432 ret = clk_prepare_enable(dwmac->clk_ethstp);
436 clk_disable_unprepare(dwmac->clk_tx);
437 clk_disable_unprepare(dwmac->syscfg_clk);
438 if (dwmac->clk_eth_ck)
439 clk_disable_unprepare(dwmac->clk_eth_ck);
444 static void stm32mp1_resume(struct stm32_dwmac *dwmac)
446 clk_disable_unprepare(dwmac->clk_ethstp);
449 static int stm32mcu_suspend(struct stm32_dwmac *dwmac)
451 clk_disable_unprepare(dwmac->clk_tx);
452 clk_disable_unprepare(dwmac->clk_rx);
457 #ifdef CONFIG_PM_SLEEP
458 static int stm32_dwmac_suspend(struct device *dev)
460 struct net_device *ndev = dev_get_drvdata(dev);
461 struct stmmac_priv *priv = netdev_priv(ndev);
462 struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
466 ret = stmmac_suspend(dev);
468 if (dwmac->ops->suspend)
469 ret = dwmac->ops->suspend(dwmac);
474 static int stm32_dwmac_resume(struct device *dev)
476 struct net_device *ndev = dev_get_drvdata(dev);
477 struct stmmac_priv *priv = netdev_priv(ndev);
478 struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
481 if (dwmac->ops->resume)
482 dwmac->ops->resume(dwmac);
484 ret = stm32_dwmac_init(priv->plat);
488 ret = stmmac_resume(dev);
492 #endif /* CONFIG_PM_SLEEP */
494 static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
495 stm32_dwmac_suspend, stm32_dwmac_resume);
497 static struct stm32_ops stm32mcu_dwmac_data = {
498 .set_mode = stm32mcu_set_mode,
499 .suspend = stm32mcu_suspend,
500 .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
503 static struct stm32_ops stm32mp1_dwmac_data = {
504 .set_mode = stm32mp1_set_mode,
505 .clk_prepare = stm32mp1_clk_prepare,
506 .suspend = stm32mp1_suspend,
507 .resume = stm32mp1_resume,
508 .parse_data = stm32mp1_parse_data,
509 .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK
512 static const struct of_device_id stm32_dwmac_match[] = {
513 { .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
514 { .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
517 MODULE_DEVICE_TABLE(of, stm32_dwmac_match);
519 static struct platform_driver stm32_dwmac_driver = {
520 .probe = stm32_dwmac_probe,
521 .remove = stm32_dwmac_remove,
523 .name = "stm32-dwmac",
524 .pm = &stm32_dwmac_pm_ops,
525 .of_match_table = stm32_dwmac_match,
528 module_platform_driver(stm32_dwmac_driver);
530 MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@gmail.com>");
531 MODULE_AUTHOR("Christophe Roullier <christophe.roullier@st.com>");
532 MODULE_DESCRIPTION("STMicroelectronics STM32 DWMAC Specific Glue layer");
533 MODULE_LICENSE("GPL v2");