ipq806x: replace caf nss-gmac driver by upstream stmmac
authorJohn Crispin <john@openwrt.org>
Fri, 29 May 2015 12:26:01 +0000 (12:26 +0000)
committerJohn Crispin <john@openwrt.org>
Fri, 29 May 2015 12:26:01 +0000 (12:26 +0000)
This driver has been cherry-picked and backported from the following
LKML thread:
*https://lkml.org/lkml/2015/5/26/744

It also updates the DT accordingly.

Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
SVN-Revision: 45831

31 files changed:
target/linux/ipq806x/Makefile
target/linux/ipq806x/patches-3.18/022-add-db149-dts.patch
target/linux/ipq806x/patches-3.18/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch
target/linux/ipq806x/patches-3.18/124-regulator-rpm-add-support-for-RPM-controller-SMB208.patch
target/linux/ipq806x/patches-3.18/125-regulator-qcom-rpm-Add-missing-state-flag-in-call-to.patch
target/linux/ipq806x/patches-3.18/126-add-rpm-to-ipq8064-dts.patch
target/linux/ipq806x/patches-3.18/130-clk_mux-Fix-set_parent-doing-the-wrong-thing-when-IN.patch
target/linux/ipq806x/patches-3.18/132-clk-Add-clk_unregister_-divider-gate-mux-to-close-me.patch
target/linux/ipq806x/patches-3.18/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch
target/linux/ipq806x/patches-3.18/700-add-gmac-dts-suport.patch [deleted file]
target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch [new file with mode: 0644]
target/linux/ipq806x/patches-3.18/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch [new file with mode: 0644]
target/linux/ipq806x/patches-3.18/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch [new file with mode: 0644]
target/linux/ipq806x/patches-3.18/703-stmmac-add-fixed-link-device-tree-support.patch [new file with mode: 0644]
target/linux/ipq806x/patches-3.18/704-stmmac-add-ipq806x-glue-layer.patch [new file with mode: 0644]
target/linux/ipq806x/patches-3.18/705-net-stmmac-ipq806x-document-device-tree-bindings.patch [new file with mode: 0644]
target/linux/ipq806x/patches-3.18/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch [new file with mode: 0644]
target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch [new file with mode: 0644]
target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.0/022-add-db149-dts.patch
target/linux/ipq806x/patches-4.0/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch
target/linux/ipq806x/patches-4.0/700-add-gmac-dts-suport.patch [deleted file]
target/linux/ipq806x/patches-4.0/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.0/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.0/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.0/703-stmmac-add-fixed-link-device-tree-support.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.0/704-stmmac-add-ipq806x-glue-layer.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.0/705-net-stmmac-ipq806x-document-device-tree-bindings.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.0/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.0/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.0/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch [new file with mode: 0644]

index f97db74fc3545336e49e33c01abcf8b2c367fe0b..da841a631427fab34d74a643702dbf851e456dce 100644 (file)
@@ -15,7 +15,7 @@ KERNELNAME:=zImage Image dtbs
 
 include $(INCLUDE_DIR)/target.mk
 DEFAULT_PACKAGES += \
-       kmod-leds-gpio kmod-gpio-button-hotplug kmod-qca-nss-gmac swconfig \
+       kmod-leds-gpio kmod-gpio-button-hotplug kmod-stmmac swconfig \
        kmod-ata-core kmod-ata-ahci kmod-ata-ahci-platform
 
 
index 85a0f7246ab77fd03dbdc5336e315df27c13cf3d..bd6ec1e94f38b1a308ae7417118d60c5be034dca 100644 (file)
@@ -25,7 +25,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
        qcom-msm8974-sony-xperia-honami.dtb
 --- /dev/null
 +++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-@@ -0,0 +1,257 @@
+@@ -0,0 +1,132 @@
 +#include "qcom-ipq8064-v1.0.dtsi"
 +
 +/ {
@@ -50,15 +50,8 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
 +              linux,stdout-path = "serial0:115200n8";
 +      };
 +
