};
};
};
+};
+&gmac {
+// power_ctl_by = "gpio"; //"gpio" "pmu"
+ power-gpio = <&gpio0 GPIO_A6 GPIO_ACTIVE_HIGH>;
+// power-pmu = "act_ldo"
+ reset-gpio = <&gpio4 GPIO_A7 GPIO_ACTIVE_HIGH>;
};
&pinctrl {
<&clk_vepu 300000000>, <&clk_vdpu 300000000>,
<&clk_edp 200000000>, <&clk_isp 200000000>,
<&clk_isp_jpe 400000000>, <&clk_tsp 80000000>,
- <&clk_tspout 80000000>, <&clk_mac 50000000>;
+ <&clk_tspout 80000000>, <&clk_mac 125000000>;
};
i2c0: i2c@ff650000 {
reg = <0xff290000 0x10000>;
interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; /*irq=59*/
interrupt-names = "macirq";
- phy-mode = "rmii";
- //phy-mode = "gmii";
+ //phy-mode = "rmii";
+ phy-mode = "rgmii";
pinctrl-names = "default";
pinctrl-0 = <&mac_clk &mac_txpins &mac_rxpins &mac_mdpins>;
};
-obj-$(CONFIG_RK_GMAC_ETH) += stmmac.o rk_gmac_phy_ctl.o
+obj-$(CONFIG_RK_GMAC_ETH) += stmmac.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 \
+++ /dev/null
-
-#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");
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);
+struct bsp_priv {
+ char pwr_ctl_by[8];
+ int power_io;
+ int reset_io;
+ int phy_iface;
+ int (*phy_power_on)(struct plat_stmmacenet_data *plat, int enable);
};
-extern struct rk_gmac_platform_data rk_board_gmac_data;
-
extern int phyaddr;
extern int stmmac_mdio_unregister(struct net_device *ndev);
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);
- }
}
/**
clk_prepare_enable(priv->stmmac_clk);
- if (priv->rk_pdata->gmac_io_init) {
- priv->rk_pdata->gmac_io_init(priv->device);
+ if ((priv->plat) && (priv->plat->bsp_priv)) {
+ struct bsp_priv * bsp_priv = priv->plat->bsp_priv;
+ if ((bsp_priv) && (bsp_priv->phy_power_on)) {
+ bsp_priv->phy_power_on(priv->plat, 1);
+ }
}
stmmac_check_ether_addr(priv);
- if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
+ if (priv->pcs != STMMAC_PCS_SGMII && priv->pcs != STMMAC_PCS_TBI &&
priv->pcs != STMMAC_PCS_RTBI) {
ret = stmmac_init_phy(dev);
if (ret) {
stmmac_release_ptp(priv);
- if (priv->rk_pdata->gmac_io_deinit) {
- priv->rk_pdata->gmac_io_deinit(priv->device);
+ if ((priv->plat) && (priv->plat->bsp_priv)) {
+ struct bsp_priv * bsp_priv = priv->plat->bsp_priv;
+ if ((bsp_priv) && (bsp_priv->phy_power_on)) {
+ bsp_priv->phy_power_on(priv->plat, 0);
+ }
}
return 0;
goto error_netdev_register;
}
- priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME);
+ priv->stmmac_clk = clk_get(priv->device, "clk_mac"/*STMMAC_RESOURCE_NAME*/);
if (IS_ERR(priv->stmmac_clk)) {
pr_warn("%s: warning: cannot get CSR clock\n", __func__);
goto error_clk_get;
stmmac_check_pcs_mode(priv);
- if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
+ if (priv->pcs != STMMAC_PCS_SGMII && priv->pcs != STMMAC_PCS_TBI &&
priv->pcs != STMMAC_PCS_RTBI) {
/* MDIO bus Registration */
ret = stmmac_mdio_register(ndev);
priv->hw->dma->stop_tx(priv->ioaddr);
stmmac_set_mac(priv->ioaddr, false);
- if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
+ if (priv->pcs != STMMAC_PCS_SGMII && priv->pcs != STMMAC_PCS_TBI &&
priv->pcs != STMMAC_PCS_RTBI)
stmmac_mdio_unregister(ndev);
netif_carrier_off(ndev);
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_net.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
#include "stmmac.h"
+#include <linux/rockchip/iomap.h>
+#include <linux/rockchip/grf.h>
+
+#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))
+#define GMAC_RMII_MODE_CLR ((0x4000 << 16) | (0x0000))
+
+// RK3288_GRF_SOC_CON3
+#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))
+#if 0
+#define GMAC_CLK_RX_DL_CFG ((0x3F80 << 16) | (0x0800))
+#define GMAC_CLK_TX_DL_CFG ((0x007F << 16) | (0x0040))
+#else
+#define GMAC_CLK_RX_DL_CFG(val) ((0x3F80 << 16) | (val<<7)) // 7bit
+#define GMAC_CLK_TX_DL_CFG(val) ((0x007F << 16) | (val)) // 7bit
+#endif
+struct bsp_priv g_bsp_priv;
+
+static int phy_power_on(struct plat_stmmacenet_data *plat, int enable)
+{
+ struct bsp_priv * bsp_priv;
+
+ printk("enter %s ,enable = %d \n",__func__,enable);
+
+ if ((plat) && (plat->bsp_priv)) {
+ bsp_priv = plat->bsp_priv;
+ } else {
+ printk("ERROR: platform data or private data is NULL. %s\n", __FUNCTION__);
+ return -1;
+ }
+
+ if (enable) {
+ //power on
+ if (gpio_is_valid(bsp_priv->power_io)) {
+ gpio_direction_output(bsp_priv->power_io, 0);
+ gpio_set_value(bsp_priv->power_io, 1);
+ }
+
+ //reset
+ if (gpio_is_valid(bsp_priv->reset_io)) {
+ gpio_direction_output(bsp_priv->reset_io, 0);
+ gpio_set_value(bsp_priv->reset_io, 0);
+ msleep(10);
+ gpio_set_value(bsp_priv->reset_io, 1);
+ }
+ } else {
+ //power off
+ if (gpio_is_valid(bsp_priv->power_io)) {
+ gpio_direction_output(bsp_priv->power_io, 0);
+ gpio_set_value(bsp_priv->power_io, 0);
+ }
+ }
+
+ return 0;
+}
+
+int stmmc_pltfr_init(struct platform_device *pdev) {
+ struct pinctrl_state *gmac_state;
+ int phy_iface;
+ int err;
+
+ printk("enter func %s...\n", __func__);
+
+//iomux
+#if 0
+ if ((pdev->dev.pins) && (pdev->dev.pins->p)) {
+ gmac_state = pinctrl_lookup_state(pdev->dev.pins->p, "default");
+ if (IS_ERR(gmac_state)) {
+ dev_err(&pdev->dev, "no gmc pinctrl state\n");
+ return -1;
+ }
+
+ pinctrl_select_state(pdev->dev.pins->p, gmac_state);
+ }
+#endif
+
+ struct bsp_priv * bsp_priv = &g_bsp_priv;
+ phy_iface = bsp_priv->phy_iface;
+//power
+ if (!gpio_is_valid(bsp_priv->power_io)) {
+ printk("%s: ERROR: Get power-gpio failed.\n", __func__);
+ //return -EINVAL;
+ }
+
+ err = gpio_request(bsp_priv->power_io, "gmac_phy_power");
+ if (err) {
+ printk("%s: ERROR: Request gmac phy power pin failed.\n", __func__);
+ //return -EINVAL;
+ }
+
+ if (!gpio_is_valid(bsp_priv->reset_io)) {
+ printk("%s: ERROR: Get reset-gpio failed.\n", __func__);
+ //return -EINVAL;
+ }
+
+ err = gpio_request(bsp_priv->reset_io, "gmac_phy_reset");
+ if (err) {
+ printk("%s: ERROR: Request gmac phy reset pin failed.\n", __func__);
+ //return -EINVAL;
+ }
+
+//rmii or rgmii
+ if (phy_iface & PHY_INTERFACE_MODE_RGMII) {
+ printk("init for RGMII\n");
+ grf_writel(GMAC_PHY_INTF_SEL_RGMII, RK3288_GRF_SOC_CON1);
+ grf_writel(GMAC_RMII_MODE_CLR, RK3288_GRF_SOC_CON1);
+ grf_writel(GMAC_RXCLK_DLY_ENABLE, RK3288_GRF_SOC_CON3);
+ grf_writel(GMAC_TXCLK_DLY_ENABLE, RK3288_GRF_SOC_CON3);
+ grf_writel(GMAC_CLK_RX_DL_CFG(0x10), RK3288_GRF_SOC_CON3);
+ grf_writel(GMAC_CLK_TX_DL_CFG(0x40), RK3288_GRF_SOC_CON3);
+ } else if (phy_iface & PHY_INTERFACE_MODE_RMII) {
+ printk("init for RMII\n");
+ grf_writel(GMAC_PHY_INTF_SEL_RMII, RK3288_GRF_SOC_CON1);
+ grf_writel(GMAC_RMII_MODE, RK3288_GRF_SOC_CON1);
+ } else {
+ printk("ERROR: NO interface defined!\n");
+ }
+
+ return 0;
+}
+
+void * stmmc_pltfr_fix_mac_speed(void *priv, unsigned int speed){
+ printk("enter func %s...\n", __func__);
+ struct bsp_priv * bsp_priv = priv;
+ int interface;
+
+ printk("fix speed to %d\n", speed);
+
+ if (bsp_priv) {
+ interface = bsp_priv->phy_iface;
+ }
+
+ if (interface & PHY_INTERFACE_MODE_RGMII) {
+ printk("fix speed for RGMII\n");
+
+ switch (speed) {
+ case 10: {
+ grf_writel(GMAC_CLK_2_5M, RK3288_GRF_SOC_CON1);
+ break;
+ }
+ case 100: {
+ grf_writel(GMAC_CLK_25M, RK3288_GRF_SOC_CON1);
+ break;
+ }
+ case 1000: {
+ grf_writel(GMAC_CLK_125M, RK3288_GRF_SOC_CON1);
+ break;
+ }
+ default: {
+ printk("ERROR: speed %d is not defined!\n");
+ }
+ }
+
+ } else if (interface & PHY_INTERFACE_MODE_RMII) {
+ printk("fix speed for RMII\n");
+ switch (speed) {
+ case 10: {
+ grf_writel(GMAC_RMII_CLK_2_5M, RK3288_GRF_SOC_CON1);
+ break;
+ }
+ case 100: {
+ grf_writel(GMAC_RMII_CLK_25M, RK3288_GRF_SOC_CON1);
+ break;
+ }
+ default: {
+ printk("ERROR: speed %d is not defined!\n");
+ }
+ }
+ } else {
+ printk("ERROR: NO interface defined!\n");
+ }
+
+ return NULL;
+}
+
#ifdef CONFIG_OF
static int stmmac_probe_config_dt(struct platform_device *pdev,
const char **mac)
{
struct device_node *np = pdev->dev.of_node;
+ enum of_gpio_flags flags;
if (!np)
return -ENODEV;
sizeof(struct stmmac_mdio_bus_data),
GFP_KERNEL);
+ plat->init = stmmc_pltfr_init;
+ plat->fix_mac_speed = stmmc_pltfr_fix_mac_speed;
+
+ g_bsp_priv.reset_io =
+ of_get_named_gpio_flags(np, "reset-gpio", 0, &flags);
+ g_bsp_priv.power_io =
+ of_get_named_gpio_flags(np, "power-gpio", 0, &flags);
+
+ g_bsp_priv.phy_iface = plat->interface;
+ g_bsp_priv.phy_power_on = phy_power_on;
+
+ plat->bsp_priv = &g_bsp_priv;
+
/*
* Currently only the properties needed on SPEAr600
* are provided. All other properties should be added
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;