ethernet: vmac driver for 3036
authorroger <cz@rock-chips.com>
Fri, 25 Jul 2014 01:03:53 +0000 (09:03 +0800)
committerroger <cz@rock-chips.com>
Fri, 25 Jul 2014 01:03:53 +0000 (09:03 +0800)
arch/arm/boot/dts/rk3036-clocks.dtsi
arch/arm/boot/dts/rk3036-pinctrl.dtsi
arch/arm/boot/dts/rk3036-sdk.dts
arch/arm/boot/dts/rk3036.dtsi
arch/arm/configs/rk3036_defconfig
drivers/net/ethernet/rockchip/vmac/rk29_vmac.c
drivers/net/ethernet/rockchip/vmac/rk29_vmac.h
drivers/net/ethernet/rockchip/vmac/rk29_vmac_phy.c

index 41aab4620f0489e242f707d2cfd406d44406d853..9b60bf8d65670e0365eae38ab1222c27c4e494de 100755 (executable)
@@ -42,7 +42,7 @@
                        rmii_clkin: rmii_clkin {
                                compatible = "rockchip,rk-fixed-clock";
                                clock-output-names = "rmii_clkin";
-                               clock-frequency = <0>;
+                               clock-frequency = <50000000>;
                                #clock-cells = <0>;
                        };
 
                                #clock-cells = <0>;
                        };
 
+                       io_mac_mdclkout: io_mac_mdclkout {
+                               compatible = "rockchip,rk-fixed-factor-clock";
+                               clocks = <&aclk_peri_pre>;
+                               clock-output-names = "io_mac_mdclkout";
+                               clock-div = <2>;
+                               clock-mult = <1>;
+                               #clock-cells = <0>;
+                       };
                };
 
                clock_regs {
                                                "g_hp_axi_matrix",              "g_pp_axi_matrix",
                                                "g_aclk_cpu_peri",              "g_ap_axi_matrix",
 
-                                               "reserved",             "reserved",
+                                               "reserved",             "g_hclk_mac",
                                                "reserved",             "reserved",
 
                                                "reserved",             "reserved",
index d5225b100b8a5e2dc39e615b080282909c228eed..5261973393d0a4d8728491f47cc8936b2a53472a 100755 (executable)
                        };
                };
 
-               gpio2_gmac {            
+               gpio2_gmac {
+                       mac_clk: mac-clk {
+                               rockchip,pins = <MAC_CLKOUT>;
+                               rockchip,pull = <VALUE_PULL_DEFAULT>;
+                       };
+               
                        mac_txpins: mac-txpins {
                                rockchip,pins = <MAC_TXD0>, <MAC_TXD1>,  <MAC_TXEN>;
                                rockchip,pull = <VALUE_PULL_DEFAULT>;
index 8e0f60d5b6f5036aee103eb5bbbef20f8a53eef4..d83cb97b7f83a042146bee71008b3131c28eab69 100755 (executable)
        status = "okay";
        //rockchips,hdmi_audio_source = <0>;
 };
+
+&vmac {
+//     pmu_regulator = "act_ldo5";
+//     pmu_enable_level = <1>; //1->HIGH, 0->LOW
+//      power-gpio = <&gpio0 GPIO_A6 GPIO_ACTIVE_HIGH>;
+        reset-gpio = <&gpio2 GPIO_C6 GPIO_ACTIVE_LOW>;
+};
index 6337905951a167421b5ef1336a81657eb44cc8a9..30c9557980675a7b5d207d6952262051708cf942 100755 (executable)
                        <&clk_gpu_pre 300000000>,        <&aclk_vio_pre 300000000>,
                        <&hclk_vio_pre 150000000>, <&aclk_vcodec_pre 300000000>,
                        <&clk_hevc_core 200000000>, <&clk_mac_pll_div 50000000>,
-                       <&clk_mac_ref_div 50000000>;
+                       <&clk_mac_ref_div 25000000>;
        /*      rockchip,clocks-uboot-has-init =
                        <&aclk_vio1>;*/
        };
                interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "vpu_mmu";
        };
