ethernet: adjust gmac code
authorhwg <hwg@rock-chips.com>
Wed, 12 Mar 2014 12:23:10 +0000 (20:23 +0800)
committerhwg <hwg@rock-chips.com>
Wed, 12 Mar 2014 12:23:36 +0000 (20:23 +0800)
arch/arm/boot/dts/rk3188.dtsi
arch/arm/boot/dts/rk3288-pinctrl.dtsi
arch/arm/boot/dts/rk3288.dtsi
drivers/net/ethernet/rockchip/gmac/Makefile
drivers/net/ethernet/rockchip/gmac/rk_gmac_phy_ctl.c [new file with mode: 0755]
drivers/net/ethernet/rockchip/gmac/stmmac.h
drivers/net/ethernet/rockchip/gmac/stmmac_main.c
drivers/net/ethernet/rockchip/gmac/stmmac_platform.c

index 8cb5081981122e428000046fea9dc220b2de387d..95580910032c0dac3049f32ecc0d47bb9ca12d5f 100755 (executable)
                              "hsicphy12m", "hsic_otgphy1";
        };
 
-       vmac@0x10204000 {
+       vmac@10204000 {
                compatible = "rockchip,vmac";
                reg = <0x10204000 0x4000>;
                interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
index 83bd7174a5957f0b724d459c6991025995630cb9..6ca665fc31cd00fabd810ef357c5553f25ada555 100755 (executable)
                        };
 
                };
+               
+               gmac {
+                       mac_clk: mac-clk {
+                               rockchip,pins = <MAC_CLK>;
+                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               //rockchip,voltage = <VALUE_VOL_DEFAULT>;
+                               rockchip,drive = <VALUE_DRV_DEFAULT>;
+                               //rockchip,tristate = <VALUE_TRI_DEFAULT>;
+                       };
+                       
+                       mac_txpins: mac-txpins {
+                               rockchip,pins = <MAC_TXD0>, <MAC_TXD1>, <MAC_TXD2>, <MAC_TXD3>, <MAC_TXEN>, <MAC_TXCLK>;
+                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               //rockchip,voltage = <VALUE_VOL_DEFAULT>;
+                               rockchip,drive = <VALUE_DRV_DEFAULT>;
+                               //rockchip,tristate = <VALUE_TRI_DEFAULT>;
+                       };
+                       
+                       mac_rxpins: mac-rxpins {
+                               rockchip,pins = <MAC_RXD0>, <MAC_RXD1>, <MAC_RXD2>, <MAC_RXD3>, <MAC_RXDV>, <MAC_RXER>, <MAC_RXCLK>, <MAC_CRS>, <MAC_COL>;
+                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               //rockchip,voltage = <VALUE_VOL_DEFAULT>;
+                               rockchip,drive = <VALUE_DRV_DEFAULT>;
+                               //rockchip,tristate = <VALUE_TRI_DEFAULT>;
+                       };
+                       
+                       mac_mdpins: mac-mdpins {
+                               rockchip,pins = <MAC_MDIO>, <MAC_MDC>;
+                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               //rockchip,voltage = <VALUE_VOL_DEFAULT>;
+                               rockchip,drive = <VALUE_DRV_DEFAULT>;
+                               //rockchip,tristate = <VALUE_TRI_DEFAULT>;
+                       };
+               };
 
                //to add
        };
index 88231724bbb6fb5b0aa844b4848cabb46b128f83..fa5e0c16543bda7cb2c1be9b9968ef300b95f5ac 100755 (executable)
                /*clock-names = "hsicphy480m", "hclk_hsic",*/
                /*            "hsicphy12m", "hsic_otgphy1";*/
        };
+       
+       gmac: eth@ff290000 {
+               compatible = "rockchip,gmac";
+               reg = <0xff290000 0x10000>;
+               interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;  /*irq=59*/
+               interrupt-names = "macirq";
+               phy-mode = "rmii";
+               //phy-mode = "gmii";
+               pinctrl-names = "default";
+               pinctrl-0 = <&mac_clk &mac_txpins &mac_rxpins &mac_mdpins>;
+       };
 };
index 7abf9db73cc2e7b24c4f97fb599c442fbcf3c41a..ce1099b142b52b08ac353ff0eb566fb97e26a37b 100755 (executable)
@@ -1,4 +1,4 @@
-obj-$(CONFIG_RK_GMAC_ETH) += stmmac.o
+obj-$(CONFIG_RK_GMAC_ETH) += stmmac.o rk_gmac_phy_ctl.o
 stmmac-$(CONFIG_RK_GMAC_ETH) += stmmac_platform.o
 stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
 stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
