From: Srinivas Kandagatla <[email protected]>

This patch adds support to STiH415 SOC, which has two ethernet
snps,dwmac controllers version 3.610. With this patch B2000 and B2020
boards can boot with ethernet in MII and RGMII modes.

Tested on both B2020 and B2000.

Signed-off-by: Srinivas Kandagatla <[email protected]>
---
 arch/arm/boot/dts/stih415-pinctrl.dtsi |   82 ++++++++++++++++
 arch/arm/boot/dts/stih415.dtsi         |   34 +++++++
 arch/arm/boot/dts/stih41x-b2000.dtsi   |   21 ++++
 arch/arm/boot/dts/stih41x-b2020.dtsi   |   14 +++
 arch/arm/mach-sti/Makefile             |    2 +-
 arch/arm/mach-sti/board-dt.c           |    2 +
 arch/arm/mach-sti/stih41x.c            |  166 ++++++++++++++++++++++++++++++++
 arch/arm/mach-sti/stih41x.h            |    4 +
 8 files changed, 324 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-sti/stih41x.c
 create mode 100644 arch/arm/mach-sti/stih41x.h

diff --git a/arch/arm/boot/dts/stih415-pinctrl.dtsi 
b/arch/arm/boot/dts/stih415-pinctrl.dtsi
index 1d322b2..c087af8 100644
--- a/arch/arm/boot/dts/stih415-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih415-pinctrl.dtsi
@@ -86,6 +86,57 @@
                                        };
                                };
                        };
+
+                       gmac1 {
+                               pinctrl_mii1: mii1 {
+                                               st,pins {
+                                                txd0   = <&PIO0 0 ALT1 OUT  
SE_NICLK_IO        0       CLK_A>;
+                                                txd1   = <&PIO0 1 ALT1 OUT  
SE_NICLK_IO        0       CLK_A>;
+                                                txd2   = <&PIO0 2 ALT1 OUT  
SE_NICLK_IO        0       CLK_A>;
+                                                txd3   = <&PIO0 3 ALT1 OUT  
SE_NICLK_IO        0       CLK_A>;
+                                                txer   = <&PIO0 4 ALT1 OUT  
SE_NICLK_IO        0       CLK_A>;
+                                                txen   = <&PIO0 5 ALT1 OUT  
SE_NICLK_IO        0       CLK_A>;
+                                                txclk  = <&PIO0 6 ALT1 IN   
NICLK      0       CLK_A>;
+                                                col    = <&PIO0 7 ALT1 IN   
BYPASS     1000>;
+                                                mdio   = <&PIO1 0 ALT1 OUT  
BYPASS     0>;
+                                                mdc    = <&PIO1 1 ALT1 OUT  
NICLK      0       CLK_A>;
+                                                crs    = <&PIO1 2 ALT1 IN   
BYPASS     1000>;
+                                                mdint  = <&PIO1 3 ALT1 IN   
BYPASS     0>;
+                                                rxd0   = <&PIO1 4 ALT1 IN   
SE_NICLK_IO        0       CLK_A>;
+                                                rxd1   = <&PIO1 5 ALT1 IN   
SE_NICLK_IO        0       CLK_A>;
+                                                rxd2   = <&PIO1 6 ALT1 IN   
SE_NICLK_IO        0       CLK_A>;
+                                                rxd3   = <&PIO1 7 ALT1 IN   
SE_NICLK_IO        0       CLK_A>;
+                                                rxdv   = <&PIO2 0 ALT1 IN   
SE_NICLK_IO        0       CLK_A>;
+                                                rx_er  = <&PIO2 1 ALT1 IN   
SE_NICLK_IO        0       CLK_A>;
+                                                rxclk  = <&PIO2 2 ALT1 IN   
NICLK      0       CLK_A>;
+                                                phyclk = <&PIO2 3 ALT1 IN   
NICLK      1000    CLK_A>;
+                                       };
+                               };
+
+                               pinctrl_rgmii1: rgmii1-0 {
+                                       st,pins {
+                                                txd0 =  <&PIO0 0 ALT1 OUT 
DE_IO        1000    CLK_A>;
+                                                txd1 =  <&PIO0 1 ALT1 OUT 
DE_IO        1000    CLK_A>;
+                                                txd2 =  <&PIO0 2 ALT1 OUT 
DE_IO        1000    CLK_A>;
+                                                txd3 =  <&PIO0 3 ALT1 OUT 
DE_IO        1000    CLK_A>;
+                                                txen =  <&PIO0 5 ALT1 OUT 
DE_IO        0       CLK_A>;
+                                                txclk = <&PIO0 6 ALT1 IN       
NICLK   0       CLK_A>;
+                                                mdio =  <&PIO1 0 ALT1 OUT      
BYPASS  0>;
+                                                mdc =   <&PIO1 1 ALT1 OUT      
NICLK   0       CLK_A>;
+                                                rxd0 =  <&PIO1 4 ALT1 IN DE_IO 
0       CLK_A>;
+                                                rxd1 =  <&PIO1 5 ALT1 IN DE_IO 
0       CLK_A>;
+                                                rxd2 =  <&PIO1 6 ALT1 IN DE_IO 
0       CLK_A>;
+                                                rxd3 =  <&PIO1 7 ALT1 IN DE_IO 
0       CLK_A>;
+
+                                                rxdv =   <&PIO2 0 ALT1 IN 
DE_IO        500     CLK_A>;
+                                                rxclk =  <&PIO2 2 ALT1 IN      
NICLK   0       CLK_A>;
+                                                phyclk = <&PIO2 3 ALT4 OUT     
NICLK   0       CLK_B>;
+
+                                                clk125= <&PIO3 7 ALT4 IN       
NICLK   0       CLK_A>;
+                                       };
+                               };
+                       };
+
                };
 
                pin-controller-front {
@@ -197,6 +248,37 @@
                                        };
                                };
                        };
