ethernet: adjust gmac code

This commit is contained in:
hwg
2014-03-12 20:23:10 +08:00
parent 19f3753f60
commit ac19c52a3c
8 changed files with 273 additions and 8 deletions

View File

@@ -669,7 +669,7 @@
"hsicphy12m", "hsic_otgphy1";
};
vmac@0x10204000 {
vmac@10204000 {
compatible = "rockchip,vmac";
reg = <0x10204000 0x4000>;
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;

View File

@@ -807,6 +807,40 @@
};
};
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
};

View File

@@ -477,4 +477,15 @@
/*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>;
};
};

View File

@@ -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 \

View File

@@ -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");

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);