diff --git a/drivers/net/ethernet/rockchip/gmac/rk_gmac_phy_ctl.c b/drivers/net/ethernet/rockchip/gmac/rk_gmac_phy_ctl.c
new file mode 100755 (executable)
index 0000000..7b83533
--- /dev/null
@@ -0,0 +1,197 @@
+
+#include <linux/clk.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/wakelock.h>
+#include <linux/version.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <asm/irq.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+
+#include <linux/rockchip/iomap.h>
+#include <linux/rockchip/grf.h>
+
+#include "stmmac.h"
+
+
+struct gmac_phy_data {
+       int power_io;
+       int power_io_enable;
+};
+struct gmac_phy_data g_gmac_phy_data;
+
+#define grf_readl(offset)      readl_relaxed(RK_GRF_VIRT + offset)
+#define grf_writel(v, offset)  do { writel_relaxed(v, RK_GRF_VIRT + offset); dsb(); } while (0)
+
+// RK3288_GRF_SOC_CON1
+#define GMAC_PHY_INTF_SEL_RGMII ((0x01C0 << 16) | (0x0040))
+#define GMAC_PHY_INTF_SEL_RMII  ((0x01C0 << 16) | (0x0100))
+#define GMAC_FLOW_CTRL          ((0x0200 << 16) | (0x0200))
+#define GMAC_FLOW_CTRL_CLR      ((0x0200 << 16) | (0x0000))
+#define GMAC_SPEED_10M          ((0x0400 << 16) | (0x0400))
+#define GMAC_SPEED_100M         ((0x0400 << 16) | (0x0000))
+#define GMAC_RMII_CLK_25M       ((0x0800 << 16) | (0x0800))
+#define GMAC_RMII_CLK_2_5M      ((0x0800 << 16) | (0x0000))
+#define GMAC_CLK_125M           ((0x3000 << 16) | (0x0000))
+#define GMAC_CLK_25M            ((0x3000 << 16) | (0x3000))
+#define GMAC_CLK_2_5M           ((0x3000 << 16) | (0x2000))
+#define GMAC_RMII_MODE          ((0x4000 << 16) | (0x4000))
+
+// RK3288_GRF_SOC_CON3
+#define GMAC_CLK_TX_DL_CFG(val) ((0x007F << 16) | (val))           // 7bit
+#define GMAC_CLK_RX_DL_CFG(val) ((0x007F << 16) | (val<<7))        // 7bit
+#define GMAC_TXCLK_DLY_ENABLE   ((0x4000 << 16) | (0x4000)) 
+#define GMAC_TXCLK_DLY_DISABLE  ((0x4000 << 16) | (0x0000))
+#define GMAC_RXCLK_DLY_ENABLE   ((0x8000 << 16) | (0x8000)) 
+#define GMAC_RXCLK_DLY_DISABLE  ((0x8000 << 16) | (0x0000)) 
+
+static int rk_gmac_register_init(void)
+{
+       printk("enter %s \n",__func__);
+       
+       //select rmii
+       grf_writel(GMAC_PHY_INTF_SEL_RMII, RK3288_GRF_SOC_CON1);
+
+       return 0;
+}
+
+static int rk_gmac_power_control(int enable)
+{
+       struct gmac_phy_data *pdata = &g_gmac_phy_data;
+       
+       printk("enter %s ,enable = %d \n",__func__,enable);
+       if (enable) {
+               if (gpio_is_valid(pdata->power_io)) {
+                       gpio_direction_output(pdata->power_io, pdata->power_io_enable);
+                       gpio_set_value(pdata->power_io, pdata->power_io_enable);
+               }       
+       }else {
+               if (gpio_is_valid(pdata->power_io)) {
+                       gpio_direction_output(pdata->power_io, !pdata->power_io_enable);
+                       gpio_set_value(pdata->power_io, !pdata->power_io_enable);
+               }
+       }
+       return 0;
+}
+
+static int rk_gmac_io_init(struct device *device)
+{
+       printk("enter %s \n",__func__);
+
+       // iomux
+       
+       // clock enable
+       
+       // phy power on
+       rk_gmac_power_control(1);
+
+       return 0;
+}
+
+static int rk_gmac_io_deinit(struct device *device)
+{
+       printk("enter %s \n",__func__);
+       
+       // clock disable
+       
+       // phy power down
+       rk_gmac_power_control(0);
+       
+       return 0;
+}
+
+static int rk_gmac_speed_switch(int speed)
+{
+       printk("%s: speed = %d\n", __func__, speed);
+
+       return 0;
+}
+
+struct rk_gmac_platform_data rk_board_gmac_data = {
+       .gmac_register_init = rk_gmac_register_init,
+       .gmac_io_init = rk_gmac_io_init,
+       .gmac_io_deinit = rk_gmac_io_deinit,
+       .gmac_speed_switch = rk_gmac_speed_switch,
+};
+
+static int gmac_phy_probe(struct platform_device *pdev)
+{
+       struct gmac_phy_data *pdata = pdev->dev.platform_data;
+       enum of_gpio_flags flags;
+       int ret = 0, err;
+       struct device_node *node = pdev->dev.of_node;
+
+    printk("enter %s \n",__func__);
+       if (!pdata) {
+               pdata = &g_gmac_phy_data;
+
+               pdata->power_io = of_get_named_gpio_flags(node, "power-gpios", 0, &flags);
+               if (!gpio_is_valid(pdata->power_io)) {
+                       printk("%s: Get power-gpios failed.\n", __func__);
+                       return -EINVAL;
+               }
+               
+               if(flags & OF_GPIO_ACTIVE_LOW)
+                       pdata->power_io_enable = 0;
+               else
+                       pdata->power_io_enable = 1;
+       }
+       
+       // disable power
+       /*err = gpio_request(pdata->power_io, "gmac_phy_power");
+       if (err) {
+               printk("%s: Request gmac phy power pin failed.\n", __func__);
+               return -EINVAL;
+       }*/     
+       
+       gpio_direction_output(pdata->power_io, !pdata->power_io_enable);
+       gpio_set_value(pdata->power_io, !pdata->power_io_enable);
+
+       return ret;
+}
+
+static int gmac_phy_remove(struct platform_device *pdev)
+{
+       struct gmac_phy_data *pdata = pdev->dev.platform_data;
+       
+       printk("enter %s \n",__func__);
+       if (gpio_is_valid(pdata->power_io))
+               gpio_free(pdata->power_io);
+               
+       return 0;
+}
+
+static struct of_device_id gmac_phy_of_match[] = {
+       { .compatible = "rockchip,gmac-phy" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gmac_phy_of_match);
+
+static struct platform_driver gmac_phy_driver = {
+       .driver         = {
+               .name           = "rockchip,gmac-phy",
+               .owner          = THIS_MODULE,
+               .of_match_table = of_match_ptr(gmac_phy_of_match),
+       },
+       .probe          = gmac_phy_probe,
+       .remove         = gmac_phy_remove,
+};
+
+module_platform_driver(gmac_phy_driver);
+
+MODULE_DESCRIPTION("GMAC PHY Power Driver");
+MODULE_LICENSE("GPL");
index f1970c4acbfdff91aa2d200c984b6cf6f38365a2..e0914aa198998ae1525904485c1ab60864c05f9b 100755 (executable)
@@ -107,8 +107,18 @@ struct stmmac_priv {
        u32 adv_ts;
        int use_riwt;
        spinlock_t ptp_lock;
+       struct rk_gmac_platform_data *rk_pdata;
 };
 
+struct rk_gmac_platform_data {
+    int (*gmac_register_init)(void);
+    int (*gmac_io_init)(struct device *device);
+    int (*gmac_io_deinit)(struct device *device);
+    int(*gmac_speed_switch)(int speed);
+};
+
+extern struct rk_gmac_platform_data rk_board_gmac_data;
+
 extern int phyaddr;
 
 extern int stmmac_mdio_unregister(struct net_device *ndev);
index 8d2da8b562d961b764df017a124d3d2639052baf..24b0d07aa2e7e70b5884e3a24c063de01673f738 100755 (executable)
@@ -248,6 +248,10 @@ static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv)
 
        if (likely(priv->plat->fix_mac_speed))
                priv->plat->fix_mac_speed(priv->plat->bsp_priv, phydev->speed);