+
+       vmac: eth@10200000 {
+               compatible = "rockchip,vmac";
+               reg = <0x10200000 0x4000>;
+               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "macirq";
+               clocks = <&clk_mac_pll>, <&clk_mac_ref>, 
+                       <&clk_mac_pll_div>, <&clk_mac_ref_div>, 
+                       <&clk_gates2 6>, <&clk_gates3 5>;
+                clock-names = "clk_mac_pll", "clk_mac_ref",
+                          "clk_mac_pll_div", "clk_mac_ref_div",
+                          "clk_tx_rx_gate", "hclk_mac";
+                pinctrl-names = "default";
+                pinctrl-0 = <&mac_clk &mac_txpins &mac_rxpins &mac_crs &mac_mdpins>;
+        };
 };
index a64a5275efcff3f1fc579d2f72d2590750199ed5..93672bac6c9297905eb924e7f23a09c3f8ef4aa6 100644 (file)
@@ -225,6 +225,7 @@ CONFIG_DM_UEVENT=y
 CONFIG_DM_VERITY=y
 CONFIG_NETDEVICES=y
 CONFIG_TUN=y
+CONFIG_RK_VMAC_ETH=y
 CONFIG_PPP=y
 CONFIG_PPP_BSDCOMP=y
 CONFIG_PPP_DEFLATE=y
index 16e69c4e2510df07cb32070043933879ce34ff0b..99b7af0dfae83d3772753805273ed926fe3f8fe2 100755 (executable)
 #include <linux/completion.h>\r
 #include <linux/of.h>\r
 #include <linux/of_platform.h>\r
-\r
+#include <linux/of.h>\r
+#include <linux/of_net.h>\r
+#include <linux/gpio.h>\r
+#include <linux/of_gpio.h>\r
+#include <linux/of_device.h>\r
 #include "rk29_vmac.h"\r
 \r
 //static struct wake_lock idlelock; /* add by lyx @ 20110302 */\r
@@ -766,7 +770,7 @@ static irqreturn_t vmac_intr(int irq, void *dev_instance)
        if (unlikely(ap->shutdown))\r
                dev_err(&ap->pdev->dev, "ISR during close\n");\r
 \r
-       if (unlikely(!status & (RXINT_MASK|MDIO_MASK|ERR_MASK)))\r
+       if (unlikely((!status) & (RXINT_MASK|MDIO_MASK|ERR_MASK)))\r
                dev_err(&ap->pdev->dev, "No source of IRQ found\n");\r
 #endif\r
 \r
@@ -1017,12 +1021,8 @@ int vmac_open(struct net_device *dev)
        struct phy_device *phydev;\r
        unsigned int temp;\r
        int err = 0;\r
-       struct clk *mac_clk = NULL;\r
-       struct clk *mac_parent = NULL;\r
-       struct clk *arm_clk = NULL;\r
        struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;\r
        unsigned char current_mac[6];\r
-       int ret = 0;\r
        struct pinctrl_state *clkout_state;\r
 \r
        printk("enter func %s...\n", __func__);\r
@@ -1033,7 +1033,7 @@ int vmac_open(struct net_device *dev)
        wake_lock_timeout(&ap->resume_lock, 5*HZ);\r
 \r
        ap->shutdown = 0;\r
-       \r
+\r
        // switch to rmii\r
        printk("ap->pdev->dev.pins->p = %p\n", ap->pdev->dev.pins->p);\r
        clkout_state = pinctrl_lookup_state(ap->pdev->dev.pins->p, "default");\r
@@ -1041,45 +1041,41 @@ int vmac_open(struct net_device *dev)
                dev_err(&ap->pdev->dev, "no clkout pinctrl state\n");\r
                goto err_out;\r
        }\r
-       \r
+\r
        printk("in pinctrl_select_state.\n");\r
        pinctrl_select_state(ap->pdev->dev.pins->p, clkout_state);\r
                \r
        //set rmii ref clock 50MHz\r
