From ac19c52a3cc5ae2576b01e8e7bf8b91e1b65abb6 Mon Sep 17 00:00:00 2001 From: hwg Date: Wed, 12 Mar 2014 20:23:10 +0800 Subject: [PATCH] ethernet: adjust gmac code --- arch/arm/boot/dts/rk3188.dtsi | 2 +- arch/arm/boot/dts/rk3288-pinctrl.dtsi | 34 +++ arch/arm/boot/dts/rk3288.dtsi | 11 + drivers/net/ethernet/rockchip/gmac/Makefile | 2 +- .../ethernet/rockchip/gmac/rk_gmac_phy_ctl.c | 197 ++++++++++++++++++ drivers/net/ethernet/rockchip/gmac/stmmac.h | 10 + .../net/ethernet/rockchip/gmac/stmmac_main.c | 12 ++ .../ethernet/rockchip/gmac/stmmac_platform.c | 13 +- 8 files changed, 273 insertions(+), 8 deletions(-) create mode 100755 drivers/net/ethernet/rockchip/gmac/rk_gmac_phy_ctl.c diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 8cb508198112..95580910032c 100755 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -669,7 +669,7 @@ "hsicphy12m", "hsic_otgphy1"; }; - vmac@0x10204000 { + vmac@10204000 { compatible = "rockchip,vmac"; reg = <0x10204000 0x4000>; interrupts = ; diff --git a/arch/arm/boot/dts/rk3288-pinctrl.dtsi b/arch/arm/boot/dts/rk3288-pinctrl.dtsi index 83bd7174a595..6ca665fc31cd 100755 --- a/arch/arm/boot/dts/rk3288-pinctrl.dtsi +++ b/arch/arm/boot/dts/rk3288-pinctrl.dtsi @@ -807,6 +807,40 @@ }; }; + + gmac { + mac_clk: mac-clk { + rockchip,pins = ; + rockchip,pull = ; + //rockchip,voltage = ; + rockchip,drive = ; + //rockchip,tristate = ; + }; + + mac_txpins: mac-txpins { + rockchip,pins = , , , , , ; + rockchip,pull = ; + //rockchip,voltage = ; + rockchip,drive = ; + //rockchip,tristate = ; + }; + + mac_rxpins: mac-rxpins { + rockchip,pins = , , , , , , , , ; + rockchip,pull = ; + //rockchip,voltage = ; + rockchip,drive = ; + //rockchip,tristate = ; + }; + + mac_mdpins: mac-mdpins { + rockchip,pins = , ; + rockchip,pull = ; + //rockchip,voltage = ; + rockchip,drive = ; + //rockchip,tristate = ; + }; + }; //to add }; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 88231724bbb6..fa5e0c16543b 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -477,4 +477,15 @@ /*clock-names = "hsicphy480m", "hclk_hsic",*/ /* "hsicphy12m", "hsic_otgphy1";*/ }; + + gmac: eth@ff290000 { + compatible = "rockchip,gmac"; + reg = <0xff290000 0x10000>; + interrupts = ; /*irq=59*/ + interrupt-names = "macirq"; + phy-mode = "rmii"; + //phy-mode = "gmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac_clk &mac_txpins &mac_rxpins &mac_mdpins>; + }; }; diff --git a/drivers/net/ethernet/rockchip/gmac/Makefile b/drivers/net/ethernet/rockchip/gmac/Makefile index 7abf9db73cc2..ce1099b142b5 100755 --- a/drivers/net/ethernet/rockchip/gmac/Makefile +++ b/drivers/net/ethernet/rockchip/gmac/Makefile @@ -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 index 000000000000..7b83533cbb7b --- /dev/null +++ b/drivers/net/ethernet/rockchip/gmac/rk_gmac_phy_ctl.c @@ -0,0 +1,197 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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"); diff --git a/drivers/net/ethernet/rockchip/gmac/stmmac.h b/drivers/net/ethernet/rockchip/gmac/stmmac.h index f1970c4acbfd..e0914aa19899 100755 --- a/drivers/net/ethernet/rockchip/gmac/stmmac.h +++ b/drivers/net/ethernet/rockchip/gmac/stmmac.h @@ -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); diff --git a/drivers/net/ethernet/rockchip/gmac/stmmac_main.c b/drivers/net/ethernet/rockchip/gmac/stmmac_main.c index 8d2da8b562d9..24b0d07aa2e7 100755 --- a/drivers/net/ethernet/rockchip/gmac/stmmac_main.c +++ b/drivers/net/ethernet/rockchip/gmac/stmmac_main.c @@ -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; } diff --git a/drivers/net/ethernet/rockchip/gmac/stmmac_platform.c b/drivers/net/ethernet/rockchip/gmac/stmmac_platform.c index 1d3780f55ba2..48c69791b0bd 100755 --- a/drivers/net/ethernet/rockchip/gmac/stmmac_platform.c +++ b/drivers/net/ethernet/rockchip/gmac/stmmac_platform.c @@ -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); -- 2.34.1