hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
....@@ -1,24 +1,15 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*******************************************************************************
23 This contains the functions to handle the platform driver.
34
45 Copyright (C) 2007-2011 STMicroelectronics Ltd
56
6
- This program is free software; you can redistribute it and/or modify it
7
- under the terms and conditions of the GNU General Public License,
8
- version 2, as published by the Free Software Foundation.
9
-
10
- This program is distributed in the hope it will be useful, but WITHOUT
11
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
- more details.
14
-
15
- The full GNU General Public License is included in this distribution in
16
- the file called "COPYING".
177
188 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
199 *******************************************************************************/
2010
2111 #include <linux/platform_device.h>
12
+#include <linux/pm_runtime.h>
2213 #include <linux/module.h>
2314 #include <linux/io.h>
2415 #include <linux/of.h>
....@@ -33,6 +24,7 @@
3324
3425 /**
3526 * dwmac1000_validate_mcast_bins - validates the number of Multicast filter bins
27
+ * @dev: struct device of the platform device
3628 * @mcast_bins: Multicast filtering bins
3729 * Description:
3830 * this function validates the number of Multicast filtering bins specified
....@@ -43,7 +35,7 @@
4335 * invalid and will cause the filtering algorithm to use Multicast
4436 * promiscuous mode.
4537 */
46
-static int dwmac1000_validate_mcast_bins(int mcast_bins)
38
+static int dwmac1000_validate_mcast_bins(struct device *dev, int mcast_bins)
4739 {
4840 int x = mcast_bins;
4941
....@@ -54,8 +46,8 @@
5446 break;
5547 default:
5648 x = 0;
57
- pr_info("Hash table entries set to unexpected value %d",
58
- mcast_bins);
49
+ dev_info(dev, "Hash table entries set to unexpected value %d\n",
50
+ mcast_bins);
5951 break;
6052 }
6153 return x;
....@@ -63,6 +55,7 @@
6355
6456 /**
6557 * dwmac1000_validate_ucast_entries - validate the Unicast address entries
58
+ * @dev: struct device of the platform device
6659 * @ucast_entries: number of Unicast address entries
6760 * Description:
6861 * This function validates the number of Unicast address entries supported
....@@ -72,7 +65,8 @@
7265 * selected, and defaults to 1 Unicast address if an unsupported
7366 * configuration is selected.
7467 */
75
-static int dwmac1000_validate_ucast_entries(int ucast_entries)
68
+static int dwmac1000_validate_ucast_entries(struct device *dev,
69
+ int ucast_entries)
7670 {
7771 int x = ucast_entries;
7872
....@@ -83,8 +77,8 @@
8377 break;
8478 default:
8579 x = 1;
86
- pr_info("Unicast table entries set to unexpected value %d\n",
87
- ucast_entries);
80
+ dev_info(dev, "Unicast table entries set to unexpected value %d\n",
81
+ ucast_entries);
8882 break;
8983 }
9084 return x;
....@@ -114,10 +108,10 @@
114108
115109 axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
116110 axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
117
- axi->axi_kbbe = of_property_read_bool(np, "snps,axi_kbbe");
118
- axi->axi_fb = of_property_read_bool(np, "snps,axi_fb");
119
- axi->axi_mb = of_property_read_bool(np, "snps,axi_mb");
120
- axi->axi_rb = of_property_read_bool(np, "snps,axi_rb");
111
+ axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
112
+ axi->axi_fb = of_property_read_bool(np, "snps,fb");
113
+ axi->axi_mb = of_property_read_bool(np, "snps,mb");
114
+ axi->axi_rb = of_property_read_bool(np, "snps,rb");
121115
122116 if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
123117 axi->axi_wr_osr_lmt = 1;
....@@ -132,6 +126,7 @@
132126 /**
133127 * stmmac_mtl_setup - parse DT parameters for multiple queues configuration
134128 * @pdev: platform device
129
+ * @plat: enet data
135130 */
136131 static int stmmac_mtl_setup(struct platform_device *pdev,
137132 struct plat_stmmacenet_data *plat)
....@@ -327,26 +322,11 @@
327322 static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
328323 struct device_node *np, struct device *dev)
329324 {
330
- bool mdio = true;
325
+ bool mdio = !of_phy_is_fixed_link(np);
331326 static const struct of_device_id need_mdio_ids[] = {
332327 { .compatible = "snps,dwc-qos-ethernet-4.10" },
333328 {},
334329 };
335
-
336
- /* If phy-handle property is passed from DT, use it as the PHY */
337
- plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
338
- if (plat->phy_node)
339
- dev_dbg(dev, "Found phy-handle subnode\n");
340
-
341
- /* If phy-handle is not specified, check if we have a fixed-phy */
342
- if (!plat->phy_node && of_phy_is_fixed_link(np)) {
343
- if ((of_phy_register_fixed_link(np) < 0))
344
- return -ENODEV;
345
-
346
- dev_dbg(dev, "Found fixed-link subnode\n");
347
- plat->phy_node = of_node_get(np);
348
- mdio = false;
349
- }
350330
351331 if (of_match_node(need_mdio_ids, np)) {
352332 plat->mdio_node = of_get_child_by_name(np, "mdio");
....@@ -367,11 +347,43 @@
367347 mdio = true;
368348 }
369349
370
- if (mdio)
350
+ if (mdio) {
371351 plat->mdio_bus_data =
372352 devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data),
373353 GFP_KERNEL);
354
+ if (!plat->mdio_bus_data)
355
+ return -ENOMEM;
356
+
357
+ plat->mdio_bus_data->needs_reset = true;
358
+ }
359
+
374360 return 0;
361
+}
362
+
363
+/**
364
+ * stmmac_of_get_mac_mode - retrieves the interface of the MAC
365
+ * @np: - device-tree node
366
+ * Description:
367
+ * Similar to `of_get_phy_mode()`, this function will retrieve (from
368
+ * the device-tree) the interface mode on the MAC side. This assumes
369
+ * that there is mode converter in-between the MAC & PHY
370
+ * (e.g. GMII-to-RGMII).
371
+ */
372
+static int stmmac_of_get_mac_mode(struct device_node *np)
373
+{
374
+ const char *pm;
375
+ int err, i;
376
+
377
+ err = of_property_read_string(np, "mac-mode", &pm);
378
+ if (err < 0)
379
+ return err;
380
+
381
+ for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
382
+ if (!strcasecmp(pm, phy_modes(i)))
383
+ return i;
384
+ }
385
+
386
+ return -ENODEV;
375387 }
376388
377389 /**
....@@ -388,6 +400,7 @@
388400 struct device_node *np = pdev->dev.of_node;
389401 struct plat_stmmacenet_data *plat;
390402 struct stmmac_dma_cfg *dma_cfg;
403
+ int phy_mode;
391404 int rc;
392405
393406 plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
....@@ -395,11 +408,31 @@
395408 return ERR_PTR(-ENOMEM);
396409
397410 *mac = of_get_mac_address(np);
398
- plat->interface = of_get_phy_mode(np);
411
+ if (IS_ERR(*mac)) {
412
+ if (PTR_ERR(*mac) == -EPROBE_DEFER)
413
+ return ERR_CAST(*mac);
414
+
415
+ *mac = NULL;
416
+ }
417
+
418
+ phy_mode = device_get_phy_mode(&pdev->dev);
419
+ if (phy_mode < 0)
420
+ return ERR_PTR(phy_mode);
421
+
422
+ plat->phy_interface = phy_mode;
423
+ plat->interface = stmmac_of_get_mac_mode(np);
424
+ if (plat->interface < 0)
425
+ plat->interface = plat->phy_interface;
426
+
427
+ /* Some wrapper drivers still rely on phy_node. Let's save it while
428
+ * they are not converted to phylink. */
429
+ plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
430
+
431
+ /* PHYLINK automatically parses the phy-handle property */
432
+ plat->phylink_node = np;
399433
400434 /* Get max speed of operation from device tree */
401
- if (of_property_read_u32(np, "max-speed", &plat->max_speed))
402
- plat->max_speed = -1;
435
+ of_property_read_u32(np, "max-speed", &plat->max_speed);
403436
404437 plat->bus_id = of_alias_get_id(np, "ethernet");
405438 if (plat->bus_id < 0)
....@@ -407,6 +440,12 @@
407440
408441 /* Default to phy auto-detection */
409442 plat->phy_addr = -1;
443
+
444
+ /* Default to get clk_csr from stmmac_clk_crs_set(),
445
+ * or get clk_csr from device tree.
446
+ */
447
+ plat->clk_csr = -1;
448
+ of_property_read_u32(np, "clk_csr", &plat->clk_csr);
410449
411450 /* "snps,phy-addr" is not a standard property. Mark it as deprecated
412451 * and warn of its use. Remove this when phy node support is added.
....@@ -422,6 +461,9 @@
422461 of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
423462
424463 of_property_read_u32(np, "rx-fifo-depth", &plat->rx_fifo_size);
464
+
465
+ of_property_read_u32(np, "tx-dma-size", &plat->dma_tx_size);
466
+ of_property_read_u32(np, "rx-dma-size", &plat->dma_rx_size);
425467
426468 plat->force_sf_dma_mode =
427469 of_property_read_bool(np, "snps,force_sf_dma_mode");
....@@ -462,9 +504,9 @@
462504 of_property_read_u32(np, "snps,perfect-filter-entries",
463505 &plat->unicast_filter_entries);
464506 plat->unicast_filter_entries = dwmac1000_validate_ucast_entries(
465
- plat->unicast_filter_entries);
507
+ &pdev->dev, plat->unicast_filter_entries);
466508 plat->multicast_filter_bins = dwmac1000_validate_mcast_bins(
467
- plat->multicast_filter_bins);
509
+ &pdev->dev, plat->multicast_filter_bins);
468510 plat->has_gmac = 1;
469511 plat->pmt = 1;
470512 }
....@@ -479,7 +521,8 @@
479521
480522 if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
481523 of_device_is_compatible(np, "snps,dwmac-4.10a") ||
482
- of_device_is_compatible(np, "snps,dwmac-4.20a")) {
524
+ of_device_is_compatible(np, "snps,dwmac-4.20a") ||
525
+ of_device_is_compatible(np, "snps,dwmac-5.10a")) {
483526 plat->has_gmac4 = 1;
484527 plat->has_gmac = 0;
485528 plat->pmt = 1;
....@@ -519,12 +562,16 @@
519562 dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
520563
521564 plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
522
- if (plat->force_thresh_dma_mode) {
565
+ if (plat->force_thresh_dma_mode && plat->force_sf_dma_mode) {
523566 plat->force_sf_dma_mode = 0;
524
- pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set.");
567
+ dev_warn(&pdev->dev,
568
+ "force_sf_dma_mode is ignored if force_thresh_dma_mode is set.\n");
525569 }
526570
527571 of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
572
+
573
+ if (of_property_read_u32(np, "snps,flow-ctrl", &plat->flow_ctrl))
574
+ plat->flow_ctrl = FLOW_AUTO;
528575
529576 plat->axi = stmmac_axi_setup(pdev);
530577
....@@ -535,13 +582,15 @@
535582 }
536583
537584 /* clock setup */
538
- plat->stmmac_clk = devm_clk_get(&pdev->dev,
539
- STMMAC_RESOURCE_NAME);
540
- if (IS_ERR(plat->stmmac_clk)) {
541
- dev_warn(&pdev->dev, "Cannot get CSR clock\n");
542
- plat->stmmac_clk = NULL;
585
+ if (!of_device_is_compatible(np, "snps,dwc-qos-ethernet-4.10")) {
586
+ plat->stmmac_clk = devm_clk_get(&pdev->dev,
587
+ STMMAC_RESOURCE_NAME);
588
+ if (IS_ERR(plat->stmmac_clk)) {
589
+ dev_warn(&pdev->dev, "Cannot get CSR clock\n");
590
+ plat->stmmac_clk = NULL;
591
+ }
592
+ clk_prepare_enable(plat->stmmac_clk);
543593 }
544
- clk_prepare_enable(plat->stmmac_clk);
545594
546595 plat->pclk = devm_clk_get(&pdev->dev, "pclk_mac");
547596 if (IS_ERR(plat->pclk)) {
....@@ -557,7 +606,7 @@
557606 if (IS_ERR(plat->clk_ptp_ref)) {
558607 plat->clk_ptp_rate = clk_get_rate(plat->stmmac_clk);
559608 plat->clk_ptp_ref = NULL;
560
- dev_warn(&pdev->dev, "PTP uses main clock\n");
609
+ dev_info(&pdev->dev, "PTP uses main clock\n");
561610 } else {
562611 plat->clk_ptp_rate = clk_get_rate(plat->clk_ptp_ref);
563612 dev_dbg(&pdev->dev, "PTP rate %d\n", plat->clk_ptp_rate);
....@@ -593,10 +642,8 @@
593642 void stmmac_remove_config_dt(struct platform_device *pdev,
594643 struct plat_stmmacenet_data *plat)
595644 {
596
- struct device_node *np = pdev->dev.of_node;
597
-
598
- if (of_phy_is_fixed_link(np))
599
- of_phy_deregister_fixed_link(np);
645
+ clk_disable_unprepare(plat->stmmac_clk);
646
+ clk_disable_unprepare(plat->pclk);
600647 of_node_put(plat->phy_node);
601648 of_node_put(plat->mdio_node);
602649 }
....@@ -618,21 +665,14 @@
618665 int stmmac_get_platform_resources(struct platform_device *pdev,
619666 struct stmmac_resources *stmmac_res)
620667 {
621
- struct resource *res;
622
-
623668 memset(stmmac_res, 0, sizeof(*stmmac_res));
624669
625670 /* Get IRQ information early to have an ability to ask for deferred
626671 * probe if needed before we went too far with resource allocation.
627672 */
628673 stmmac_res->irq = platform_get_irq_byname(pdev, "macirq");
629
- if (stmmac_res->irq < 0) {
630
- if (stmmac_res->irq != -EPROBE_DEFER) {
631
- dev_err(&pdev->dev,
632
- "MAC IRQ configuration information not found\n");
633
- }
674
+ if (stmmac_res->irq < 0)
634675 return stmmac_res->irq;
635
- }
636676
637677 /* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
638678 * The external wake up irq can be passed through the platform code
....@@ -641,19 +681,24 @@
641681 * In case the wake up interrupt is not passed from the platform
642682 * so the driver will continue to use the mac irq (ndev->irq)
643683 */
644
- stmmac_res->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
684
+ stmmac_res->wol_irq =
685
+ platform_get_irq_byname_optional(pdev, "eth_wake_irq");
645686 if (stmmac_res->wol_irq < 0) {
646687 if (stmmac_res->wol_irq == -EPROBE_DEFER)
647688 return -EPROBE_DEFER;
689
+ dev_info(&pdev->dev, "IRQ eth_wake_irq not found\n");
648690 stmmac_res->wol_irq = stmmac_res->irq;
649691 }
650692
651
- stmmac_res->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
652
- if (stmmac_res->lpi_irq == -EPROBE_DEFER)
653
- return -EPROBE_DEFER;
693
+ stmmac_res->lpi_irq =
694
+ platform_get_irq_byname_optional(pdev, "eth_lpi");
695
+ if (stmmac_res->lpi_irq < 0) {
696
+ if (stmmac_res->lpi_irq == -EPROBE_DEFER)
697
+ return -EPROBE_DEFER;
698
+ dev_info(&pdev->dev, "IRQ eth_lpi not found\n");
699
+ }
654700
655
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
656
- stmmac_res->addr = devm_ioremap_resource(&pdev->dev, res);
701
+ stmmac_res->addr = devm_platform_ioremap_resource(pdev, 0);
657702
658703 return PTR_ERR_OR_ZERO(stmmac_res->addr);
659704 }
....@@ -681,7 +726,6 @@
681726 }
682727 EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
683728
684
-#ifdef CONFIG_PM_SLEEP
685729 /**
686730 * stmmac_pltfr_suspend
687731 * @dev: device pointer
....@@ -689,7 +733,7 @@
689733 * call the main suspend function and then, if required, on some platform, it
690734 * can call an exit helper.
691735 */
692
-static int stmmac_pltfr_suspend(struct device *dev)
736
+static int __maybe_unused stmmac_pltfr_suspend(struct device *dev)
693737 {
694738 int ret;
695739 struct net_device *ndev = dev_get_drvdata(dev);
....@@ -710,7 +754,7 @@
710754 * the main resume function, on some platforms, it can call own init helper
711755 * if required.
712756 */
713
-static int stmmac_pltfr_resume(struct device *dev)
757
+static int __maybe_unused stmmac_pltfr_resume(struct device *dev)
714758 {
715759 struct net_device *ndev = dev_get_drvdata(dev);
716760 struct stmmac_priv *priv = netdev_priv(ndev);
....@@ -721,10 +765,78 @@
721765
722766 return stmmac_resume(dev);
723767 }
724
-#endif /* CONFIG_PM_SLEEP */
725768
726
-SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend,
727
- stmmac_pltfr_resume);
769
+static int __maybe_unused stmmac_runtime_suspend(struct device *dev)
770
+{
771
+ struct net_device *ndev = dev_get_drvdata(dev);
772
+ struct stmmac_priv *priv = netdev_priv(ndev);
773
+
774
+ stmmac_bus_clks_config(priv, false);
775
+
776
+ return 0;
777
+}
778
+
779
+static int __maybe_unused stmmac_runtime_resume(struct device *dev)
780
+{
781
+ struct net_device *ndev = dev_get_drvdata(dev);
782
+ struct stmmac_priv *priv = netdev_priv(ndev);
783
+
784
+ return stmmac_bus_clks_config(priv, true);
785
+}
786
+
787
+static int __maybe_unused stmmac_pltfr_noirq_suspend(struct device *dev)
788
+{
789
+ struct net_device *ndev = dev_get_drvdata(dev);
790
+ struct stmmac_priv *priv = netdev_priv(ndev);
791
+ int ret;
792
+
793
+ if (!netif_running(ndev))
794
+ return 0;
795
+
796
+ if (!device_may_wakeup(priv->device) || !priv->plat->pmt) {
797
+ /* Disable clock in case of PWM is off */
798
+ clk_disable_unprepare(priv->plat->clk_ptp_ref);
799
+
800
+ ret = pm_runtime_force_suspend(dev);
801
+ if (ret)
802
+ return ret;
803
+ }
804
+
805
+ return 0;
806
+}
807
+
808
+static int __maybe_unused stmmac_pltfr_noirq_resume(struct device *dev)
809
+{
810
+ struct net_device *ndev = dev_get_drvdata(dev);
811
+ struct stmmac_priv *priv = netdev_priv(ndev);
812
+ int ret;
813
+
814
+ if (!netif_running(ndev))
815
+ return 0;
816
+
817
+ if (!device_may_wakeup(priv->device) || !priv->plat->pmt) {
818
+ /* enable the clk previously disabled */
819
+ ret = pm_runtime_force_resume(dev);
820
+ if (ret)
821
+ return ret;
822
+
823
+ ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
824
+ if (ret < 0) {
825
+ netdev_warn(priv->dev,
826
+ "failed to enable PTP reference clock: %pe\n",
827
+ ERR_PTR(ret));
828
+ return ret;
829
+ }
830
+ }
831
+
832
+ return 0;
833
+}
834
+
835
+const struct dev_pm_ops stmmac_pltfr_pm_ops = {
836
+ SET_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_suspend, stmmac_pltfr_resume)
837
+ SET_RUNTIME_PM_OPS(stmmac_runtime_suspend, stmmac_runtime_resume, NULL)
838
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_noirq_suspend, stmmac_pltfr_noirq_resume)
839
+};
728840 EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
729841
730842 MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");