-       mac_clk = devm_clk_get(&ap->pdev->dev, "clk_mac");\r
-       /*if (IS_ERR(mac_clk))\r
-               mac_clk = NULL;\r
-       arm_clk = clk_get(NULL, "arm_pll");\r
-       if (IS_ERR(arm_clk))\r
-               arm_clk = NULL;\r
-       if (mac_clk) {\r
-               mac_parent = clk_get_parent(mac_clk);\r
-               if (IS_ERR(mac_parent))\r
-                       mac_parent = NULL;\r
+       pdata->clk_mac_pll_div = clk_get(&ap->pdev->dev, "clk_mac_pll_div");\r
+       if (IS_ERR(pdata->clk_mac_pll_div)) {\r
+               printk("get clk_mac_pll_div failed\n");\r
        }\r
-       if (arm_clk && mac_parent && (arm_clk == mac_parent))\r
-               wake_lock(&idlelock);\r
-\r
-        if(pdata && pdata->rmii_extclk_sel && pdata->rmii_extclk_sel())\r
-        {\r
-            struct clk * mac_clkin = NULL;\r
-            mac_clkin = clk_get(NULL, "rmii_clkin");\r
-            if (IS_ERR(mac_clkin)) {\r
-                pr_err("mac_clkin get fail\n");\r
-            }\r
-            clk_set_parent(mac_clk, mac_clkin); \r
-        }*/\r
-        \r
-       clk_set_rate(mac_clk, 50000000);\r
-       clk_prepare_enable(mac_clk);\r
-       //clk_enable(clk_get(NULL,"mii_rx"));\r
-       //clk_enable(clk_get(NULL,"mii_tx"));\r
-       //clk_enable(clk_get(NULL,"hclk_mac"));\r
+\r
+       pdata->clk_mac_ref_div = clk_get(&ap->pdev->dev, "clk_mac_ref_div");\r
+       if (IS_ERR(pdata->clk_mac_ref_div)) {\r
+               printk("get clk_mac_ref_div failed\n");\r
+       }\r
+\r
+       pdata->hclk_mac = clk_get(&ap->pdev->dev, "hclk_mac");\r
+       if (IS_ERR(pdata->hclk_mac)) {\r
+               printk("get hclk_mac failed\n");\r
+       }\r
+\r
+       clk_prepare_enable(pdata->hclk_mac);\r
+       clk_prepare_enable(pdata->clk_mac_pll_div);\r
+       clk_prepare_enable(pdata->clk_mac_ref_div);\r
 \r
        //phy power on\r
        if (pdata && pdata->rmii_power_control)\r
                pdata->rmii_power_control(1);\r
 \r
+       if (gpio_is_valid(pdata->reset_io)) {\r
+               gpio_direction_output(pdata->reset_io, pdata->reset_io_enable);\r
+               gpio_set_value(pdata->reset_io, pdata->reset_io_enable);\r
+               msleep(20);\r
+               gpio_set_value(pdata->reset_io, !pdata->reset_io_enable);\r
+       }\r
+\r
        msleep(1000);\r
 \r
        vmac_hw_init(dev);\r
@@ -1090,7 +1086,7 @@ int vmac_open(struct net_device *dev)
        }\r
 \r
 #ifdef CONFIG_ETH_MAC_FROM_EEPROM\r
-       ret = eeprom_read_data(0,dev->dev_addr,6);\r
+       err = eeprom_read_data(0,dev->dev_addr,6);\r
        if (ret != 6){\r
                printk("read mac from Eeprom fail.\n");\r
        }else {\r
@@ -1215,9 +1211,6 @@ int vmac_close(struct net_device *dev)
 {\r
        struct vmac_priv *ap = netdev_priv(dev);\r
        unsigned int temp;\r
-       struct clk *mac_clk = NULL;\r
-       struct clk *arm_clk = NULL;\r
-       struct clk *mac_parent = NULL;\r
        struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;\r
 \r
        printk("enter func %s...\n", __func__);\r
@@ -1259,26 +1252,13 @@ int vmac_close(struct net_device *dev)
        if (pdata && pdata->rmii_power_control)\r
                pdata->rmii_power_control(0);\r
 \r
-       //clock close\r
-       /*mac_clk = clk_get(NULL, "mac_ref_div");\r
-       if (IS_ERR(mac_clk))\r
-               mac_clk = NULL;\r
-       if (mac_clk) {\r
-               mac_parent = clk_get_parent(mac_clk);\r
-               if (IS_ERR(mac_parent))\r
-                       mac_parent = NULL;\r
+       if (gpio_is_valid(pdata->reset_io)) {\r
+               gpio_set_value(pdata->reset_io, !pdata->reset_io_enable);\r
        }\r
-       arm_clk = clk_get(NULL, "arm_pll");\r
-       if (IS_ERR(arm_clk))\r
-               arm_clk = NULL;\r
 \r
-       if (arm_clk && mac_parent && (arm_clk == mac_parent))\r
-               wake_unlock(&idlelock);*/\r
-       \r
-       clk_disable(clk_get(&ap->pdev->dev,"clk_mac"));\r
-       //clk_disable(clk_get(NULL,"mii_tx"));\r
-       //clk_disable(clk_get(NULL,"hclk_mac"));\r
-       //clk_disable(clk_get(NULL,"clk_mac_pll"));\r
+       clk_disable_unprepare(pdata->clk_mac_ref_div);\r
+       clk_disable_unprepare(pdata->clk_mac_pll_div);\r
+       clk_disable_unprepare(pdata->hclk_mac);\r
 \r
        return 0;\r
 }\r
@@ -1413,7 +1393,7 @@ void vmac_tx_timeout(struct net_device *dev)
 \r
        spin_unlock_irqrestore(&ap->lock, flags);\r
 }\r