+
+                       gmac0{
+                               pinctrl_mii0: mii0 {
+                                       st,pins {
+                                        mdint =        <&PIO13 6 ALT2  IN      
BYPASS          0>;
+                                        txen =         <&PIO13 7 ALT2  OUT     
SE_NICLK_IO     0       CLK_A>;
+
+                                        txd0 =         <&PIO14 0 ALT2  OUT     
SE_NICLK_IO     0       CLK_A>;
+                                        txd1 =         <&PIO14 1 ALT2  OUT     
SE_NICLK_IO     0       CLK_A>;
+                                        txd2 =         <&PIO14 2 ALT2  OUT     
SE_NICLK_IO     0       CLK_B>;
+                                        txd3 =         <&PIO14 3 ALT2  OUT     
SE_NICLK_IO     0       CLK_B>;
+
+                                        txclk =        <&PIO15 0 ALT2  IN      
NICLK           0       CLK_A>;
+                                        txer =         <&PIO15 1 ALT2  OUT     
SE_NICLK_IO     0       CLK_A>;
+                                        crs =          <&PIO15 2 ALT2  IN      
BYPASS          1000>;
+                                        col =          <&PIO15 3 ALT2  IN      
BYPASS          1000>;
+                                        mdio  =        <&PIO15 4 ALT2  OUT     
BYPASS  3000>;
+                                        mdc   =        <&PIO15 5 ALT2  OUT     
NICLK   0       CLK_B>;
+
+                                        rxd0 =         <&PIO16 0 ALT2  IN      
SE_NICLK_IO     0       CLK_A>;
+                                        rxd1 =         <&PIO16 1 ALT2  IN      
SE_NICLK_IO     0       CLK_A>;
+                                        rxd2 =         <&PIO16 2 ALT2  IN      
SE_NICLK_IO     0       CLK_A>;
+                                        rxd3 =         <&PIO16 3 ALT2  IN      
SE_NICLK_IO     0       CLK_A>;
+                                        rxdv =         <&PIO15 6 ALT2  IN      
SE_NICLK_IO     0       CLK_A>;
+                                        rx_er =        <&PIO15 7 ALT2  IN      
SE_NICLK_IO     0       CLK_A>;
+                                        rxclk =        <&PIO17 0 ALT2  IN      
NICLK           0       CLK_A>;
+                                        phyclk =       <&PIO13 5 ALT2  OUT     
NICLK   1000    CLK_A>;
+
+                                       };
+                               };
+                       };
                };
 
                pin-controller-left {
diff --git a/arch/arm/boot/dts/stih415.dtsi b/arch/arm/boot/dts/stih415.dtsi
index 74ab8de..a77939d 100644
--- a/arch/arm/boot/dts/stih415.dtsi
+++ b/arch/arm/boot/dts/stih415.dtsi
@@ -83,5 +83,39 @@
                        pinctrl-names   = "default";
                        pinctrl-0       = <&pinctrl_sbc_serial1>;
                };