-+      aliases {
-+              mdio-gpio0 = &mdio0;
-+      };
-+
 +      soc {
 +              pinmux@800000 {
-+                      pinctrl-0 = <&mdio0_pins &rgmii0_pinmux>;
-+                      pinctrl-names = "default";
-+
 +                      i2c4_pins: i2c4_pinmux {
 +                              pins = "gpio12", "gpio13";
 +                              function = "gsbi4";
@@ -73,23 +66,6 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
 +                                      bias-none;
 +                              };
 +                      };
-+
-+                      mdio0_pins: mdio0_pins {
-+                              mux {
-+                                      pins = "gpio0", "gpio1";
-+                                      function = "gpio";
-+                                      drive-strength = <8>;
-+                                      bias-disable;
-+                              };
-+                      };
-+
-+                      rgmii0_pinmux: rgmii0_pinmux {
-+                              mux {
-+                                      pins = "gpio2", "gpio66";
-+                                      drive-strength = <8>;
-+                                      bias-disable;
-+                              };
-+                      };
 +              };
 +
 +              gsbi2: gsbi@12480000 {
@@ -180,106 +156,5 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
 +              usb30@1 {
 +                      status = "ok";
 +              };
-+
-+              mdio0: mdio {
-+                      compatible = "virtual,mdio-gpio";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+                      gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
-+
-+                      phy0: ethernet-phy@0 {
-+                              device_type = "ethernet-phy";
-+                              reg = <0>;
-+                              qca,ar8327-initvals = <
-+                                      0x00004 0x7600000   /* PAD0_MODE */
-+                                      0x00008 0x1000000   /* PAD5_MODE */
-+                                      0x0000c 0x80        /* PAD6_MODE */
-+                                      0x000e4 0xaa545     /* MAC_POWER_SEL */
-+                                      0x000e0 0xc74164de  /* SGMII_CTRL */
-+                                      0x0007c 0x4e        /* PORT0_STATUS */
-+                                      0x00094 0x4e        /* PORT6_STATUS */
-+                              >;
-+                      };
-+
-+                      phy4: ethernet-phy@4 {
-+                              device_type = "ethernet-phy";
-+                              reg = <4>;
-+                      };
-+
-+                      phy6: ethernet-phy@6 {
-+                              device_type = "ethernet-phy";
-+                              reg = <6>;
-+                      };
-+
-+                      phy7: ethernet-phy@7 {
-+                              device_type = "ethernet-phy";
-+                              reg = <7>;
-+                      };
-+              };
-+
-+              nss-gmac-common {
-+                      reg = <0x03000000 0x0000FFFF 0x1bb00000 0x0000FFFF 0x00900000 0x00004000>;
-+                      reg-names = "nss_reg_base" , "qsgmii_reg_base", "clk_ctl_base";
-+              };
-+
-+              gmac0: ethernet@37000000 {
-+                      status = "ok";
-+                      phy-mode = "rgmii";
-+                      qcom,id = <0>;
-+                      qcom,phy_mdio_addr = <4>;
-+                      qcom,poll_required = <1>;
-+                      qcom,rgmii_delay = <1>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <1000>;
-+                      qcom,forced_duplex = <1>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-+
-+              gmac1: ethernet@37200000 {
-+                      status = "ok";
-+                      phy-mode = "sgmii";
-+                      qcom,id = <1>;
-+                      qcom,phy_mdio_addr = <0>;
-+                      qcom,poll_required = <0>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <1000>;
-+                      qcom,forced_duplex = <1>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-+
-+              gmac2: ethernet@37400000 {
-+                      status = "ok";
-+                      phy-mode = "sgmii";
-+                      qcom,id = <2>;
-+                      qcom,phy_mdio_addr = <6>;
-+                      qcom,poll_required = <1>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <0>;
-+                      qcom,forced_duplex = <0>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-+
-+              gmac3: ethernet@37600000 {
-+                      status = "ok";
-+                      phy-mode = "sgmii";
-+                      qcom,id = <3>;
-+                      qcom,phy_mdio_addr = <7>;
-+                      qcom,poll_required = <1>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <0>;
-+                      qcom,forced_duplex = <0>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
 +      };
 +};
index 7bee560e3911c75c60e614a05cb3dfb6df90c885..80ac25faeb601215ddb2b92a7cec7cb4f5073742 100644 (file)
@@ -60,7 +60,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
  };
 --- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts
 +++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-@@ -37,6 +37,30 @@
+@@ -30,6 +30,30 @@
                                bias-disable;
                        };
  
@@ -91,10 +91,11 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
                        spi_pins: spi_pins {
                                mux {
                                        pins = "gpio18", "gpio19", "gpio21";
-@@ -153,6 +177,27 @@
+@@ -128,5 +152,26 @@
+               usb30@1 {
                        status = "ok";
                };
++
 +              pcie0: pci@1b500000 {
 +                      status = "ok";
 +                      reset-gpio = <&qcom_pinmux 3 0>;
@@ -115,10 +116,8 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
 +                      pinctrl-0 = <&pcie3_pins>;
 +                      pinctrl-names = "default";
 +              };
-+
-               mdio0: mdio {
-                       compatible = "virtual,mdio-gpio";
-                       #address-cells = <1>;
+       };
+ };
 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
 +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
 @@ -3,6 +3,8 @@
@@ -130,7 +129,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
  
  / {
        model = "Qualcomm IPQ8064";
-@@ -306,6 +307,129 @@
+@@ -306,6 +308,129 @@
                        #reset-cells = <1>;
                };
  
@@ -260,7 +259,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
                hs_phy_1: phy@100f8800 {
                        compatible = "qcom,dwc3-hs-usb-phy";
                        reg = <0x100f8800 0x30>;
-@@ -389,6 +513,5 @@
+@@ -389,6 +514,5 @@
                                dr_mode = "host";
                        };
                };
index c411c1ce8494cb5874d6ebe343141dc99760e92a..e4f094c2132cc9eca8611d7796dc8e3044768ec6 100644 (file)
@@ -14,11 +14,9 @@ Signed-off-by: Mark Brown <broonie@kernel.org>
  drivers/regulator/qcom_rpm-regulator.c | 19 +++++++++++++++++++
  1 file changed, 19 insertions(+)
 
-diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c
-index b55cd5b..fbcbd3f 100644
 --- a/drivers/regulator/qcom_rpm-regulator.c
 +++ b/drivers/regulator/qcom_rpm-regulator.c
-@@ -183,6 +183,13 @@ static const struct regulator_linear_range ftsmps_ranges[] = {
+@@ -183,6 +183,13 @@ static const struct regulator_linear_ran
        REGULATOR_LINEAR_RANGE(1500000,  64, 100, 50000),
  };
  
@@ -32,7 +30,7 @@ index b55cd5b..fbcbd3f 100644
  static const struct regulator_linear_range ncp_ranges[] = {
        REGULATOR_LINEAR_RANGE(1500000,   0,  31, 50000),
  };
-@@ -559,6 +566,16 @@ static const struct qcom_rpm_reg pm8921_switch = {
+@@ -559,6 +566,16 @@ static const struct qcom_rpm_reg pm8921_
        .parts = &rpm8960_switch_parts,
  };
  
@@ -49,7 +47,7 @@ index b55cd5b..fbcbd3f 100644
  static const struct of_device_id rpm_of_match[] = {
        { .compatible = "qcom,rpm-pm8058-pldo",     .data = &pm8058_pldo },
        { .compatible = "qcom,rpm-pm8058-nldo",     .data = &pm8058_nldo },
-@@ -578,6 +595,8 @@ static const struct of_device_id rpm_of_match[] = {
+@@ -578,6 +595,8 @@ static const struct of_device_id rpm_of_
        { .compatible = "qcom,rpm-pm8921-ftsmps",   .data = &pm8921_ftsmps },
        { .compatible = "qcom,rpm-pm8921-ncp",      .data = &pm8921_ncp },
        { .compatible = "qcom,rpm-pm8921-switch",   .data = &pm8921_switch },
@@ -58,6 +56,3 @@ index b55cd5b..fbcbd3f 100644
        { }
  };
  MODULE_DEVICE_TABLE(of, rpm_of_match);
--- 
-2.1.4
-
index 11a296af7002ef0918d5cef3f006a448d00ddf94..48921a842912ade0971cbd1c0ce042e6f9ed4384 100644 (file)
@@ -13,11 +13,9 @@ Signed-off-by: Lee Jones <lee.jones@linaro.org>
  drivers/regulator/qcom_rpm-regulator.c | 1 +
  1 file changed, 1 insertion(+)
 
-diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c
-index 8364ff3..edd0a17 100644
 --- a/drivers/regulator/qcom_rpm-regulator.c
 +++ b/drivers/regulator/qcom_rpm-regulator.c
-@@ -205,6 +205,7 @@ static int rpm_reg_write(struct qcom_rpm_reg *vreg,
+@@ -205,6 +205,7 @@ static int rpm_reg_write(struct qcom_rpm
        vreg->val[req->word] |= value << req->shift;
  
        return qcom_rpm_write(vreg->rpm,
@@ -25,6 +23,3 @@ index 8364ff3..edd0a17 100644
                              vreg->resource,
                              vreg->val,
                              vreg->parts->request_len);
--- 
-2.1.4
-
index 854131c7f69c8a605050ae048798c4346f63b58d..7e4c5cb1f673d1aded3d903ebae40cd82e123c81 100644 (file)
@@ -7,8 +7,8 @@
 +#include <dt-bindings/mfd/qcom-rpm.h>
  #include <dt-bindings/soc/qcom,gsbi.h>
  #include <dt-bindings/reset/qcom,gcc-ipq806x.h>
-@@ -75,6 +76,63 @@
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+@@ -76,6 +77,63 @@
                ranges;
                compatible = "simple-bus";
  
@@ -72,7 +72,7 @@
                qcom_pinmux: pinmux@800000 {
                        compatible = "qcom,ipq8064-pinctrl";
                        reg = <0x800000 0x4000>;
-@@ -119,6 +177,12 @@
+@@ -120,6 +178,12 @@
                        reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
                };
  
index d943ad511d63c05cef0800b7d472c545fbcc9060..29f74b760d358e4b2581ad9df8f7ad0520965e10 100644 (file)
@@ -42,11 +42,9 @@ Signed-off-by: Michael Turquette <mturquette@linaro.org>
  drivers/clk/clk-mux.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
-index 4f96ff3..6e1ecf9 100644
 --- a/drivers/clk/clk-mux.c
 +++ b/drivers/clk/clk-mux.c
-@@ -77,7 +77,7 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
+@@ -77,7 +77,7 @@ static int clk_mux_set_parent(struct clk
  
        else {
                if (mux->flags & CLK_MUX_INDEX_BIT)
@@ -55,6 +53,3 @@ index 4f96ff3..6e1ecf9 100644
  
                if (mux->flags & CLK_MUX_INDEX_ONE)
                        index++;
--- 
-2.1.4
-
index 127afd265f4fc364f216b42bf7d35a18543ae3ac..790f25d28db2704a892f2b509765b2492b67eb69 100644 (file)
@@ -22,7 +22,7 @@ Signed-off-by: Michael Turquette <mturquette@linaro.org>
 
 --- a/drivers/clk/clk-divider.c
 +++ b/drivers/clk/clk-divider.c
-@@ -463,3 +463,19 @@ struct clk *clk_register_divider_table(s
+@@ -461,3 +461,19 @@ struct clk *clk_register_divider_table(s
                        width, clk_divider_flags, table, lock);
  }
  EXPORT_SYMBOL_GPL(clk_register_divider_table);
index 9f8d8cb7e8b243492fafb3a925550caa2e2a2742..a3c3bbfc9eb06a504ab980dd34629987c7f53766 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
 +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -23,6 +23,11 @@
+@@ -24,6 +24,11 @@
                        next-level-cache = <&L2>;
                        qcom,acc = <&acc0>;
                        qcom,saw = <&saw0>;
@@ -12,7 +12,7 @@
                };
  
                cpu@1 {
-@@ -33,11 +38,24 @@
+@@ -34,11 +39,24 @@
                        next-level-cache = <&L2>;
                        qcom,acc = <&acc1>;
                        qcom,saw = <&saw1>;
@@ -37,7 +37,7 @@
                };
        };
  
-@@ -70,6 +88,46 @@
+@@ -71,6 +89,46 @@
                };
        };
  
@@ -84,7 +84,7 @@
        soc: soc {
                #address-cells = <1>;
                #size-cells = <1>;
-@@ -170,11 +228,13 @@
+@@ -171,11 +229,13 @@
                acc0: clock-controller@2088000 {
                        compatible = "qcom,kpss-acc-v1";
                        reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
diff --git a/target/linux/ipq806x/patches-3.18/700-add-gmac-dts-suport.patch b/target/linux/ipq806x/patches-3.18/700-add-gmac-dts-suport.patch
deleted file mode 100644 (file)
index 3c81f88..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -22,8 +22,15 @@
-               linux,stdout-path = "serial0:115200n8";
-       };
-+      aliases {
-+              mdio-gpio0 = &mdio0;
-+      };
-+
-       soc {
-               pinmux@800000 {
-+                      pinctrl-0 = <&mdio0_pins &rgmii2_pins>;
-+                      pinctrl-names = "default";
-+
-                       i2c4_pins: i2c4_pinmux {
-                               pins = "gpio12", "gpio13";
-                               function = "gsbi4";
-@@ -54,6 +61,25 @@
-                                       bias-none;
-                               };
-                       };
-+
-+                      mdio0_pins: mdio0_pins {
-+                              mux {
-+                                      pins = "gpio0", "gpio1";
-+                                      function = "gpio";
-+                                      drive-strength = <8>;
-+                                      bias-disable;
-+                              };
-+                      };
-+
-+                      rgmii2_pins: rgmii2_pins {
-+                              mux {
-+                                      pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+                                             "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62" ;
-+                                      function = "rgmii2";
-+                                      drive-strength = <8>;
-+                                      bias-disable;
-+                              };
-+                      };
-               };
-               gsbi@16300000 {
-@@ -89,6 +115,7 @@
-                                       #size-cells = <1>;
-                                       spi-max-frequency = <50000000>;
-                                       reg = <0>;
-+                                      m25p,fast-read;
-                                       partition@0 {
-                                               label = "lowlevel_init";
-@@ -163,5 +190,66 @@
-                       pinctrl-0 = <&pcie2_pins>;
-                       pinctrl-names = "default";
-               };
-+
-+              mdio0: mdio {
-+                      compatible = "virtual,mdio-gpio";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+                      gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
-+
-+                      phy0: ethernet-phy@0 {
-+                              device_type = "ethernet-phy";
-+                              reg = <0>;
-+                              qca,ar8327-initvals = <
-+                                      0x00004 0x7600000   /* PAD0_MODE */
-+                                      0x00008 0x1000000   /* PAD5_MODE */
-+                                      0x0000c 0x80        /* PAD6_MODE */
-+                                      0x000e4 0xaa545     /* MAC_POWER_SEL */
-+                                      0x000e0 0xc74164de  /* SGMII_CTRL */
-+                                      0x0007c 0x4e        /* PORT0_STATUS */
-+                                      0x00094 0x4e        /* PORT6_STATUS */
-+                              >;
-+                      };
-+
-+                      phy4: ethernet-phy@4 {
-+                              device_type = "ethernet-phy";
-+                              reg = <4>;
-+                      };
-+              };
-+
-+              nss-gmac-common {
-+                      reg = <0x03000000 0x0000FFFF 0x1bb00000 0x0000FFFF 0x00900000 0x00004000>;
-+                      reg-names = "nss_reg_base" , "qsgmii_reg_base", "clk_ctl_base";
-+              };
-+
-+              gmac1: ethernet@37200000 {
-+                      status = "ok";
-+                      phy-mode = "rgmii";
-+                      qcom,id = <1>;
-+                      qcom,phy_mdio_addr = <4>;
-+                      qcom,poll_required = <1>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <1000>;
-+                      qcom,forced_duplex = <1>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-+
-+              gmac2: ethernet@37400000 {
-+                      status = "ok";
-+                      phy-mode = "sgmii";
-+                      qcom,id = <2>;
-+                      qcom,phy_mdio_addr = <0>;
-+                      qcom,poll_required = <0>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <1000>;
-+                      qcom,forced_duplex = <1>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-       };
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -637,5 +638,42 @@
-                               dr_mode = "host";
-                       };
-               };
-+
-+              nss-gmac-common {
-+                      reg = <0x03000000 0x0000FFFF 0x1bb00000 0x0000FFFF 0x00900000 0x00004000>;
-+                      reg-names = "nss_reg_base" , "qsgmii_reg_base", "clk_ctl_base";
-+              };
-+
-+              gmac0: ethernet@37000000 {
-+                      device_type = "network";
-+                      compatible = "qcom,nss-gmac";
-+                      reg = <0x37000000 0x200000>;
-+                      interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
-+                      status = "disabled";
-+              };
-+
-+              gmac1: ethernet@37200000 {
-+                      device_type = "network";
-+                      compatible = "qcom,nss-gmac";
-+                      reg = <0x37200000 0x200000>;
-+                      interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
-+                      status = "disabled";
-+              };
-+
-+              gmac2: ethernet@37400000 {
-+                      device_type = "network";
-+                      compatible = "qcom,nss-gmac";
-+                      reg = <0x37400000 0x200000>;
-+                      interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
-+                      status = "disabled";
-+              };
-+
-+              gmac3: ethernet@37600000 {
-+                      device_type = "network";
-+                      compatible = "qcom,nss-gmac";
-+                      reg = <0x37600000 0x200000>;
-+                      interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
-+                      status = "disabled";
-+              };
-       };
- };
diff --git a/target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch b/target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch
new file mode 100644 (file)
index 0000000..d7d6b69
--- /dev/null
@@ -0,0 +1,733 @@
+From 2fbb18f85826a9ba308fedb2cf90d3a661a39fd7 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Fri, 27 Mar 2015 00:16:14 -0700
+Subject: [PATCH] clk: qcom: Add support for NSS/GMAC clocks and resets
+
+Add the NSS/GMAC clocks and the TCM clock and NSS resets.
+
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/qcom/gcc-ipq806x.c               | 594 ++++++++++++++++++++++++++-
+ drivers/clk/qcom/gcc-ipq806x.c.rej           |  50 +++
+ include/dt-bindings/clock/qcom,gcc-ipq806x.h |   2 +
+ include/dt-bindings/reset/qcom,gcc-ipq806x.h |  43 ++
+ 4 files changed, 688 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/clk/qcom/gcc-ipq806x.c.rej
+
+--- a/drivers/clk/qcom/gcc-ipq806x.c
++++ b/drivers/clk/qcom/gcc-ipq806x.c
+@@ -209,11 +209,46 @@ static struct clk_regmap pll14_vote = {
+       },
+ };
++#define NSS_PLL_RATE(f, _l, _m, _n, i) \
++      {  \
++              .freq = f,  \
++              .l = _l, \
++              .m = _m, \
++              .n = _n, \
++              .ibits = i, \
++      }
++
++static struct pll_freq_tbl pll18_freq_tbl[] = {
++      NSS_PLL_RATE(550000000, 44, 0, 1, 0x01495625),
++      NSS_PLL_RATE(733000000, 58, 16, 25, 0x014b5625),
++};
++
++static struct clk_pll pll18 = {
++      .l_reg = 0x31a4,
++      .m_reg = 0x31a8,
++      .n_reg = 0x31ac,
++      .config_reg = 0x31b4,
++      .mode_reg = 0x31a0,
++      .status_reg = 0x31b8,
++      .status_bit = 16,
++      .post_div_shift = 16,
++      .post_div_width = 1,
++      .freq_tbl = pll18_freq_tbl,
++      .clkr.hw.init = &(struct clk_init_data){
++              .name = "pll18",
++              .parent_names = (const char *[]){ "pxo" },
++              .num_parents = 1,
++              .ops = &clk_pll_ops,
++      },
++};
++
+ #define P_PXO 0
+ #define P_PLL8        1
+ #define P_PLL3        1
+ #define P_PLL0        2
+ #define P_CXO 2
++#define P_PLL14       3
++#define P_PLL18 4
+ static const u8 gcc_pxo_pll8_map[] = {
+       [P_PXO]         = 0,
+@@ -264,6 +299,22 @@ static const char *gcc_pxo_pll8_pll0_map
+       "pll0_vote",
+ };
++static const u8 gcc_pxo_pll8_pll14_pll18_pll0_map[] = {
++      [P_PXO] = 0 ,
++      [P_PLL8] = 4,
++      [P_PLL0] = 2,
++      [P_PLL14] = 5,
++      [P_PLL18] = 1,
++};
++
++static const char *gcc_pxo_pll8_pll14_pll18_pll0[] = {
++      "pxo",
++      "pll8_vote",
++      "pll0_vote",
++      "pll14",
++      "pll18",
++};
++
+ static struct freq_tbl clk_tbl_gsbi_uart[] = {
+       {  1843200, P_PLL8, 2,  6, 625 },
+       {  3686400, P_PLL8, 2, 12, 625 },
+@@ -2239,6 +2290,472 @@ static struct clk_branch usb_fs1_h_clk =
+       },
+ };
++static const struct freq_tbl clk_tbl_gmac[] = {
++      { 133000000, P_PLL0, 1,  50, 301 },
++      { 266000000, P_PLL0, 1, 127, 382 },
++      { }
++};
++
++static struct clk_dyn_rcg gmac_core1_src = {
++      .ns_reg[0] = 0x3cac,
++      .ns_reg[1] = 0x3cb0,
++      .md_reg[0] = 0x3ca4,
++      .md_reg[1] = 0x3ca8,
++      .bank_reg = 0x3ca0,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_gmac,
++      .clkr = {
++              .enable_reg = 0x3ca0,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core1_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch gmac_core1_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 4,
++      .hwcg_reg = 0x3cb4,
++      .hwcg_bit = 6,
++      .clkr = {
++              .enable_reg = 0x3cb4,
++              .enable_mask = BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core1_clk",
++                      .parent_names = (const char *[]){
++                              "gmac_core1_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static struct clk_dyn_rcg gmac_core2_src = {
++      .ns_reg[0] = 0x3ccc,
++      .ns_reg[1] = 0x3cd0,
++      .md_reg[0] = 0x3cc4,
++      .md_reg[1] = 0x3cc8,
++      .bank_reg = 0x3ca0,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_gmac,
++      .clkr = {
++              .enable_reg = 0x3cc0,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core2_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch gmac_core2_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 5,
++      .hwcg_reg = 0x3cd4,
++      .hwcg_bit = 6,
++      .clkr = {
++              .enable_reg = 0x3cd4,
++              .enable_mask = BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core2_clk",
++                      .parent_names = (const char *[]){
++                              "gmac_core2_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static struct clk_dyn_rcg gmac_core3_src = {
++      .ns_reg[0] = 0x3cec,
++      .ns_reg[1] = 0x3cf0,
++      .md_reg[0] = 0x3ce4,
++      .md_reg[1] = 0x3ce8,
++      .bank_reg = 0x3ce0,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_gmac,
++      .clkr = {
++              .enable_reg = 0x3ce0,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core3_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch gmac_core3_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 6,
++      .hwcg_reg = 0x3cf4,
++      .hwcg_bit = 6,
++      .clkr = {
++              .enable_reg = 0x3cf4,
++              .enable_mask = BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core3_clk",
++                      .parent_names = (const char *[]){
++                              "gmac_core3_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static struct clk_dyn_rcg gmac_core4_src = {
++      .ns_reg[0] = 0x3d0c,
++      .ns_reg[1] = 0x3d10,
++      .md_reg[0] = 0x3d04,
++      .md_reg[1] = 0x3d08,
++      .bank_reg = 0x3d00,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_gmac,
++      .clkr = {
++              .enable_reg = 0x3d00,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core4_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch gmac_core4_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 7,
++      .hwcg_reg = 0x3d14,
++      .hwcg_bit = 6,
++      .clkr = {
++              .enable_reg = 0x3d14,
++              .enable_mask = BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core4_clk",
++                      .parent_names = (const char *[]){
++                              "gmac_core4_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static const struct freq_tbl clk_tbl_nss_tcm[] = {
++      { 266000000, P_PLL0, 3, 0, 0 },
++      { 400000000, P_PLL0, 2, 0, 0 },
++      { }
++};
++
++static struct clk_dyn_rcg nss_tcm_src = {
++      .ns_reg[0] = 0x3dc4,
++      .ns_reg[1] = 0x3dc8,
++      .bank_reg = 0x3dc0,
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 4,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 4,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_nss_tcm,
++      .clkr = {
++              .enable_reg = 0x3dc0,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "nss_tcm_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch nss_tcm_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 14,
++      .clkr = {
++              .enable_reg = 0x3dd0,
++              .enable_mask = BIT(6) | BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "nss_tcm_clk",
++                      .parent_names = (const char *[]){
++                              "nss_tcm_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static const struct freq_tbl clk_tbl_nss[] = {
++      { 110000000, P_PLL18, 1, 1, 5 },
++      { 275000000, P_PLL18, 2, 0, 0 },
++      { 550000000, P_PLL18, 1, 0, 0 },
++      { 733000000, P_PLL18, 1, 0, 0 },
++      { }
++};
++
++static struct clk_dyn_rcg ubi32_core1_src_clk = {
++      .ns_reg[0] = 0x3d2c,
++      .ns_reg[1] = 0x3d30,
++      .md_reg[0] = 0x3d24,
++      .md_reg[1] = 0x3d28,
++      .bank_reg = 0x3d20,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_nss,
++      .clkr = {
++              .enable_reg = 0x3d20,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "ubi32_core1_src_clk",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++                      .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
++              },
++      },
++};
++
++static struct clk_dyn_rcg ubi32_core2_src_clk = {
++      .ns_reg[0] = 0x3d4c,
++      .ns_reg[1] = 0x3d50,
++      .md_reg[0] = 0x3d44,
++      .md_reg[1] = 0x3d48,
++      .bank_reg = 0x3d40,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_nss,
++      .clkr = {
++              .enable_reg = 0x3d40,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "ubi32_core2_src_clk",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++                      .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
++              },
++      },
++};
++
+ static struct clk_regmap *gcc_ipq806x_clks[] = {
+       [PLL0] = &pll0.clkr,
+       [PLL0_VOTE] = &pll0_vote,
+@@ -2247,6 +2764,7 @@ static struct clk_regmap *gcc_ipq806x_cl
+       [PLL8_VOTE] = &pll8_vote,
+       [PLL14] = &pll14.clkr,
+       [PLL14_VOTE] = &pll14_vote,
++      [PLL18] = &pll18.clkr,
+       [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
+       [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
+       [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
+@@ -2344,6 +2862,18 @@ static struct clk_regmap *gcc_ipq806x_cl
+       [PLL9] = &hfpll0.clkr,
+       [PLL10] = &hfpll1.clkr,
+       [PLL12] = &hfpll_l2.clkr,
++      [GMAC_CORE1_CLK_SRC] = &gmac_core1_src.clkr,
++      [GMAC_CORE1_CLK] = &gmac_core1_clk.clkr,
++      [GMAC_CORE2_CLK_SRC] = &gmac_core2_src.clkr,
++      [GMAC_CORE2_CLK] = &gmac_core2_clk.clkr,
++      [GMAC_CORE3_CLK_SRC] = &gmac_core3_src.clkr,
++      [GMAC_CORE3_CLK] = &gmac_core3_clk.clkr,
++      [GMAC_CORE4_CLK_SRC] = &gmac_core4_src.clkr,
++      [GMAC_CORE4_CLK] = &gmac_core4_clk.clkr,
++      [UBI32_CORE1_CLK_SRC] = &ubi32_core1_src_clk.clkr,
++      [UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr,
++      [NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
++      [NSSTCM_CLK] = &nss_tcm_clk.clkr,
+ };
+ static const struct qcom_reset_map gcc_ipq806x_resets[] = {
+@@ -2462,6 +2992,48 @@ static const struct qcom_reset_map gcc_i
+       [USB30_1_PHY_RESET] = { 0x3b58, 0 },
+       [NSSFB0_RESET] = { 0x3b60, 6 },
+       [NSSFB1_RESET] = { 0x3b60, 7 },
++      [UBI32_CORE1_CLKRST_CLAMP_RESET] = { 0x3d3c, 3},
++      [UBI32_CORE1_CLAMP_RESET] = { 0x3d3c, 2 },
++      [UBI32_CORE1_AHB_RESET] = { 0x3d3c, 1 },
++      [UBI32_CORE1_AXI_RESET] = { 0x3d3c, 0 },
++      [UBI32_CORE2_CLKRST_CLAMP_RESET] = { 0x3d5c, 3 },
++      [UBI32_CORE2_CLAMP_RESET] = { 0x3d5c, 2 },
++      [UBI32_CORE2_AHB_RESET] = { 0x3d5c, 1 },
++      [UBI32_CORE2_AXI_RESET] = { 0x3d5c, 0 },
++      [GMAC_CORE1_RESET] = { 0x3cbc, 0 },
++      [GMAC_CORE2_RESET] = { 0x3cdc, 0 },
++      [GMAC_CORE3_RESET] = { 0x3cfc, 0 },
++      [GMAC_CORE4_RESET] = { 0x3d1c, 0 },
++      [GMAC_AHB_RESET] = { 0x3e24, 0 },
++      [NSS_CH0_RST_RX_CLK_N_RESET] = { 0x3b60, 0 },
++      [NSS_CH0_RST_TX_CLK_N_RESET] = { 0x3b60, 1 },
++      [NSS_CH0_RST_RX_125M_N_RESET] = { 0x3b60, 2 },
++      [NSS_CH0_HW_RST_RX_125M_N_RESET] = { 0x3b60, 3 },
++      [NSS_CH0_RST_TX_125M_N_RESET] = { 0x3b60, 4 },
++      [NSS_CH1_RST_RX_CLK_N_RESET] = { 0x3b60, 5 },
++      [NSS_CH1_RST_TX_CLK_N_RESET] = { 0x3b60, 6 },
++      [NSS_CH1_RST_RX_125M_N_RESET] = { 0x3b60, 7 },
++      [NSS_CH1_HW_RST_RX_125M_N_RESET] = { 0x3b60, 8 },
++      [NSS_CH1_RST_TX_125M_N_RESET] = { 0x3b60, 9 },
++      [NSS_CH2_RST_RX_CLK_N_RESET] = { 0x3b60, 10 },
++      [NSS_CH2_RST_TX_CLK_N_RESET] = { 0x3b60, 11 },
++      [NSS_CH2_RST_RX_125M_N_RESET] = { 0x3b60, 12 },
++      [NSS_CH2_HW_RST_RX_125M_N_RESET] = { 0x3b60, 13 },
++      [NSS_CH2_RST_TX_125M_N_RESET] = { 0x3b60, 14 },
++      [NSS_CH3_RST_RX_CLK_N_RESET] = { 0x3b60, 15 },
++      [NSS_CH3_RST_TX_CLK_N_RESET] = { 0x3b60, 16 },
++      [NSS_CH3_RST_RX_125M_N_RESET] = { 0x3b60, 17 },
++      [NSS_CH3_HW_RST_RX_125M_N_RESET] = { 0x3b60, 18 },
++      [NSS_CH3_RST_TX_125M_N_RESET] = { 0x3b60, 19 },
++      [NSS_RST_RX_250M_125M_N_RESET] = { 0x3b60, 20 },
++      [NSS_RST_TX_250M_125M_N_RESET] = { 0x3b60, 21 },
++      [NSS_QSGMII_TXPI_RST_N_RESET] = { 0x3b60, 22 },
++      [NSS_QSGMII_CDR_RST_N_RESET] = { 0x3b60, 23 },
++      [NSS_SGMII2_CDR_RST_N_RESET] = { 0x3b60, 24 },
++      [NSS_SGMII3_CDR_RST_N_RESET] = { 0x3b60, 25 },
++      [NSS_CAL_PRBS_RST_N_RESET] = { 0x3b60, 26 },
++      [NSS_LCKDT_RST_N_RESET] = { 0x3b60, 27 },
++      [NSS_SRDS_N_RESET] = { 0x3b60, 28 },
+ };
+ static const struct regmap_config gcc_ipq806x_regmap_config = {
+@@ -2490,6 +3062,8 @@ static int gcc_ipq806x_probe(struct plat
+ {
+       struct clk *clk;
+       struct device *dev = &pdev->dev;
++      struct regmap *regmap;
++      int ret;
+       /* Temporary until RPM clocks supported */
+       clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
+@@ -2500,7 +3074,25 @@ static int gcc_ipq806x_probe(struct plat
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+-      return qcom_cc_probe(pdev, &gcc_ipq806x_desc);
++      ret = qcom_cc_probe(pdev, &gcc_ipq806x_desc);
++      if (ret)
++              return ret;
++
++      regmap = dev_get_regmap(dev, NULL);
++      if (!regmap)
++              return -ENODEV;
++
++      /* Setup PLL18 static bits */
++      regmap_update_bits(regmap, 0x31a4, 0xffffffc0, 0x40000400);
++      regmap_write(regmap, 0x31b0, 0x3080);
++
++      /* Set GMAC footswitch sleep/wakeup values */
++      regmap_write(regmap, 0x3cb8, 8);
++      regmap_write(regmap, 0x3cd8, 8);
++      regmap_write(regmap, 0x3cf8, 8);
++      regmap_write(regmap, 0x3d18, 8);
++
++      return 0;
+ }
+ static int gcc_ipq806x_remove(struct platform_device *pdev)
+--- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
++++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
+@@ -289,5 +289,7 @@
+ #define UBI32_CORE2_CLK_SRC                   278
+ #define UBI32_CORE1_CLK                               279
+ #define UBI32_CORE2_CLK                               280
++#define NSSTCM_CLK_SRC                                281
++#define NSSTCM_CLK                            282
+ #endif
+--- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h
++++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h
+@@ -129,4 +129,47 @@
+ #define USB30_1_PHY_RESET                             112
+ #define NSSFB0_RESET                                  113
+ #define NSSFB1_RESET                                  114
++#define UBI32_CORE1_CLKRST_CLAMP_RESET                        115
++#define UBI32_CORE1_CLAMP_RESET                               116
++#define UBI32_CORE1_AHB_RESET                         117
++#define UBI32_CORE1_AXI_RESET                         118
++#define UBI32_CORE2_CLKRST_CLAMP_RESET                        119
++#define UBI32_CORE2_CLAMP_RESET                               120
++#define UBI32_CORE2_AHB_RESET                         121
++#define UBI32_CORE2_AXI_RESET                         122
++#define GMAC_CORE1_RESET                              123
++#define GMAC_CORE2_RESET                              124
++#define GMAC_CORE3_RESET                              125
++#define GMAC_CORE4_RESET                              126
++#define GMAC_AHB_RESET                                        127
++#define NSS_CH0_RST_RX_CLK_N_RESET                    128
++#define NSS_CH0_RST_TX_CLK_N_RESET                    129
++#define NSS_CH0_RST_RX_125M_N_RESET                   130
++#define NSS_CH0_HW_RST_RX_125M_N_RESET                        131
++#define NSS_CH0_RST_TX_125M_N_RESET                   132
++#define NSS_CH1_RST_RX_CLK_N_RESET                    133
++#define NSS_CH1_RST_TX_CLK_N_RESET                    134
++#define NSS_CH1_RST_RX_125M_N_RESET                   135
++#define NSS_CH1_HW_RST_RX_125M_N_RESET                        136
++#define NSS_CH1_RST_TX_125M_N_RESET                   137
++#define NSS_CH2_RST_RX_CLK_N_RESET                    138
++#define NSS_CH2_RST_TX_CLK_N_RESET                    139
++#define NSS_CH2_RST_RX_125M_N_RESET                   140
++#define NSS_CH2_HW_RST_RX_125M_N_RESET                        141
++#define NSS_CH2_RST_TX_125M_N_RESET                   142
++#define NSS_CH3_RST_RX_CLK_N_RESET                    143
++#define NSS_CH3_RST_TX_CLK_N_RESET                    144
++#define NSS_CH3_RST_RX_125M_N_RESET                   145
++#define NSS_CH3_HW_RST_RX_125M_N_RESET                        146
++#define NSS_CH3_RST_TX_125M_N_RESET                   147
++#define NSS_RST_RX_250M_125M_N_RESET                  148
++#define NSS_RST_TX_250M_125M_N_RESET                  149
++#define NSS_QSGMII_TXPI_RST_N_RESET                   150
++#define NSS_QSGMII_CDR_RST_N_RESET                    151
++#define NSS_SGMII2_CDR_RST_N_RESET                    152
++#define NSS_SGMII3_CDR_RST_N_RESET                    153
++#define NSS_CAL_PRBS_RST_N_RESET                      154
++#define NSS_LCKDT_RST_N_RESET                         155
++#define NSS_SRDS_N_RESET                              156
++
+ #endif
diff --git a/target/linux/ipq806x/patches-3.18/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch b/target/linux/ipq806x/patches-3.18/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch
new file mode 100644 (file)
index 0000000..8e59b5c
--- /dev/null
@@ -0,0 +1,105 @@
+From 4f09499bc1d9bb095caccbcd73ff951ee631e521 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 15:42:40 -0700
+Subject: [PATCH 1/8] stmmac: add phy-handle support to the platform layer
+
+On stmmac driver, PHY specification in device-tree was done using the
+non-standard property "snps,phy-addr". Specifying a PHY on a different
+MDIO bus that the one within the stmmac controller doesn't seem to be
+possible when device-tree is used.
+
+This change adds support for the phy-handle property, as specified in
+Documentation/devicetree/bindings/net/ethernet.txt.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 28 ++++++++++++++--------
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |  6 ++++-
+ include/linux/stmmac.h                             |  1 +
+ 3 files changed, 24 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -52,6 +52,7 @@
+ #include "stmmac_ptp.h"
+ #include "stmmac.h"
+ #include <linux/reset.h>
++#include <linux/of_mdio.h>
+ #define STMMAC_ALIGN(x)       L1_CACHE_ALIGN(x)
+@@ -818,18 +819,25 @@ static int stmmac_init_phy(struct net_de
+       priv->speed = 0;
+       priv->oldduplex = -1;
+-      if (priv->plat->phy_bus_name)
+-              snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
+-                       priv->plat->phy_bus_name, priv->plat->bus_id);
+-      else
+-              snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
+-                       priv->plat->bus_id);
+-
+-      snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
+-               priv->plat->phy_addr);
+-      pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id_fmt);
++      if (priv->plat->phy_node) {
++              phydev = of_phy_connect(dev, priv->plat->phy_node,
++                                      &stmmac_adjust_link, 0, interface);
++      } else {
++              if (priv->plat->phy_bus_name)
++                      snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
++                               priv->plat->phy_bus_name, priv->plat->bus_id);
++              else
++                      snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
++                               priv->plat->bus_id);
++
++              snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
++                       priv->plat->phy_addr);
++              pr_debug("stmmac_init_phy:  trying to attach to %s\n",
++                       phy_id_fmt);
+-      phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
++              phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
++                                   interface);
++      }
+       if (IS_ERR(phydev)) {
+               pr_err("%s: Could not attach to PHY\n", dev->name);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -27,6 +27,7 @@
+ #include <linux/of.h>
+ #include <linux/of_net.h>
+ #include <linux/of_device.h>
++#include <linux/of_mdio.h>
+ #include "stmmac.h"
+ static const struct of_device_id stmmac_dt_ids[] = {
+@@ -155,13 +156,16 @@ static int stmmac_probe_config_dt(struct
+       /* Default to phy auto-detection */
+       plat->phy_addr = -1;
++      /* If we find a phy-handle property, use it as the PHY */
++      plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
++
+       /* "snps,phy-addr" is not a standard property. Mark it as deprecated
+        * and warn of its use. Remove this when phy node support is added.
+        */
+       if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
+               dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
+-      if (plat->phy_bus_name)
++      if (plat->phy_node || plat->phy_bus_name)
+               plat->mdio_bus_data = NULL;
+       else
+               plat->mdio_bus_data =
+--- a/include/linux/stmmac.h
++++ b/include/linux/stmmac.h
+@@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
+       int phy_addr;
+       int interface;
+       struct stmmac_mdio_bus_data *mdio_bus_data;
++      struct device_node *phy_node;
+       struct stmmac_dma_cfg *dma_cfg;
+       int clk_csr;
+       int has_gmac;
diff --git a/target/linux/ipq806x/patches-3.18/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch b/target/linux/ipq806x/patches-3.18/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch
new file mode 100644 (file)
index 0000000..e8f9b5c
--- /dev/null
@@ -0,0 +1,65 @@
+From 0149d275415cd1b2382ce94e5eb32641590097d0 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 15:57:12 -0700
+Subject: [PATCH 2/8] stmmac: move error path at the end of
+ stmmac_probe_config_dt()
+
+We will want to do additional clean-up on certain errors. Therefore,
+this change moves the error path at the end of the function for better
+code readability.
+
+This patch doesn't change anything functionally.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -117,13 +117,18 @@ static int stmmac_probe_config_dt(struct
+       struct device_node *np = pdev->dev.of_node;
+       struct stmmac_dma_cfg *dma_cfg;
+       const struct of_device_id *device;
++      int ret;
+-      if (!np)
+-              return -ENODEV;
++      if (!np) {
++              ret = -ENODEV;
++              goto err;
++      }
+       device = of_match_device(stmmac_dt_ids, &pdev->dev);
+-      if (!device)
+-              return -ENODEV;
++      if (!device) {
++              ret = -ENODEV;
++              goto err;
++      }
+       if (device->data) {
+               const struct stmmac_of_data *data = device->data;
+@@ -219,8 +224,10 @@ static int stmmac_probe_config_dt(struct
+       if (of_find_property(np, "snps,pbl", NULL)) {
+               dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
+                                      GFP_KERNEL);
+-              if (!dma_cfg)
+-                      return -ENOMEM;
++              if (!dma_cfg) {
++                      ret = -ENOMEM;
++                      goto err;
++              }
+               plat->dma_cfg = dma_cfg;
+               of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
+               dma_cfg->fixed_burst =
+@@ -235,6 +242,9 @@ static int stmmac_probe_config_dt(struct
+       }
+       return 0;
++
++err:
++      return ret;
+ }
+ #else
+ static int stmmac_probe_config_dt(struct platform_device *pdev,
diff --git a/target/linux/ipq806x/patches-3.18/703-stmmac-add-fixed-link-device-tree-support.patch b/target/linux/ipq806x/patches-3.18/703-stmmac-add-fixed-link-device-tree-support.patch
new file mode 100644 (file)
index 0000000..3c20fe4
--- /dev/null
@@ -0,0 +1,64 @@
+From 3a95f75867be562cb919ff23a738f70357188fbd Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 16:02:03 -0700
+Subject: [PATCH 3/8] stmmac: add fixed-link device-tree support
+
+In case DT is used, this change adds the ability to the stmmac driver to
+detect a fixed-link PHY, instanciate it, and use it during
+phy_connect().
+
+Fixed link PHYs DT usage is described in:
+Documentation/devicetree/bindings/net/fixed-link.txt
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c     |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 12 +++++++++++-
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -858,7 +858,7 @@ static int stmmac_init_phy(struct net_de
+        * device as well.
+        * Note: phydev->phy_id is the result of reading the UID PHY registers.
+        */
+-      if (phydev->phy_id == 0) {
++      if (!priv->plat->phy_node && phydev->phy_id == 0) {
+               phy_disconnect(phydev);
+               return -ENODEV;
+       }
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -164,6 +164,14 @@ static int stmmac_probe_config_dt(struct
+       /* If we find a phy-handle property, use it as the PHY */
+       plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
++      /* If phy-handle is not specified, check if we have a fixed-phy */
++      if (!plat->phy_node && of_phy_is_fixed_link(np)) {
++              if ((of_phy_register_fixed_link(np) < 0))
++                      return -ENODEV;
++
++              plat->phy_node = of_node_get(np);
++      }
++
+       /* "snps,phy-addr" is not a standard property. Mark it as deprecated
+        * and warn of its use. Remove this when phy node support is added.
+        */
+@@ -226,7 +234,7 @@ static int stmmac_probe_config_dt(struct
+                                      GFP_KERNEL);
+               if (!dma_cfg) {
+                       ret = -ENOMEM;
+-                      goto err;
++                      goto err2;
+               }
+               plat->dma_cfg = dma_cfg;
+               of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
+@@ -243,6 +251,8 @@ static int stmmac_probe_config_dt(struct
+       return 0;
++err2:
++      of_node_put(np);
+ err:
+       return ret;
+ }
diff --git a/target/linux/ipq806x/patches-3.18/704-stmmac-add-ipq806x-glue-layer.patch b/target/linux/ipq806x/patches-3.18/704-stmmac-add-ipq806x-glue-layer.patch
new file mode 100644 (file)
index 0000000..fa67404
--- /dev/null
@@ -0,0 +1,427 @@
+From 69fb970ad3fe05af7cb99ea78230c69c7ca0d03b Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 16:10:22 -0700
+Subject: [PATCH 4/8] stmmac: add ipq806x glue layer
+
+The ethernet controller available in IPQ806x is a Synopsys DesignWare
+Gigabit MAC IP core, already supported by the stmmac driver.
+
+This glue layer implements some platform specific settings required to
+get the controller working on an IPQ806x based platform.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/Kconfig        |   1 +
+ drivers/net/ethernet/stmicro/stmmac/Makefile       |   2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c    | 324 +++++++++++++++++++++
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   1 +
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |   1 +
+ 5 files changed, 328 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c
+
+--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+@@ -16,6 +16,7 @@ if STMMAC_ETH
+ config STMMAC_PLATFORM
+       bool "STMMAC Platform bus support"
+       depends on STMMAC_ETH
++      select MFD_SYSCON
+       default y
+       ---help---
+         This selects the platform specific bus support for
+@@ -26,6 +27,15 @@ config STMMAC_PLATFORM
+         If unsure, say N.
++config DWMAC_IPQ806X
++      bool "QCA IPQ806x dwmac support"
++      depends on STMMAC_PLATFORM && ARCH_QCOM
++      help
++        Support for Ethernet controller on QCA IPQ806x SoC.
++
++        This selects the QCA IPQ806x SoC glue layer support for
++        the stmmac device driver.
++
+ config DWMAC_MESON
+       bool "Amlogic Meson dwmac support"
+       depends on STMMAC_PLATFORM && ARCH_MESON
+--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
++++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
+@@ -1,6 +1,7 @@
+ obj-$(CONFIG_STMMAC_ETH) += stmmac.o
+ stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
+ stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
++stmmac-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o
+ stmmac-$(CONFIG_DWMAC_MESON) += dwmac-meson.o
+ stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
+ stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -46,6 +46,9 @@ static const struct of_device_id stmmac_
+ #ifdef CONFIG_DWMAC_SOCFPGA
+       { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
+ #endif
++#ifdef CONFIG_DWMAC_IPQ806X
++      { .compatible = "qcom,ipq806x-gmac", .data = &ipq806x_gmac_data },
++#endif
+       /* SoC specific glue layers should come before generic bindings */
+       { .compatible = "st,spear600-gmac"},
+       { .compatible = "snps,dwmac-3.610"},
+--- /dev/null
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+@@ -0,0 +1,343 @@
++/*
++ * Qualcomm Atheros IPQ806x GMAC glue layer
++ *
++ * Copyright (C) 2015 The Linux Foundation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/phy.h>
++#include <linux/regmap.h>
++#include <linux/clk.h>
++#include <linux/reset.h>
++#include <linux/of_net.h>
++#include <linux/mfd/syscon.h>
++#include <linux/stmmac.h>
++#include <linux/of_mdio.h>
++
++#include "stmmac.h"
++
++#define NSS_COMMON_CLK_GATE                   0x8
++#define NSS_COMMON_CLK_GATE_PTP_EN(x)         BIT(0x10 + x)
++#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x)    BIT(0x9 + (x * 2))
++#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x)    BIT(0x8 + (x * 2))
++#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x)     BIT(0x4 + x)
++#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x)     BIT(0x0 + x)
++
++#define NSS_COMMON_CLK_DIV0                   0xC
++#define NSS_COMMON_CLK_DIV_OFFSET(x)          (x * 8)
++#define NSS_COMMON_CLK_DIV_MASK                       0x7f
++
++#define NSS_COMMON_CLK_SRC_CTRL                       0x14
++#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x)     (1 << x)
++/* Mode is coded on 1 bit but is different depending on the MAC ID:
++ * MAC0: QSGMII=0 RGMII=1
++ * MAC1: QSGMII=0 SGMII=0 RGMII=1
++ * MAC2 & MAC3: QSGMII=0 SGMII=1
++ */
++#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x)      1
++#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x)      ((x >= 2) ? 1 : 0)
++
++#define NSS_COMMON_MACSEC_CTL                 0x28
++#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x)        (1 << x)
++
++#define NSS_COMMON_GMAC_CTL(x)                        (0x30 + (x * 4))
++#define NSS_COMMON_GMAC_CTL_CSYS_REQ          BIT(19)
++#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL     BIT(16)
++#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET  8
++#define NSS_COMMON_GMAC_CTL_IFG_OFFSET                0
++#define NSS_COMMON_GMAC_CTL_IFG_MASK          0x3f
++
++#define NSS_COMMON_CLK_DIV_RGMII_1000         1
++#define NSS_COMMON_CLK_DIV_RGMII_100          9
++#define NSS_COMMON_CLK_DIV_RGMII_10           99
++#define NSS_COMMON_CLK_DIV_SGMII_1000         0
++#define NSS_COMMON_CLK_DIV_SGMII_100          4
++#define NSS_COMMON_CLK_DIV_SGMII_10           49
++
++#define QSGMII_PCS_MODE_CTL                   0x68
++#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x)     BIT((x * 8) + 7)
++
++#define QSGMII_PCS_CAL_LCKDT_CTL              0x120
++#define QSGMII_PCS_CAL_LCKDT_CTL_RST          BIT(19)
++
++/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
++#define QSGMII_PHY_SGMII_CTL(x)                       ((x == 1) ? 0x134 : \
++                                               (0x13c + (4 * (x - 2))))
++#define QSGMII_PHY_CDR_EN                     BIT(0)
++#define QSGMII_PHY_RX_FRONT_EN                        BIT(1)
++#define QSGMII_PHY_RX_SIGNAL_DETECT_EN                BIT(2)
++#define QSGMII_PHY_TX_DRIVER_EN                       BIT(3)
++#define QSGMII_PHY_QSGMII_EN                  BIT(7)
++#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET     12
++#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK               0x7
++#define QSGMII_PHY_RX_DC_BIAS_OFFSET          18
++#define QSGMII_PHY_RX_DC_BIAS_MASK            0x3
++#define QSGMII_PHY_RX_INPUT_EQU_OFFSET                20
++#define QSGMII_PHY_RX_INPUT_EQU_MASK          0x3
++#define QSGMII_PHY_CDR_PI_SLEW_OFFSET         22
++#define QSGMII_PHY_CDR_PI_SLEW_MASK           0x3
++#define QSGMII_PHY_TX_DRV_AMP_OFFSET          28
++#define QSGMII_PHY_TX_DRV_AMP_MASK            0xf
++
++struct ipq806x_gmac {
++      struct platform_device *pdev;
++      struct regmap *nss_common;
++      struct regmap *qsgmii_csr;
++      uint32_t id;
++      struct clk *core_clk;
++      phy_interface_t phy_mode;
++};
++
++static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
++{
++      struct device *dev = &gmac->pdev->dev;
++      int div;
++
++      switch (speed) {
++      case SPEED_1000:
++              div = NSS_COMMON_CLK_DIV_SGMII_1000;
++              break;
++
++      case SPEED_100:
++              div = NSS_COMMON_CLK_DIV_SGMII_100;
++              break;
++
++      case SPEED_10:
++              div = NSS_COMMON_CLK_DIV_SGMII_10;
++              break;
++
++      default:
++              dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
++              return -EINVAL;
++      }
++
++      return div;
++}
++
++static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
++{
++      struct device *dev = &gmac->pdev->dev;
++      int div;
++
++      switch (speed) {
++      case SPEED_1000:
++              div = NSS_COMMON_CLK_DIV_RGMII_1000;
++              break;
++
++      case SPEED_100:
++              div = NSS_COMMON_CLK_DIV_RGMII_100;
++              break;
++
++      case SPEED_10:
++              div = NSS_COMMON_CLK_DIV_RGMII_10;
++              break;
++
++      default:
++              dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
++              return -EINVAL;
++      }
++
++      return div;
++}
++
++static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
++{
++      uint32_t clk_bits, val;
++      int div;
++
++      switch (gmac->phy_mode) {
++      case PHY_INTERFACE_MODE_RGMII:
++              div = get_clk_div_rgmii(gmac, speed);
++              clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
++                         NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
++              break;
++
++      case PHY_INTERFACE_MODE_SGMII:
++              div = get_clk_div_sgmii(gmac, speed);
++              clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
++                         NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
++              break;
++
++      default:
++              dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
++                      phy_modes(gmac->phy_mode));
++              return -EINVAL;
++      }
++
++      /* Disable the clocks */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
++      val &= ~clk_bits;
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
++
++      /* Set the divider */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
++      val &= ~(NSS_COMMON_CLK_DIV_MASK
++               << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
++      val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
++
++      /* Enable the clock back */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
++      val |= clk_bits;
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
++
++      return 0;
++}
++
++static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
++{
++      struct device *dev = &gmac->pdev->dev;
++
++      gmac->phy_mode = of_get_phy_mode(dev->of_node);
++      if (gmac->phy_mode < 0) {
++              dev_err(dev, "missing phy mode property\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
++              dev_err(dev, "missing qcom id property\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      /* The GMACs are called 1 to 4 in the documentation, but to simplify the
++       * code and keep it consistent with the Linux convention, we'll number
++       * them from 0 to 3 here.
++       */
++      if (gmac->id < 0 || gmac->id > 3) {
++              dev_err(dev, "invalid gmac id\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      gmac->core_clk = devm_clk_get(dev, "stmmaceth");
++      if (IS_ERR(gmac->core_clk)) {
++              dev_err(dev, "missing stmmaceth clk property\n");
++              return gmac->core_clk;
++      }
++      clk_set_rate(gmac->core_clk, 266000000);
++
++      /* Setup the register map for the nss common registers */
++      gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
++                                                         "qcom,nss-common");
++      if (IS_ERR(gmac->nss_common)) {
++              dev_err(dev, "missing nss-common node\n");
++              return gmac->nss_common;
++      }
++
++      /* Setup the register map for the qsgmii csr registers */
++      gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
++                                                         "qcom,qsgmii-csr");
++      if (IS_ERR(gmac->qsgmii_csr)) {
++              dev_err(dev, "missing qsgmii-csr node\n");
++              return gmac->qsgmii_csr;
++      }
++
++      return NULL;
++}
++
++static void *ipq806x_gmac_setup(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct ipq806x_gmac *gmac;
++      int val;
++      void *err;
++
++      gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
++      if (!gmac)
++              return ERR_PTR(-ENOMEM);
++
++      gmac->pdev = pdev;
++
++      err = ipq806x_gmac_of_parse(gmac);
++      if (err) {
++              dev_err(dev, "device tree parsing error\n");
++              return err;
++      }
++
++      regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
++                   QSGMII_PCS_CAL_LCKDT_CTL_RST);
++
++      /* Inter frame gap is set to 12 */
++      val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
++            12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
++      /* We also initiate an AXI low power exit request */
++      val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
++      switch (gmac->phy_mode) {
++      case PHY_INTERFACE_MODE_RGMII:
++              val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
++              break;
++      case PHY_INTERFACE_MODE_SGMII:
++              val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
++              break;
++      default:
++              dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
++                      phy_modes(gmac->phy_mode));
++              return NULL;
++      }
++      regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
++
++      /* Configure the clock src according to the mode */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
++      val &= ~NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
++      switch (gmac->phy_mode) {
++      case PHY_INTERFACE_MODE_RGMII:
++              val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
++                      NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
++              break;
++      case PHY_INTERFACE_MODE_SGMII:
++              val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
++                      NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
++              break;
++      default:
++              dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
++                      phy_modes(gmac->phy_mode));
++              return NULL;
++      }
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
++
++      /* Enable PTP clock */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
++      val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
++
++      if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
++              regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
++                           QSGMII_PHY_CDR_EN |
++                           QSGMII_PHY_RX_FRONT_EN |
++                           QSGMII_PHY_RX_SIGNAL_DETECT_EN |
++                           QSGMII_PHY_TX_DRIVER_EN |
++                           QSGMII_PHY_QSGMII_EN |
++                           0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
++                           0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET |
++                           0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
++                           0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
++                           0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET);
++      }
++
++      return gmac;
++}
++
++static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
++{
++      struct ipq806x_gmac *gmac = priv;
++
++      ipq806x_gmac_set_speed(gmac, speed);
++}
++
++const struct stmmac_of_data ipq806x_gmac_data = {
++      .has_gmac       = 1,
++      .setup          = ipq806x_gmac_setup,
++      .fix_mac_speed  = ipq806x_gmac_fix_mac_speed,
++};
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -137,6 +137,9 @@ void stmmac_disable_eee_mode(struct stmm
+ bool stmmac_eee_init(struct stmmac_priv *priv);
+ #ifdef CONFIG_STMMAC_PLATFORM
++#ifdef CONFIG_DWMAC_IPQ806X
++extern const struct stmmac_of_data ipq806x_gmac_data;
++#endif
+ #ifdef CONFIG_DWMAC_MESON
+ extern const struct stmmac_of_data meson6_dwmac_data;
+ #endif
diff --git a/target/linux/ipq806x/patches-3.18/705-net-stmmac-ipq806x-document-device-tree-bindings.patch b/target/linux/ipq806x/patches-3.18/705-net-stmmac-ipq806x-document-device-tree-bindings.patch
new file mode 100644 (file)
index 0000000..3144fa3
--- /dev/null
@@ -0,0 +1,52 @@
+From 0f9605d9409b77a89daef91cc68239fc2ff50457 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 16:51:25 -0700
+Subject: [PATCH 5/8] net: stmmac: ipq806x: document device tree bindings
+
+Add the device tree bindings documentation for the QCA IPQ806x
+variant of the Synopsys DesignWare MAC.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ .../devicetree/bindings/net/ipq806x-dwmac.txt      | 35 ++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
+@@ -0,0 +1,35 @@
++* IPQ806x DWMAC Ethernet controller
++
++The device inherits all the properties of the dwmac/stmmac devices
++described in the file net/stmmac.txt with the following changes.
++
++Required properties:
++
++- compatible: should be "qcom,ipq806x-gmac" along with "snps,dwmac"
++            and any applicable more detailed version number
++            described in net/stmmac.txt
++
++- qcom,nss-common: should contain a phandle to a syscon device mapping the
++                 nss-common registers.
++
++- qcom,qsgmii-csr: should contain a phandle to a syscon device mapping the
++                 qsgmii-csr registers.
++
++Example:
++
++      gmac: ethernet@37000000 {
++              device_type = "network";
++              compatible = "qcom,ipq806x-gmac";
++              reg = <0x37000000 0x200000>;
++              interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
++              interrupt-names = "macirq";
++
++              qcom,nss-common = <&nss_common>;
++              qcom,qsgmii-csr = <&qsgmii_csr>;
++
++              clocks = <&gcc GMAC_CORE1_CLK>;
++              clock-names = "stmmaceth";
++
++              resets = <&gcc GMAC_CORE1_RESET>;
++              reset-names = "stmmaceth";
++      };
diff --git a/target/linux/ipq806x/patches-3.18/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch b/target/linux/ipq806x/patches-3.18/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch
new file mode 100644 (file)
index 0000000..50127fd
--- /dev/null
@@ -0,0 +1,171 @@
+From df944689d491e6af533173bf2ef448c3dd334f15 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Mon, 11 May 2015 15:15:25 -0700
+Subject: [PATCH 6/8] net: stmmac: create one debugfs dir per net-device
+
+stmmac DebugFS entries are currently global to the driver. As a result,
+having more than one stmmac device in the system creates the following
+error:
+* ERROR stmmaceth, debugfs create directory failed
+* stmmac_hw_setup: failed debugFS registration
+
+This also results in being able to access the debugfs information for
+the first registered device only.
+
+This patch changes the debugfs structure to have one sub-directory per
+net-device. Files under "/sys/kernel/debug/stmmaceth" will now show-up
+under /sys/kernel/debug/stmmaceth/ethN/.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h      |  6 ++
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 76 ++++++++++++++++-------
+ 2 files changed, 59 insertions(+), 23 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -116,6 +116,12 @@ struct stmmac_priv {
+       int use_riwt;
+       int irq_wake;
+       spinlock_t ptp_lock;
++
++#ifdef CONFIG_DEBUG_FS
++      struct dentry *dbgfs_dir;
++      struct dentry *dbgfs_rings_status;
++      struct dentry *dbgfs_dma_cap;
++#endif
+ };
+ int stmmac_mdio_unregister(struct net_device *ndev);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -119,7 +119,7 @@ static irqreturn_t stmmac_interrupt(int
+ #ifdef CONFIG_STMMAC_DEBUG_FS
+ static int stmmac_init_fs(struct net_device *dev);
+-static void stmmac_exit_fs(void);
++static void stmmac_exit_fs(struct net_device *dev);
+ #endif
+ #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
+@@ -1879,7 +1879,7 @@ static int stmmac_release(struct net_dev
+       netif_carrier_off(dev);
+ #ifdef CONFIG_STMMAC_DEBUG_FS
+-      stmmac_exit_fs();
++      stmmac_exit_fs(dev);
+ #endif
+       stmmac_release_ptp(priv);
+@@ -2467,8 +2467,6 @@ static int stmmac_ioctl(struct net_devic
+ #ifdef CONFIG_STMMAC_DEBUG_FS
+ static struct dentry *stmmac_fs_dir;
+-static struct dentry *stmmac_rings_status;
+-static struct dentry *stmmac_dma_cap;
+ static void sysfs_display_ring(void *head, int size, int extend_desc,
+                              struct seq_file *seq)
+@@ -2607,36 +2605,39 @@ static const struct file_operations stmm
+ static int stmmac_init_fs(struct net_device *dev)
+ {
+-      /* Create debugfs entries */
+-      stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
++      struct stmmac_priv *priv = netdev_priv(dev);
++
++      /* Create per netdev entries */
++      priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir);
+-      if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
+-              pr_err("ERROR %s, debugfs create directory failed\n",
+-                     STMMAC_RESOURCE_NAME);
++      if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) {
++              pr_err("ERROR %s/%s, debugfs create directory failed\n",
++                     STMMAC_RESOURCE_NAME, dev->name);
+               return -ENOMEM;
+       }
+       /* Entry to report DMA RX/TX rings */
+-      stmmac_rings_status = debugfs_create_file("descriptors_status",
+-                                                S_IRUGO, stmmac_fs_dir, dev,
+-                                                &stmmac_rings_status_fops);
++      priv->dbgfs_rings_status =
++              debugfs_create_file("descriptors_status", S_IRUGO,
++                                  priv->dbgfs_dir, dev,
++                                  &stmmac_rings_status_fops);
+-      if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
++      if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) {
+               pr_info("ERROR creating stmmac ring debugfs file\n");
+-              debugfs_remove(stmmac_fs_dir);
++              debugfs_remove_recursive(priv->dbgfs_dir);
+               return -ENOMEM;
+       }
+       /* Entry to report the DMA HW features */
+-      stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
+-                                           dev, &stmmac_dma_cap_fops);
++      priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO,
++                                          priv->dbgfs_dir,
++                                          dev, &stmmac_dma_cap_fops);
+-      if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
++      if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) {
+               pr_info("ERROR creating stmmac MMC debugfs file\n");
+-              debugfs_remove(stmmac_rings_status);
+-              debugfs_remove(stmmac_fs_dir);
++              debugfs_remove_recursive(priv->dbgfs_dir);
+               return -ENOMEM;
+       }
+@@ -2644,11 +2645,11 @@ static int stmmac_init_fs(struct net_dev
+       return 0;
+ }
+-static void stmmac_exit_fs(void)
++static void stmmac_exit_fs(struct net_device *dev)
+ {
+-      debugfs_remove(stmmac_rings_status);
+-      debugfs_remove(stmmac_dma_cap);
+-      debugfs_remove(stmmac_fs_dir);
++      struct stmmac_priv *priv = netdev_priv(dev);
++
++      debugfs_remove_recursive(priv->dbgfs_dir);
+ }
+ #endif /* CONFIG_STMMAC_DEBUG_FS */
+@@ -3032,6 +3033,21 @@ static int __init stmmac_init(void)
+       ret = stmmac_register_pci();
+       if (ret)
+               goto err_pci;
++
++#ifdef CONFIG_STMMAC_DEBUG_FS
++      /* Create debugfs main directory if it doesn't exist yet */
++      if (stmmac_fs_dir == NULL) {
++              stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
++
++              if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
++                      pr_err("ERROR %s, debugfs create directory failed\n",
++                             STMMAC_RESOURCE_NAME);
++
++                      return -ENOMEM;
++              }
++      }
++#endif
++
+       return 0;
+ err_pci:
+       stmmac_unregister_platform();
+@@ -3042,6 +3058,9 @@ err:
+ static void __exit stmmac_exit(void)
+ {
++#ifdef CONFIG_STMMAC_DEBUG_FS
++      debugfs_remove_recursive(stmmac_fs_dir);
++#endif
+       stmmac_unregister_platform();
+       stmmac_unregister_pci();
+ }
diff --git a/target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch b/target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch
new file mode 100644 (file)
index 0000000..809d743
--- /dev/null
@@ -0,0 +1,145 @@
+From e81de9d28bd0421c236df322872e64edf4ee1852 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Mon, 11 May 2015 16:32:09 -0700
+Subject: [PATCH 7/8] ARM: dts: qcom: add mdio nodes to ap148 & db149
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 40 ++++++++++++++++++++++++++-
+ arch/arm/boot/dts/qcom-ipq8064-db149.dts | 46 ++++++++++++++++++++++++++++++++
+ 2 files changed, 85 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
++++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
+@@ -14,8 +14,9 @@
+               };
+       };
+-      alias {
++      aliases {
+               serial0 = &uart4;
++              mdio-gpio0 = &mdio0;
+       };
+       chosen {
+@@ -54,6 +55,15 @@
+                                       bias-none;
+                               };
+                       };
++
++                      mdio0_pins: mdio0_pins {
++                              mux {
++                                      pins = "gpio0", "gpio1";
++                                      function = "gpio";
++                                      drive-strength = <8>;
++                                      bias-disable;
++                              };
++                      };
+               };
+               gsbi@16300000 {
+@@ -163,5 +173,33 @@
+                       pinctrl-0 = <&pcie2_pins>;
+                       pinctrl-names = "default";
+               };
++
++              mdio0: mdio {
++                      compatible = "virtual,mdio-gpio";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
++                      pinctrl-0 = <&mdio0_pins>;
++                      pinctrl-names = "default";
++
++                      phy0: ethernet-phy@0 {
++                              device_type = "ethernet-phy";
++                              reg = <0>;
++                              qca,ar8327-initvals = <
++                                      0x00004 0x7600000   /* PAD0_MODE */
++                                      0x00008 0x1000000   /* PAD5_MODE */
++                                      0x0000c 0x80        /* PAD6_MODE */
++                                      0x000e4 0xaa545     /* MAC_POWER_SEL */
++                                      0x000e0 0xc74164de  /* SGMII_CTRL */
++                                      0x0007c 0x4e        /* PORT0_STATUS */
++                                      0x00094 0x4e        /* PORT6_STATUS */
++                                      >;
++                      };
++
++                      phy4: ethernet-phy@4 {
++                              device_type = "ethernet-phy";
++                              reg = <4>;
++                      };
++              };
+       };
+ };
+--- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts
++++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
+@@ -16,6 +16,7 @@
+       alias {
+               serial0 = &uart2;
++              mdio-gpio0 = &mdio0;
+       };
+       chosen {
+@@ -62,6 +63,15 @@
+                                       bias-none;
+                               };
+                       };
++
++                      mdio0_pins: mdio0_pins {
++                              mux {
++                                      pins = "gpio0", "gpio1";
++                                      function = "gpio";
++                                      drive-strength = <8>;
++                                      bias-disable;
++                              };
++                      };
+               };
+               gsbi2: gsbi@12480000 {
+@@ -173,5 +183,44 @@
+                       pinctrl-0 = <&pcie3_pins>;
+                       pinctrl-names = "default";
+               };
++
++              mdio0: mdio {
++                      compatible = "virtual,mdio-gpio";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
++
++                      pinctrl-0 = <&mdio0_pins>;
++                      pinctrl-names = "default";
++
++                      phy0: ethernet-phy@0 {
++                              device_type = "ethernet-phy";
++                              reg = <0>;
++                              qca,ar8327-initvals = <
++                                      0x00004 0x7600000   /* PAD0_MODE */
++                                      0x00008 0x1000000   /* PAD5_MODE */
++                                      0x0000c 0x80        /* PAD6_MODE */
++                                      0x000e4 0xaa545     /* MAC_POWER_SEL */
++                                      0x000e0 0xc74164de  /* SGMII_CTRL */
++                                      0x0007c 0x4e        /* PORT0_STATUS */
++                                      0x00094 0x4e        /* PORT6_STATUS */
++                              >;
++                      };
++
++                      phy4: ethernet-phy@4 {
++                              device_type = "ethernet-phy";
++                              reg = <4>;
++                      };
++
++                      phy6: ethernet-phy@6 {
++                              device_type = "ethernet-phy";
++                              reg = <6>;
++                      };
++
++                      phy7: ethernet-phy@7 {
++                              device_type = "ethernet-phy";
++                              reg = <7>;
++                      };
++              };
+       };
+ };
diff --git a/target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch b/target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch
new file mode 100644 (file)
index 0000000..cce30b0
--- /dev/null
@@ -0,0 +1,210 @@
+From cab1f4720e82f2e17eaeed9a9ad9e4f07c742977 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Mon, 11 May 2015 12:29:18 -0700
+Subject: [PATCH 8/8] ARM: dts: qcom: add gmac nodes to ipq806x platforms
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 31 ++++++++++++
+ arch/arm/boot/dts/qcom-ipq8064-db149.dts | 43 ++++++++++++++++
+ arch/arm/boot/dts/qcom-ipq8064.dtsi      | 86 ++++++++++++++++++++++++++++++++
+ 3 files changed, 160 insertions(+)
+
+--- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
++++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
+@@ -64,6 +64,16 @@
+                                       bias-disable;
+                               };
+                       };
++
++                      rgmii2_pins: rgmii2_pins {
++                              mux {
++                                      pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
++                                             "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62" ;
++                                      function = "rgmii2";
++                                      drive-strength = <8>;
++                                      bias-disable;
++                              };
++                      };
+               };
+               gsbi@16300000 {
+@@ -201,5 +211,26 @@
+                               reg = <4>;
+                       };
+               };
++
++              gmac1: ethernet@37200000 {
++                      status = "ok";
++                      phy-mode = "rgmii";
++                      phy-handle = <&phy4>;
++                      qcom,id = <1>;
++
++                      pinctrl-0 = <&rgmii2_pins>;
++                      pinctrl-names = "default";
++              };
++
++              gmac2: ethernet@37400000 {
++                      status = "ok";
++                      phy-mode = "sgmii";
++                      qcom,id = <2>;
++
++                      fixed-link {
++                              speed = <1000>;
++                              full-duplex;
++                      };
++              };
+       };
+ };
+--- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts
++++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
+@@ -72,6 +72,14 @@
+                                       bias-disable;
+                               };
+                       };
++
++                      rgmii0_pins: rgmii0_pins {
++                              mux {
++                                      pins = "gpio2", "gpio66";
++                                      drive-strength = <8>;
++                                      bias-disable;
++                              };
++                      };
+               };
+               gsbi2: gsbi@12480000 {
+@@ -222,5 +230,40 @@
+                               reg = <7>;
+                       };
+               };
++
++              gmac0: ethernet@37000000 {
++                      status = "ok";
++                      phy-mode = "rgmii";
++                      qcom,id = <0>;
++                      phy-handle = <&phy4>;
++
++                      pinctrl-0 = <&rgmii0_pins>;
++                      pinctrl-names = "default";
++              };
++
++              gmac1: ethernet@37200000 {
++                      status = "ok";
++                      phy-mode = "sgmii";
++                      qcom,id = <1>;
++
++                      fixed-link {
++                              speed = <1000>;
++                              full-duplex;
++                      };
++              };
++
++              gmac2: ethernet@37400000 {
++                      status = "ok";
++                      phy-mode = "sgmii";
++                      qcom,id = <2>;
++                      phy-handle = <&phy6>;
++              };
++
++              gmac3: ethernet@37600000 {
++                      status = "ok";
++                      phy-mode = "sgmii";
++                      qcom,id = <3>;
++                      phy-handle = <&phy7>;
++              };
+       };
+ };
+--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
+@@ -638,5 +638,91 @@
+                               dr_mode = "host";
+                       };
+               };
++
++              nss_common: syscon@03000000 {
++                      compatible = "syscon";
++                      reg = <0x03000000 0x0000FFFF>;
++              };
++
++              qsgmii_csr: syscon@1bb00000 {
++                      compatible = "syscon";
++                      reg = <0x1bb00000 0x000001FF>;
++              };
++
++              gmac0: ethernet@37000000 {
++                      device_type = "network";
++                      compatible = "qcom,ipq806x-gmac";
++                      reg = <0x37000000 0x200000>;
++                      interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "macirq";
++
++                      qcom,nss-common = <&nss_common>;
++                      qcom,qsgmii-csr = <&qsgmii_csr>;
++
++                      clocks = <&gcc GMAC_CORE1_CLK>;
++                      clock-names = "stmmaceth";
++
++                      resets = <&gcc GMAC_CORE1_RESET>;
++                      reset-names = "stmmaceth";
++
++                      status = "disabled";
++              };
++
++              gmac1: ethernet@37200000 {
++                      device_type = "network";
++                      compatible = "qcom,ipq806x-gmac";
++                      reg = <0x37200000 0x200000>;
++                      interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "macirq";
++
++                      qcom,nss-common = <&nss_common>;
++                      qcom,qsgmii-csr = <&qsgmii_csr>;
++
++                      clocks = <&gcc GMAC_CORE2_CLK>;
++                      clock-names = "stmmaceth";
++
++                      resets = <&gcc GMAC_CORE2_RESET>;
++                      reset-names = "stmmaceth";
++
++                      status = "disabled";
++              };
++
++              gmac2: ethernet@37400000 {
++                      device_type = "network";
++                      compatible = "qcom,ipq806x-gmac";
++                      reg = <0x37400000 0x200000>;
++                      interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "macirq";
++
++                      qcom,nss-common = <&nss_common>;
++                      qcom,qsgmii-csr = <&qsgmii_csr>;
++
++                      clocks = <&gcc GMAC_CORE3_CLK>;
++                      clock-names = "stmmaceth";
++
++                      resets = <&gcc GMAC_CORE3_RESET>;
++                      reset-names = "stmmaceth";
++
++                      status = "disabled";
++              };
++
++              gmac3: ethernet@37600000 {
++                      device_type = "network";
++                      compatible = "qcom,ipq806x-gmac";
++                      reg = <0x37600000 0x200000>;
++                      interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "macirq";
++
++                      qcom,nss-common = <&nss_common>;
++                      qcom,qsgmii-csr = <&qsgmii_csr>;
++
++                      clocks = <&gcc GMAC_CORE4_CLK>;
++                      clock-names = "stmmaceth";
++
++                      resets = <&gcc GMAC_CORE4_RESET>;
++                      reset-names = "stmmaceth";
++
++                      status = "disabled";
++              };
+       };
+ };
index a274f245d4b024034d8d391ea77c4cf7a6570721..29631b2c281a8b20e252ae7abd88040a47317fbc 100644 (file)
@@ -1,4 +1,4 @@
-From a32d6e7c8fca6371a2614924b89981bc912b6378 Mon Sep 17 00:00:00 2001
+From f26cc3733bdd697bd81ae505fc133fa7c9b6ea19 Mon Sep 17 00:00:00 2001
 From: Mathieu Olivari <mathieu@codeaurora.org>
 Date: Tue, 7 Apr 2015 19:58:58 -0700
 Subject: [PATCH] ARM: dts: qcom: add initial DB149 device-tree