-\r
+#if 0\r
 static void create_multicast_filter(struct net_device *dev,\r
        unsigned long *bitmask)\r
 {\r
@@ -1463,6 +1443,7 @@ static void create_multicast_filter(struct net_device *dev,
        }\r
 #endif\r
 }\r
+\r
 static void vmac_set_multicast_list(struct net_device *dev)\r
 {\r
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))\r
@@ -1519,6 +1500,7 @@ static void vmac_set_multicast_list(struct net_device *dev)
        spin_unlock_irqrestore(&ap->lock, flags);\r
 #endif\r
 }\r
+#endif\r
 \r
 static struct ethtool_ops vmac_ethtool_ops = {\r
        .get_settings           = vmacether_get_settings,\r
@@ -1549,13 +1531,32 @@ static int vmac_probe(struct platform_device *pdev)
        int err;\r
        struct rk29_vmac_platform_data *pdata;\r
        struct device_node *np = pdev->dev.of_node;\r
-       \r
+       enum of_gpio_flags flags;\r
+\r
        printk("vmac_probe.\n");\r
        dev_dbg(&pdev->dev, "vmac_probe 1.\n");\r
        \r
        pdev->dev.platform_data = &board_vmac_data;\r
        pdata = pdev->dev.platform_data;\r
 \r
+       pdata->reset_io = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags);\r
+       if (!gpio_is_valid(pdata->reset_io)) {\r
+               printk("%s: Get reset-gpio failed.\n", __func__);\r
+               return -EINVAL;\r
+        } else {\r
+                err = gpio_request(pdata->reset_io, "phy_reset");\r
+                if (err) {\r
+                        pr_err("%s: ERROR: Request phy reset pin failed.\n", __func__);\r
+                        //return -EINVAL;\r
+                }\r
+        }\r
+\r
+       if(flags & OF_GPIO_ACTIVE_LOW) {\r
+               pdata->reset_io_enable = 0;\r
+       } else {\r
+               pdata->reset_io_enable = 1;\r
+       }\r
+\r
        dev = alloc_etherdev(sizeof(*ap));\r
        if (!dev) {\r
                dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n");\r
@@ -1588,7 +1589,7 @@ static int vmac_probe(struct platform_device *pdev)
        }\r
        \r
        printk("mem_base = 0x%08x, mem_size = 0x%08x, irq = %d, regs = 0x%08x\n", \r
-               mem_base, mem_size, irq, ap->regs);\r
+               mem_base, mem_size, irq, (unsigned int)(ap->regs));\r
 \r
        /* no checksum support, hence no scatter/gather */\r
        dev->features |= NETIF_F_HIGHDMA;\r
@@ -1692,25 +1693,6 @@ static int vmac_remove(struct platform_device *pdev)
        return 0;\r
 }\r
 \r
