File Index
Files and directories
Sign in
FILE

dwmac-stm32.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU
  4 *
  5 * Copyright (C) STMicroelectronics SA 2017
  6 * Author:  Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
  7 */
  8
  9#include <linux/clk.h>
 10#include <linux/kernel.h>
 11#include <linux/mfd/syscon.h>
 12#include <linux/module.h>
 13#include <linux/of.h>
 14#include <linux/of_net.h>
 15#include <linux/phy.h>
 16#include <linux/platform_device.h>
 17#include <linux/pm_wakeirq.h>
 18#include <linux/regmap.h>
 19#include <linux/slab.h>
 20#include <linux/stmmac.h>
 21
 22#include "stmmac_platform.h"
 23
 24#define SYSCFG_MCU_ETH_MASK		BIT(23)
 25#define SYSCFG_MP1_ETH_MASK		GENMASK(23, 16)
 26#define SYSCFG_PMCCLRR_OFFSET		0x40
 27
 28#define SYSCFG_PMCR_ETH_CLK_SEL		BIT(16)
 29#define SYSCFG_PMCR_ETH_REF_CLK_SEL	BIT(17)
 30
 31/* CLOCK feed to PHY*/
 32#define ETH_CK_F_25M	25000000
 33#define ETH_CK_F_50M	50000000
 34#define ETH_CK_F_125M	125000000
 35
 36/*  Ethernet PHY interface selection in register SYSCFG Configuration
 37 *------------------------------------------
 38 * src	 |BIT(23)| BIT(22)| BIT(21)|BIT(20)|
 39 *------------------------------------------
 40 * MII   |   0	 |   0	  |   0    |   1   |
 41 *------------------------------------------
 42 * GMII  |   0	 |   0	  |   0    |   0   |
 43 *------------------------------------------
 44 * RGMII |   0	 |   0	  |   1	   |  n/a  |
 45 *------------------------------------------
 46 * RMII  |   1	 |   0	  |   0	   |  n/a  |
 47 *------------------------------------------
 48 */
 49#define SYSCFG_PMCR_ETH_SEL_MII		BIT(20)
 50#define SYSCFG_PMCR_PHY_INTF_SEL_MASK	GENMASK(23, 21)
 51#define SYSCFG_MCU_ETH_SEL_MII		0
 52#define SYSCFG_MCU_ETH_SEL_RMII		1
 53
 54/* STM32MP2 register definitions */
 55#define SYSCFG_MP2_ETH_MASK		GENMASK(31, 0)
 56
 57#define SYSCFG_ETHCR_ETH_SEL_MASK	GENMASK(6, 4)
 58#define SYSCFG_ETHCR_ETH_PTP_CLK_SEL	BIT(2)
 59#define SYSCFG_ETHCR_ETH_CLK_SEL	BIT(1)
 60#define SYSCFG_ETHCR_ETH_REF_CLK_SEL	BIT(0)
 61
 62/* STM32MPx register definitions
 63 *
 64 * Below table summarizes the clock requirement and clock sources for
 65 * supported phy interface modes.
 66 * __________________________________________________________________________
 67 *|PHY_MODE | Normal | PHY wo crystal|   PHY wo crystal   |No 125MHz from PHY|
 68 *|         |        |      25MHz    |        50MHz       |                  |
 69 * ---------------------------------------------------------------------------
 70 *|  MII    |	 -   |     eth-ck    |	      n/a	  |	  n/a        |
 71 *|         |        | st,ext-phyclk |                    |		     |
 72 * ---------------------------------------------------------------------------
 73 *|  GMII   |	 -   |     eth-ck    |	      n/a	  |	  n/a        |
 74 *|         |        | st,ext-phyclk |                    |		     |
 75 * ---------------------------------------------------------------------------
 76 *| RGMII   |	 -   |     eth-ck    |	      n/a	  |      eth-ck      |
 77 *|         |        | st,ext-phyclk |                    | st,eth-clk-sel or|
 78 *|         |        |               |                    | st,ext-phyclk    |
 79 * ---------------------------------------------------------------------------
 80 *| RMII    |	 -   |     eth-ck    |	    eth-ck        |	  n/a        |
 81 *|         |        | st,ext-phyclk | st,eth-ref-clk-sel |		     |
 82 *|         |        |               | or st,ext-phyclk   |		     |
 83 * ---------------------------------------------------------------------------
 84 *
 85 */
 86
 87struct stm32_dwmac {
 88	struct clk *clk_tx;
 89	struct clk *clk_rx;
 90	struct clk *clk_eth_ck;
 91	struct clk *clk_ethstp;
 92	struct clk *syscfg_clk;
 93	int ext_phyclk;
 94	int enable_eth_ck;
 95	int eth_clk_sel_reg;
 96	int eth_ref_clk_sel_reg;
 97	int irq_pwr_wakeup;
 98	u32 mode_reg;		 /* MAC glue-logic mode register */
 99	u32 mode_mask;
100	struct regmap *regmap;
101	u32 speed;
102	const struct stm32_ops *ops;
103	struct device *dev;
104};
105
106struct stm32_ops {
107	int (*set_mode)(struct plat_stmmacenet_data *plat_dat);
108	int (*suspend)(struct stm32_dwmac *dwmac);
109	void (*resume)(struct stm32_dwmac *dwmac);
110	int (*parse_data)(struct stm32_dwmac *dwmac,
111			  struct device *dev);
112	bool clk_rx_enable_in_suspend;
113	bool is_mp13, is_mp2;
114	u32 syscfg_clr_off;
115};
116
117static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac)
118{
119	int ret;
120
121	ret = clk_prepare_enable(dwmac->clk_tx);
122	if (ret)
123		goto err_clk_tx;
124
125	ret = clk_prepare_enable(dwmac->clk_rx);
126	if (ret)
127		goto err_clk_rx;
128
129	ret = clk_prepare_enable(dwmac->syscfg_clk);
130	if (ret)
131		goto err_syscfg_clk;
132
133	if (dwmac->enable_eth_ck) {
134		ret = clk_prepare_enable(dwmac->clk_eth_ck);
135		if (ret)
136			goto err_clk_eth_ck;
137	}
138
139	return ret;
140
141err_clk_eth_ck:
142	clk_disable_unprepare(dwmac->syscfg_clk);
143err_syscfg_clk:
144	clk_disable_unprepare(dwmac->clk_rx);
145err_clk_rx:
146	clk_disable_unprepare(dwmac->clk_tx);
147err_clk_tx:
148	return ret;
149}
150
151static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
152{
153	struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
154	int ret;
155
156	if (dwmac->ops->set_mode) {
157		ret = dwmac->ops->set_mode(plat_dat);
158		if (ret)
159			return ret;
160	}
161
162	return stm32_dwmac_clk_enable(dwmac);
163}
164
165static int stm32mp1_select_ethck_external(struct plat_stmmacenet_data *plat_dat)
166{
167	struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
168
169	switch (plat_dat->phy_interface) {
170	case PHY_INTERFACE_MODE_MII:
171		dwmac->enable_eth_ck = dwmac->ext_phyclk;
172		return 0;
173	case PHY_INTERFACE_MODE_GMII:
174		dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg ||
175				       dwmac->ext_phyclk;
176		return 0;
177	case PHY_INTERFACE_MODE_RMII:
178		dwmac->enable_eth_ck = dwmac->eth_ref_clk_sel_reg ||
179				       dwmac->ext_phyclk;
180		return 0;
181	case PHY_INTERFACE_MODE_RGMII:
182	case PHY_INTERFACE_MODE_RGMII_ID:
183	case PHY_INTERFACE_MODE_RGMII_RXID:
184	case PHY_INTERFACE_MODE_RGMII_TXID:
185		dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg ||
186				       dwmac->ext_phyclk;
187		return 0;
188	default:
189		dwmac->enable_eth_ck = false;
190		dev_err(dwmac->dev, "Mode %s not supported",
191			phy_modes(plat_dat->phy_interface));
192		return -EINVAL;
193	}
194}
195
196static int stm32mp1_validate_ethck_rate(struct plat_stmmacenet_data *plat_dat)
197{
198	struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
199	const u32 clk_rate = clk_get_rate(dwmac->clk_eth_ck);
200
201	if (!dwmac->enable_eth_ck)
202		return 0;
203
204	switch (plat_dat->phy_interface) {
205	case PHY_INTERFACE_MODE_MII:
206	case PHY_INTERFACE_MODE_GMII:
207		if (clk_rate == ETH_CK_F_25M)
208			return 0;
209		break;
210	case PHY_INTERFACE_MODE_RMII:
211		if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M)
212			return 0;
213		break;
214	case PHY_INTERFACE_MODE_RGMII:
215	case PHY_INTERFACE_MODE_RGMII_ID:
216	case PHY_INTERFACE_MODE_RGMII_RXID:
217	case PHY_INTERFACE_MODE_RGMII_TXID:
218		if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M)
219			return 0;
220		break;
221	default:
222		break;
223	}
224
225	dev_err(dwmac->dev, "Mode %s does not match eth-ck frequency %d Hz",
226		phy_modes(plat_dat->phy_interface), clk_rate);
227	return -EINVAL;
228}
229
230static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat,
231				   u8 phy_intf_sel)
232{
233	struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
234	u32 reg = dwmac->mode_reg;
235	int val;
236
237	val = FIELD_PREP(SYSCFG_PMCR_PHY_INTF_SEL_MASK, phy_intf_sel);
238
239	switch (plat_dat->phy_interface) {
240	case PHY_INTERFACE_MODE_MII:
241		/*
242		 * STM32MP15xx supports both MII and GMII, STM32MP13xx MII only.
243		 * SYSCFG_PMCSETR ETH_SELMII is present only on STM32MP15xx and
244		 * acts as a selector between 0:GMII and 1:MII. As STM32MP13xx
245		 * supports only MII, ETH_SELMII is not present.
246		 */
247		if (!dwmac->ops->is_mp13)  /* Select MII mode on STM32MP15xx */
248			val |= SYSCFG_PMCR_ETH_SEL_MII;
249		break;
250	case PHY_INTERFACE_MODE_GMII:
251		if (dwmac->enable_eth_ck)
252			val |= SYSCFG_PMCR_ETH_CLK_SEL;
253		break;
254	case PHY_INTERFACE_MODE_RMII:
255		if (dwmac->enable_eth_ck)
256			val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
257		break;
258	case PHY_INTERFACE_MODE_RGMII:
259	case PHY_INTERFACE_MODE_RGMII_ID:
260	case PHY_INTERFACE_MODE_RGMII_RXID:
261	case PHY_INTERFACE_MODE_RGMII_TXID:
262		if (dwmac->enable_eth_ck)
263			val |= SYSCFG_PMCR_ETH_CLK_SEL;
264		break;
265	default:
266		dev_err(dwmac->dev, "Mode %s not supported",
267			phy_modes(plat_dat->phy_interface));
268		/* Do not manage others interfaces */
269		return -EINVAL;
270	}
271
272	dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->phy_interface));
273
274	/* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
275	val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);
276
277	/* Need to update PMCCLRR (clear register) */
278	regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
279		     dwmac->mode_mask);
280
281	/* Update PMCSETR (set register) */
282	return regmap_update_bits(dwmac->regmap, reg,
283				 dwmac->mode_mask, val);
284}
285
286static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data *plat_dat,
287				     u8 phy_intf_sel)
288{
289	struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
290	u32 reg = dwmac->mode_reg;
291	int val;
292
293	val = FIELD_PREP(SYSCFG_ETHCR_ETH_SEL_MASK, phy_intf_sel);
294
295	switch (plat_dat->phy_interface) {
296	case PHY_INTERFACE_MODE_MII:
297		/* ETH_REF_CLK_SEL bit in SYSCFG register is not applicable in MII mode */
298		break;
299	case PHY_INTERFACE_MODE_RMII:
300		if (dwmac->enable_eth_ck) {
301			/* Internal clock ETH_CLK of 50MHz from RCC is used */
302			val |= SYSCFG_ETHCR_ETH_REF_CLK_SEL;
303		}
304		break;
305	case PHY_INTERFACE_MODE_RGMII:
306	case PHY_INTERFACE_MODE_RGMII_ID:
307	case PHY_INTERFACE_MODE_RGMII_RXID:
308	case PHY_INTERFACE_MODE_RGMII_TXID:
309	case PHY_INTERFACE_MODE_GMII:
310		if (dwmac->enable_eth_ck) {
311			/* Internal clock ETH_CLK of 125MHz from RCC is used */
312			val |= SYSCFG_ETHCR_ETH_CLK_SEL;
313		}
314		break;
315	default:
316		dev_err(dwmac->dev, "Mode %s not supported",
317			phy_modes(plat_dat->phy_interface));
318		/* Do not manage others interfaces */
319		return -EINVAL;
320	}
321
322	dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->phy_interface));
323
324	/* Select PTP (IEEE1588) clock selection from RCC (ck_ker_ethxptp) */
325	val |= SYSCFG_ETHCR_ETH_PTP_CLK_SEL;
326
327	/* Update ETHCR (set register) */
328	return regmap_update_bits(dwmac->regmap, reg,
329				 SYSCFG_MP2_ETH_MASK, val);
330}
331
332static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
333{
334	struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
335	int phy_intf_sel, ret;
336
337	ret = stm32mp1_select_ethck_external(plat_dat);
338	if (ret)
339		return ret;
340
341	ret = stm32mp1_validate_ethck_rate(plat_dat);
342	if (ret)
343		return ret;
344
345	phy_intf_sel = stmmac_get_phy_intf_sel(plat_dat->phy_interface);
346	if (phy_intf_sel != PHY_INTF_SEL_GMII_MII &&
347	    phy_intf_sel != PHY_INTF_SEL_RGMII &&
348	    phy_intf_sel != PHY_INTF_SEL_RMII) {
349		dev_err(dwmac->dev, "Mode %s not supported\n",
350			phy_modes(plat_dat->phy_interface));
351		return phy_intf_sel < 0 ? phy_intf_sel : -EINVAL;
352	}
353
354	if (!dwmac->ops->is_mp2)
355		return stm32mp1_configure_pmcr(plat_dat, phy_intf_sel);
356	else
357		return stm32mp2_configure_syscfg(plat_dat, phy_intf_sel);
358}
359
360static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
361{
362	struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
363	u32 reg = dwmac->mode_reg;
364	int val;
365
366	switch (plat_dat->phy_interface) {
367	case PHY_INTERFACE_MODE_MII:
368		val = SYSCFG_MCU_ETH_SEL_MII;
369		break;
370	case PHY_INTERFACE_MODE_RMII:
371		val = SYSCFG_MCU_ETH_SEL_RMII;
372		break;
373	default:
374		dev_err(dwmac->dev, "Mode %s not supported",
375			phy_modes(plat_dat->phy_interface));
376		/* Do not manage others interfaces */
377		return -EINVAL;
378	}
379
380	dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->phy_interface));
381
382	return regmap_update_bits(dwmac->regmap, reg,
383				 SYSCFG_MCU_ETH_MASK, val << 23);
384}
385
386static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac)
387{
388	clk_disable_unprepare(dwmac->clk_tx);
389	clk_disable_unprepare(dwmac->clk_rx);
390	clk_disable_unprepare(dwmac->syscfg_clk);
391	if (dwmac->enable_eth_ck)
392		clk_disable_unprepare(dwmac->clk_eth_ck);
393}
394
395static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
396				  struct device *dev)
397{
398	struct device_node *np = dev->of_node;
399	int err;
400
401	/*  Get TX/RX clocks */
402	dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx");
403	if (IS_ERR(dwmac->clk_tx)) {
404		dev_err(dev, "No ETH Tx clock provided...\n");
405		return PTR_ERR(dwmac->clk_tx);
406	}
407
408	dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx");
409	if (IS_ERR(dwmac->clk_rx)) {
410		dev_err(dev, "No ETH Rx clock provided...\n");
411		return PTR_ERR(dwmac->clk_rx);
412	}
413
414	if (dwmac->ops->parse_data) {
415		err = dwmac->ops->parse_data(dwmac, dev);
416		if (err)
417			return err;
418	}
419
420	/* Get mode register */
421	dwmac->regmap = syscon_regmap_lookup_by_phandle_args(np, "st,syscon",
422							     1, &dwmac->mode_reg);
423	if (IS_ERR(dwmac->regmap))
424		return PTR_ERR(dwmac->regmap);
425
426	if (dwmac->ops->is_mp2)
427		return 0;
428
429	dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
430	err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
431	if (err) {
432		if (dwmac->ops->is_mp13) {
433			dev_err(dev, "Sysconfig register mask must be set (%d)\n", err);
434		} else {
435			dev_dbg(dev, "Warning sysconfig register mask not set\n");
436			err = 0;
437		}
438	}
439
440	return err;
441}
442
443static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
444			       struct device *dev)
445{
446	struct platform_device *pdev = to_platform_device(dev);
447	struct device_node *np = dev->of_node;
448	int err = 0;
449
450	/* Ethernet PHY have no crystal */
451	dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
452
453	/* Gigabit Ethernet 125MHz clock selection. */
454	dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel");
455
456	/* Ethernet 50MHz RMII clock selection */
457	dwmac->eth_ref_clk_sel_reg =
458		of_property_read_bool(np, "st,eth-ref-clk-sel");
459
460	/*  Get ETH_CLK clocks */
461	dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck");
462	if (IS_ERR(dwmac->clk_eth_ck)) {
463		dev_info(dev, "No phy clock provided...\n");
464		dwmac->clk_eth_ck = NULL;
465	}
466
467	/*  Clock used for low power mode */
468	dwmac->clk_ethstp = devm_clk_get(dev, "ethstp");
469	if (IS_ERR(dwmac->clk_ethstp)) {
470		dev_err(dev,
471			"No ETH peripheral clock provided for CStop mode ...\n");
472		return PTR_ERR(dwmac->clk_ethstp);
473	}
474
475	/*  Optional Clock for sysconfig */
476	dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk");
477	if (IS_ERR(dwmac->syscfg_clk))
478		dwmac->syscfg_clk = NULL;
479
480	/* Get IRQ information early to have an ability to ask for deferred
481	 * probe if needed before we went too far with resource allocation.
482	 */
483	dwmac->irq_pwr_wakeup = platform_get_irq_byname_optional(pdev,
484							"stm32_pwr_wakeup");
485	if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER)
486		return -EPROBE_DEFER;
487
488	if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) {
489		err = device_init_wakeup(&pdev->dev, true);
490		if (err) {
491			dev_err(&pdev->dev, "Failed to init wake up irq\n");
492			return err;
493		}
494		err = dev_pm_set_dedicated_wake_irq(&pdev->dev,
495						    dwmac->irq_pwr_wakeup);
496		if (err) {
497			dev_err(&pdev->dev, "Failed to set wake up irq\n");
498			device_init_wakeup(&pdev->dev, false);
499		}
500		device_set_wakeup_enable(&pdev->dev, false);
501	}
502	return err;
503}
504
505static int stm32_dwmac_suspend(struct device *dev, void *bsp_priv)
506{
507	struct stm32_dwmac *dwmac = bsp_priv;
508
509	stm32_dwmac_clk_disable(dwmac);
510
511	return dwmac->ops->suspend ? dwmac->ops->suspend(dwmac) : 0;
512}
513
514static int stm32_dwmac_resume(struct device *dev, void *bsp_priv)
515{
516	struct stmmac_priv *priv = netdev_priv(dev_get_drvdata(dev));
517	struct stm32_dwmac *dwmac = bsp_priv;
518
519	if (dwmac->ops->resume)
520		dwmac->ops->resume(dwmac);
521
522	return stm32_dwmac_init(priv->plat);
523}
524
525static int stm32_dwmac_probe(struct platform_device *pdev)
526{
527	struct plat_stmmacenet_data *plat_dat;
528	struct stmmac_resources stmmac_res;
529	struct stm32_dwmac *dwmac;
530	const struct stm32_ops *data;
531	int ret;
532
533	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
534	if (ret)
535		return ret;
536
537	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
538	if (IS_ERR(plat_dat))
539		return PTR_ERR(plat_dat);
540
541	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
542	if (!dwmac)
543		return -ENOMEM;
544
545	data = of_device_get_match_data(&pdev->dev);
546	if (!data) {
547		dev_err(&pdev->dev, "no of match data provided\n");
548		return -EINVAL;
549	}
550
551	dwmac->ops = data;
552	dwmac->dev = &pdev->dev;
553
554	ret = stm32_dwmac_parse_data(dwmac, &pdev->dev);
555	if (ret) {
556		dev_err(&pdev->dev, "Unable to parse OF data\n");
557		return ret;
558	}
559
560	plat_dat->flags |= STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP;
561	plat_dat->bsp_priv = dwmac;
562	plat_dat->suspend = stm32_dwmac_suspend;
563	plat_dat->resume = stm32_dwmac_resume;
564
565	ret = stm32_dwmac_init(plat_dat);
566	if (ret)
567		return ret;
568
569	/* If this platform requires the clock to be running in suspend,
570	 * prepare and enable the receive clock an additional time to keep
571	 * it running.
572	 */
573	if (dwmac->ops->clk_rx_enable_in_suspend) {
574		ret = clk_prepare_enable(dwmac->clk_rx);
575		if (ret)
576			goto err_clk_disable;
577	}
578
579	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
580	if (ret)
581		goto err_clk_disable_suspend;
582
583	return 0;
584
585err_clk_disable_suspend:
586	if (dwmac->ops->clk_rx_enable_in_suspend)
587		clk_disable_unprepare(dwmac->clk_rx);
588
589err_clk_disable:
590	stm32_dwmac_clk_disable(dwmac);
591
592	return ret;
593}
594
595static void stm32_dwmac_remove(struct platform_device *pdev)
596{
597	struct net_device *ndev = platform_get_drvdata(pdev);
598	struct stmmac_priv *priv = netdev_priv(ndev);
599	struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
600
601	stmmac_dvr_remove(&pdev->dev);
602
603	/* If this platform requires the clock to be running in suspend,
604	 * we need to disable and unprepare the receive clock an additional
605	 * time to balance the extra clk_prepare_enable() in the probe
606	 * function.
607	 */
608	if (dwmac->ops->clk_rx_enable_in_suspend)
609		clk_disable_unprepare(dwmac->clk_rx);
610
611	stm32_dwmac_clk_disable(dwmac);
612
613	if (dwmac->irq_pwr_wakeup >= 0) {
614		dev_pm_clear_wake_irq(&pdev->dev);
615		device_init_wakeup(&pdev->dev, false);
616	}
617}
618
619static int stm32mp1_suspend(struct stm32_dwmac *dwmac)
620{
621	return clk_prepare_enable(dwmac->clk_ethstp);
622}
623
624static void stm32mp1_resume(struct stm32_dwmac *dwmac)
625{
626	clk_disable_unprepare(dwmac->clk_ethstp);
627}
628
629static struct stm32_ops stm32mcu_dwmac_data = {
630	.set_mode = stm32mcu_set_mode
631};
632
633static struct stm32_ops stm32mp1_dwmac_data = {
634	.set_mode = stm32mp1_set_mode,
635	.suspend = stm32mp1_suspend,
636	.resume = stm32mp1_resume,
637	.parse_data = stm32mp1_parse_data,
638	.syscfg_clr_off = 0x44,
639	.is_mp13 = false,
640	.clk_rx_enable_in_suspend = true
641};
642
643static struct stm32_ops stm32mp13_dwmac_data = {
644	.set_mode = stm32mp1_set_mode,
645	.suspend = stm32mp1_suspend,
646	.resume = stm32mp1_resume,
647	.parse_data = stm32mp1_parse_data,
648	.syscfg_clr_off = 0x08,
649	.is_mp13 = true,
650	.clk_rx_enable_in_suspend = true
651};
652
653static struct stm32_ops stm32mp25_dwmac_data = {
654	.set_mode = stm32mp1_set_mode,
655	.suspend = stm32mp1_suspend,
656	.resume = stm32mp1_resume,
657	.parse_data = stm32mp1_parse_data,
658	.is_mp2 = true,
659	.clk_rx_enable_in_suspend = true
660};
661
662static const struct of_device_id stm32_dwmac_match[] = {
663	{ .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
664	{ .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
665	{ .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data},
666	{ .compatible = "st,stm32mp25-dwmac", .data = &stm32mp25_dwmac_data},
667	{ }
668};
669MODULE_DEVICE_TABLE(of, stm32_dwmac_match);
670
671static struct platform_driver stm32_dwmac_driver = {
672	.probe  = stm32_dwmac_probe,
673	.remove = stm32_dwmac_remove,
674	.driver = {
675		.name           = "stm32-dwmac",
676		.pm		= &stmmac_simple_pm_ops,
677		.of_match_table = stm32_dwmac_match,
678	},
679};
680module_platform_driver(stm32_dwmac_driver);
681
682MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@gmail.com>");
683MODULE_AUTHOR("Christophe Roullier <christophe.roullier@st.com>");
684MODULE_DESCRIPTION("STMicroelectronics STM32 DWMAC Specific Glue layer");
685MODULE_LICENSE("GPL v2");
~/ Read-only file preview.