summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-01-22 09:49:21 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-01-22 09:49:21 +0100
commit63a96a03b6c9dbc40f0d94a8be22f002bee4962e (patch)
treeb9d1f248b9f3696ce4a8703ebc431a61b35f564b /drivers
parent5ebdae4863f64a32826c25c6e0d1dfbc1612d904 (diff)
parent0becc3085f4d948d8f2674b43e0e9e5f5425fcc7 (diff)
downloadbarebox-63a96a03b6c9dbc40f0d94a8be22f002bee4962e.tar.gz
barebox-63a96a03b6c9dbc40f0d94a8be22f002bee4962e.tar.xz
Merge branch 'for-next/net-designware'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/Kconfig19
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/designware.c66
-rw-r--r--drivers/net/designware.h33
-rw-r--r--drivers/net/designware_generic.c59
-rw-r--r--drivers/net/designware_socfpga.c184
6 files changed, 307 insertions, 56 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9d69b6aeb0..09676b3d60 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -64,13 +64,30 @@ config DRIVER_NET_DAVINCI_EMAC
select PHYLIB
config DRIVER_NET_DESIGNWARE
- bool "Designware Universal MAC ethernet driver"
+ bool "Designware Universal MAC ethernet platform support"
depends on HAS_DMA
select PHYLIB
help
This option enables support for the Synopsys
Designware Core Univesal MAC 10M/100M/1G ethernet IP.
+if DRIVER_NET_DESIGNWARE
+
+config DRIVER_NET_DESIGNWARE_GENERIC
+ bool "Designware Universal MAC ethernet generic driver"
+ help
+ This option enables support for the Synopsys
+ Designware Core Univesal MAC 10M/100M/1G ethernet IP on SoCFPGA.
+
+config DRIVER_NET_DESIGNWARE_SOCFPGA
+ bool "Designware Universal MAC ethernet driver for SoCFPGA platforms"
+ depends on ARCH_SOCFPGA
+ help
+ This option enables support for the Synopsys
+ Designware Core Univesal MAC 10M/100M/1G ethernet IP on SoCFPGA.
+
+endif
+
config DRIVER_NET_DM9K
bool "Davicom dm9k[E|A|B] ethernet driver"
depends on HAS_DM9000
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 86c8ac32f9..304bbba02d 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -9,6 +9,8 @@ obj-$(CONFIG_DRIVER_NET_CS8900) += cs8900.o
obj-$(CONFIG_DRIVER_NET_CPSW) += cpsw.o
obj-$(CONFIG_DRIVER_NET_DAVINCI_EMAC) += davinci_emac.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE) += designware.o
+obj-$(CONFIG_DRIVER_NET_DESIGNWARE_GENERIC) += designware_generic.o
+obj-$(CONFIG_DRIVER_NET_DESIGNWARE_SOCFPGA) += designware_socfpga.o
obj-$(CONFIG_DRIVER_NET_DM9K) += dm9k.o
obj-$(CONFIG_DRIVER_NET_E1000) += e1000/regio.o e1000/main.o e1000/eeprom.o
obj-$(CONFIG_DRIVER_NET_ENC28J60) += enc28j60.o
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 1d3a68384e..862ee2f046 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -32,36 +32,6 @@
#include <linux/err.h>
#include "designware.h"
-struct dw_eth_dev {
- struct eth_device netdev;
- struct mii_bus miibus;
-
- void (*fix_mac_speed)(int speed);
- u8 macaddr[6];
- u32 tx_currdescnum;
- u32 rx_currdescnum;
-
- struct dmamacdescr *tx_mac_descrtable;
- struct dmamacdescr *rx_mac_descrtable;
-
- u8 *txbuffs;
- u8 *rxbuffs;
-
- struct eth_mac_regs *mac_regs_p;
- struct eth_dma_regs *dma_regs_p;
- int phy_addr;
- phy_interface_t interface;
- int enh_desc;
-};
-
-struct dw_eth_drvdata {
- bool enh_desc;
-};
-
-static struct dw_eth_drvdata dwmac_370a_drvdata = {
- .enh_desc = 1,
-};
-
/* Speed specific definitions */
#define SPEED_10M 1
#define SPEED_100M 2
@@ -447,7 +417,7 @@ static int dwc_probe_dt(struct device_d *dev, struct dw_eth_dev *priv)
return 0;
}
-static int dwc_ether_probe(struct device_d *dev)
+struct dw_eth_dev *dwc_drv_probe(struct device_d *dev)
{
struct resource *iores;
struct dw_eth_dev *priv;
@@ -462,9 +432,13 @@ static int dwc_ether_probe(struct device_d *dev)
ret = dev_get_drvdata(dev, (const void **)&drvdata);
if (ret)
- return ret;
+ return ERR_PTR(ret);
+
+ if (drvdata && drvdata->enh_desc)
+ priv->enh_desc = drvdata->enh_desc;
+ else
+ dev_warn(dev, "No drvdata specified\n");
- priv->enh_desc = drvdata->enh_desc;
if (pdata) {
priv->phy_addr = pdata->phy_addr;
@@ -473,12 +447,12 @@ static int dwc_ether_probe(struct device_d *dev)
} else {
ret = dwc_probe_dt(dev, priv);
if (ret)
- return ret;
+ return ERR_PTR(ret);
}
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
- return PTR_ERR(iores);
+ return ERR_CAST(iores);
base = IOMEM(iores->start);
priv->mac_regs_p = base;
@@ -512,24 +486,6 @@ static int dwc_ether_probe(struct device_d *dev)
mdiobus_register(miibus);
eth_register(edev);
- return 0;
-}
-static __maybe_unused struct of_device_id dwc_ether_compatible[] = {
- {
- .compatible = "snps,dwmac-3.70a",
- .data = &dwmac_370a_drvdata,
- }, {
- .compatible = "snps,dwmac-3.72a",
- .data = &dwmac_370a_drvdata,
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d dwc_ether_driver = {
- .name = "designware_eth",
- .probe = dwc_ether_probe,
- .of_compatible = DRV_OF_COMPAT(dwc_ether_compatible),
-};
-device_platform_driver(dwc_ether_driver);
+ return priv;
+}
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index c36ba78779..c9dc27a594 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -20,6 +20,39 @@
#ifndef __DESIGNWARE_ETH_H
#define __DESIGNWARE_ETH_H
+struct eth_device;
+struct mii_bus;
+
+struct dw_eth_dev {
+ struct eth_device netdev;
+ struct mii_bus miibus;
+
+ void (*fix_mac_speed)(int speed);
+ u8 macaddr[6];
+ u32 tx_currdescnum;
+ u32 rx_currdescnum;
+
+ struct dmamacdescr *tx_mac_descrtable;
+ struct dmamacdescr *rx_mac_descrtable;
+
+ u8 *txbuffs;
+ u8 *rxbuffs;
+
+ struct eth_mac_regs *mac_regs_p;
+ struct eth_dma_regs *dma_regs_p;
+ int phy_addr;
+ phy_interface_t interface;
+ int enh_desc;
+
+ struct reset_control *rst;
+};
+
+struct dw_eth_drvdata {
+ bool enh_desc;
+};
+
+struct dw_eth_dev *dwc_drv_probe(struct device_d *dev);
+
#define CONFIG_TX_DESCR_NUM 16
#define CONFIG_RX_DESCR_NUM 16
#define CONFIG_ETH_BUFSIZE 2048
diff --git a/drivers/net/designware_generic.c b/drivers/net/designware_generic.c
new file mode 100644
index 0000000000..0e5b9c067b
--- /dev/null
+++ b/drivers/net/designware_generic.c
@@ -0,0 +1,59 @@
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * Designware ethernet IP driver for u-boot
+ */
+
+#include <common.h>
+#include "designware.h"
+
+static struct dw_eth_drvdata dwmac_370a_drvdata = {
+ .enh_desc = 1,
+};
+
+static int dwc_ether_probe(struct device_d *dev)
+{
+ struct dw_eth_dev *dwc;
+
+ dwc = dwc_drv_probe(dev);
+ if (IS_ERR(dwc))
+ return PTR_ERR(dwc);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id dwc_ether_compatible[] = {
+ {
+ .compatible = "snps,dwmac-3.70a",
+ .data = &dwmac_370a_drvdata,
+ }, {
+ .compatible = "snps,dwmac-3.72a",
+ .data = &dwmac_370a_drvdata,
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d dwc_ether_driver = {
+ .name = "designware_eth",
+ .probe = dwc_ether_probe,
+ .of_compatible = DRV_OF_COMPAT(dwc_ether_compatible),
+};
+device_platform_driver(dwc_ether_driver);
diff --git a/drivers/net/designware_socfpga.c b/drivers/net/designware_socfpga.c
new file mode 100644
index 0000000000..154c38f9a1
--- /dev/null
+++ b/drivers/net/designware_socfpga.c
@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * Designware ethernet IP driver for u-boot
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <net.h>
+#include <of_net.h>
+#include <linux/reset.h>
+#include <mach/cyclone5-system-manager.h>
+#include <mfd/syscon.h>
+#include "designware.h"
+
+#define SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x00000010
+
+struct socfpga_dwc_dev {
+ struct dw_eth_dev *priv;
+ u32 reg_offset;
+ u32 reg_shift;
+ void __iomem *sys_mgr_base;
+ bool f2h_ptp_ref_clk;
+};
+
+static int socfpga_dwc_set_phy_mode(struct socfpga_dwc_dev *dwc_dev)
+{
+ struct dw_eth_dev *eth_dev = dwc_dev->priv;
+ int phymode = eth_dev->interface;
+ u32 reg_offset = dwc_dev->reg_offset;
+ u32 reg_shift = dwc_dev->reg_shift;
+ u32 ctrl, val;
+
+ switch (phymode) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
+ break;
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_GMII:
+ case PHY_INTERFACE_MODE_SGMII:
+ val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
+ break;
+ default:
+ dev_err(&eth_dev->netdev.dev, "bad phy mode %d\n", phymode);
+ return -EINVAL;
+ }
+
+ /* Assert reset to the enet controller before changing the phy mode */
+ if (eth_dev->rst)
+ reset_control_assert(eth_dev->rst);
+
+ ctrl = readl(dwc_dev->sys_mgr_base + reg_offset);
+ ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
+ ctrl |= val << reg_shift;
+
+ if (dwc_dev->f2h_ptp_ref_clk ||
+ phymode == PHY_INTERFACE_MODE_MII ||
+ phymode == PHY_INTERFACE_MODE_GMII ||
+ phymode == PHY_INTERFACE_MODE_SGMII) {
+ u32 module;
+
+ ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2);
+ module = readl(dwc_dev->sys_mgr_base + SYSMGR_FPGAGRP_MODULE);
+ module |= (SYSMGR_FPGAGRP_MODULE_EMAC << (reg_shift / 2));
+
+ writel(module, dwc_dev->sys_mgr_base + SYSMGR_FPGAGRP_MODULE);
+ } else {
+ ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2));
+ }
+
+ writel(ctrl, dwc_dev->sys_mgr_base + reg_offset);
+
+ /* Deassert reset for the phy configuration to be sampled by
+ * the enet controller, and operation to start in requested mode
+ */
+ if (eth_dev->rst)
+ reset_control_deassert(eth_dev->rst);
+
+ return 0;
+}
+
+static int socfpga_dwc_probe_dt(struct device_d *dev, struct socfpga_dwc_dev *priv)
+{
+ u32 reg_offset, reg_shift;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_OFTREE))
+ return -ENODEV;
+
+ ret = of_property_read_u32_index(dev->device_node, "altr,sysmgr-syscon",
+ 1, &reg_offset);
+ if (ret) {
+ dev_err(dev, "Could not read reg_offset from sysmgr-syscon! Please update the devicetree.\n");
+
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32_index(dev->device_node, "altr,sysmgr-syscon",
+ 2, &reg_shift);
+ if (ret) {
+ dev_err(dev, "Could not read reg_shift from sysmgr-syscon! Please update the devicetree.\n");
+ return -EINVAL;
+ }
+
+ priv->f2h_ptp_ref_clk = of_property_read_bool(dev->device_node, "altr,f2h_ptp_ref_clk");
+
+ priv->reg_offset = reg_offset;
+ priv->reg_shift = reg_shift;
+
+ return 0;
+}
+
+static int socfpga_dwc_ether_probe(struct device_d *dev)
+{
+ struct socfpga_dwc_dev *dwc_dev;
+ struct dw_eth_dev *priv;
+ int ret;
+
+ dwc_dev = xzalloc(sizeof(*dwc_dev));
+
+ priv = dwc_drv_probe(dev);
+ if (IS_ERR(priv))
+ return PTR_ERR(priv);
+
+ priv->rst = reset_control_get(dev, NULL);
+ if (IS_ERR(priv->rst))
+ dev_warn(dev, "No reset lines.\n");
+
+ dwc_dev->priv = priv;
+
+ dwc_dev->sys_mgr_base = syscon_base_lookup_by_phandle(dev->device_node,
+ "altr,sysmgr-syscon");
+ if (IS_ERR(dwc_dev->sys_mgr_base)) {
+ dev_err(dev, "Could not get sysmgr-syscon node\n");
+ return PTR_ERR(dwc_dev->sys_mgr_base);
+ }
+
+ ret = socfpga_dwc_probe_dt(dev, dwc_dev);
+ if (ret)
+ return ret;
+
+ socfpga_dwc_set_phy_mode(dwc_dev);
+
+ return 0;
+}
+
+static struct dw_eth_drvdata socfpga_stmmac_drvdata = {
+ .enh_desc = 1,
+};
+
+static __maybe_unused struct of_device_id socfpga_dwc_ether_compatible[] = {
+ {
+ .compatible = "altr,socfpga-stmmac",
+ .data = &socfpga_stmmac_drvdata,
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d socfpga_dwc_ether_driver = {
+ .name = "socfpga_designware_eth",
+ .probe = socfpga_dwc_ether_probe,
+ .of_compatible = DRV_OF_COMPAT(socfpga_dwc_ether_compatible),
+};
+device_platform_driver(socfpga_dwc_ether_driver);