+
+       if (priv->rk_pdata->gmac_speed_switch) {
+               priv->rk_pdata->gmac_speed_switch(phydev->speed);
+       }
 }
 
 /**
@@ -1571,6 +1575,10 @@ static int stmmac_open(struct net_device *dev)
 
        clk_prepare_enable(priv->stmmac_clk);
 
+       if (priv->rk_pdata->gmac_io_init) {
+               priv->rk_pdata->gmac_io_init(priv->device);
+       }
+
        stmmac_check_ether_addr(priv);
 
        if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
@@ -1759,6 +1767,10 @@ static int stmmac_release(struct net_device *dev)
 
        stmmac_release_ptp(priv);
 
+       if (priv->rk_pdata->gmac_io_deinit) {
+               priv->rk_pdata->gmac_io_deinit(priv->device);
+       }
+
        return 0;
 }
 
index 1d3780f55ba2c9397641b1b5986b952680259e0c..48c69791b0bdddcdc806a5af0513bea28f2f7f5e 100755 (executable)
@@ -49,9 +49,7 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
         * are provided. All other properties should be added
         * once needed on other platforms.
         */
-       if (of_device_is_compatible(np, "st,spear600-gmac") ||
-               of_device_is_compatible(np, "snps,dwmac-3.70a") ||
-               of_device_is_compatible(np, "snps,dwmac")) {
+       if (of_device_is_compatible(np, "rockchip,gmac")) {
                plat->has_gmac = 1;
                plat->pmt = 1;
        }
@@ -151,6 +149,11 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, priv->dev);
 
+       priv->rk_pdata = &rk_board_gmac_data;
+       if (priv->rk_pdata->gmac_register_init) {
+               priv->rk_pdata->gmac_register_init();
+       }
+
        pr_debug("STMMAC platform driver registration completed");
 
        return 0;
@@ -229,9 +232,7 @@ static const struct dev_pm_ops stmmac_pltfr_pm_ops;
 #endif /* CONFIG_PM */
 
 static const struct of_device_id stmmac_dt_ids[] = {
-       { .compatible = "st,spear600-gmac"},
-       { .compatible = "snps,dwmac-3.70a"},
-       { .compatible = "snps,dwmac"},
+       { .compatible = "rockchip,gmac"},
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, stmmac_dt_ids);