From 85c8e84b900de79466e609b2d62968b51ff243a9 Mon Sep 17 00:00:00 2001 From: roger Date: Fri, 25 Jul 2014 09:03:53 +0800 Subject: [PATCH] ethernet: vmac driver for 3036 --- arch/arm/boot/dts/rk3036-clocks.dtsi | 12 +- arch/arm/boot/dts/rk3036-pinctrl.dtsi | 7 +- arch/arm/boot/dts/rk3036-sdk.dts | 7 + arch/arm/boot/dts/rk3036.dtsi | 17 ++- arch/arm/configs/rk3036_defconfig | 1 + .../net/ethernet/rockchip/vmac/rk29_vmac.c | 142 ++++++++---------- .../net/ethernet/rockchip/vmac/rk29_vmac.h | 16 +- .../ethernet/rockchip/vmac/rk29_vmac_phy.c | 24 +-- 8 files changed, 127 insertions(+), 99 deletions(-) diff --git a/arch/arm/boot/dts/rk3036-clocks.dtsi b/arch/arm/boot/dts/rk3036-clocks.dtsi index 41aab4620f04..9b60bf8d6567 100755 --- a/arch/arm/boot/dts/rk3036-clocks.dtsi +++ b/arch/arm/boot/dts/rk3036-clocks.dtsi @@ -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>; }; @@ -104,6 +104,14 @@ #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 { @@ -1290,7 +1298,7 @@ "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", diff --git a/arch/arm/boot/dts/rk3036-pinctrl.dtsi b/arch/arm/boot/dts/rk3036-pinctrl.dtsi index d5225b100b8a..5261973393d0 100755 --- a/arch/arm/boot/dts/rk3036-pinctrl.dtsi +++ b/arch/arm/boot/dts/rk3036-pinctrl.dtsi @@ -538,7 +538,12 @@ }; }; - gpio2_gmac { + gpio2_gmac { + mac_clk: mac-clk { + rockchip,pins = ; + rockchip,pull = ; + }; + mac_txpins: mac-txpins { rockchip,pins = , , ; rockchip,pull = ; diff --git a/arch/arm/boot/dts/rk3036-sdk.dts b/arch/arm/boot/dts/rk3036-sdk.dts index 8e0f60d5b6f5..d83cb97b7f83 100755 --- a/arch/arm/boot/dts/rk3036-sdk.dts +++ b/arch/arm/boot/dts/rk3036-sdk.dts @@ -193,3 +193,10 @@ 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>; +}; diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index 6337905951a1..30c955798067 100755 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -257,7 +257,7 @@ <&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>;*/ }; @@ -676,4 +676,19 @@ interrupts = ; interrupt-names = "vpu_mmu"; }; + + vmac: eth@10200000 { + compatible = "rockchip,vmac"; + reg = <0x10200000 0x4000>; + interrupts = ; + 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>; + }; }; diff --git a/arch/arm/configs/rk3036_defconfig b/arch/arm/configs/rk3036_defconfig index a64a5275efcf..93672bac6c92 100644 --- a/arch/arm/configs/rk3036_defconfig +++ b/arch/arm/configs/rk3036_defconfig @@ -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 diff --git a/drivers/net/ethernet/rockchip/vmac/rk29_vmac.c b/drivers/net/ethernet/rockchip/vmac/rk29_vmac.c index 16e69c4e2510..99b7af0dfae8 100755 --- a/drivers/net/ethernet/rockchip/vmac/rk29_vmac.c +++ b/drivers/net/ethernet/rockchip/vmac/rk29_vmac.c @@ -52,7 +52,11 @@ #include #include #include - +#include +#include +#include +#include +#include #include "rk29_vmac.h" //static struct wake_lock idlelock; /* add by lyx @ 20110302 */ @@ -766,7 +770,7 @@ static irqreturn_t vmac_intr(int irq, void *dev_instance) if (unlikely(ap->shutdown)) dev_err(&ap->pdev->dev, "ISR during close\n"); - if (unlikely(!status & (RXINT_MASK|MDIO_MASK|ERR_MASK))) + if (unlikely((!status) & (RXINT_MASK|MDIO_MASK|ERR_MASK))) dev_err(&ap->pdev->dev, "No source of IRQ found\n"); #endif @@ -1017,12 +1021,8 @@ int vmac_open(struct net_device *dev) struct phy_device *phydev; unsigned int temp; int err = 0; - struct clk *mac_clk = NULL; - struct clk *mac_parent = NULL; - struct clk *arm_clk = NULL; struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data; unsigned char current_mac[6]; - int ret = 0; struct pinctrl_state *clkout_state; printk("enter func %s...\n", __func__); @@ -1033,7 +1033,7 @@ int vmac_open(struct net_device *dev) wake_lock_timeout(&ap->resume_lock, 5*HZ); ap->shutdown = 0; - + // switch to rmii printk("ap->pdev->dev.pins->p = %p\n", ap->pdev->dev.pins->p); clkout_state = pinctrl_lookup_state(ap->pdev->dev.pins->p, "default"); @@ -1041,45 +1041,41 @@ int vmac_open(struct net_device *dev) dev_err(&ap->pdev->dev, "no clkout pinctrl state\n"); goto err_out; } - + printk("in pinctrl_select_state.\n"); pinctrl_select_state(ap->pdev->dev.pins->p, clkout_state); //set rmii ref clock 50MHz - mac_clk = devm_clk_get(&ap->pdev->dev, "clk_mac"); - /*if (IS_ERR(mac_clk)) - mac_clk = NULL; - arm_clk = clk_get(NULL, "arm_pll"); - if (IS_ERR(arm_clk)) - arm_clk = NULL; - if (mac_clk) { - mac_parent = clk_get_parent(mac_clk); - if (IS_ERR(mac_parent)) - mac_parent = NULL; + pdata->clk_mac_pll_div = clk_get(&ap->pdev->dev, "clk_mac_pll_div"); + if (IS_ERR(pdata->clk_mac_pll_div)) { + printk("get clk_mac_pll_div failed\n"); } - if (arm_clk && mac_parent && (arm_clk == mac_parent)) - wake_lock(&idlelock); - - if(pdata && pdata->rmii_extclk_sel && pdata->rmii_extclk_sel()) - { - struct clk * mac_clkin = NULL; - mac_clkin = clk_get(NULL, "rmii_clkin"); - if (IS_ERR(mac_clkin)) { - pr_err("mac_clkin get fail\n"); - } - clk_set_parent(mac_clk, mac_clkin); - }*/ - - clk_set_rate(mac_clk, 50000000); - clk_prepare_enable(mac_clk); - //clk_enable(clk_get(NULL,"mii_rx")); - //clk_enable(clk_get(NULL,"mii_tx")); - //clk_enable(clk_get(NULL,"hclk_mac")); + + pdata->clk_mac_ref_div = clk_get(&ap->pdev->dev, "clk_mac_ref_div"); + if (IS_ERR(pdata->clk_mac_ref_div)) { + printk("get clk_mac_ref_div failed\n"); + } + + pdata->hclk_mac = clk_get(&ap->pdev->dev, "hclk_mac"); + if (IS_ERR(pdata->hclk_mac)) { + printk("get hclk_mac failed\n"); + } + + clk_prepare_enable(pdata->hclk_mac); + clk_prepare_enable(pdata->clk_mac_pll_div); + clk_prepare_enable(pdata->clk_mac_ref_div); //phy power on if (pdata && pdata->rmii_power_control) pdata->rmii_power_control(1); + if (gpio_is_valid(pdata->reset_io)) { + gpio_direction_output(pdata->reset_io, pdata->reset_io_enable); + gpio_set_value(pdata->reset_io, pdata->reset_io_enable); + msleep(20); + gpio_set_value(pdata->reset_io, !pdata->reset_io_enable); + } + msleep(1000); vmac_hw_init(dev); @@ -1090,7 +1086,7 @@ int vmac_open(struct net_device *dev) } #ifdef CONFIG_ETH_MAC_FROM_EEPROM - ret = eeprom_read_data(0,dev->dev_addr,6); + err = eeprom_read_data(0,dev->dev_addr,6); if (ret != 6){ printk("read mac from Eeprom fail.\n"); }else { @@ -1215,9 +1211,6 @@ int vmac_close(struct net_device *dev) { struct vmac_priv *ap = netdev_priv(dev); unsigned int temp; - struct clk *mac_clk = NULL; - struct clk *arm_clk = NULL; - struct clk *mac_parent = NULL; struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data; printk("enter func %s...\n", __func__); @@ -1259,26 +1252,13 @@ int vmac_close(struct net_device *dev) if (pdata && pdata->rmii_power_control) pdata->rmii_power_control(0); - //clock close - /*mac_clk = clk_get(NULL, "mac_ref_div"); - if (IS_ERR(mac_clk)) - mac_clk = NULL; - if (mac_clk) { - mac_parent = clk_get_parent(mac_clk); - if (IS_ERR(mac_parent)) - mac_parent = NULL; + if (gpio_is_valid(pdata->reset_io)) { + gpio_set_value(pdata->reset_io, !pdata->reset_io_enable); } - arm_clk = clk_get(NULL, "arm_pll"); - if (IS_ERR(arm_clk)) - arm_clk = NULL; - if (arm_clk && mac_parent && (arm_clk == mac_parent)) - wake_unlock(&idlelock);*/ - - clk_disable(clk_get(&ap->pdev->dev,"clk_mac")); - //clk_disable(clk_get(NULL,"mii_tx")); - //clk_disable(clk_get(NULL,"hclk_mac")); - //clk_disable(clk_get(NULL,"clk_mac_pll")); + clk_disable_unprepare(pdata->clk_mac_ref_div); + clk_disable_unprepare(pdata->clk_mac_pll_div); + clk_disable_unprepare(pdata->hclk_mac); return 0; } @@ -1413,7 +1393,7 @@ void vmac_tx_timeout(struct net_device *dev) spin_unlock_irqrestore(&ap->lock, flags); } - +#if 0 static void create_multicast_filter(struct net_device *dev, unsigned long *bitmask) { @@ -1463,6 +1443,7 @@ static void create_multicast_filter(struct net_device *dev, } #endif } + static void vmac_set_multicast_list(struct net_device *dev) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)) @@ -1519,6 +1500,7 @@ static void vmac_set_multicast_list(struct net_device *dev) spin_unlock_irqrestore(&ap->lock, flags); #endif } +#endif static struct ethtool_ops vmac_ethtool_ops = { .get_settings = vmacether_get_settings, @@ -1549,13 +1531,32 @@ static int vmac_probe(struct platform_device *pdev) int err; struct rk29_vmac_platform_data *pdata; struct device_node *np = pdev->dev.of_node; - + enum of_gpio_flags flags; + printk("vmac_probe.\n"); dev_dbg(&pdev->dev, "vmac_probe 1.\n"); pdev->dev.platform_data = &board_vmac_data; pdata = pdev->dev.platform_data; + pdata->reset_io = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); + if (!gpio_is_valid(pdata->reset_io)) { + printk("%s: Get reset-gpio failed.\n", __func__); + return -EINVAL; + } else { + err = gpio_request(pdata->reset_io, "phy_reset"); + if (err) { + pr_err("%s: ERROR: Request phy reset pin failed.\n", __func__); + //return -EINVAL; + } + } + + if(flags & OF_GPIO_ACTIVE_LOW) { + pdata->reset_io_enable = 0; + } else { + pdata->reset_io_enable = 1; + } + dev = alloc_etherdev(sizeof(*ap)); if (!dev) { dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n"); @@ -1588,7 +1589,7 @@ static int vmac_probe(struct platform_device *pdev) } printk("mem_base = 0x%08x, mem_size = 0x%08x, irq = %d, regs = 0x%08x\n", - mem_base, mem_size, irq, ap->regs); + mem_base, mem_size, irq, (unsigned int)(ap->regs)); /* no checksum support, hence no scatter/gather */ dev->features |= NETIF_F_HIGHDMA; @@ -1692,25 +1693,6 @@ static int vmac_remove(struct platform_device *pdev) return 0; } -static void rk29_vmac_power_off(struct net_device *dev) -{ - struct vmac_priv *ap = netdev_priv(dev); - struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data; - - printk("enter func %s...\n", __func__); - - //phy power off - if (pdata && pdata->rmii_power_control) - pdata->rmii_power_control(0); - - //clock close - clk_disable(clk_get(&ap->pdev->dev,"clk_mac")); - //clk_disable(clk_get(NULL,"mii_tx")); - //clk_disable(clk_get(NULL,"hclk_mac")); - //clk_disable(clk_get(NULL,"clk_mac_pll")); - -} - static int rk29_vmac_suspend(struct device *dev) { diff --git a/drivers/net/ethernet/rockchip/vmac/rk29_vmac.h b/drivers/net/ethernet/rockchip/vmac/rk29_vmac.h index a6cf94e28ea0..9f577d3f41ba 100755 --- a/drivers/net/ethernet/rockchip/vmac/rk29_vmac.h +++ b/drivers/net/ethernet/rockchip/vmac/rk29_vmac.h @@ -275,11 +275,17 @@ static inline int fifo_inc_ct(int ct, int size) /*vmac*/ struct rk29_vmac_platform_data { - int (*vmac_register_set)(void); - int (*rmii_io_init)(void); - int (*rmii_io_deinit)(void); - int (*rmii_power_control)(int enable); - int(*rmii_speed_switch)(int speed); + int (*vmac_register_set)(void); + int (*rmii_io_init)(void); + int (*rmii_io_deinit)(void); + int (*rmii_power_control)(int enable); + int (*rmii_speed_switch)(int speed); + struct clk *clk_mac_pll_div; + struct clk *clk_mac_ref_div; + struct clk *mac_parent; + struct clk *hclk_mac; + int reset_io; + int reset_io_enable; }; extern struct rk29_vmac_platform_data board_vmac_data; diff --git a/drivers/net/ethernet/rockchip/vmac/rk29_vmac_phy.c b/drivers/net/ethernet/rockchip/vmac/rk29_vmac_phy.c index 3b328d3ffbdf..20ba49169a1f 100755 --- a/drivers/net/ethernet/rockchip/vmac/rk29_vmac_phy.c +++ b/drivers/net/ethernet/rockchip/vmac/rk29_vmac_phy.c @@ -26,20 +26,23 @@ #include #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 -- 2.34.1