@@ -9,8 +9,8 @@ SATA, USB2, USB3 and NOR flash.
 Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
 ---
  arch/arm/boot/dts/Makefile               |   1 +
- arch/arm/boot/dts/qcom-ipq8064-db149.dts | 257 +++++++++++++++++++++++++++++++
- 2 files changed, 258 insertions(+)
+ arch/arm/boot/dts/qcom-ipq8064-db149.dts | 132 +++++++++++++++++++++++++++++++
+ 2 files changed, 133 insertions(+)
  create mode 100644 arch/arm/boot/dts/qcom-ipq8064-db149.dts
 
 --- a/arch/arm/boot/dts/Makefile
@@ -25,7 +25,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
        qcom-msm8974-sony-xperia-honami.dtb
 --- /dev/null
 +++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-@@ -0,0 +1,257 @@
+@@ -0,0 +1,132 @@
 +#include "qcom-ipq8064-v1.0.dtsi"
 +
 +/ {
@@ -50,15 +50,8 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
 +              linux,stdout-path = "serial0:115200n8";
 +      };
 +
-+      aliases {
-+              mdio-gpio0 = &mdio0;
-+      };
-+
 +      soc {
 +              pinmux@800000 {
-+                      pinctrl-0 = <&mdio0_pins &rgmii0_pinmux>;
-+                      pinctrl-names = "default";
-+
 +                      i2c4_pins: i2c4_pinmux {
 +                              pins = "gpio12", "gpio13";
 +                              function = "gsbi4";
@@ -73,23 +66,6 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
 +                                      bias-none;
 +                              };
 +                      };
-+
-+                      mdio0_pins: mdio0_pins {
-+                              mux {
-+                                      pins = "gpio0", "gpio1";
-+                                      function = "gpio";
-+                                      drive-strength = <8>;
-+                                      bias-disable;
-+                              };
-+                      };
-+
-+                      rgmii0_pinmux: rgmii0_pinmux {
-+                              mux {
-+                                      pins = "gpio2", "gpio66";
-+                                      drive-strength = <8>;
-+                                      bias-disable;
-+                              };
-+                      };
 +              };
 +
 +              gsbi2: gsbi@12480000 {
@@ -180,106 +156,5 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
 +              usb30@1 {
 +                      status = "ok";
 +              };
-+
-+              mdio0: mdio {
-+                      compatible = "virtual,mdio-gpio";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+                      gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
-+
-+                      phy0: ethernet-phy@0 {
-+                              device_type = "ethernet-phy";
-+                              reg = <0>;
-+                              qca,ar8327-initvals = <
-+                                      0x00004 0x7600000   /* PAD0_MODE */
-+                                      0x00008 0x1000000   /* PAD5_MODE */
-+                                      0x0000c 0x80        /* PAD6_MODE */
-+                                      0x000e4 0xaa545     /* MAC_POWER_SEL */
-+                                      0x000e0 0xc74164de  /* SGMII_CTRL */
-+                                      0x0007c 0x4e        /* PORT0_STATUS */
-+                                      0x00094 0x4e        /* PORT6_STATUS */
-+                              >;
-+                      };
-+
-+                      phy4: ethernet-phy@4 {
-+                              device_type = "ethernet-phy";
-+                              reg = <4>;
-+                      };
-+
-+                      phy6: ethernet-phy@6 {
-+                              device_type = "ethernet-phy";
-+                              reg = <6>;
-+                      };
-+
-+                      phy7: ethernet-phy@7 {
-+                              device_type = "ethernet-phy";
-+                              reg = <7>;
-+                      };
-+              };
-+
-+              nss-gmac-common {
-+                      reg = <0x03000000 0x0000FFFF 0x1bb00000 0x0000FFFF 0x00900000 0x00004000>;
-+                      reg-names = "nss_reg_base" , "qsgmii_reg_base", "clk_ctl_base";
-+              };
-+
-+              gmac0: ethernet@37000000 {
-+                      status = "ok";
-+                      phy-mode = "rgmii";
-+                      qcom,id = <0>;
-+                      qcom,phy_mdio_addr = <4>;
-+                      qcom,poll_required = <1>;
-+                      qcom,rgmii_delay = <1>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <1000>;
-+                      qcom,forced_duplex = <1>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-+
-+              gmac1: ethernet@37200000 {
-+                      status = "ok";
-+                      phy-mode = "sgmii";
-+                      qcom,id = <1>;
-+                      qcom,phy_mdio_addr = <0>;
-+                      qcom,poll_required = <0>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <1000>;
-+                      qcom,forced_duplex = <1>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-+
-+              gmac2: ethernet@37400000 {
-+                      status = "ok";
-+                      phy-mode = "sgmii";
-+                      qcom,id = <2>;
-+                      qcom,phy_mdio_addr = <6>;
-+                      qcom,poll_required = <1>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <0>;
-+                      qcom,forced_duplex = <0>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-+
-+              gmac3: ethernet@37600000 {
-+                      status = "ok";
-+                      phy-mode = "sgmii";
-+                      qcom,id = <3>;
-+                      qcom,phy_mdio_addr = <7>;
-+                      qcom,poll_required = <1>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <0>;
-+                      qcom,forced_duplex = <0>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
 +      };
 +};
index ad0a7401be857f97d342b9d445ff65126f4f6c53..957b054b8c02832a306e825d8dc5a193e84bb460 100644 (file)
@@ -60,7 +60,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
  };
 --- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts
 +++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-@@ -37,6 +37,30 @@
+@@ -30,6 +30,30 @@
                                bias-disable;
                        };
  
@@ -91,10 +91,11 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
                        spi_pins: spi_pins {
                                mux {
                                        pins = "gpio18", "gpio19", "gpio21";
-@@ -153,6 +177,27 @@
+@@ -128,5 +152,26 @@
+               usb30@1 {
                        status = "ok";
                };
++
 +              pcie0: pci@1b500000 {
 +                      status = "ok";
 +                      reset-gpio = <&qcom_pinmux 3 0>;
@@ -115,10 +116,8 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
 +                      pinctrl-0 = <&pcie3_pins>;
 +                      pinctrl-names = "default";
 +              };
-+
-               mdio0: mdio {
-                       compatible = "virtual,mdio-gpio";
-                       #address-cells = <1>;
+       };
+ };
 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
 +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
 @@ -3,6 +3,8 @@
@@ -130,7 +129,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
  
  / {
        model = "Qualcomm IPQ8064";
-@@ -291,5 +292,128 @@
+@@ -291,5 +293,128 @@
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                };
diff --git a/target/linux/ipq806x/patches-4.0/700-add-gmac-dts-suport.patch b/target/linux/ipq806x/patches-4.0/700-add-gmac-dts-suport.patch
deleted file mode 100644 (file)
index b5a3f19..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -22,8 +22,15 @@
-               linux,stdout-path = "serial0:115200n8";
-       };
-+      aliases {
-+              mdio-gpio0 = &mdio0;
-+      };
-+
-       soc {
-               pinmux@800000 {
-+                      pinctrl-0 = <&mdio0_pins &rgmii2_pins>;
-+                      pinctrl-names = "default";
-+
-                       i2c4_pins: i2c4_pinmux {
-                               pins = "gpio12", "gpio13";
-                               function = "gsbi4";
-@@ -54,6 +61,25 @@
-                                       bias-none;
-                               };
-                       };
-+
-+                      mdio0_pins: mdio0_pins {
-+                              mux {
-+                                      pins = "gpio0", "gpio1";
-+                                      function = "gpio";
-+                                      drive-strength = <8>;
-+                                      bias-disable;
-+                              };
-+                      };
-+
-+                      rgmii2_pins: rgmii2_pins {
-+                              mux {
-+                                      pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+                                             "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62" ;
-+                                      function = "rgmii2";
-+                                      drive-strength = <8>;
-+                                      bias-disable;
-+                              };
-+                      };
-               };
-               gsbi@16300000 {
-@@ -89,6 +115,7 @@
-                                       #size-cells = <1>;
-                                       spi-max-frequency = <50000000>;
-                                       reg = <0>;
-+                                      m25p,fast-read;
-                                       partition@0 {
-                                               label = "lowlevel_init";
-@@ -139,5 +166,66 @@
-                       pinctrl-0 = <&pcie2_pins>;
-                       pinctrl-names = "default";
-               };
-+
-+              mdio0: mdio {
-+                      compatible = "virtual,mdio-gpio";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+                      gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
-+
-+                      phy0: ethernet-phy@0 {
-+                              device_type = "ethernet-phy";
-+                              reg = <0>;
-+                              qca,ar8327-initvals = <
-+                                      0x00004 0x7600000   /* PAD0_MODE */
-+                                      0x00008 0x1000000   /* PAD5_MODE */
-+                                      0x0000c 0x80        /* PAD6_MODE */
-+                                      0x000e4 0xaa545     /* MAC_POWER_SEL */
-+                                      0x000e0 0xc74164de  /* SGMII_CTRL */
-+                                      0x0007c 0x4e        /* PORT0_STATUS */
-+                                      0x00094 0x4e        /* PORT6_STATUS */
-+                              >;
-+                      };
-+
-+                      phy4: ethernet-phy@4 {
-+                              device_type = "ethernet-phy";
-+                              reg = <4>;
-+                      };
-+              };
-+
-+              nss-gmac-common {
-+                      reg = <0x03000000 0x0000FFFF 0x1bb00000 0x0000FFFF 0x00900000 0x00004000>;
-+                      reg-names = "nss_reg_base" , "qsgmii_reg_base", "clk_ctl_base";
-+              };
-+
-+              gmac1: ethernet@37200000 {
-+                      status = "ok";
-+                      phy-mode = "rgmii";
-+                      qcom,id = <1>;
-+                      qcom,phy_mdio_addr = <4>;
-+                      qcom,poll_required = <1>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <1000>;
-+                      qcom,forced_duplex = <1>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-+
-+              gmac2: ethernet@37400000 {
-+                      status = "ok";
-+                      phy-mode = "sgmii";
-+                      qcom,id = <2>;
-+                      qcom,phy_mdio_addr = <0>;
-+                      qcom,poll_required = <0>;
-+                      qcom,rgmii_delay = <0>;
-+                      qcom,emulation = <0>;
-+                      qcom,forced_speed = <1000>;
-+                      qcom,forced_duplex = <1>;
-+                      qcom,socver = <0>;
-+                      local-mac-address = [000000000000];
-+                      mdiobus = <&mdio0>;
-+              };
-       };
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -539,5 +540,42 @@
-                       status = "disabled";
-               };
-+
-+              nss-gmac-common {
-+                      reg = <0x03000000 0x0000FFFF 0x1bb00000 0x0000FFFF 0x00900000 0x00004000>;
-+                      reg-names = "nss_reg_base" , "qsgmii_reg_base", "clk_ctl_base";
-+              };
-+
-+              gmac0: ethernet@37000000 {
-+                      device_type = "network";
-+                      compatible = "qcom,nss-gmac";
-+                      reg = <0x37000000 0x200000>;
-+                      interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
-+                      status = "disabled";
-+              };
-+
-+              gmac1: ethernet@37200000 {
-+                      device_type = "network";
-+                      compatible = "qcom,nss-gmac";
-+                      reg = <0x37200000 0x200000>;
-+                      interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
-+                      status = "disabled";
-+              };
-+
-+              gmac2: ethernet@37400000 {
-+                      device_type = "network";
-+                      compatible = "qcom,nss-gmac";
-+                      reg = <0x37400000 0x200000>;
-+                      interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
-+                      status = "disabled";
-+              };
-+
-+              gmac3: ethernet@37600000 {
-+                      device_type = "network";
-+                      compatible = "qcom,nss-gmac";
-+                      reg = <0x37600000 0x200000>;
-+                      interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
-+                      status = "disabled";
-+              };
-       };
- };
diff --git a/target/linux/ipq806x/patches-4.0/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch b/target/linux/ipq806x/patches-4.0/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch
new file mode 100644 (file)
index 0000000..1b9d47b
--- /dev/null
@@ -0,0 +1,733 @@
+From 2fbb18f85826a9ba308fedb2cf90d3a661a39fd7 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Fri, 27 Mar 2015 00:16:14 -0700
+Subject: [PATCH] clk: qcom: Add support for NSS/GMAC clocks and resets
+
+Add the NSS/GMAC clocks and the TCM clock and NSS resets.
+
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/qcom/gcc-ipq806x.c               | 594 ++++++++++++++++++++++++++-
+ drivers/clk/qcom/gcc-ipq806x.c.rej           |  50 +++
+ include/dt-bindings/clock/qcom,gcc-ipq806x.h |   2 +
+ include/dt-bindings/reset/qcom,gcc-ipq806x.h |  43 ++
+ 4 files changed, 688 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/clk/qcom/gcc-ipq806x.c.rej
+
+--- a/drivers/clk/qcom/gcc-ipq806x.c
++++ b/drivers/clk/qcom/gcc-ipq806x.c
+@@ -220,11 +220,46 @@ static struct clk_regmap pll14_vote = {
+       },
+ };
++#define NSS_PLL_RATE(f, _l, _m, _n, i) \
++      {  \
++              .freq = f,  \
++              .l = _l, \
++              .m = _m, \
++              .n = _n, \
++              .ibits = i, \
++      }
++
++static struct pll_freq_tbl pll18_freq_tbl[] = {
++      NSS_PLL_RATE(550000000, 44, 0, 1, 0x01495625),
++      NSS_PLL_RATE(733000000, 58, 16, 25, 0x014b5625),
++};
++
++static struct clk_pll pll18 = {
++      .l_reg = 0x31a4,
++      .m_reg = 0x31a8,
++      .n_reg = 0x31ac,
++      .config_reg = 0x31b4,
++      .mode_reg = 0x31a0,
++      .status_reg = 0x31b8,
++      .status_bit = 16,
++      .post_div_shift = 16,
++      .post_div_width = 1,
++      .freq_tbl = pll18_freq_tbl,
++      .clkr.hw.init = &(struct clk_init_data){
++              .name = "pll18",
++              .parent_names = (const char *[]){ "pxo" },
++              .num_parents = 1,
++              .ops = &clk_pll_ops,
++      },
++};
++
+ #define P_PXO 0
+ #define P_PLL8        1
+ #define P_PLL3        1
+ #define P_PLL0        2
+ #define P_CXO 2
++#define P_PLL14       3
++#define P_PLL18 4
+ static const u8 gcc_pxo_pll8_map[] = {
+       [P_PXO]         = 0,
+@@ -275,6 +310,22 @@ static const char *gcc_pxo_pll8_pll0_map
+       "pll0_vote",
+ };
++static const u8 gcc_pxo_pll8_pll14_pll18_pll0_map[] = {
++      [P_PXO] = 0 ,
++      [P_PLL8] = 4,
++      [P_PLL0] = 2,
++      [P_PLL14] = 5,
++      [P_PLL18] = 1,
++};
++
++static const char *gcc_pxo_pll8_pll14_pll18_pll0[] = {
++      "pxo",
++      "pll8_vote",
++      "pll0_vote",
++      "pll14",
++      "pll18",
++};
++
+ static struct freq_tbl clk_tbl_gsbi_uart[] = {
+       {  1843200, P_PLL8, 2,  6, 625 },
+       {  3686400, P_PLL8, 2, 12, 625 },
+@@ -2250,6 +2301,472 @@ static struct clk_branch usb_fs1_h_clk =
+       },
+ };
++static const struct freq_tbl clk_tbl_gmac[] = {
++      { 133000000, P_PLL0, 1,  50, 301 },
++      { 266000000, P_PLL0, 1, 127, 382 },
++      { }
++};
++
++static struct clk_dyn_rcg gmac_core1_src = {
++      .ns_reg[0] = 0x3cac,
++      .ns_reg[1] = 0x3cb0,
++      .md_reg[0] = 0x3ca4,
++      .md_reg[1] = 0x3ca8,
++      .bank_reg = 0x3ca0,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_gmac,
++      .clkr = {
++              .enable_reg = 0x3ca0,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core1_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch gmac_core1_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 4,
++      .hwcg_reg = 0x3cb4,
++      .hwcg_bit = 6,
++      .clkr = {
++              .enable_reg = 0x3cb4,
++              .enable_mask = BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core1_clk",
++                      .parent_names = (const char *[]){
++                              "gmac_core1_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static struct clk_dyn_rcg gmac_core2_src = {
++      .ns_reg[0] = 0x3ccc,
++      .ns_reg[1] = 0x3cd0,
++      .md_reg[0] = 0x3cc4,
++      .md_reg[1] = 0x3cc8,
++      .bank_reg = 0x3ca0,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_gmac,
++      .clkr = {
++              .enable_reg = 0x3cc0,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core2_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch gmac_core2_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 5,
++      .hwcg_reg = 0x3cd4,
++      .hwcg_bit = 6,
++      .clkr = {
++              .enable_reg = 0x3cd4,
++              .enable_mask = BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core2_clk",
++                      .parent_names = (const char *[]){
++                              "gmac_core2_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static struct clk_dyn_rcg gmac_core3_src = {
++      .ns_reg[0] = 0x3cec,
++      .ns_reg[1] = 0x3cf0,
++      .md_reg[0] = 0x3ce4,
++      .md_reg[1] = 0x3ce8,
++      .bank_reg = 0x3ce0,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_gmac,
++      .clkr = {
++              .enable_reg = 0x3ce0,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core3_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch gmac_core3_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 6,
++      .hwcg_reg = 0x3cf4,
++      .hwcg_bit = 6,
++      .clkr = {
++              .enable_reg = 0x3cf4,
++              .enable_mask = BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core3_clk",
++                      .parent_names = (const char *[]){
++                              "gmac_core3_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static struct clk_dyn_rcg gmac_core4_src = {
++      .ns_reg[0] = 0x3d0c,
++      .ns_reg[1] = 0x3d10,
++      .md_reg[0] = 0x3d04,
++      .md_reg[1] = 0x3d08,
++      .bank_reg = 0x3d00,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_gmac,
++      .clkr = {
++              .enable_reg = 0x3d00,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core4_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch gmac_core4_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 7,
++      .hwcg_reg = 0x3d14,
++      .hwcg_bit = 6,
++      .clkr = {
++              .enable_reg = 0x3d14,
++              .enable_mask = BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "gmac_core4_clk",
++                      .parent_names = (const char *[]){
++                              "gmac_core4_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static const struct freq_tbl clk_tbl_nss_tcm[] = {
++      { 266000000, P_PLL0, 3, 0, 0 },
++      { 400000000, P_PLL0, 2, 0, 0 },
++      { }
++};
++
++static struct clk_dyn_rcg nss_tcm_src = {
++      .ns_reg[0] = 0x3dc4,
++      .ns_reg[1] = 0x3dc8,
++      .bank_reg = 0x3dc0,
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 4,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 4,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_nss_tcm,
++      .clkr = {
++              .enable_reg = 0x3dc0,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "nss_tcm_src",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++              },
++      },
++};
++
++static struct clk_branch nss_tcm_clk = {
++      .halt_reg = 0x3c20,
++      .halt_bit = 14,
++      .clkr = {
++              .enable_reg = 0x3dd0,
++              .enable_mask = BIT(6) | BIT(4),
++              .hw.init = &(struct clk_init_data){
++                      .name = "nss_tcm_clk",
++                      .parent_names = (const char *[]){
++                              "nss_tcm_src",
++                      },
++                      .num_parents = 1,
++                      .ops = &clk_branch_ops,
++                      .flags = CLK_SET_RATE_PARENT,
++              },
++      },
++};
++
++static const struct freq_tbl clk_tbl_nss[] = {
++      { 110000000, P_PLL18, 1, 1, 5 },
++      { 275000000, P_PLL18, 2, 0, 0 },
++      { 550000000, P_PLL18, 1, 0, 0 },
++      { 733000000, P_PLL18, 1, 0, 0 },
++      { }
++};
++
++static struct clk_dyn_rcg ubi32_core1_src_clk = {
++      .ns_reg[0] = 0x3d2c,
++      .ns_reg[1] = 0x3d30,
++      .md_reg[0] = 0x3d24,
++      .md_reg[1] = 0x3d28,
++      .bank_reg = 0x3d20,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_nss,
++      .clkr = {
++              .enable_reg = 0x3d20,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "ubi32_core1_src_clk",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++                      .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
++              },
++      },
++};
++
++static struct clk_dyn_rcg ubi32_core2_src_clk = {
++      .ns_reg[0] = 0x3d4c,
++      .ns_reg[1] = 0x3d50,
++      .md_reg[0] = 0x3d44,
++      .md_reg[1] = 0x3d48,
++      .bank_reg = 0x3d40,
++      .mn[0] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .mn[1] = {
++              .mnctr_en_bit = 8,
++              .mnctr_reset_bit = 7,
++              .mnctr_mode_shift = 5,
++              .n_val_shift = 16,
++              .m_val_shift = 16,
++              .width = 8,
++      },
++      .s[0] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .s[1] = {
++              .src_sel_shift = 0,
++              .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
++      },
++      .p[0] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .p[1] = {
++              .pre_div_shift = 3,
++              .pre_div_width = 2,
++      },
++      .mux_sel_bit = 0,
++      .freq_tbl = clk_tbl_nss,
++      .clkr = {
++              .enable_reg = 0x3d40,
++              .enable_mask = BIT(1),
++              .hw.init = &(struct clk_init_data){
++                      .name = "ubi32_core2_src_clk",
++                      .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
++                      .num_parents = 5,
++                      .ops = &clk_dyn_rcg_ops,
++                      .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
++              },
++      },
++};
++
+ static struct clk_regmap *gcc_ipq806x_clks[] = {
+       [PLL0] = &pll0.clkr,
+       [PLL0_VOTE] = &pll0_vote,
+@@ -2259,6 +2776,7 @@ static struct clk_regmap *gcc_ipq806x_cl
+       [PLL8_VOTE] = &pll8_vote,
+       [PLL14] = &pll14.clkr,
+       [PLL14_VOTE] = &pll14_vote,
++      [PLL18] = &pll18.clkr,
+       [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
+       [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
+       [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
+@@ -2356,6 +2874,18 @@ static struct clk_regmap *gcc_ipq806x_cl
+       [PLL9] = &hfpll0.clkr,
+       [PLL10] = &hfpll1.clkr,
+       [PLL12] = &hfpll_l2.clkr,
++      [GMAC_CORE1_CLK_SRC] = &gmac_core1_src.clkr,
++      [GMAC_CORE1_CLK] = &gmac_core1_clk.clkr,
++      [GMAC_CORE2_CLK_SRC] = &gmac_core2_src.clkr,
++      [GMAC_CORE2_CLK] = &gmac_core2_clk.clkr,
++      [GMAC_CORE3_CLK_SRC] = &gmac_core3_src.clkr,
++      [GMAC_CORE3_CLK] = &gmac_core3_clk.clkr,
++      [GMAC_CORE4_CLK_SRC] = &gmac_core4_src.clkr,
++      [GMAC_CORE4_CLK] = &gmac_core4_clk.clkr,
++      [UBI32_CORE1_CLK_SRC] = &ubi32_core1_src_clk.clkr,
++      [UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr,
++      [NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
++      [NSSTCM_CLK] = &nss_tcm_clk.clkr,
+ };
+ static const struct qcom_reset_map gcc_ipq806x_resets[] = {
+@@ -2474,6 +3004,48 @@ static const struct qcom_reset_map gcc_i
+       [USB30_1_PHY_RESET] = { 0x3b58, 0 },
+       [NSSFB0_RESET] = { 0x3b60, 6 },
+       [NSSFB1_RESET] = { 0x3b60, 7 },
++      [UBI32_CORE1_CLKRST_CLAMP_RESET] = { 0x3d3c, 3},
++      [UBI32_CORE1_CLAMP_RESET] = { 0x3d3c, 2 },
++      [UBI32_CORE1_AHB_RESET] = { 0x3d3c, 1 },
++      [UBI32_CORE1_AXI_RESET] = { 0x3d3c, 0 },
++      [UBI32_CORE2_CLKRST_CLAMP_RESET] = { 0x3d5c, 3 },
++      [UBI32_CORE2_CLAMP_RESET] = { 0x3d5c, 2 },
++      [UBI32_CORE2_AHB_RESET] = { 0x3d5c, 1 },
++      [UBI32_CORE2_AXI_RESET] = { 0x3d5c, 0 },
++      [GMAC_CORE1_RESET] = { 0x3cbc, 0 },
++      [GMAC_CORE2_RESET] = { 0x3cdc, 0 },
++      [GMAC_CORE3_RESET] = { 0x3cfc, 0 },
++      [GMAC_CORE4_RESET] = { 0x3d1c, 0 },
++      [GMAC_AHB_RESET] = { 0x3e24, 0 },
++      [NSS_CH0_RST_RX_CLK_N_RESET] = { 0x3b60, 0 },
++      [NSS_CH0_RST_TX_CLK_N_RESET] = { 0x3b60, 1 },
++      [NSS_CH0_RST_RX_125M_N_RESET] = { 0x3b60, 2 },
++      [NSS_CH0_HW_RST_RX_125M_N_RESET] = { 0x3b60, 3 },
++      [NSS_CH0_RST_TX_125M_N_RESET] = { 0x3b60, 4 },
++      [NSS_CH1_RST_RX_CLK_N_RESET] = { 0x3b60, 5 },
++      [NSS_CH1_RST_TX_CLK_N_RESET] = { 0x3b60, 6 },
++      [NSS_CH1_RST_RX_125M_N_RESET] = { 0x3b60, 7 },
++      [NSS_CH1_HW_RST_RX_125M_N_RESET] = { 0x3b60, 8 },
++      [NSS_CH1_RST_TX_125M_N_RESET] = { 0x3b60, 9 },
++      [NSS_CH2_RST_RX_CLK_N_RESET] = { 0x3b60, 10 },
++      [NSS_CH2_RST_TX_CLK_N_RESET] = { 0x3b60, 11 },
++      [NSS_CH2_RST_RX_125M_N_RESET] = { 0x3b60, 12 },
++      [NSS_CH2_HW_RST_RX_125M_N_RESET] = { 0x3b60, 13 },
++      [NSS_CH2_RST_TX_125M_N_RESET] = { 0x3b60, 14 },
++      [NSS_CH3_RST_RX_CLK_N_RESET] = { 0x3b60, 15 },
++      [NSS_CH3_RST_TX_CLK_N_RESET] = { 0x3b60, 16 },
++      [NSS_CH3_RST_RX_125M_N_RESET] = { 0x3b60, 17 },
++      [NSS_CH3_HW_RST_RX_125M_N_RESET] = { 0x3b60, 18 },
++      [NSS_CH3_RST_TX_125M_N_RESET] = { 0x3b60, 19 },
++      [NSS_RST_RX_250M_125M_N_RESET] = { 0x3b60, 20 },
++      [NSS_RST_TX_250M_125M_N_RESET] = { 0x3b60, 21 },
++      [NSS_QSGMII_TXPI_RST_N_RESET] = { 0x3b60, 22 },
++      [NSS_QSGMII_CDR_RST_N_RESET] = { 0x3b60, 23 },
++      [NSS_SGMII2_CDR_RST_N_RESET] = { 0x3b60, 24 },
++      [NSS_SGMII3_CDR_RST_N_RESET] = { 0x3b60, 25 },
++      [NSS_CAL_PRBS_RST_N_RESET] = { 0x3b60, 26 },
++      [NSS_LCKDT_RST_N_RESET] = { 0x3b60, 27 },
++      [NSS_SRDS_N_RESET] = { 0x3b60, 28 },
+ };
+ static const struct regmap_config gcc_ipq806x_regmap_config = {
+@@ -2502,6 +3074,8 @@ static int gcc_ipq806x_probe(struct plat
+ {
+       struct clk *clk;
+       struct device *dev = &pdev->dev;
++      struct regmap *regmap;
++      int ret;
+       /* Temporary until RPM clocks supported */
+       clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
+@@ -2512,7 +3086,25 @@ static int gcc_ipq806x_probe(struct plat
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+-      return qcom_cc_probe(pdev, &gcc_ipq806x_desc);
++      ret = qcom_cc_probe(pdev, &gcc_ipq806x_desc);
++      if (ret)
++              return ret;
++
++      regmap = dev_get_regmap(dev, NULL);
++      if (!regmap)
++              return -ENODEV;
++
++      /* Setup PLL18 static bits */
++      regmap_update_bits(regmap, 0x31a4, 0xffffffc0, 0x40000400);
++      regmap_write(regmap, 0x31b0, 0x3080);
++
++      /* Set GMAC footswitch sleep/wakeup values */
++      regmap_write(regmap, 0x3cb8, 8);
++      regmap_write(regmap, 0x3cd8, 8);
++      regmap_write(regmap, 0x3cf8, 8);
++      regmap_write(regmap, 0x3d18, 8);
++
++      return 0;
+ }
+ static int gcc_ipq806x_remove(struct platform_device *pdev)
+--- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
++++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
+@@ -288,5 +288,7 @@
+ #define UBI32_CORE2_CLK_SRC                   278
+ #define UBI32_CORE1_CLK                               279
+ #define UBI32_CORE2_CLK                               280
++#define NSSTCM_CLK_SRC                                281
++#define NSSTCM_CLK                            282
+ #endif
+--- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h
++++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h
+@@ -129,4 +129,47 @@
+ #define USB30_1_PHY_RESET                             112
+ #define NSSFB0_RESET                                  113
+ #define NSSFB1_RESET                                  114
++#define UBI32_CORE1_CLKRST_CLAMP_RESET                        115
++#define UBI32_CORE1_CLAMP_RESET                               116
++#define UBI32_CORE1_AHB_RESET                         117
++#define UBI32_CORE1_AXI_RESET                         118
++#define UBI32_CORE2_CLKRST_CLAMP_RESET                        119
++#define UBI32_CORE2_CLAMP_RESET                               120
++#define UBI32_CORE2_AHB_RESET                         121
++#define UBI32_CORE2_AXI_RESET                         122
++#define GMAC_CORE1_RESET                              123
++#define GMAC_CORE2_RESET                              124
++#define GMAC_CORE3_RESET                              125
++#define GMAC_CORE4_RESET                              126
++#define GMAC_AHB_RESET                                        127
++#define NSS_CH0_RST_RX_CLK_N_RESET                    128
++#define NSS_CH0_RST_TX_CLK_N_RESET                    129
++#define NSS_CH0_RST_RX_125M_N_RESET                   130
++#define NSS_CH0_HW_RST_RX_125M_N_RESET                        131
++#define NSS_CH0_RST_TX_125M_N_RESET                   132
++#define NSS_CH1_RST_RX_CLK_N_RESET                    133
++#define NSS_CH1_RST_TX_CLK_N_RESET                    134
++#define NSS_CH1_RST_RX_125M_N_RESET                   135
++#define NSS_CH1_HW_RST_RX_125M_N_RESET                        136
++#define NSS_CH1_RST_TX_125M_N_RESET                   137
++#define NSS_CH2_RST_RX_CLK_N_RESET                    138
++#define NSS_CH2_RST_TX_CLK_N_RESET                    139
++#define NSS_CH2_RST_RX_125M_N_RESET                   140
++#define NSS_CH2_HW_RST_RX_125M_N_RESET                        141
++#define NSS_CH2_RST_TX_125M_N_RESET                   142
++#define NSS_CH3_RST_RX_CLK_N_RESET                    143
++#define NSS_CH3_RST_TX_CLK_N_RESET                    144
++#define NSS_CH3_RST_RX_125M_N_RESET                   145
++#define NSS_CH3_HW_RST_RX_125M_N_RESET                        146
++#define NSS_CH3_RST_TX_125M_N_RESET                   147
++#define NSS_RST_RX_250M_125M_N_RESET                  148
++#define NSS_RST_TX_250M_125M_N_RESET                  149
++#define NSS_QSGMII_TXPI_RST_N_RESET                   150
++#define NSS_QSGMII_CDR_RST_N_RESET                    151
++#define NSS_SGMII2_CDR_RST_N_RESET                    152
++#define NSS_SGMII3_CDR_RST_N_RESET                    153
++#define NSS_CAL_PRBS_RST_N_RESET                      154
++#define NSS_LCKDT_RST_N_RESET                         155
++#define NSS_SRDS_N_RESET                              156
++
+ #endif
diff --git a/target/linux/ipq806x/patches-4.0/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch b/target/linux/ipq806x/patches-4.0/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch
new file mode 100644 (file)
index 0000000..e94a746
--- /dev/null
@@ -0,0 +1,105 @@
+From 4f09499bc1d9bb095caccbcd73ff951ee631e521 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 15:42:40 -0700
+Subject: [PATCH 1/8] stmmac: add phy-handle support to the platform layer
+
+On stmmac driver, PHY specification in device-tree was done using the
+non-standard property "snps,phy-addr". Specifying a PHY on a different
+MDIO bus that the one within the stmmac controller doesn't seem to be
+possible when device-tree is used.
+
+This change adds support for the phy-handle property, as specified in
+Documentation/devicetree/bindings/net/ethernet.txt.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 28 ++++++++++++++--------
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |  6 ++++-
+ include/linux/stmmac.h                             |  1 +
+ 3 files changed, 24 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -52,6 +52,7 @@
+ #include "stmmac_ptp.h"
+ #include "stmmac.h"
+ #include <linux/reset.h>
++#include <linux/of_mdio.h>
+ #define STMMAC_ALIGN(x)       L1_CACHE_ALIGN(x)
+@@ -816,18 +817,25 @@ static int stmmac_init_phy(struct net_de
+       priv->speed = 0;
+       priv->oldduplex = -1;
+-      if (priv->plat->phy_bus_name)
+-              snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
+-                       priv->plat->phy_bus_name, priv->plat->bus_id);
+-      else
+-              snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
+-                       priv->plat->bus_id);
+-
+-      snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
+-               priv->plat->phy_addr);
+-      pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id_fmt);
++      if (priv->plat->phy_node) {
++              phydev = of_phy_connect(dev, priv->plat->phy_node,
++                                      &stmmac_adjust_link, 0, interface);
++      } else {
++              if (priv->plat->phy_bus_name)
++                      snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
++                               priv->plat->phy_bus_name, priv->plat->bus_id);
++              else
++                      snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
++                               priv->plat->bus_id);
++
++              snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
++                       priv->plat->phy_addr);
++              pr_debug("stmmac_init_phy:  trying to attach to %s\n",
++                       phy_id_fmt);
+-      phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
++              phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
++                                   interface);
++      }
+       if (IS_ERR(phydev)) {
+               pr_err("%s: Could not attach to PHY\n", dev->name);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -27,6 +27,7 @@
+ #include <linux/of.h>
+ #include <linux/of_net.h>
+ #include <linux/of_device.h>
++#include <linux/of_mdio.h>
+ #include "stmmac.h"
+ #include "stmmac_platform.h"
+@@ -167,13 +168,16 @@ static int stmmac_probe_config_dt(struct
+       /* Default to phy auto-detection */
+       plat->phy_addr = -1;
++      /* If we find a phy-handle property, use it as the PHY */
++      plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
++
+       /* "snps,phy-addr" is not a standard property. Mark it as deprecated
+        * and warn of its use. Remove this when phy node support is added.
+        */
+       if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
+               dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
+-      if (plat->phy_bus_name)
++      if (plat->phy_node || plat->phy_bus_name)
+               plat->mdio_bus_data = NULL;
+       else
+               plat->mdio_bus_data =
+--- a/include/linux/stmmac.h
++++ b/include/linux/stmmac.h
+@@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
+       int phy_addr;
+       int interface;
+       struct stmmac_mdio_bus_data *mdio_bus_data;
++      struct device_node *phy_node;
+       struct stmmac_dma_cfg *dma_cfg;
+       int clk_csr;
+       int has_gmac;
diff --git a/target/linux/ipq806x/patches-4.0/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch b/target/linux/ipq806x/patches-4.0/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch
new file mode 100644 (file)
index 0000000..3b2134e
--- /dev/null
@@ -0,0 +1,65 @@
+From 0149d275415cd1b2382ce94e5eb32641590097d0 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 15:57:12 -0700
+Subject: [PATCH 2/8] stmmac: move error path at the end of
+ stmmac_probe_config_dt()
+
+We will want to do additional clean-up on certain errors. Therefore,
+this change moves the error path at the end of the function for better
+code readability.
+
+This patch doesn't change anything functionally.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -129,13 +129,18 @@ static int stmmac_probe_config_dt(struct
+       struct device_node *np = pdev->dev.of_node;
+       struct stmmac_dma_cfg *dma_cfg;
+       const struct of_device_id *device;
++      int ret;
+-      if (!np)
+-              return -ENODEV;
++      if (!np) {
++              ret = -ENODEV;
++              goto err;
++      }
+       device = of_match_device(stmmac_dt_ids, &pdev->dev);
+-      if (!device)
+-              return -ENODEV;
++      if (!device) {
++              ret = -ENODEV;
++              goto err;
++      }
+       if (device->data) {
+               const struct stmmac_of_data *data = device->data;
+@@ -231,8 +236,10 @@ static int stmmac_probe_config_dt(struct
+       if (of_find_property(np, "snps,pbl", NULL)) {
+               dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
+                                      GFP_KERNEL);
+-              if (!dma_cfg)
+-                      return -ENOMEM;
++              if (!dma_cfg) {
++                      ret = -ENOMEM;
++                      goto err;
++              }
+               plat->dma_cfg = dma_cfg;
+               of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
+               dma_cfg->fixed_burst =
+@@ -250,6 +257,9 @@ static int stmmac_probe_config_dt(struct
+       }
+       return 0;
++
++err:
++      return ret;
+ }
+ #else
+ static int stmmac_probe_config_dt(struct platform_device *pdev,
diff --git a/target/linux/ipq806x/patches-4.0/703-stmmac-add-fixed-link-device-tree-support.patch b/target/linux/ipq806x/patches-4.0/703-stmmac-add-fixed-link-device-tree-support.patch
new file mode 100644 (file)
index 0000000..4b2c9b5
--- /dev/null
@@ -0,0 +1,64 @@
+From 3a95f75867be562cb919ff23a738f70357188fbd Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 16:02:03 -0700
+Subject: [PATCH 3/8] stmmac: add fixed-link device-tree support
+
+In case DT is used, this change adds the ability to the stmmac driver to
+detect a fixed-link PHY, instanciate it, and use it during
+phy_connect().
+
+Fixed link PHYs DT usage is described in:
+Documentation/devicetree/bindings/net/fixed-link.txt
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c     |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 12 +++++++++++-
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -856,7 +856,7 @@ static int stmmac_init_phy(struct net_de
+        * device as well.
+        * Note: phydev->phy_id is the result of reading the UID PHY registers.
+        */
+-      if (phydev->phy_id == 0) {
++      if (!priv->plat->phy_node && phydev->phy_id == 0) {
+               phy_disconnect(phydev);
+               return -ENODEV;
+       }
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -176,6 +176,14 @@ static int stmmac_probe_config_dt(struct
+       /* If we find a phy-handle property, use it as the PHY */
+       plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
++      /* If phy-handle is not specified, check if we have a fixed-phy */
++      if (!plat->phy_node && of_phy_is_fixed_link(np)) {
++              if ((of_phy_register_fixed_link(np) < 0))
++                      return -ENODEV;
++
++              plat->phy_node = of_node_get(np);
++      }
++
+       /* "snps,phy-addr" is not a standard property. Mark it as deprecated
+        * and warn of its use. Remove this when phy node support is added.
+        */
+@@ -238,7 +246,7 @@ static int stmmac_probe_config_dt(struct
+                                      GFP_KERNEL);
+               if (!dma_cfg) {
+                       ret = -ENOMEM;
+-                      goto err;
++                      goto err2;
+               }
+               plat->dma_cfg = dma_cfg;
+               of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
+@@ -258,6 +266,8 @@ static int stmmac_probe_config_dt(struct
+       return 0;
++err2:
++      of_node_put(np);
+ err:
+       return ret;
+ }
diff --git a/target/linux/ipq806x/patches-4.0/704-stmmac-add-ipq806x-glue-layer.patch b/target/linux/ipq806x/patches-4.0/704-stmmac-add-ipq806x-glue-layer.patch
new file mode 100644 (file)
index 0000000..fecc958
--- /dev/null
@@ -0,0 +1,407 @@
+From 69fb970ad3fe05af7cb99ea78230c69c7ca0d03b Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 16:10:22 -0700
+Subject: [PATCH 4/8] stmmac: add ipq806x glue layer
+
+The ethernet controller available in IPQ806x is a Synopsys DesignWare
+Gigabit MAC IP core, already supported by the stmmac driver.
+
+This glue layer implements some platform specific settings required to
+get the controller working on an IPQ806x based platform.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/Kconfig        |   1 +
+ drivers/net/ethernet/stmicro/stmmac/Makefile       |   2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c    | 324 +++++++++++++++++++++
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   1 +
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |   1 +
+ 5 files changed, 328 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c
+
+--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+@@ -16,6 +16,7 @@ if STMMAC_ETH
+ config STMMAC_PLATFORM
+       tristate "STMMAC Platform bus support"
+       depends on STMMAC_ETH
++      select MFD_SYSCON
+       default y
+       ---help---
+         This selects the platform specific bus support for the stmmac driver.
+--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
++++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
+@@ -6,7 +6,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethto
+ obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
+ stmmac-platform-objs:= stmmac_platform.o dwmac-meson.o dwmac-sunxi.o  \
+-                     dwmac-sti.o dwmac-socfpga.o dwmac-rk.o
++                     dwmac-sti.o dwmac-socfpga.o dwmac-rk.o dwmac-ipq806x.o
+ obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
+ stmmac-pci-objs:= stmmac_pci.o
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -42,6 +42,7 @@ static const struct of_device_id stmmac_
+       { .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
+       { .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
+       { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
++      { .compatible = "qcom,ipq806x-gmac", .data = &ipq806x_gmac_data },
+       { .compatible = "st,spear600-gmac"},
+       { .compatible = "snps,dwmac-3.610"},
+       { .compatible = "snps,dwmac-3.70a"},
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
+@@ -25,5 +25,6 @@ extern const struct stmmac_of_data stih4
+ extern const struct stmmac_of_data stid127_dwmac_data;
+ extern const struct stmmac_of_data socfpga_gmac_data;
+ extern const struct stmmac_of_data rk3288_gmac_data;
++extern const struct stmmac_of_data ipq806x_gmac_data;
+ #endif /* __STMMAC_PLATFORM_H__ */
+--- /dev/null
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+@@ -0,0 +1,343 @@
++/*
++ * Qualcomm Atheros IPQ806x GMAC glue layer
++ *
++ * Copyright (C) 2015 The Linux Foundation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/phy.h>
++#include <linux/regmap.h>
++#include <linux/clk.h>
++#include <linux/reset.h>
++#include <linux/of_net.h>
++#include <linux/mfd/syscon.h>
++#include <linux/stmmac.h>
++#include <linux/of_mdio.h>
++
++#include "stmmac_platform.h"
++
++#define NSS_COMMON_CLK_GATE                   0x8
++#define NSS_COMMON_CLK_GATE_PTP_EN(x)         BIT(0x10 + x)
++#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x)    BIT(0x9 + (x * 2))
++#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x)    BIT(0x8 + (x * 2))
++#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x)     BIT(0x4 + x)
++#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x)     BIT(0x0 + x)
++
++#define NSS_COMMON_CLK_DIV0                   0xC
++#define NSS_COMMON_CLK_DIV_OFFSET(x)          (x * 8)
++#define NSS_COMMON_CLK_DIV_MASK                       0x7f
++
++#define NSS_COMMON_CLK_SRC_CTRL                       0x14
++#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x)     (1 << x)
++/* Mode is coded on 1 bit but is different depending on the MAC ID:
++ * MAC0: QSGMII=0 RGMII=1
++ * MAC1: QSGMII=0 SGMII=0 RGMII=1
++ * MAC2 & MAC3: QSGMII=0 SGMII=1
++ */
++#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x)      1
++#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x)      ((x >= 2) ? 1 : 0)
++
++#define NSS_COMMON_MACSEC_CTL                 0x28
++#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x)        (1 << x)
++
++#define NSS_COMMON_GMAC_CTL(x)                        (0x30 + (x * 4))
++#define NSS_COMMON_GMAC_CTL_CSYS_REQ          BIT(19)
++#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL     BIT(16)
++#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET  8
++#define NSS_COMMON_GMAC_CTL_IFG_OFFSET                0
++#define NSS_COMMON_GMAC_CTL_IFG_MASK          0x3f
++
++#define NSS_COMMON_CLK_DIV_RGMII_1000         1
++#define NSS_COMMON_CLK_DIV_RGMII_100          9
++#define NSS_COMMON_CLK_DIV_RGMII_10           99
++#define NSS_COMMON_CLK_DIV_SGMII_1000         0
++#define NSS_COMMON_CLK_DIV_SGMII_100          4
++#define NSS_COMMON_CLK_DIV_SGMII_10           49
++
++#define QSGMII_PCS_MODE_CTL                   0x68
++#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x)     BIT((x * 8) + 7)
++
++#define QSGMII_PCS_CAL_LCKDT_CTL              0x120
++#define QSGMII_PCS_CAL_LCKDT_CTL_RST          BIT(19)
++
++/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
++#define QSGMII_PHY_SGMII_CTL(x)                       ((x == 1) ? 0x134 : \
++                                               (0x13c + (4 * (x - 2))))
++#define QSGMII_PHY_CDR_EN                     BIT(0)
++#define QSGMII_PHY_RX_FRONT_EN                        BIT(1)
++#define QSGMII_PHY_RX_SIGNAL_DETECT_EN                BIT(2)
++#define QSGMII_PHY_TX_DRIVER_EN                       BIT(3)
++#define QSGMII_PHY_QSGMII_EN                  BIT(7)
++#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET     12
++#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK               0x7
++#define QSGMII_PHY_RX_DC_BIAS_OFFSET          18
++#define QSGMII_PHY_RX_DC_BIAS_MASK            0x3
++#define QSGMII_PHY_RX_INPUT_EQU_OFFSET                20
++#define QSGMII_PHY_RX_INPUT_EQU_MASK          0x3
++#define QSGMII_PHY_CDR_PI_SLEW_OFFSET         22
++#define QSGMII_PHY_CDR_PI_SLEW_MASK           0x3
++#define QSGMII_PHY_TX_DRV_AMP_OFFSET          28
++#define QSGMII_PHY_TX_DRV_AMP_MASK            0xf
++
++struct ipq806x_gmac {
++      struct platform_device *pdev;
++      struct regmap *nss_common;
++      struct regmap *qsgmii_csr;
++      uint32_t id;
++      struct clk *core_clk;
++      phy_interface_t phy_mode;
++};
++
++static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
++{
++      struct device *dev = &gmac->pdev->dev;
++      int div;
++
++      switch (speed) {
++      case SPEED_1000:
++              div = NSS_COMMON_CLK_DIV_SGMII_1000;
++              break;
++
++      case SPEED_100:
++              div = NSS_COMMON_CLK_DIV_SGMII_100;
++              break;
++
++      case SPEED_10:
++              div = NSS_COMMON_CLK_DIV_SGMII_10;
++              break;
++
++      default:
++              dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
++              return -EINVAL;
++      }
++
++      return div;
++}
++
++static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
++{
++      struct device *dev = &gmac->pdev->dev;
++      int div;
++
++      switch (speed) {
++      case SPEED_1000:
++              div = NSS_COMMON_CLK_DIV_RGMII_1000;
++              break;
++
++      case SPEED_100:
++              div = NSS_COMMON_CLK_DIV_RGMII_100;
++              break;
++
++      case SPEED_10:
++              div = NSS_COMMON_CLK_DIV_RGMII_10;
++              break;
++
++      default:
++              dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
++              return -EINVAL;
++      }
++
++      return div;
++}
++
++static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
++{
++      uint32_t clk_bits, val;
++      int div;
++
++      switch (gmac->phy_mode) {
++      case PHY_INTERFACE_MODE_RGMII:
++              div = get_clk_div_rgmii(gmac, speed);
++              clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
++                         NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
++              break;
++
++      case PHY_INTERFACE_MODE_SGMII:
++              div = get_clk_div_sgmii(gmac, speed);
++              clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
++                         NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
++              break;
++
++      default:
++              dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
++                      phy_modes(gmac->phy_mode));
++              return -EINVAL;
++      }
++
++      /* Disable the clocks */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
++      val &= ~clk_bits;
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
++
++      /* Set the divider */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
++      val &= ~(NSS_COMMON_CLK_DIV_MASK
++               << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
++      val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
++
++      /* Enable the clock back */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
++      val |= clk_bits;
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
++
++      return 0;
++}
++
++static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
++{
++      struct device *dev = &gmac->pdev->dev;
++
++      gmac->phy_mode = of_get_phy_mode(dev->of_node);
++      if (gmac->phy_mode < 0) {
++              dev_err(dev, "missing phy mode property\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
++              dev_err(dev, "missing qcom id property\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      /* The GMACs are called 1 to 4 in the documentation, but to simplify the
++       * code and keep it consistent with the Linux convention, we'll number
++       * them from 0 to 3 here.
++       */
++      if (gmac->id < 0 || gmac->id > 3) {
++              dev_err(dev, "invalid gmac id\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      gmac->core_clk = devm_clk_get(dev, "stmmaceth");
++      if (IS_ERR(gmac->core_clk)) {
++              dev_err(dev, "missing stmmaceth clk property\n");
++              return gmac->core_clk;
++      }
++      clk_set_rate(gmac->core_clk, 266000000);
++
++      /* Setup the register map for the nss common registers */
++      gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
++                                                         "qcom,nss-common");
++      if (IS_ERR(gmac->nss_common)) {
++              dev_err(dev, "missing nss-common node\n");
++              return gmac->nss_common;
++      }
++
++      /* Setup the register map for the qsgmii csr registers */
++      gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
++                                                         "qcom,qsgmii-csr");
++      if (IS_ERR(gmac->qsgmii_csr)) {
++              dev_err(dev, "missing qsgmii-csr node\n");
++              return gmac->qsgmii_csr;
++      }
++
++      return NULL;
++}
++
++static void *ipq806x_gmac_setup(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct ipq806x_gmac *gmac;
++      int val;
++      void *err;
++
++      gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
++      if (!gmac)
++              return ERR_PTR(-ENOMEM);
++
++      gmac->pdev = pdev;
++
++      err = ipq806x_gmac_of_parse(gmac);
++      if (err) {
++              dev_err(dev, "device tree parsing error\n");
++              return err;
++      }
++
++      regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
++                   QSGMII_PCS_CAL_LCKDT_CTL_RST);
++
++      /* Inter frame gap is set to 12 */
++      val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
++            12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
++      /* We also initiate an AXI low power exit request */
++      val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
++      switch (gmac->phy_mode) {
++      case PHY_INTERFACE_MODE_RGMII:
++              val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
++              break;
++      case PHY_INTERFACE_MODE_SGMII:
++              val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
++              break;
++      default:
++              dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
++                      phy_modes(gmac->phy_mode));
++              return NULL;
++      }
++      regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
++
++      /* Configure the clock src according to the mode */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
++      val &= ~NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
++      switch (gmac->phy_mode) {
++      case PHY_INTERFACE_MODE_RGMII:
++              val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
++                      NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
++              break;
++      case PHY_INTERFACE_MODE_SGMII:
++              val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
++                      NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
++              break;
++      default:
++              dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
++                      phy_modes(gmac->phy_mode));
++              return NULL;
++      }
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
++
++      /* Enable PTP clock */
++      regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
++      val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
++      regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
++
++      if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
++              regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
++                           QSGMII_PHY_CDR_EN |
++                           QSGMII_PHY_RX_FRONT_EN |
++                           QSGMII_PHY_RX_SIGNAL_DETECT_EN |
++                           QSGMII_PHY_TX_DRIVER_EN |
++                           QSGMII_PHY_QSGMII_EN |
++                           0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
++                           0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET |
++                           0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
++                           0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
++                           0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET);
++      }
++
++      return gmac;
++}
++
++static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
++{
++      struct ipq806x_gmac *gmac = priv;
++
++      ipq806x_gmac_set_speed(gmac, speed);
++}
++
++const struct stmmac_of_data ipq806x_gmac_data = {
++      .has_gmac       = 1,
++      .setup          = ipq806x_gmac_setup,
++      .fix_mac_speed  = ipq806x_gmac_fix_mac_speed,
++};
diff --git a/target/linux/ipq806x/patches-4.0/705-net-stmmac-ipq806x-document-device-tree-bindings.patch b/target/linux/ipq806x/patches-4.0/705-net-stmmac-ipq806x-document-device-tree-bindings.patch
new file mode 100644 (file)
index 0000000..3144fa3
--- /dev/null
@@ -0,0 +1,52 @@
+From 0f9605d9409b77a89daef91cc68239fc2ff50457 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Fri, 8 May 2015 16:51:25 -0700
+Subject: [PATCH 5/8] net: stmmac: ipq806x: document device tree bindings
+
+Add the device tree bindings documentation for the QCA IPQ806x
+variant of the Synopsys DesignWare MAC.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ .../devicetree/bindings/net/ipq806x-dwmac.txt      | 35 ++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
+@@ -0,0 +1,35 @@
++* IPQ806x DWMAC Ethernet controller
++
++The device inherits all the properties of the dwmac/stmmac devices
++described in the file net/stmmac.txt with the following changes.
++
++Required properties:
++
++- compatible: should be "qcom,ipq806x-gmac" along with "snps,dwmac"
++            and any applicable more detailed version number
++            described in net/stmmac.txt
++
++- qcom,nss-common: should contain a phandle to a syscon device mapping the
++                 nss-common registers.
++
++- qcom,qsgmii-csr: should contain a phandle to a syscon device mapping the
++                 qsgmii-csr registers.
++
++Example:
++
++      gmac: ethernet@37000000 {
++              device_type = "network";
++              compatible = "qcom,ipq806x-gmac";
++              reg = <0x37000000 0x200000>;
++              interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
++              interrupt-names = "macirq";
++
++              qcom,nss-common = <&nss_common>;
++              qcom,qsgmii-csr = <&qsgmii_csr>;
++
++              clocks = <&gcc GMAC_CORE1_CLK>;
++              clock-names = "stmmaceth";
++
++              resets = <&gcc GMAC_CORE1_RESET>;
++              reset-names = "stmmaceth";
++      };
diff --git a/target/linux/ipq806x/patches-4.0/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch b/target/linux/ipq806x/patches-4.0/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch
new file mode 100644 (file)
index 0000000..a9a2d55
--- /dev/null
@@ -0,0 +1,175 @@
+From df944689d491e6af533173bf2ef448c3dd334f15 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Mon, 11 May 2015 15:15:25 -0700
+Subject: [PATCH 6/8] net: stmmac: create one debugfs dir per net-device
+
+stmmac DebugFS entries are currently global to the driver. As a result,
+having more than one stmmac device in the system creates the following
+error:
+* ERROR stmmaceth, debugfs create directory failed
+* stmmac_hw_setup: failed debugFS registration
+
+This also results in being able to access the debugfs information for
+the first registered device only.
+
+This patch changes the debugfs structure to have one sub-directory per
+net-device. Files under "/sys/kernel/debug/stmmaceth" will now show-up
+under /sys/kernel/debug/stmmaceth/ethN/.
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h      |  6 ++
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 76 ++++++++++++++++-------
+ 2 files changed, 59 insertions(+), 23 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -116,6 +116,12 @@ struct stmmac_priv {
+       int use_riwt;
+       int irq_wake;
+       spinlock_t ptp_lock;
++
++#ifdef CONFIG_DEBUG_FS
++      struct dentry *dbgfs_dir;
++      struct dentry *dbgfs_rings_status;
++      struct dentry *dbgfs_dma_cap;
++#endif
+ };
+ int stmmac_mdio_unregister(struct net_device *ndev);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -119,7 +119,7 @@ static irqreturn_t stmmac_interrupt(int
+ #ifdef CONFIG_DEBUG_FS
+ static int stmmac_init_fs(struct net_device *dev);
+-static void stmmac_exit_fs(void);
++static void stmmac_exit_fs(struct net_device *dev);
+ #endif
+ #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
+@@ -1918,7 +1918,7 @@ static int stmmac_release(struct net_dev
+       netif_carrier_off(dev);
+ #ifdef CONFIG_DEBUG_FS
+-      stmmac_exit_fs();
++      stmmac_exit_fs(dev);
+ #endif
+       stmmac_release_ptp(priv);
+@@ -2510,8 +2510,6 @@ static int stmmac_ioctl(struct net_devic
+ #ifdef CONFIG_DEBUG_FS
+ static struct dentry *stmmac_fs_dir;
+-static struct dentry *stmmac_rings_status;
+-static struct dentry *stmmac_dma_cap;
+ static void sysfs_display_ring(void *head, int size, int extend_desc,
+                              struct seq_file *seq)
+@@ -2650,36 +2648,39 @@ static const struct file_operations stmm
+ static int stmmac_init_fs(struct net_device *dev)
+ {
+-      /* Create debugfs entries */
+-      stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
++      struct stmmac_priv *priv = netdev_priv(dev);
++
++      /* Create per netdev entries */
++      priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir);
+-      if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
+-              pr_err("ERROR %s, debugfs create directory failed\n",
+-                     STMMAC_RESOURCE_NAME);
++      if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) {
++              pr_err("ERROR %s/%s, debugfs create directory failed\n",
++                     STMMAC_RESOURCE_NAME, dev->name);
+               return -ENOMEM;
+       }
+       /* Entry to report DMA RX/TX rings */
+-      stmmac_rings_status = debugfs_create_file("descriptors_status",
+-                                                S_IRUGO, stmmac_fs_dir, dev,
+-                                                &stmmac_rings_status_fops);
++      priv->dbgfs_rings_status =
++              debugfs_create_file("descriptors_status", S_IRUGO,
++                                  priv->dbgfs_dir, dev,
++                                  &stmmac_rings_status_fops);
+-      if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
++      if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) {
+               pr_info("ERROR creating stmmac ring debugfs file\n");
+-              debugfs_remove(stmmac_fs_dir);
++              debugfs_remove_recursive(priv->dbgfs_dir);
+               return -ENOMEM;
+       }
+       /* Entry to report the DMA HW features */
+-      stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
+-                                           dev, &stmmac_dma_cap_fops);
++      priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO,
++                                          priv->dbgfs_dir,
++                                          dev, &stmmac_dma_cap_fops);
+-      if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
++      if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) {
+               pr_info("ERROR creating stmmac MMC debugfs file\n");
+-              debugfs_remove(stmmac_rings_status);
+-              debugfs_remove(stmmac_fs_dir);
++              debugfs_remove_recursive(priv->dbgfs_dir);
+               return -ENOMEM;
+       }
+@@ -2687,11 +2688,11 @@ static int stmmac_init_fs(struct net_dev
+       return 0;
+ }
+-static void stmmac_exit_fs(void)
++static void stmmac_exit_fs(struct net_device *dev)
+ {
+-      debugfs_remove(stmmac_rings_status);
+-      debugfs_remove(stmmac_dma_cap);
+-      debugfs_remove(stmmac_fs_dir);
++      struct stmmac_priv *priv = netdev_priv(dev);
++
++      debugfs_remove_recursive(priv->dbgfs_dir);
+ }
+ #endif /* CONFIG_DEBUG_FS */
+@@ -3136,6 +3137,35 @@ err:
+ __setup("stmmaceth=", stmmac_cmdline_opt);
+ #endif /* MODULE */
++static int __init stmmac_init(void)
++{
++#ifdef CONFIG_DEBUG_FS
++      /* Create debugfs main directory if it doesn't exist yet */
++      if (stmmac_fs_dir == NULL) {
++              stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
++
++              if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
++                      pr_err("ERROR %s, debugfs create directory failed\n",
++                             STMMAC_RESOURCE_NAME);
++
++                      return -ENOMEM;
++              }
++      }
++#endif
++
++      return 0;
++}
++
++static void __exit stmmac_exit(void)
++{
++#ifdef CONFIG_DEBUG_FS
++      debugfs_remove_recursive(stmmac_fs_dir);
++#endif
++}
++
++module_init(stmmac_init)
++module_exit(stmmac_exit)
++
+ MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver");
+ MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
+ MODULE_LICENSE("GPL");
diff --git a/target/linux/ipq806x/patches-4.0/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch b/target/linux/ipq806x/patches-4.0/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch
new file mode 100644 (file)
index 0000000..20d8502
--- /dev/null
@@ -0,0 +1,145 @@
+From e81de9d28bd0421c236df322872e64edf4ee1852 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Mon, 11 May 2015 16:32:09 -0700
+Subject: [PATCH 7/8] ARM: dts: qcom: add mdio nodes to ap148 & db149
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 40 ++++++++++++++++++++++++++-
+ arch/arm/boot/dts/qcom-ipq8064-db149.dts | 46 ++++++++++++++++++++++++++++++++
+ 2 files changed, 85 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
++++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
+@@ -14,8 +14,9 @@
+               };
+       };
+-      alias {
++      aliases {
+               serial0 = &uart4;
++              mdio-gpio0 = &mdio0;
+       };
+       chosen {
+@@ -54,6 +55,15 @@
+                                       bias-none;
+                               };
+                       };
++
++                      mdio0_pins: mdio0_pins {
++                              mux {
++                                      pins = "gpio0", "gpio1";
++                                      function = "gpio";
++                                      drive-strength = <8>;
++                                      bias-disable;
++                              };
++                      };
+               };
+               gsbi@16300000 {
+@@ -139,5 +149,33 @@
+                       pinctrl-0 = <&pcie2_pins>;
+                       pinctrl-names = "default";
+               };
++
++              mdio0: mdio {
++                      compatible = "virtual,mdio-gpio";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
++                      pinctrl-0 = <&mdio0_pins>;
++                      pinctrl-names = "default";
++
++                      phy0: ethernet-phy@0 {
++                              device_type = "ethernet-phy";
++                              reg = <0>;
++                              qca,ar8327-initvals = <
++                                      0x00004 0x7600000   /* PAD0_MODE */
++                                      0x00008 0x1000000   /* PAD5_MODE */
++                                      0x0000c 0x80        /* PAD6_MODE */
++                                      0x000e4 0xaa545     /* MAC_POWER_SEL */
++                                      0x000e0 0xc74164de  /* SGMII_CTRL */
++                                      0x0007c 0x4e        /* PORT0_STATUS */
++                                      0x00094 0x4e        /* PORT6_STATUS */
++                                      >;
++                      };
++
++                      phy4: ethernet-phy@4 {
++                              device_type = "ethernet-phy";
++                              reg = <4>;
++                      };
++              };
+       };
+ };
+--- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts
++++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
+@@ -16,6 +16,7 @@
+       alias {
+               serial0 = &uart2;
++              mdio-gpio0 = &mdio0;
+       };
+       chosen {
+@@ -62,6 +63,15 @@
+                                       bias-none;
+                               };
+                       };
++
++                      mdio0_pins: mdio0_pins {
++                              mux {
++                                      pins = "gpio0", "gpio1";
++                                      function = "gpio";
++                                      drive-strength = <8>;
++                                      bias-disable;
++                              };
++                      };
+               };
+               gsbi2: gsbi@12480000 {
+@@ -173,5 +183,44 @@
+                       pinctrl-0 = <&pcie3_pins>;
+                       pinctrl-names = "default";
+               };
++
++              mdio0: mdio {
++                      compatible = "virtual,mdio-gpio";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
++
++                      pinctrl-0 = <&mdio0_pins>;
++                      pinctrl-names = "default";
++
++                      phy0: ethernet-phy@0 {
++                              device_type = "ethernet-phy";
++                              reg = <0>;
++                              qca,ar8327-initvals = <
++                                      0x00004 0x7600000   /* PAD0_MODE */
++                                      0x00008 0x1000000   /* PAD5_MODE */
++                                      0x0000c 0x80        /* PAD6_MODE */
++                                      0x000e4 0xaa545     /* MAC_POWER_SEL */
++                                      0x000e0 0xc74164de  /* SGMII_CTRL */
++                                      0x0007c 0x4e        /* PORT0_STATUS */
++                                      0x00094 0x4e        /* PORT6_STATUS */
++                              >;
++                      };
++
++                      phy4: ethernet-phy@4 {
++                              device_type = "ethernet-phy";
++                              reg = <4>;
++                      };
++
++                      phy6: ethernet-phy@6 {
++                              device_type = "ethernet-phy";
++                              reg = <6>;
++                      };
++
++                      phy7: ethernet-phy@7 {
++                              device_type = "ethernet-phy";
++                              reg = <7>;
++                      };
++              };
+       };
+ };
diff --git a/target/linux/ipq806x/patches-4.0/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch b/target/linux/ipq806x/patches-4.0/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch
new file mode 100644 (file)
index 0000000..6a14f9f
--- /dev/null
@@ -0,0 +1,210 @@
+From cab1f4720e82f2e17eaeed9a9ad9e4f07c742977 Mon Sep 17 00:00:00 2001
+From: Mathieu Olivari <mathieu@codeaurora.org>
+Date: Mon, 11 May 2015 12:29:18 -0700
+Subject: [PATCH 8/8] ARM: dts: qcom: add gmac nodes to ipq806x platforms
+
+Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+---
+ arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 31 ++++++++++++
+ arch/arm/boot/dts/qcom-ipq8064-db149.dts | 43 ++++++++++++++++
+ arch/arm/boot/dts/qcom-ipq8064.dtsi      | 86 ++++++++++++++++++++++++++++++++
+ 3 files changed, 160 insertions(+)
+
+--- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
++++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
+@@ -64,6 +64,16 @@
+                                       bias-disable;
+                               };
+                       };
++
++                      rgmii2_pins: rgmii2_pins {
++                              mux {
++                                      pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
++                                             "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62" ;
++                                      function = "rgmii2";
++                                      drive-strength = <8>;
++                                      bias-disable;
++                              };
++                      };
+               };
+               gsbi@16300000 {
+@@ -177,5 +187,26 @@
+                               reg = <4>;
+                       };
+               };
++
++              gmac1: ethernet@37200000 {
++                      status = "ok";
++                      phy-mode = "rgmii";
++                      phy-handle = <&phy4>;
++                      qcom,id = <1>;
++
++                      pinctrl-0 = <&rgmii2_pins>;
++                      pinctrl-names = "default";
++              };
++
++              gmac2: ethernet@37400000 {
++                      status = "ok";
++                      phy-mode = "sgmii";
++                      qcom,id = <2>;
++
++                      fixed-link {
++                              speed = <1000>;
++                              full-duplex;
++                      };
++              };
+       };
+ };
+--- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts
++++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
+@@ -72,6 +72,14 @@
+                                       bias-disable;
+                               };
+                       };
++
++                      rgmii0_pins: rgmii0_pins {
++                              mux {
++                                      pins = "gpio2", "gpio66";
++                                      drive-strength = <8>;
++                                      bias-disable;
++                              };
++                      };
+               };
+               gsbi2: gsbi@12480000 {
+@@ -222,5 +230,40 @@
+                               reg = <7>;
+                       };
+               };
++
++              gmac0: ethernet@37000000 {
++                      status = "ok";
++                      phy-mode = "rgmii";
++                      qcom,id = <0>;
++                      phy-handle = <&phy4>;
++
++                      pinctrl-0 = <&rgmii0_pins>;
++                      pinctrl-names = "default";
++              };
++
++              gmac1: ethernet@37200000 {
++                      status = "ok";
++                      phy-mode = "sgmii";
++                      qcom,id = <1>;
++
++                      fixed-link {
++                              speed = <1000>;
++                              full-duplex;
++                      };
++              };
++
++              gmac2: ethernet@37400000 {
++                      status = "ok";
++                      phy-mode = "sgmii";
++                      qcom,id = <2>;
++                      phy-handle = <&phy6>;
++              };
++
++              gmac3: ethernet@37600000 {
++                      status = "ok";
++                      phy-mode = "sgmii";
++                      qcom,id = <3>;
++                      phy-handle = <&phy7>;
++              };
+       };
+ };
+--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
+@@ -540,5 +540,91 @@
+                       status = "disabled";
+               };
++
++              nss_common: syscon@03000000 {
++                      compatible = "syscon";
++                      reg = <0x03000000 0x0000FFFF>;
++              };
++
++              qsgmii_csr: syscon@1bb00000 {
++                      compatible = "syscon";
++                      reg = <0x1bb00000 0x000001FF>;
++              };
++
++              gmac0: ethernet@37000000 {
++                      device_type = "network";
++                      compatible = "qcom,ipq806x-gmac";
++                      reg = <0x37000000 0x200000>;
++                      interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "macirq";
++
++                      qcom,nss-common = <&nss_common>;
++                      qcom,qsgmii-csr = <&qsgmii_csr>;
++
++                      clocks = <&gcc GMAC_CORE1_CLK>;
++                      clock-names = "stmmaceth";
++
++                      resets = <&gcc GMAC_CORE1_RESET>;
++                      reset-names = "stmmaceth";
++
++                      status = "disabled";
++              };
++
++              gmac1: ethernet@37200000 {
++                      device_type = "network";
++                      compatible = "qcom,ipq806x-gmac";
++                      reg = <0x37200000 0x200000>;
++                      interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "macirq";
++
++                      qcom,nss-common = <&nss_common>;
++                      qcom,qsgmii-csr = <&qsgmii_csr>;
++
++                      clocks = <&gcc GMAC_CORE2_CLK>;
++                      clock-names = "stmmaceth";
++
++                      resets = <&gcc GMAC_CORE2_RESET>;
++                      reset-names = "stmmaceth";
++
++                      status = "disabled";
++              };
++
++              gmac2: ethernet@37400000 {
++                      device_type = "network";
++                      compatible = "qcom,ipq806x-gmac";
++                      reg = <0x37400000 0x200000>;
++                      interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "macirq";
++
++                      qcom,nss-common = <&nss_common>;
++                      qcom,qsgmii-csr = <&qsgmii_csr>;
++
++                      clocks = <&gcc GMAC_CORE3_CLK>;
++                      clock-names = "stmmaceth";
++
++                      resets = <&gcc GMAC_CORE3_RESET>;
++                      reset-names = "stmmaceth";
++
++                      status = "disabled";
++              };
++
++              gmac3: ethernet@37600000 {
++                      device_type = "network";
++                      compatible = "qcom,ipq806x-gmac";
++                      reg = <0x37600000 0x200000>;
++                      interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "macirq";
++
++                      qcom,nss-common = <&nss_common>;
++                      qcom,qsgmii-csr = <&qsgmii_csr>;
++
++                      clocks = <&gcc GMAC_CORE4_CLK>;
++                      clock-names = "stmmaceth";
++
++                      resets = <&gcc GMAC_CORE4_RESET>;
++                      reset-names = "stmmaceth";
++
++                      status = "disabled";
++              };
+       };
+ };