Merge branch 'CR_1946_515_GMAC_yanhong.wang' into 'jh7110-5.15.y-devel'
authorandy.hu <andy.hu@starfivetech.com>
Wed, 7 Sep 2022 07:31:30 +0000 (07:31 +0000)
committerandy.hu <andy.hu@starfivetech.com>
Wed, 7 Sep 2022 07:31:30 +0000 (07:31 +0000)
Cr 1946 515 gmac yanhong.wang

See merge request sdk/linux!416

Documentation/devicetree/bindings/net/starfive,dwmac-plat.yaml [new file with mode: 0644]
arch/riscv/boot/dts/starfive/jh7110.dtsi [changed mode: 0755->0644]
arch/riscv/configs/starfive_jh7110_defconfig
drivers/net/ethernet/stmicro/stmmac/Kconfig
drivers/net/ethernet/stmicro/stmmac/Makefile
drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
drivers/net/ethernet/stmicro/stmmac/dwmac-starfive-plat.c [new file with mode: 0644]

diff --git a/Documentation/devicetree/bindings/net/starfive,dwmac-plat.yaml b/Documentation/devicetree/bindings/net/starfive,dwmac-plat.yaml
new file mode 100644 (file)
index 0000000..b88069e
--- /dev/null
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/starfive,dwmac-plat.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive DWMAC glue layer Device Tree Bindings
+
+maintainers:
+  - Tan Chun Hau <chunhau.tan@starfivetech.com>
+
+select:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - starfive,dwmac
+  required:
+    - compatible
+
+allOf:
+  - $ref: "snps,dwmac.yaml#"
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - starfive,dwmac
+          - const: snps,dwmac-5.10a
+
+  clocks:
+    items:
+      - description: Gtx clock
+      - description: Tx clock
+      - description: PTP reference clock
+      - description: GMAC main clock
+      - description: PTP reference clock
+      - description: Gtxc clock
+
+  clock-names:
+    items:
+      - const: gtx
+      - const: tx
+      - const: ptp_ref
+      - const: stmmaceth
+      - const: pclk
+      - const: gtxc
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+Example:
+  - |
+    #include <dt-bindings/reset/starfive-jh7110.h>
+    #include <dt-bindings/clock/starfive-jh7110-clkgen.h>
+
+    /* gmac device configuration */
+    stmmac_axi_setup: stmmac-axi-config {
+      snps,wr_osr_lmt = <0xf>;
+      snps,rd_osr_lmt = <0xf>;
+      snps,blen = <256 128 64 32 0 0 0>;
+    };
+
+    gmac0: gmac@17020000 {
+      compatible = "starfive,dwmac","snps,dwmac-5.10a";
+      reg = <0x0 0x17020000 0x0 0x10000>;
+      interrupts = <7>, <6>, <5>;
+      interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+      phy-reset-gpios = <&gpio 63 0>;
+      clock-names = "gtx",
+        "tx",
+        "ptp_ref",
+        "stmmaceth",
+        "pclk",
+        "gtxc";
+      clocks = <&clkgen JH7110_GMAC0_GTXCLK>,
+         <&clkgen JH7110_U0_GMAC5_CLK_TX>,
+         <&clkgen JH7110_GMAC0_PTP>,
+         <&clkgen JH7110_U0_GMAC5_CLK_AHB>,
+         <&clkgen JH7110_U0_GMAC5_CLK_AXI>,
+         <&clkgen JH7110_GMAC0_GTXC>;
+      resets = <&rstgen RSTN_U0_DW_GMAC5_AXI64_AHB>,
+         <&rstgen RSTN_U0_DW_GMAC5_AXI64_AXI>;
+      reset-names = "ahb", "stmmaceth";
+      max-frame-size = <1500>;
+      phy-mode = "rgmii-id";
+      snps,multicast-filter-bins = <64>;
+      snps,perfect-filter-entries = <128>;
+      rx-fifo-depth = <2048>;
+      tx-fifo-depth = <2048>;
+      snps,fixed-burst;
+      snps,no-pbl-x8;
+      snps,force_thresh_dma_mode;
+      snps,axi-config = <&stmmac_axi_setup>;
+      snps,tso;
+      snps,en-tx-lpi-clockgating;
+      snps,txpbl = <4>;
+      snps,rxpbl = <4>;
+    };
+
old mode 100755 (executable)
new mode 100644 (file)
index 2698dc9..2519b04
                };
 
                gmac0: ethernet@16030000 {
-                       compatible = "starfive,jh7110-eqos-5.20";
+                       compatible = "starfive,dwmac","snps,dwmac-5.10a";
                        reg = <0x0 0x16030000 0x0 0x10000>;
                        clock-names = "gtx",
                                "tx",
                };
 
                gmac1: ethernet@16040000 {
-                       compatible = "starfive,jh7110-eqos-5.20";
+                       compatible = "starfive,dwmac","snps,dwmac-5.10a";
                        reg = <0x0 0x16040000 0x0 0x10000>;
                        clock-names = "gtx",
                                "tx",
index 7f165eb..7db31de 100644 (file)
@@ -128,7 +128,7 @@ CONFIG_R8169=y
 # CONFIG_NET_VENDOR_SOCIONEXT is not set
 CONFIG_STMMAC_ETH=y
 CONFIG_STMMAC_SELFTESTS=y
-CONFIG_DWMAC_DWC_QOS_ETH=y
+CONFIG_DWMAC_STARFIVE_PLAT=y
 # CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
index 929cfc2..b7e1133 100644 (file)
@@ -232,6 +232,16 @@ config DWMAC_INTEL_PLAT
          the stmmac device driver. This driver is used for the Intel Keem Bay
          SoC.
 
+config DWMAC_STARFIVE_PLAT
+       tristate "StarFive dwmac support"
+       depends on OF && COMMON_CLK
+       depends on STMMAC_ETH
+       help
+         Support for ethernet controllers on StarFive SoCs
+
+         This selects the StarFive platform specific glue layer support for
+         the stmmac device driver. This driver is used for StarFive SoCs.
+
 config DWMAC_VISCONTI
        tristate "Toshiba Visconti DWMAC support"
        default ARCH_VISCONTI
index d4e12e9..1df002c 100644 (file)
@@ -29,6 +29,7 @@ obj-$(CONFIG_DWMAC_SUNXI)     += dwmac-sunxi.o
 obj-$(CONFIG_DWMAC_SUN8I)      += dwmac-sun8i.o
 obj-$(CONFIG_DWMAC_DWC_QOS_ETH)        += dwmac-dwc-qos-eth.o
 obj-$(CONFIG_DWMAC_INTEL_PLAT) += dwmac-intel-plat.o
+obj-$(CONFIG_DWMAC_STARFIVE_PLAT)      += dwmac-starfive-plat.o
 obj-$(CONFIG_DWMAC_GENERIC)    += dwmac-generic.o
 obj-$(CONFIG_DWMAC_IMX8)       += dwmac-imx.o
 obj-$(CONFIG_DWMAC_VISCONTI)   += dwmac-visconti.o
index f8b4246..bc91fd8 100644 (file)
@@ -37,14 +37,6 @@ struct tegra_eqos {
        struct gpio_desc *reset;
 };
 
-struct starfive_eqos {
-       struct device *dev;
-       void __iomem *regs;
-       struct clk *clk_tx;
-       struct clk *clk_gtx;
-       struct clk *clk_gtxc;
-};
-
 static int dwc_eth_dwmac_config_dt(struct platform_device *pdev,
                                   struct plat_stmmacenet_data *plat_dat)
 {
@@ -405,135 +397,6 @@ static int tegra_eqos_remove(struct platform_device *pdev)
        return 0;
 }
 
-static void starfive_eqos_fix_speed(void *priv, unsigned int speed)
-{
-       struct starfive_eqos *eqos = priv;
-       unsigned long rate;
-       int err;
-
-       switch (speed) {
-       case SPEED_1000:
-               rate = 125000000;
-               break;
-       case SPEED_100:
-               rate = 25000000;
-               break;
-       case SPEED_10:
-               rate = 2500000;
-               break;
-       default:
-               dev_err(eqos->dev, "invalid speed %u\n", speed);
-               return;
-       }
-
-       err = clk_set_rate(eqos->clk_gtx, rate);
-       if (err < 0)
-               dev_err(eqos->dev, "failed to set tx rate %lu\n", rate);
-}
-
-static int starfive_eqos_probe(struct platform_device *pdev,
-                              struct plat_stmmacenet_data *data,
-                              struct stmmac_resources *res)
-{
-       struct device *dev = &pdev->dev;
-       struct starfive_eqos *eqos;
-       int err;
-
-       /* Get IRQ information early to have an ability to ask for deferred
-        * probe if needed before we went too far with resource allocation.
-        */
-       res->irq = platform_get_irq_byname(pdev, "macirq");
-       if (res->irq < 0)
-               return res->irq;
-
-       /* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
-        * The external wake up irq can be passed through the platform code
-        * named as "eth_wake_irq"
-        *
-        * In case the wake up interrupt is not passed from the platform
-        * so the driver will continue to use the mac irq (ndev->irq)
-        */
-       res->wol_irq =
-               platform_get_irq_byname_optional(pdev, "eth_wake_irq");
-       if (res->wol_irq < 0) {
-               if (res->wol_irq == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
-               dev_info(&pdev->dev, "IRQ eth_wake_irq not found\n");
-               res->wol_irq = res->irq;
-       }
-
-       res->lpi_irq =
-               platform_get_irq_byname_optional(pdev, "eth_lpi");
-       if (res->lpi_irq < 0) {
-               if (res->lpi_irq == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
-               dev_info(&pdev->dev, "IRQ eth_lpi not found\n");
-       }
-
-       eqos = devm_kzalloc(&pdev->dev, sizeof(*eqos), GFP_KERNEL);
-       if (!eqos)
-               return -ENOMEM;
-
-       eqos->dev = &pdev->dev;
-       eqos->regs = res->addr;
-
-       if (!is_of_node(dev->fwnode))
-               goto bypass_clk_reset_gpio;
-
-       eqos->clk_tx = devm_clk_get(&pdev->dev, "tx");
-       if (IS_ERR(eqos->clk_tx)) {
-               err = PTR_ERR(eqos->clk_tx);
-               goto err;
-       }
-
-       err = clk_prepare_enable(eqos->clk_tx);
-       if (err < 0)
-               goto err;
-
-       eqos->clk_gtx = devm_clk_get(&pdev->dev, "gtx");
-       if (IS_ERR(eqos->clk_gtx)) {
-               err = PTR_ERR(eqos->clk_gtx);
-               goto disable_tx;
-       }
-
-       err = clk_prepare_enable(eqos->clk_gtx);
-       if (err < 0)
-               goto disable_tx;
-
-       eqos->clk_gtxc = devm_clk_get(&pdev->dev, "gtxc");
-       if (IS_ERR(eqos->clk_gtxc)) {
-               err = PTR_ERR(eqos->clk_gtxc);
-               goto disable_gtx;
-       }
-
-       err = clk_prepare_enable(eqos->clk_gtxc);
-       if (err < 0)
-               goto disable_gtx;
-
-bypass_clk_reset_gpio:
-       data->fix_mac_speed = starfive_eqos_fix_speed;
-       data->init = NULL;
-       data->bsp_priv = eqos;
-       return 0;
-
-disable_gtx:
-       clk_disable_unprepare(eqos->clk_gtx);
-disable_tx:
-       clk_disable_unprepare(eqos->clk_tx);
-err:
-       return err;
-}
-
-static int starfive_eqos_remove(struct platform_device *pdev)
-{
-       struct starfive_eqos *eqos = get_stmmac_bsp_priv(&pdev->dev);
-
-       clk_disable_unprepare(eqos->clk_tx);
-       clk_disable_unprepare(eqos->clk_gtx);
-
-       return 0;
-}
-
 struct dwc_eth_dwmac_data {
        int (*probe)(struct platform_device *pdev,
                     struct plat_stmmacenet_data *data,
@@ -551,11 +414,6 @@ static const struct dwc_eth_dwmac_data tegra_eqos_data = {
        .remove = tegra_eqos_remove,
 };
 
-static const struct dwc_eth_dwmac_data starfive_eqos_data = {
-       .probe = starfive_eqos_probe,
-       .remove = starfive_eqos_remove,
-};
-
 static int dwc_eth_dwmac_probe(struct platform_device *pdev)
 {
        const struct dwc_eth_dwmac_data *data;
@@ -636,7 +494,6 @@ static int dwc_eth_dwmac_remove(struct platform_device *pdev)
 static const struct of_device_id dwc_eth_dwmac_match[] = {
        { .compatible = "snps,dwc-qos-ethernet-4.10", .data = &dwc_qos_data },
        { .compatible = "nvidia,tegra186-eqos", .data = &tegra_eqos_data },
-       { .compatible = "starfive,jh7110-eqos-5.20", .data = &starfive_eqos_data },
        { }
 };
 MODULE_DEVICE_TABLE(of, dwc_eth_dwmac_match);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive-plat.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive-plat.c
new file mode 100644 (file)
index 0000000..c563582
--- /dev/null
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/* StarFive DWMAC platform driver
+ *
+ * Copyright(C) 2022 StarFive Technology Co., Ltd.
+ */
+
+#include <linux/of_device.h>
+#include "stmmac_platform.h"
+
+struct starfive_dwmac {
+       struct device *dev;
+       void __iomem *regs;
+       struct clk *clk_tx;
+       struct clk *clk_gtx;
+       struct clk *clk_gtxc;
+};
+
+static void starfive_eth_fix_mac_speed(void *priv, unsigned int speed)
+{
+       struct starfive_dwmac *dwmac = priv;
+       unsigned long rate;
+       int err;
+
+       switch (speed) {
+       case SPEED_1000:
+               rate = 125000000;
+               break;
+       case SPEED_100:
+               rate = 25000000;
+               break;
+       case SPEED_10:
+               rate = 2500000;
+               break;
+       default:
+               dev_err(dwmac->dev, "invalid speed %u\n", speed);
+               return;
+       }
+
+       err = clk_set_rate(dwmac->clk_gtx, rate);
+       if (err < 0)
+               dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
+}
+
+static const struct of_device_id starfive_eth_plat_match[] = {
+       {.compatible = "starfive,dwmac"},
+       { }
+};
+
+static int starfive_eth_plat_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct plat_stmmacenet_data *plat_dat;
+       struct stmmac_resources stmmac_res;
+       struct starfive_dwmac *dwmac;
+       int err;
+
+       err = stmmac_get_platform_resources(pdev, &stmmac_res);
+       if (err)
+               return err;
+
+       plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat)) {
+               dev_err(&pdev->dev, "dt configuration failed\n");
+               return PTR_ERR(plat_dat);
+       }
+
+       dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
+       if (!dwmac)
+               return -ENOMEM;
+
+       dwmac->dev = &pdev->dev;
+       dwmac->regs = stmmac_res.addr;
+
+       if (!is_of_node(dev->fwnode))
+               goto bypass_clk_reset_gpio;
+
+       dwmac->clk_tx = devm_clk_get(&pdev->dev, "tx");
+       if (IS_ERR(dwmac->clk_tx)) {
+               err = PTR_ERR(dwmac->clk_tx);
+               goto err;
+       }
+
+       err = clk_prepare_enable(dwmac->clk_tx);
+       if (err < 0)
+               goto err;
+
+       dwmac->clk_gtx = devm_clk_get(&pdev->dev, "gtx");
+       if (IS_ERR(dwmac->clk_gtx)) {
+               err = PTR_ERR(dwmac->clk_gtx);
+               goto disable_tx;
+       }
+
+       err = clk_prepare_enable(dwmac->clk_gtx);
+       if (err < 0)
+               goto disable_tx;
+
+       dwmac->clk_gtxc = devm_clk_get(&pdev->dev, "gtxc");
+       if (IS_ERR(dwmac->clk_gtxc)) {
+               err = PTR_ERR(dwmac->clk_gtxc);
+               goto disable_gtx;
+       }
+
+       err = clk_prepare_enable(dwmac->clk_gtxc);
+       if (err < 0)
+               goto disable_gtx;
+
+       err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (err)
+               goto err;
+
+bypass_clk_reset_gpio:
+       plat_dat->fix_mac_speed = starfive_eth_fix_mac_speed;
+       plat_dat->init = NULL;
+       plat_dat->bsp_priv = dwmac;
+       return 0;
+
+disable_gtx:
+       clk_disable_unprepare(dwmac->clk_gtx);
+disable_tx:
+       clk_disable_unprepare(dwmac->clk_tx);
+err:
+       stmmac_remove_config_dt(pdev, plat_dat);
+       return err;
+}
+
+static int starfive_eth_plat_remove(struct platform_device *pdev)
+{
+       struct starfive_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev);
+
+       clk_disable_unprepare(dwmac->clk_gtxc);
+       clk_disable_unprepare(dwmac->clk_gtx);
+       clk_disable_unprepare(dwmac->clk_tx);
+
+       return 0;
+}
+
+static struct platform_driver starfive_eth_plat_driver = {
+       .probe  = starfive_eth_plat_probe,
+       .remove = starfive_eth_plat_remove,
+       .driver = {
+               .name = "starfive-eth-plat",
+               .pm = &stmmac_pltfr_pm_ops,
+               .of_match_table = starfive_eth_plat_match,
+       },
+};
+
+module_platform_driver(starfive_eth_plat_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("StarFive DWMAC platform driver");
+