+
+               ethernet0: ethernet@fe810000{
+                       device_type     = "network";
+                       compatible      = "snps,dwmac", "snps,dwmac-3.610";
+                       status          = "disabled";
+                       reg             = <0xfe810000 0x8000>;
+                       interrupts      = <0 147 0>;
+                       interrupt-names = "macirq";
+
+                       snps,pbl        = <32>;
+                       snps,mixed-burst;
+
+                       pinctrl-names   = "default";
+                       pinctrl-0       = <&pinctrl_mii0>;
+                       clock-names     = "stmmaceth";
+                       clocks          = <&CLKS_ICN_REG_0>;
+               };
+
+               ethernet1: ethernet@fef08000 {
+                       device_type = "network";
+                       compatible      = "snps,dwmac", "snps,dwmac-3.610";
+                       status          = "disabled";
+                       reg             = <0xfef08000 0x8000>;
+                       interrupts      = <0 150 0>;
+                       interrupt-names = "macirq";
+
+                       snps,pbl        = <32>;
+                       snps,mixed-burst;
+
+                       pinctrl-names   = "default";
+                       pinctrl-0       = <&pinctrl_mii1>;
+                       clock-names     = "stmmaceth";
+                       clocks          = <&CLKS_ICN_REG_0>;
+               };
        };
 };
diff --git a/arch/arm/boot/dts/stih41x-b2000.dtsi 
b/arch/arm/boot/dts/stih41x-b2000.dtsi
index 8e694d2..55e68d3 100644
--- a/arch/arm/boot/dts/stih41x-b2000.dtsi
+++ b/arch/arm/boot/dts/stih41x-b2000.dtsi
@@ -20,6 +20,8 @@
 
        aliases {
                ttyAS0 = &serial2;
+               ethernet0 = &ethernet0;
+               ethernet1 = &ethernet1;
        };
 
        soc {
@@ -37,5 +39,24 @@
                        };
                };
 
+               ethernet0: ethernet@fe810000 {
+                       status                  = "okay";
+                       phy-mode                = "mii";
+                       snps,phy-addr           = <0x1>;
+
+                       snps,reset-gpio         = <&PIO106 2>;
+                       snps,reset-active-low;
+                       snps,reset-delays-us    = <0 10000 10000>;
+               };
+               ethernet1: ethernet@fef08000 {
+                       status                  = "okay";
+                       phy-mode                = "mii";
+                       snps,phy-addr           = <0x1>;
+
+                       snps,reset-gpio         = <&PIO4 7>;
+                       snps,reset-active-low;
+                       snps,reset-delays-us    = <0 10000 10000>;
+               };
+
        };
 };
diff --git a/arch/arm/boot/dts/stih41x-b2020.dtsi 
b/arch/arm/boot/dts/stih41x-b2020.dtsi
index 133e181..bc5818d 100644
--- a/arch/arm/boot/dts/stih41x-b2020.dtsi
+++ b/arch/arm/boot/dts/stih41x-b2020.dtsi
@@ -19,6 +19,7 @@
 
        aliases {
                ttyAS0 = &sbc_serial1;
+               ethernet1 = &ethernet1;
        };
        soc {
                sbc_serial1: serial@fe531000 {
@@ -38,5 +39,18 @@
                                default-state = "off";
                        };
                };
+
+               ethernet1: ethernet@fef08000 {
+                       status                  = "okay";
+                       phy-mode                = "rgmii-id";
+                       snps,phy-addr           = <0x1>;
+
+                       snps,reset-gpio         = <&PIO3 0>;
+                       snps,reset-active-low;
+                       snps,reset-delays-us    = <0 10000 10000>;
+
+                       pinctrl-0       = <&pinctrl_rgmii1>;
+               };
+
        };
 };
diff --git a/arch/arm/mach-sti/Makefile b/arch/arm/mach-sti/Makefile
index acb3309..daffc49 100644
--- a/arch/arm/mach-sti/Makefile
+++ b/arch/arm/mach-sti/Makefile
@@ -1,2 +1,2 @@
 obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