-static void rk29_vmac_power_off(struct net_device *dev)\r
-{\r
-       struct vmac_priv *ap = netdev_priv(dev);\r
-       struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;\r
-\r
-       printk("enter func %s...\n", __func__);\r
-\r
-       //phy power off\r
-       if (pdata && pdata->rmii_power_control)\r
-               pdata->rmii_power_control(0);\r
-\r
-       //clock close\r
-       clk_disable(clk_get(&ap->pdev->dev,"clk_mac"));\r
-       //clk_disable(clk_get(NULL,"mii_tx"));\r
-       //clk_disable(clk_get(NULL,"hclk_mac"));\r
-       //clk_disable(clk_get(NULL,"clk_mac_pll"));\r
-\r
-}\r
-\r
 static int\r
 rk29_vmac_suspend(struct device *dev)\r
 {\r
index a6cf94e28ea05480848ebc2c305f1dd5e1d82274..9f577d3f41ba31df26375656b73518b42fa018f2 100755 (executable)
@@ -275,11 +275,17 @@ static inline int fifo_inc_ct(int ct, int size)
 \r
 /*vmac*/\r
 struct rk29_vmac_platform_data {\r
-    int (*vmac_register_set)(void);\r
-    int (*rmii_io_init)(void);\r
-    int (*rmii_io_deinit)(void);\r
-    int (*rmii_power_control)(int enable);\r
-    int(*rmii_speed_switch)(int speed);\r
+       int (*vmac_register_set)(void);\r
+       int (*rmii_io_init)(void);\r
+       int (*rmii_io_deinit)(void);\r
+       int (*rmii_power_control)(int enable);\r
+       int (*rmii_speed_switch)(int speed);\r
+       struct clk *clk_mac_pll_div;\r
+       struct clk *clk_mac_ref_div;\r
+       struct clk *mac_parent;\r
+       struct clk *hclk_mac;\r
+       int reset_io;\r
+       int reset_io_enable;\r
 };\r
 \r
 extern struct rk29_vmac_platform_data board_vmac_data;\r
index 3b328d3ffbdfa1aa4109a53cd77171e951b16c0d..20ba49169a1f69d82312e249ff0cf45fbab64970 100755 (executable)
 #include <linux/rockchip/grf.h>
 
 #include "rk29_vmac.h"
-
+#if 0
 struct vmac_phy_data {
        int power_io;
        int power_io_enable;
 };
 struct vmac_phy_data g_vmac_phy_data;
+#endif
 
-#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)
+#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)
 
 static int rk30_vmac_register_set(void)
 {
        //config rk30 vmac as rmii
-       writel_relaxed(0x3 << 16 | 0x2, RK_GRF_VIRT + RK3188_GRF_SOC_CON1);
+       grf_writel((0<<8) | ((1<<8)<<16), RK3036_GRF_SOC_CON0);
+       //newrev_en
+       grf_writel((1<<15) | ((1<<15)<<16), RK3036_GRF_SOC_CON0);
        return 0;
 }
 
@@ -48,7 +51,7 @@ static int rk30_rmii_io_init(void)
        printk("enter %s \n",__func__);
 
        //rk3188 gpio3 and sdio drive strength , 
-       grf_writel((0x0f<<16)|0x0f, RK3188_GRF_IO_CON3);
+       //grf_writel((0x0f<<16)|0x0f, RK3188_GRF_IO_CON3);
 
        return 0;
 }
@@ -62,6 +65,7 @@ static int rk30_rmii_io_deinit(void)
 
 static int rk30_rmii_power_control(int enable)
 {
+#if 0
        struct vmac_phy_data *pdata = &g_vmac_phy_data;
        
        printk("enter %s ,enable = %d \n",__func__,enable);
@@ -76,18 +80,17 @@ static int rk30_rmii_power_control(int enable)
                        gpio_set_value(pdata->power_io, !pdata->power_io_enable);
                }
        }
+#endif
        return 0;
 }
 
-#define BIT_EMAC_SPEED_100M      (1 << 1)
-#define BIT_EMAC_SPEED_10M       (0 << 1)
 static int rk29_vmac_speed_switch(int speed)
 {
        //printk("%s: speed = %d\n", __func__, speed);
        if (10 == speed) {
-           writel_relaxed((2<<16)|BIT_EMAC_SPEED_10M, RK_GRF_VIRT + RK3188_GRF_SOC_CON1);
+           grf_writel((0<<9) | ((1<<9)<<16), RK3036_GRF_SOC_CON0);
        } else {
-           writel_relaxed((2<<16)|BIT_EMAC_SPEED_100M, RK_GRF_VIRT + RK3188_GRF_SOC_CON1);
+           grf_writel((1<<9) | ((1<<9)<<16), RK3036_GRF_SOC_CON0);
        }
        return 0;
 }
@@ -99,7 +102,7 @@ struct rk29_vmac_platform_data board_vmac_data = {
        .rmii_power_control = rk30_rmii_power_control,
        .rmii_speed_switch = rk29_vmac_speed_switch,
 };
-
+#if 0
 static int vmac_phy_probe(struct platform_device *pdev)
 {
        struct vmac_phy_data *pdata = pdev->dev.platform_data;
@@ -167,3 +170,4 @@ module_platform_driver(vmac_phy_driver);
 
 MODULE_DESCRIPTION("VMAC PHY Power Driver");
 MODULE_LICENSE("GPL");
+#endif