-obj-$(CONFIG_ARCH_STI)                 += board-dt.o
+obj-$(CONFIG_ARCH_STI)                 += board-dt.o stih41x.o
diff --git a/arch/arm/mach-sti/board-dt.c b/arch/arm/mach-sti/board-dt.c
index 8fe6f0c..80080e3 100644
--- a/arch/arm/mach-sti/board-dt.c
+++ b/arch/arm/mach-sti/board-dt.c
@@ -14,6 +14,7 @@
 #include <asm/mach/arch.h>
 
 #include "smp.h"
+#include "stih41x.h"
 
 void __init stih41x_l2x0_init(void)
 {
@@ -43,6 +44,7 @@ static const char *stih41x_dt_match[] __initdata = {
 
 DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree")
        .init_time      = stih41x_timer_init,
+       .init_machine   = stih41x_init_machine,
        .smp            = smp_ops(sti_smp_ops),
        .dt_compat      = stih41x_dt_match,
 MACHINE_END
diff --git a/arch/arm/mach-sti/stih41x.c b/arch/arm/mach-sti/stih41x.c
new file mode 100644
index 0000000..c32ac40
--- /dev/null
+++ b/arch/arm/mach-sti/stih41x.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited
+ * Author: Srinivas Kandagatla <[email protected]>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ */
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/stmmac.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/regmap.h>
+#include <linux/phy.h>
+
+#define STIH415_SYSCFG_SBC(num)                        (num*4)
+#define STIH415_SYSCFG_REAR(num)               ((num - 300)*4)
+#define STIH415_SYSCFG_FRONT(num)              ((num - 100)*4)
+
+#define STIH415_SYSCFG_ETH0_CONFIG_REG         STIH415_SYSCFG_REAR(382)
+#define STIH415_SYSCFG_EN_GMAC0_REG            STIH415_SYSCFG_FRONT(166)
+#define STIH415_SYSCFG_ETH1_CONFIG_REG         STIH415_SYSCFG_SBC(29)
+#define STIH415_SYSCFG_EN_GMAC1_REG            STIH415_SYSCFG_SBC(31)
+
+/* STiH416 */
+#define STIH416_SYSCFG_SBC(num)                        (num*4)
+#define STIH416_SYSCFG_REAR(num)               ((num - 2000)*4)
+#define STIH416_SYSCFG_FRONT(num)              ((num - 1000)*4)
+
+#define STIH416_SYSCFG_EN_GMAC0_REG            STIH416_SYSCFG_FRONT(1539)
+#define STIH416_SYSCFG_ETH0_CONFIG_REG         STIH416_SYSCFG_REAR(2559)
+#define STIH416_SYSCFG_EN_GMAC1_REG            STIH416_SYSCFG_SBC(510)
+#define STIH416_SYSCFG_ETH1_CONFIG_REG         STIH416_SYSCFG_SBC(508)
+
+#define MAX_ETHS               2
+
+struct eth_syscfg {
+       const char *en_syscfg;
+       const char *cfg_syscfg;
+       u32 en_reg;
+       u32 cfg_reg;
+};
+
+struct eth_syscfg stih415_eth_config[MAX_ETHS] = {
+       [0] = {
+               .en_syscfg      = "st,stih415-front-syscfg",
+               .en_reg         = STIH415_SYSCFG_EN_GMAC0_REG,
+               .cfg_syscfg     = "st,stih415-rear-syscfg",
+               .cfg_reg        = STIH415_SYSCFG_ETH0_CONFIG_REG,
+       },
+       [1] = {
+               .en_syscfg      = "st,stih415-sbc-syscfg",
+               .en_reg         = STIH415_SYSCFG_EN_GMAC1_REG,
+               .cfg_syscfg     = "st,stih415-sbc-syscfg",
+               .cfg_reg        = STIH415_SYSCFG_ETH1_CONFIG_REG,
+       }
+};
+
+struct eth_syscfg stih416_eth_config[MAX_ETHS] = {
+       [0] = {
+               .en_syscfg      = "st,stih416-front-syscfg",
+               .en_reg         = STIH416_SYSCFG_EN_GMAC0_REG,
+               .cfg_syscfg     = "st,stih416-rear-syscfg",
+               .cfg_reg        = STIH416_SYSCFG_ETH0_CONFIG_REG,
+       },
+       [1] = {
+               .en_syscfg      = "st,stih416-sbc-syscfg",
+               .en_reg         = STIH416_SYSCFG_EN_GMAC1_REG,
+               .cfg_syscfg     = "st,stih416-sbc-syscfg",
+               .cfg_reg        = STIH416_SYSCFG_ETH1_CONFIG_REG,
+       }
+};
+
+static struct eth_syscfg *stih41x_eth_syscfg;
+
+static u32 eth_configs[] = {
+       [PHY_INTERFACE_MODE_MII]        = 0x060,
+       [PHY_INTERFACE_MODE_GMII]       = 0x020,
+       [PHY_INTERFACE_MODE_RMII]       = 0x1b0,
+       [PHY_INTERFACE_MODE_RGMII]      = 0x024,
+       [PHY_INTERFACE_MODE_RGMII_ID]   = 0x024,
+};
+
+static int stih41x_setup_ethernet(struct plat_stmmacenet_data *plat_data,
+                               int ext_phyclk)
+{
+       int phy_mode  = plat_data->interface;
+       int bus_id = plat_data->bus_id;
+       struct regmap *regmap_en, *regmap_cfg;
+       u32 eth_config;
+       struct eth_syscfg *syscfg;
+
+       if (bus_id < 0 || bus_id > MAX_ETHS)
+               return -EINVAL;
+
+       syscfg = &stih41x_eth_syscfg[bus_id];
+
+       if (!syscfg)
+               return -EINVAL;
+
+       regmap_en = syscon_regmap_lookup_by_compatible(syscfg->en_syscfg);
+       regmap_cfg = syscon_regmap_lookup_by_compatible(syscfg->cfg_syscfg);
+
+       if (IS_ERR(regmap_en) || IS_ERR(regmap_cfg))
+               return -EINVAL;
+
+       eth_config = eth_configs[phy_mode];
+       if (!ext_phyclk) /* internal clock */
+               eth_config |= 0x180;
+
+       regmap_write(regmap_en, syscfg->en_reg, 1);
+       regmap_write(regmap_cfg, syscfg->cfg_reg, eth_config);
+       return 0;
+}
+
+static int stih41x_init_ethernet(struct platform_device *pdev)
+{
+       struct plat_stmmacenet_data *plat_data = pdev->dev.platform_data;
+
+       if (stih41x_setup_ethernet(plat_data, 1))
+               return -EINVAL;
+
+       /* Will be used in speed selection */
+       plat_data->bsp_priv = pdev;
+
+       return 0;
+}
+
+static void stih41x_fix_mac_speed(void *priv, unsigned int spd)
+{
+       struct platform_device *pdev = priv;
+       struct plat_stmmacenet_data *plat_data = pdev->dev.platform_data;
+
+       /* On B2020 use internal clock at 25MHz for 100 link in RGMII mode */
+       if (plat_data->interface != PHY_INTERFACE_MODE_MII)
+               stih41x_setup_ethernet(plat_data, (spd == SPEED_1000) ? 1 : 0);
+}
+
+static struct plat_stmmacenet_data stih41x_eth0_pdata = {
+       .init = &stih41x_init_ethernet,
+       .fix_mac_speed = &stih41x_fix_mac_speed,
+};
+
+static struct plat_stmmacenet_data stih41x_eth1_pdata = {
+       .init = &stih41x_init_ethernet,
+       .fix_mac_speed = &stih41x_fix_mac_speed,
+};
+
+struct of_dev_auxdata stih41x_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("snps,dwmac", 0xfe810000, NULL, &stih41x_eth0_pdata),
+       OF_DEV_AUXDATA("snps,dwmac", 0xfef08000, NULL, &stih41x_eth1_pdata),
+       {}
+};
+
+void __init stih41x_init_machine(void)
+{
+       if (of_machine_is_compatible("st,stih415"))
+               stih41x_eth_syscfg = stih415_eth_config;
+       else if (of_machine_is_compatible("st,stih416"))
+               stih41x_eth_syscfg = stih416_eth_config;
+
+       of_platform_populate(NULL, of_default_bus_match_table,
+                       stih41x_auxdata_lookup, NULL);
+}
diff --git a/arch/arm/mach-sti/stih41x.h b/arch/arm/mach-sti/stih41x.h
new file mode 100644
index 0000000..cf2df32
--- /dev/null
+++ b/arch/arm/mach-sti/stih41x.h
@@ -0,0 +1,4 @@
+#ifndef __MACH_STIH41X_H
+#define __MACH_STIH41X_H
+extern void stih41x_init_machine(void);
+#endif /* __MACH_STIH41X_H */
-- 
1.7.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to