mirror of https://github.com/hak5/openwrt-owl.git
ipq806x: update stmmac to the version from linux 4.3
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 47593owl
parent
b1a91ca57f
commit
3789b1f5a0
|
@ -106,8 +106,10 @@ CONFIG_CRC32_SLICEBY8=y
|
||||||
CONFIG_CROSS_MEMORY_ATTACH=y
|
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||||
CONFIG_CRYPTO_DEFLATE=y
|
CONFIG_CRYPTO_DEFLATE=y
|
||||||
CONFIG_CRYPTO_LZO=y
|
CONFIG_CRYPTO_LZO=y
|
||||||
|
CONFIG_CRYPTO_RNG2=y
|
||||||
# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
|
# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
|
||||||
# CONFIG_CRYPTO_SHA512_ARM_NEON is not set
|
# CONFIG_CRYPTO_SHA512_ARM_NEON is not set
|
||||||
|
CONFIG_CRYPTO_WORKQUEUE=y
|
||||||
CONFIG_CRYPTO_XZ=y
|
CONFIG_CRYPTO_XZ=y
|
||||||
CONFIG_DCACHE_WORD_ACCESS=y
|
CONFIG_DCACHE_WORD_ACCESS=y
|
||||||
CONFIG_DEBUG_BUGVERBOSE=y
|
CONFIG_DEBUG_BUGVERBOSE=y
|
||||||
|
@ -123,7 +125,14 @@ CONFIG_DMA_ENGINE=y
|
||||||
CONFIG_DMA_OF=y
|
CONFIG_DMA_OF=y
|
||||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
||||||
CONFIG_DTC=y
|
CONFIG_DTC=y
|
||||||
|
# CONFIG_DWMAC_GENERIC is not set
|
||||||
CONFIG_DWMAC_IPQ806X=y
|
CONFIG_DWMAC_IPQ806X=y
|
||||||
|
# CONFIG_DWMAC_LPC18XX is not set
|
||||||
|
# CONFIG_DWMAC_MESON is not set
|
||||||
|
# CONFIG_DWMAC_ROCKCHIP is not set
|
||||||
|
# CONFIG_DWMAC_SOCFPGA is not set
|
||||||
|
# CONFIG_DWMAC_STI is not set
|
||||||
|
# CONFIG_DWMAC_SUNXI is not set
|
||||||
# CONFIG_DW_DMAC_CORE is not set
|
# CONFIG_DW_DMAC_CORE is not set
|
||||||
# CONFIG_DW_DMAC_PCI is not set
|
# CONFIG_DW_DMAC_PCI is not set
|
||||||
CONFIG_DYNAMIC_DEBUG=y
|
CONFIG_DYNAMIC_DEBUG=y
|
||||||
|
@ -234,7 +243,6 @@ CONFIG_KRAITCC=y
|
||||||
CONFIG_KRAIT_CLOCKS=y
|
CONFIG_KRAIT_CLOCKS=y
|
||||||
CONFIG_KRAIT_L2_ACCESSORS=y
|
CONFIG_KRAIT_L2_ACCESSORS=y
|
||||||
# CONFIG_LEDS_REGULATOR is not set
|
# CONFIG_LEDS_REGULATOR is not set
|
||||||
CONFIG_LEDS_TRIGGER_IDE_DISK=y
|
|
||||||
CONFIG_LIBFDT=y
|
CONFIG_LIBFDT=y
|
||||||
CONFIG_LOCKUP_DETECTOR=y
|
CONFIG_LOCKUP_DETECTOR=y
|
||||||
CONFIG_LZO_COMPRESS=y
|
CONFIG_LZO_COMPRESS=y
|
||||||
|
@ -387,8 +395,6 @@ CONFIG_SPI_MASTER=y
|
||||||
CONFIG_SPI_QUP=y
|
CONFIG_SPI_QUP=y
|
||||||
CONFIG_SPMI=y
|
CONFIG_SPMI=y
|
||||||
CONFIG_SPMI_MSM_PMIC_ARB=y
|
CONFIG_SPMI_MSM_PMIC_ARB=y
|
||||||
# CONFIG_STMMAC_DA is not set
|
|
||||||
CONFIG_STMMAC_DEBUG_FS=y
|
|
||||||
CONFIG_STMMAC_ETH=y
|
CONFIG_STMMAC_ETH=y
|
||||||
CONFIG_STMMAC_PLATFORM=y
|
CONFIG_STMMAC_PLATFORM=y
|
||||||
CONFIG_STOP_MACHINE=y
|
CONFIG_STOP_MACHINE=y
|
||||||
|
|
|
@ -112,6 +112,8 @@ CONFIG_CRC32_SLICEBY8=y
|
||||||
CONFIG_CROSS_MEMORY_ATTACH=y
|
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||||
CONFIG_CRYPTO_DEFLATE=y
|
CONFIG_CRYPTO_DEFLATE=y
|
||||||
CONFIG_CRYPTO_LZO=y
|
CONFIG_CRYPTO_LZO=y
|
||||||
|
CONFIG_CRYPTO_RNG2=y
|
||||||
|
CONFIG_CRYPTO_WORKQUEUE=y
|
||||||
CONFIG_CRYPTO_XZ=y
|
CONFIG_CRYPTO_XZ=y
|
||||||
CONFIG_DCACHE_WORD_ACCESS=y
|
CONFIG_DCACHE_WORD_ACCESS=y
|
||||||
CONFIG_DEBUG_BUGVERBOSE=y
|
CONFIG_DEBUG_BUGVERBOSE=y
|
||||||
|
@ -127,6 +129,14 @@ CONFIG_DMA_ENGINE=y
|
||||||
CONFIG_DMA_OF=y
|
CONFIG_DMA_OF=y
|
||||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
||||||
CONFIG_DTC=y
|
CONFIG_DTC=y
|
||||||
|
# CONFIG_DWMAC_GENERIC is not set
|
||||||
|
CONFIG_DWMAC_IPQ806X=y
|
||||||
|
# CONFIG_DWMAC_LPC18XX is not set
|
||||||
|
# CONFIG_DWMAC_MESON is not set
|
||||||
|
# CONFIG_DWMAC_ROCKCHIP is not set
|
||||||
|
# CONFIG_DWMAC_SOCFPGA is not set
|
||||||
|
# CONFIG_DWMAC_STI is not set
|
||||||
|
# CONFIG_DWMAC_SUNXI is not set
|
||||||
# CONFIG_DW_DMAC_PCI is not set
|
# CONFIG_DW_DMAC_PCI is not set
|
||||||
CONFIG_DYNAMIC_DEBUG=y
|
CONFIG_DYNAMIC_DEBUG=y
|
||||||
CONFIG_ETHERNET_PACKET_MANGLE=y
|
CONFIG_ETHERNET_PACKET_MANGLE=y
|
||||||
|
@ -241,7 +251,6 @@ CONFIG_KPSS_XCC=y
|
||||||
CONFIG_KRAITCC=y
|
CONFIG_KRAITCC=y
|
||||||
CONFIG_KRAIT_CLOCKS=y
|
CONFIG_KRAIT_CLOCKS=y
|
||||||
CONFIG_KRAIT_L2_ACCESSORS=y
|
CONFIG_KRAIT_L2_ACCESSORS=y
|
||||||
CONFIG_LEDS_TRIGGER_IDE_DISK=y
|
|
||||||
CONFIG_LIBFDT=y
|
CONFIG_LIBFDT=y
|
||||||
CONFIG_LOCKUP_DETECTOR=y
|
CONFIG_LOCKUP_DETECTOR=y
|
||||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
From 4f09499bc1d9bb095caccbcd73ff951ee631e521 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 15:42:40 -0700
|
|
||||||
Subject: [PATCH 1/8] stmmac: add phy-handle support to the platform layer
|
|
||||||
|
|
||||||
On stmmac driver, PHY specification in device-tree was done using the
|
|
||||||
non-standard property "snps,phy-addr". Specifying a PHY on a different
|
|
||||||
MDIO bus that the one within the stmmac controller doesn't seem to be
|
|
||||||
possible when device-tree is used.
|
|
||||||
|
|
||||||
This change adds support for the phy-handle property, as specified in
|
|
||||||
Documentation/devicetree/bindings/net/ethernet.txt.
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 28 ++++++++++++++--------
|
|
||||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++-
|
|
||||||
include/linux/stmmac.h | 1 +
|
|
||||||
3 files changed, 24 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
@@ -52,6 +52,7 @@
|
|
||||||
#include "stmmac_ptp.h"
|
|
||||||
#include "stmmac.h"
|
|
||||||
#include <linux/reset.h>
|
|
||||||
+#include <linux/of_mdio.h>
|
|
||||||
|
|
||||||
#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
|
|
||||||
|
|
||||||
@@ -818,18 +819,25 @@ static int stmmac_init_phy(struct net_de
|
|
||||||
priv->speed = 0;
|
|
||||||
priv->oldduplex = -1;
|
|
||||||
|
|
||||||
- if (priv->plat->phy_bus_name)
|
|
||||||
- snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
|
|
||||||
- priv->plat->phy_bus_name, priv->plat->bus_id);
|
|
||||||
- else
|
|
||||||
- snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
|
|
||||||
- priv->plat->bus_id);
|
|
||||||
-
|
|
||||||
- snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
|
|
||||||
- priv->plat->phy_addr);
|
|
||||||
- pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt);
|
|
||||||
+ if (priv->plat->phy_node) {
|
|
||||||
+ phydev = of_phy_connect(dev, priv->plat->phy_node,
|
|
||||||
+ &stmmac_adjust_link, 0, interface);
|
|
||||||
+ } else {
|
|
||||||
+ if (priv->plat->phy_bus_name)
|
|
||||||
+ snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
|
|
||||||
+ priv->plat->phy_bus_name, priv->plat->bus_id);
|
|
||||||
+ else
|
|
||||||
+ snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
|
|
||||||
+ priv->plat->bus_id);
|
|
||||||
+
|
|
||||||
+ snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
|
|
||||||
+ priv->plat->phy_addr);
|
|
||||||
+ pr_debug("stmmac_init_phy: trying to attach to %s\n",
|
|
||||||
+ phy_id_fmt);
|
|
||||||
|
|
||||||
- phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
|
|
||||||
+ phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
|
|
||||||
+ interface);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (IS_ERR(phydev)) {
|
|
||||||
pr_err("%s: Could not attach to PHY\n", dev->name);
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
@@ -27,6 +27,7 @@
|
|
||||||
#include <linux/of.h>
|
|
||||||
#include <linux/of_net.h>
|
|
||||||
#include <linux/of_device.h>
|
|
||||||
+#include <linux/of_mdio.h>
|
|
||||||
#include "stmmac.h"
|
|
||||||
|
|
||||||
static const struct of_device_id stmmac_dt_ids[] = {
|
|
||||||
@@ -155,13 +156,16 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
/* Default to phy auto-detection */
|
|
||||||
plat->phy_addr = -1;
|
|
||||||
|
|
||||||
+ /* If we find a phy-handle property, use it as the PHY */
|
|
||||||
+ plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
|
||||||
+
|
|
||||||
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
|
|
||||||
* and warn of its use. Remove this when phy node support is added.
|
|
||||||
*/
|
|
||||||
if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
|
|
||||||
dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
|
|
||||||
|
|
||||||
- if (plat->phy_bus_name)
|
|
||||||
+ if (plat->phy_node || plat->phy_bus_name)
|
|
||||||
plat->mdio_bus_data = NULL;
|
|
||||||
else
|
|
||||||
plat->mdio_bus_data =
|
|
||||||
--- a/include/linux/stmmac.h
|
|
||||||
+++ b/include/linux/stmmac.h
|
|
||||||
@@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
|
|
||||||
int phy_addr;
|
|
||||||
int interface;
|
|
||||||
struct stmmac_mdio_bus_data *mdio_bus_data;
|
|
||||||
+ struct device_node *phy_node;
|
|
||||||
struct stmmac_dma_cfg *dma_cfg;
|
|
||||||
int clk_csr;
|
|
||||||
int has_gmac;
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,65 +0,0 @@
|
||||||
From 0149d275415cd1b2382ce94e5eb32641590097d0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 15:57:12 -0700
|
|
||||||
Subject: [PATCH 2/8] stmmac: move error path at the end of
|
|
||||||
stmmac_probe_config_dt()
|
|
||||||
|
|
||||||
We will want to do additional clean-up on certain errors. Therefore,
|
|
||||||
this change moves the error path at the end of the function for better
|
|
||||||
code readability.
|
|
||||||
|
|
||||||
This patch doesn't change anything functionally.
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 22 ++++++++++++++++------
|
|
||||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
@@ -117,13 +117,18 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
struct device_node *np = pdev->dev.of_node;
|
|
||||||
struct stmmac_dma_cfg *dma_cfg;
|
|
||||||
const struct of_device_id *device;
|
|
||||||
+ int ret;
|
|
||||||
|
|
||||||
- if (!np)
|
|
||||||
- return -ENODEV;
|
|
||||||
+ if (!np) {
|
|
||||||
+ ret = -ENODEV;
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
device = of_match_device(stmmac_dt_ids, &pdev->dev);
|
|
||||||
- if (!device)
|
|
||||||
- return -ENODEV;
|
|
||||||
+ if (!device) {
|
|
||||||
+ ret = -ENODEV;
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (device->data) {
|
|
||||||
const struct stmmac_of_data *data = device->data;
|
|
||||||
@@ -219,8 +224,10 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
if (of_find_property(np, "snps,pbl", NULL)) {
|
|
||||||
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
|
|
||||||
GFP_KERNEL);
|
|
||||||
- if (!dma_cfg)
|
|
||||||
- return -ENOMEM;
|
|
||||||
+ if (!dma_cfg) {
|
|
||||||
+ ret = -ENOMEM;
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
plat->dma_cfg = dma_cfg;
|
|
||||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
|
||||||
dma_cfg->fixed_burst =
|
|
||||||
@@ -235,6 +242,9 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
+
|
|
||||||
+err:
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static int stmmac_probe_config_dt(struct platform_device *pdev,
|
|
|
@ -1,64 +0,0 @@
|
||||||
From 3a95f75867be562cb919ff23a738f70357188fbd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 16:02:03 -0700
|
|
||||||
Subject: [PATCH 3/8] stmmac: add fixed-link device-tree support
|
|
||||||
|
|
||||||
In case DT is used, this change adds the ability to the stmmac driver to
|
|
||||||
detect a fixed-link PHY, instanciate it, and use it during
|
|
||||||
phy_connect().
|
|
||||||
|
|
||||||
Fixed link PHYs DT usage is described in:
|
|
||||||
Documentation/devicetree/bindings/net/fixed-link.txt
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 12 +++++++++++-
|
|
||||||
2 files changed, 12 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
@@ -858,7 +858,7 @@ static int stmmac_init_phy(struct net_de
|
|
||||||
* device as well.
|
|
||||||
* Note: phydev->phy_id is the result of reading the UID PHY registers.
|
|
||||||
*/
|
|
||||||
- if (phydev->phy_id == 0) {
|
|
||||||
+ if (!priv->plat->phy_node && phydev->phy_id == 0) {
|
|
||||||
phy_disconnect(phydev);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
@@ -164,6 +164,14 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
/* If we find a phy-handle property, use it as the PHY */
|
|
||||||
plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
|
||||||
|
|
||||||
+ /* If phy-handle is not specified, check if we have a fixed-phy */
|
|
||||||
+ if (!plat->phy_node && of_phy_is_fixed_link(np)) {
|
|
||||||
+ if ((of_phy_register_fixed_link(np) < 0))
|
|
||||||
+ return -ENODEV;
|
|
||||||
+
|
|
||||||
+ plat->phy_node = of_node_get(np);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
|
|
||||||
* and warn of its use. Remove this when phy node support is added.
|
|
||||||
*/
|
|
||||||
@@ -226,7 +234,7 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!dma_cfg) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
- goto err;
|
|
||||||
+ goto err2;
|
|
||||||
}
|
|
||||||
plat->dma_cfg = dma_cfg;
|
|
||||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
|
||||||
@@ -243,6 +251,8 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
+err2:
|
|
||||||
+ of_node_put(np);
|
|
||||||
err:
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,427 +0,0 @@
|
||||||
From 69fb970ad3fe05af7cb99ea78230c69c7ca0d03b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 16:10:22 -0700
|
|
||||||
Subject: [PATCH 4/8] stmmac: add ipq806x glue layer
|
|
||||||
|
|
||||||
The ethernet controller available in IPQ806x is a Synopsys DesignWare
|
|
||||||
Gigabit MAC IP core, already supported by the stmmac driver.
|
|
||||||
|
|
||||||
This glue layer implements some platform specific settings required to
|
|
||||||
get the controller working on an IPQ806x based platform.
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 +
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c | 324 +++++++++++++++++++++
|
|
||||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
|
|
||||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.h | 1 +
|
|
||||||
5 files changed, 328 insertions(+), 1 deletion(-)
|
|
||||||
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
|
||||||
@@ -16,6 +16,7 @@ if STMMAC_ETH
|
|
||||||
config STMMAC_PLATFORM
|
|
||||||
bool "STMMAC Platform bus support"
|
|
||||||
depends on STMMAC_ETH
|
|
||||||
+ select MFD_SYSCON
|
|
||||||
default y
|
|
||||||
---help---
|
|
||||||
This selects the platform specific bus support for
|
|
||||||
@@ -26,6 +27,15 @@ config STMMAC_PLATFORM
|
|
||||||
|
|
||||||
If unsure, say N.
|
|
||||||
|
|
||||||
+config DWMAC_IPQ806X
|
|
||||||
+ bool "QCA IPQ806x dwmac support"
|
|
||||||
+ depends on STMMAC_PLATFORM && ARCH_QCOM
|
|
||||||
+ help
|
|
||||||
+ Support for Ethernet controller on QCA IPQ806x SoC.
|
|
||||||
+
|
|
||||||
+ This selects the QCA IPQ806x SoC glue layer support for
|
|
||||||
+ the stmmac device driver.
|
|
||||||
+
|
|
||||||
config DWMAC_MESON
|
|
||||||
bool "Amlogic Meson dwmac support"
|
|
||||||
depends on STMMAC_PLATFORM && ARCH_MESON
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
|
|
||||||
@@ -1,6 +1,7 @@
|
|
||||||
obj-$(CONFIG_STMMAC_ETH) += stmmac.o
|
|
||||||
stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
|
|
||||||
stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
|
|
||||||
+stmmac-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o
|
|
||||||
stmmac-$(CONFIG_DWMAC_MESON) += dwmac-meson.o
|
|
||||||
stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
|
|
||||||
stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
@@ -46,6 +46,9 @@ static const struct of_device_id stmmac_
|
|
||||||
#ifdef CONFIG_DWMAC_SOCFPGA
|
|
||||||
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
|
|
||||||
#endif
|
|
||||||
+#ifdef CONFIG_DWMAC_IPQ806X
|
|
||||||
+ { .compatible = "qcom,ipq806x-gmac", .data = &ipq806x_gmac_data },
|
|
||||||
+#endif
|
|
||||||
/* SoC specific glue layers should come before generic bindings */
|
|
||||||
{ .compatible = "st,spear600-gmac"},
|
|
||||||
{ .compatible = "snps,dwmac-3.610"},
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
|
|
||||||
@@ -0,0 +1,343 @@
|
|
||||||
+/*
|
|
||||||
+ * Qualcomm Atheros IPQ806x GMAC glue layer
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 2015 The Linux Foundation
|
|
||||||
+ *
|
|
||||||
+ * Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
+ * purpose with or without fee is hereby granted, provided that the above
|
|
||||||
+ * copyright notice and this permission notice appear in all copies.
|
|
||||||
+ *
|
|
||||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include <linux/device.h>
|
|
||||||
+#include <linux/platform_device.h>
|
|
||||||
+#include <linux/phy.h>
|
|
||||||
+#include <linux/regmap.h>
|
|
||||||
+#include <linux/clk.h>
|
|
||||||
+#include <linux/reset.h>
|
|
||||||
+#include <linux/of_net.h>
|
|
||||||
+#include <linux/mfd/syscon.h>
|
|
||||||
+#include <linux/stmmac.h>
|
|
||||||
+#include <linux/of_mdio.h>
|
|
||||||
+
|
|
||||||
+#include "stmmac.h"
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_CLK_GATE 0x8
|
|
||||||
+#define NSS_COMMON_CLK_GATE_PTP_EN(x) BIT(0x10 + x)
|
|
||||||
+#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x) BIT(0x9 + (x * 2))
|
|
||||||
+#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x) BIT(0x8 + (x * 2))
|
|
||||||
+#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x) BIT(0x4 + x)
|
|
||||||
+#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x) BIT(0x0 + x)
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_CLK_DIV0 0xC
|
|
||||||
+#define NSS_COMMON_CLK_DIV_OFFSET(x) (x * 8)
|
|
||||||
+#define NSS_COMMON_CLK_DIV_MASK 0x7f
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_CLK_SRC_CTRL 0x14
|
|
||||||
+#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x) (1 << x)
|
|
||||||
+/* Mode is coded on 1 bit but is different depending on the MAC ID:
|
|
||||||
+ * MAC0: QSGMII=0 RGMII=1
|
|
||||||
+ * MAC1: QSGMII=0 SGMII=0 RGMII=1
|
|
||||||
+ * MAC2 & MAC3: QSGMII=0 SGMII=1
|
|
||||||
+ */
|
|
||||||
+#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x) 1
|
|
||||||
+#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x) ((x >= 2) ? 1 : 0)
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_MACSEC_CTL 0x28
|
|
||||||
+#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x) (1 << x)
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_GMAC_CTL(x) (0x30 + (x * 4))
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_CSYS_REQ BIT(19)
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL BIT(16)
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET 8
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_IFG_OFFSET 0
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_IFG_MASK 0x3f
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_CLK_DIV_RGMII_1000 1
|
|
||||||
+#define NSS_COMMON_CLK_DIV_RGMII_100 9
|
|
||||||
+#define NSS_COMMON_CLK_DIV_RGMII_10 99
|
|
||||||
+#define NSS_COMMON_CLK_DIV_SGMII_1000 0
|
|
||||||
+#define NSS_COMMON_CLK_DIV_SGMII_100 4
|
|
||||||
+#define NSS_COMMON_CLK_DIV_SGMII_10 49
|
|
||||||
+
|
|
||||||
+#define QSGMII_PCS_MODE_CTL 0x68
|
|
||||||
+#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x) BIT((x * 8) + 7)
|
|
||||||
+
|
|
||||||
+#define QSGMII_PCS_CAL_LCKDT_CTL 0x120
|
|
||||||
+#define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
|
|
||||||
+
|
|
||||||
+/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
|
|
||||||
+#define QSGMII_PHY_SGMII_CTL(x) ((x == 1) ? 0x134 : \
|
|
||||||
+ (0x13c + (4 * (x - 2))))
|
|
||||||
+#define QSGMII_PHY_CDR_EN BIT(0)
|
|
||||||
+#define QSGMII_PHY_RX_FRONT_EN BIT(1)
|
|
||||||
+#define QSGMII_PHY_RX_SIGNAL_DETECT_EN BIT(2)
|
|
||||||
+#define QSGMII_PHY_TX_DRIVER_EN BIT(3)
|
|
||||||
+#define QSGMII_PHY_QSGMII_EN BIT(7)
|
|
||||||
+#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET 12
|
|
||||||
+#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK 0x7
|
|
||||||
+#define QSGMII_PHY_RX_DC_BIAS_OFFSET 18
|
|
||||||
+#define QSGMII_PHY_RX_DC_BIAS_MASK 0x3
|
|
||||||
+#define QSGMII_PHY_RX_INPUT_EQU_OFFSET 20
|
|
||||||
+#define QSGMII_PHY_RX_INPUT_EQU_MASK 0x3
|
|
||||||
+#define QSGMII_PHY_CDR_PI_SLEW_OFFSET 22
|
|
||||||
+#define QSGMII_PHY_CDR_PI_SLEW_MASK 0x3
|
|
||||||
+#define QSGMII_PHY_TX_DRV_AMP_OFFSET 28
|
|
||||||
+#define QSGMII_PHY_TX_DRV_AMP_MASK 0xf
|
|
||||||
+
|
|
||||||
+struct ipq806x_gmac {
|
|
||||||
+ struct platform_device *pdev;
|
|
||||||
+ struct regmap *nss_common;
|
|
||||||
+ struct regmap *qsgmii_csr;
|
|
||||||
+ uint32_t id;
|
|
||||||
+ struct clk *core_clk;
|
|
||||||
+ phy_interface_t phy_mode;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
|
|
||||||
+{
|
|
||||||
+ struct device *dev = &gmac->pdev->dev;
|
|
||||||
+ int div;
|
|
||||||
+
|
|
||||||
+ switch (speed) {
|
|
||||||
+ case SPEED_1000:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_SGMII_1000;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case SPEED_100:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_SGMII_100;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case SPEED_10:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_SGMII_10;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ default:
|
|
||||||
+ dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return div;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
|
|
||||||
+{
|
|
||||||
+ struct device *dev = &gmac->pdev->dev;
|
|
||||||
+ int div;
|
|
||||||
+
|
|
||||||
+ switch (speed) {
|
|
||||||
+ case SPEED_1000:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_RGMII_1000;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case SPEED_100:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_RGMII_100;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case SPEED_10:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_RGMII_10;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ default:
|
|
||||||
+ dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return div;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
|
|
||||||
+{
|
|
||||||
+ uint32_t clk_bits, val;
|
|
||||||
+ int div;
|
|
||||||
+
|
|
||||||
+ switch (gmac->phy_mode) {
|
|
||||||
+ case PHY_INTERFACE_MODE_RGMII:
|
|
||||||
+ div = get_clk_div_rgmii(gmac, speed);
|
|
||||||
+ clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
|
|
||||||
+ NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case PHY_INTERFACE_MODE_SGMII:
|
|
||||||
+ div = get_clk_div_sgmii(gmac, speed);
|
|
||||||
+ clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
|
|
||||||
+ NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ default:
|
|
||||||
+ dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
|
||||||
+ phy_modes(gmac->phy_mode));
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Disable the clocks */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
|
||||||
+ val &= ~clk_bits;
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
|
||||||
+
|
|
||||||
+ /* Set the divider */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
|
|
||||||
+ val &= ~(NSS_COMMON_CLK_DIV_MASK
|
|
||||||
+ << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
|
|
||||||
+ val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
|
|
||||||
+
|
|
||||||
+ /* Enable the clock back */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
|
||||||
+ val |= clk_bits;
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
|
|
||||||
+{
|
|
||||||
+ struct device *dev = &gmac->pdev->dev;
|
|
||||||
+
|
|
||||||
+ gmac->phy_mode = of_get_phy_mode(dev->of_node);
|
|
||||||
+ if (gmac->phy_mode < 0) {
|
|
||||||
+ dev_err(dev, "missing phy mode property\n");
|
|
||||||
+ return ERR_PTR(-EINVAL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
|
|
||||||
+ dev_err(dev, "missing qcom id property\n");
|
|
||||||
+ return ERR_PTR(-EINVAL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* The GMACs are called 1 to 4 in the documentation, but to simplify the
|
|
||||||
+ * code and keep it consistent with the Linux convention, we'll number
|
|
||||||
+ * them from 0 to 3 here.
|
|
||||||
+ */
|
|
||||||
+ if (gmac->id < 0 || gmac->id > 3) {
|
|
||||||
+ dev_err(dev, "invalid gmac id\n");
|
|
||||||
+ return ERR_PTR(-EINVAL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ gmac->core_clk = devm_clk_get(dev, "stmmaceth");
|
|
||||||
+ if (IS_ERR(gmac->core_clk)) {
|
|
||||||
+ dev_err(dev, "missing stmmaceth clk property\n");
|
|
||||||
+ return gmac->core_clk;
|
|
||||||
+ }
|
|
||||||
+ clk_set_rate(gmac->core_clk, 266000000);
|
|
||||||
+
|
|
||||||
+ /* Setup the register map for the nss common registers */
|
|
||||||
+ gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
|
|
||||||
+ "qcom,nss-common");
|
|
||||||
+ if (IS_ERR(gmac->nss_common)) {
|
|
||||||
+ dev_err(dev, "missing nss-common node\n");
|
|
||||||
+ return gmac->nss_common;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Setup the register map for the qsgmii csr registers */
|
|
||||||
+ gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
|
|
||||||
+ "qcom,qsgmii-csr");
|
|
||||||
+ if (IS_ERR(gmac->qsgmii_csr)) {
|
|
||||||
+ dev_err(dev, "missing qsgmii-csr node\n");
|
|
||||||
+ return gmac->qsgmii_csr;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void *ipq806x_gmac_setup(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct device *dev = &pdev->dev;
|
|
||||||
+ struct ipq806x_gmac *gmac;
|
|
||||||
+ int val;
|
|
||||||
+ void *err;
|
|
||||||
+
|
|
||||||
+ gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
|
|
||||||
+ if (!gmac)
|
|
||||||
+ return ERR_PTR(-ENOMEM);
|
|
||||||
+
|
|
||||||
+ gmac->pdev = pdev;
|
|
||||||
+
|
|
||||||
+ err = ipq806x_gmac_of_parse(gmac);
|
|
||||||
+ if (err) {
|
|
||||||
+ dev_err(dev, "device tree parsing error\n");
|
|
||||||
+ return err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
|
|
||||||
+ QSGMII_PCS_CAL_LCKDT_CTL_RST);
|
|
||||||
+
|
|
||||||
+ /* Inter frame gap is set to 12 */
|
|
||||||
+ val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
|
|
||||||
+ 12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
|
|
||||||
+ /* We also initiate an AXI low power exit request */
|
|
||||||
+ val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
|
|
||||||
+ switch (gmac->phy_mode) {
|
|
||||||
+ case PHY_INTERFACE_MODE_RGMII:
|
|
||||||
+ val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
|
|
||||||
+ break;
|
|
||||||
+ case PHY_INTERFACE_MODE_SGMII:
|
|
||||||
+ val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
|
||||||
+ phy_modes(gmac->phy_mode));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
|
|
||||||
+
|
|
||||||
+ /* Configure the clock src according to the mode */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
|
|
||||||
+ val &= ~NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
|
||||||
+ switch (gmac->phy_mode) {
|
|
||||||
+ case PHY_INTERFACE_MODE_RGMII:
|
|
||||||
+ val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
|
|
||||||
+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
|
||||||
+ break;
|
|
||||||
+ case PHY_INTERFACE_MODE_SGMII:
|
|
||||||
+ val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
|
|
||||||
+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
|
||||||
+ phy_modes(gmac->phy_mode));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
|
|
||||||
+
|
|
||||||
+ /* Enable PTP clock */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
|
||||||
+ val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
|
||||||
+
|
|
||||||
+ if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
|
|
||||||
+ regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
|
|
||||||
+ QSGMII_PHY_CDR_EN |
|
|
||||||
+ QSGMII_PHY_RX_FRONT_EN |
|
|
||||||
+ QSGMII_PHY_RX_SIGNAL_DETECT_EN |
|
|
||||||
+ QSGMII_PHY_TX_DRIVER_EN |
|
|
||||||
+ QSGMII_PHY_QSGMII_EN |
|
|
||||||
+ 0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
|
|
||||||
+ 0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET |
|
|
||||||
+ 0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
|
|
||||||
+ 0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
|
|
||||||
+ 0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return gmac;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
|
|
||||||
+{
|
|
||||||
+ struct ipq806x_gmac *gmac = priv;
|
|
||||||
+
|
|
||||||
+ ipq806x_gmac_set_speed(gmac, speed);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+const struct stmmac_of_data ipq806x_gmac_data = {
|
|
||||||
+ .has_gmac = 1,
|
|
||||||
+ .setup = ipq806x_gmac_setup,
|
|
||||||
+ .fix_mac_speed = ipq806x_gmac_fix_mac_speed,
|
|
||||||
+};
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
|
||||||
@@ -137,6 +137,9 @@ void stmmac_disable_eee_mode(struct stmm
|
|
||||||
bool stmmac_eee_init(struct stmmac_priv *priv);
|
|
||||||
|
|
||||||
#ifdef CONFIG_STMMAC_PLATFORM
|
|
||||||
+#ifdef CONFIG_DWMAC_IPQ806X
|
|
||||||
+extern const struct stmmac_of_data ipq806x_gmac_data;
|
|
||||||
+#endif
|
|
||||||
#ifdef CONFIG_DWMAC_MESON
|
|
||||||
extern const struct stmmac_of_data meson6_dwmac_data;
|
|
||||||
#endif
|
|
|
@ -1,52 +0,0 @@
|
||||||
From 0f9605d9409b77a89daef91cc68239fc2ff50457 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 16:51:25 -0700
|
|
||||||
Subject: [PATCH 5/8] net: stmmac: ipq806x: document device tree bindings
|
|
||||||
|
|
||||||
Add the device tree bindings documentation for the QCA IPQ806x
|
|
||||||
variant of the Synopsys DesignWare MAC.
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
.../devicetree/bindings/net/ipq806x-dwmac.txt | 35 ++++++++++++++++++++++
|
|
||||||
1 file changed, 35 insertions(+)
|
|
||||||
create mode 100644 Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
|
|
||||||
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
|
|
||||||
@@ -0,0 +1,35 @@
|
|
||||||
+* IPQ806x DWMAC Ethernet controller
|
|
||||||
+
|
|
||||||
+The device inherits all the properties of the dwmac/stmmac devices
|
|
||||||
+described in the file net/stmmac.txt with the following changes.
|
|
||||||
+
|
|
||||||
+Required properties:
|
|
||||||
+
|
|
||||||
+- compatible: should be "qcom,ipq806x-gmac" along with "snps,dwmac"
|
|
||||||
+ and any applicable more detailed version number
|
|
||||||
+ described in net/stmmac.txt
|
|
||||||
+
|
|
||||||
+- qcom,nss-common: should contain a phandle to a syscon device mapping the
|
|
||||||
+ nss-common registers.
|
|
||||||
+
|
|
||||||
+- qcom,qsgmii-csr: should contain a phandle to a syscon device mapping the
|
|
||||||
+ qsgmii-csr registers.
|
|
||||||
+
|
|
||||||
+Example:
|
|
||||||
+
|
|
||||||
+ gmac: ethernet@37000000 {
|
|
||||||
+ device_type = "network";
|
|
||||||
+ compatible = "qcom,ipq806x-gmac";
|
|
||||||
+ reg = <0x37000000 0x200000>;
|
|
||||||
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
+ interrupt-names = "macirq";
|
|
||||||
+
|
|
||||||
+ qcom,nss-common = <&nss_common>;
|
|
||||||
+ qcom,qsgmii-csr = <&qsgmii_csr>;
|
|
||||||
+
|
|
||||||
+ clocks = <&gcc GMAC_CORE1_CLK>;
|
|
||||||
+ clock-names = "stmmaceth";
|
|
||||||
+
|
|
||||||
+ resets = <&gcc GMAC_CORE1_RESET>;
|
|
||||||
+ reset-names = "stmmaceth";
|
|
||||||
+ };
|
|
|
@ -1,171 +0,0 @@
|
||||||
From df944689d491e6af533173bf2ef448c3dd334f15 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Mon, 11 May 2015 15:15:25 -0700
|
|
||||||
Subject: [PATCH 6/8] net: stmmac: create one debugfs dir per net-device
|
|
||||||
|
|
||||||
stmmac DebugFS entries are currently global to the driver. As a result,
|
|
||||||
having more than one stmmac device in the system creates the following
|
|
||||||
error:
|
|
||||||
* ERROR stmmaceth, debugfs create directory failed
|
|
||||||
* stmmac_hw_setup: failed debugFS registration
|
|
||||||
|
|
||||||
This also results in being able to access the debugfs information for
|
|
||||||
the first registered device only.
|
|
||||||
|
|
||||||
This patch changes the debugfs structure to have one sub-directory per
|
|
||||||
net-device. Files under "/sys/kernel/debug/stmmaceth" will now show-up
|
|
||||||
under /sys/kernel/debug/stmmaceth/ethN/.
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 ++
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 76 ++++++++++++++++-------
|
|
||||||
2 files changed, 59 insertions(+), 23 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
|
||||||
@@ -116,6 +116,12 @@ struct stmmac_priv {
|
|
||||||
int use_riwt;
|
|
||||||
int irq_wake;
|
|
||||||
spinlock_t ptp_lock;
|
|
||||||
+
|
|
||||||
+#ifdef CONFIG_DEBUG_FS
|
|
||||||
+ struct dentry *dbgfs_dir;
|
|
||||||
+ struct dentry *dbgfs_rings_status;
|
|
||||||
+ struct dentry *dbgfs_dma_cap;
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
int stmmac_mdio_unregister(struct net_device *ndev);
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
@@ -119,7 +119,7 @@ static irqreturn_t stmmac_interrupt(int
|
|
||||||
|
|
||||||
#ifdef CONFIG_STMMAC_DEBUG_FS
|
|
||||||
static int stmmac_init_fs(struct net_device *dev);
|
|
||||||
-static void stmmac_exit_fs(void);
|
|
||||||
+static void stmmac_exit_fs(struct net_device *dev);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
|
|
||||||
@@ -1879,7 +1879,7 @@ static int stmmac_release(struct net_dev
|
|
||||||
netif_carrier_off(dev);
|
|
||||||
|
|
||||||
#ifdef CONFIG_STMMAC_DEBUG_FS
|
|
||||||
- stmmac_exit_fs();
|
|
||||||
+ stmmac_exit_fs(dev);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
stmmac_release_ptp(priv);
|
|
||||||
@@ -2467,8 +2467,6 @@ static int stmmac_ioctl(struct net_devic
|
|
||||||
|
|
||||||
#ifdef CONFIG_STMMAC_DEBUG_FS
|
|
||||||
static struct dentry *stmmac_fs_dir;
|
|
||||||
-static struct dentry *stmmac_rings_status;
|
|
||||||
-static struct dentry *stmmac_dma_cap;
|
|
||||||
|
|
||||||
static void sysfs_display_ring(void *head, int size, int extend_desc,
|
|
||||||
struct seq_file *seq)
|
|
||||||
@@ -2607,36 +2605,39 @@ static const struct file_operations stmm
|
|
||||||
|
|
||||||
static int stmmac_init_fs(struct net_device *dev)
|
|
||||||
{
|
|
||||||
- /* Create debugfs entries */
|
|
||||||
- stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
|
|
||||||
+ struct stmmac_priv *priv = netdev_priv(dev);
|
|
||||||
+
|
|
||||||
+ /* Create per netdev entries */
|
|
||||||
+ priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir);
|
|
||||||
|
|
||||||
- if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
|
|
||||||
- pr_err("ERROR %s, debugfs create directory failed\n",
|
|
||||||
- STMMAC_RESOURCE_NAME);
|
|
||||||
+ if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) {
|
|
||||||
+ pr_err("ERROR %s/%s, debugfs create directory failed\n",
|
|
||||||
+ STMMAC_RESOURCE_NAME, dev->name);
|
|
||||||
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Entry to report DMA RX/TX rings */
|
|
||||||
- stmmac_rings_status = debugfs_create_file("descriptors_status",
|
|
||||||
- S_IRUGO, stmmac_fs_dir, dev,
|
|
||||||
- &stmmac_rings_status_fops);
|
|
||||||
+ priv->dbgfs_rings_status =
|
|
||||||
+ debugfs_create_file("descriptors_status", S_IRUGO,
|
|
||||||
+ priv->dbgfs_dir, dev,
|
|
||||||
+ &stmmac_rings_status_fops);
|
|
||||||
|
|
||||||
- if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
|
|
||||||
+ if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) {
|
|
||||||
pr_info("ERROR creating stmmac ring debugfs file\n");
|
|
||||||
- debugfs_remove(stmmac_fs_dir);
|
|
||||||
+ debugfs_remove_recursive(priv->dbgfs_dir);
|
|
||||||
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Entry to report the DMA HW features */
|
|
||||||
- stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
|
|
||||||
- dev, &stmmac_dma_cap_fops);
|
|
||||||
+ priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO,
|
|
||||||
+ priv->dbgfs_dir,
|
|
||||||
+ dev, &stmmac_dma_cap_fops);
|
|
||||||
|
|
||||||
- if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
|
|
||||||
+ if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) {
|
|
||||||
pr_info("ERROR creating stmmac MMC debugfs file\n");
|
|
||||||
- debugfs_remove(stmmac_rings_status);
|
|
||||||
- debugfs_remove(stmmac_fs_dir);
|
|
||||||
+ debugfs_remove_recursive(priv->dbgfs_dir);
|
|
||||||
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
@@ -2644,11 +2645,11 @@ static int stmmac_init_fs(struct net_dev
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void stmmac_exit_fs(void)
|
|
||||||
+static void stmmac_exit_fs(struct net_device *dev)
|
|
||||||
{
|
|
||||||
- debugfs_remove(stmmac_rings_status);
|
|
||||||
- debugfs_remove(stmmac_dma_cap);
|
|
||||||
- debugfs_remove(stmmac_fs_dir);
|
|
||||||
+ struct stmmac_priv *priv = netdev_priv(dev);
|
|
||||||
+
|
|
||||||
+ debugfs_remove_recursive(priv->dbgfs_dir);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_STMMAC_DEBUG_FS */
|
|
||||||
|
|
||||||
@@ -3032,6 +3033,21 @@ static int __init stmmac_init(void)
|
|
||||||
ret = stmmac_register_pci();
|
|
||||||
if (ret)
|
|
||||||
goto err_pci;
|
|
||||||
+
|
|
||||||
+#ifdef CONFIG_STMMAC_DEBUG_FS
|
|
||||||
+ /* Create debugfs main directory if it doesn't exist yet */
|
|
||||||
+ if (stmmac_fs_dir == NULL) {
|
|
||||||
+ stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
|
|
||||||
+
|
|
||||||
+ if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
|
|
||||||
+ pr_err("ERROR %s, debugfs create directory failed\n",
|
|
||||||
+ STMMAC_RESOURCE_NAME);
|
|
||||||
+
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
err_pci:
|
|
||||||
stmmac_unregister_platform();
|
|
||||||
@@ -3042,6 +3058,9 @@ err:
|
|
||||||
|
|
||||||
static void __exit stmmac_exit(void)
|
|
||||||
{
|
|
||||||
+#ifdef CONFIG_STMMAC_DEBUG_FS
|
|
||||||
+ debugfs_remove_recursive(stmmac_fs_dir);
|
|
||||||
+#endif
|
|
||||||
stmmac_unregister_platform();
|
|
||||||
stmmac_unregister_pci();
|
|
||||||
}
|
|
|
@ -9,27 +9,23 @@ Subject: [PATCH] stmac: platform: add support for retreiving mac from mtd
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||||
@@ -284,6 +284,7 @@ static int stmmac_pltfr_probe(struct pla
|
@@ -116,6 +116,19 @@ stmmac_probe_config_dt(struct platform_d
|
||||||
struct stmmac_priv *priv = NULL;
|
return ERR_PTR(-ENOMEM);
|
||||||
struct plat_stmmacenet_data *plat_dat = NULL;
|
|
||||||
const char *mac = NULL;
|
|
||||||
+ u8 mtd_mac[ETH_ALEN] = { };
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
*mac = of_get_mac_address(np);
|
||||||
addr = devm_ioremap_resource(dev, res);
|
+ if (!*mac) {
|
||||||
@@ -313,6 +314,15 @@ static int stmmac_pltfr_probe(struct pla
|
+ u8 mtd_mac[ETH_ALEN];
|
||||||
pr_err("%s: main dt probe failed", __func__);
|
+ int ret;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
+
|
+
|
||||||
+ if (!mac) {
|
+ ret = of_get_mac_address_mtd(np, mtd_mac);
|
||||||
+ ret = of_get_mac_address_mtd(dev->of_node, &mtd_mac);
|
|
||||||
+ if (ret == -EPROBE_DEFER)
|
+ if (ret == -EPROBE_DEFER)
|
||||||
+ return ret;
|
+ return ERR_PTR(ret);
|
||||||
+
|
+
|
||||||
+ if (is_valid_ether_addr(&mtd_mac))
|
+ if (is_valid_ether_addr(mtd_mac))
|
||||||
+ mac = mtd_mac;
|
+ *mac = devm_kmemdup(&pdev->dev, mtd_mac, ETH_ALEN,
|
||||||
|
+ GFP_KERNEL);
|
||||||
+ }
|
+ }
|
||||||
}
|
+
|
||||||
|
plat->interface = of_get_phy_mode(np);
|
||||||
|
|
||||||
/* Custom setup (if needed) */
|
/* Get max speed of operation from device tree */
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
From 4f09499bc1d9bb095caccbcd73ff951ee631e521 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 15:42:40 -0700
|
|
||||||
Subject: [PATCH 1/8] stmmac: add phy-handle support to the platform layer
|
|
||||||
|
|
||||||
On stmmac driver, PHY specification in device-tree was done using the
|
|
||||||
non-standard property "snps,phy-addr". Specifying a PHY on a different
|
|
||||||
MDIO bus that the one within the stmmac controller doesn't seem to be
|
|
||||||
possible when device-tree is used.
|
|
||||||
|
|
||||||
This change adds support for the phy-handle property, as specified in
|
|
||||||
Documentation/devicetree/bindings/net/ethernet.txt.
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 28 ++++++++++++++--------
|
|
||||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++-
|
|
||||||
include/linux/stmmac.h | 1 +
|
|
||||||
3 files changed, 24 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
@@ -52,6 +52,7 @@
|
|
||||||
#include "stmmac_ptp.h"
|
|
||||||
#include "stmmac.h"
|
|
||||||
#include <linux/reset.h>
|
|
||||||
+#include <linux/of_mdio.h>
|
|
||||||
|
|
||||||
#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
|
|
||||||
|
|
||||||
@@ -816,18 +817,25 @@ static int stmmac_init_phy(struct net_de
|
|
||||||
priv->speed = 0;
|
|
||||||
priv->oldduplex = -1;
|
|
||||||
|
|
||||||
- if (priv->plat->phy_bus_name)
|
|
||||||
- snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
|
|
||||||
- priv->plat->phy_bus_name, priv->plat->bus_id);
|
|
||||||
- else
|
|
||||||
- snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
|
|
||||||
- priv->plat->bus_id);
|
|
||||||
-
|
|
||||||
- snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
|
|
||||||
- priv->plat->phy_addr);
|
|
||||||
- pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt);
|
|
||||||
+ if (priv->plat->phy_node) {
|
|
||||||
+ phydev = of_phy_connect(dev, priv->plat->phy_node,
|
|
||||||
+ &stmmac_adjust_link, 0, interface);
|
|
||||||
+ } else {
|
|
||||||
+ if (priv->plat->phy_bus_name)
|
|
||||||
+ snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
|
|
||||||
+ priv->plat->phy_bus_name, priv->plat->bus_id);
|
|
||||||
+ else
|
|
||||||
+ snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
|
|
||||||
+ priv->plat->bus_id);
|
|
||||||
+
|
|
||||||
+ snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
|
|
||||||
+ priv->plat->phy_addr);
|
|
||||||
+ pr_debug("stmmac_init_phy: trying to attach to %s\n",
|
|
||||||
+ phy_id_fmt);
|
|
||||||
|
|
||||||
- phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
|
|
||||||
+ phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
|
|
||||||
+ interface);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(phydev)) {
|
|
||||||
pr_err("%s: Could not attach to PHY\n", dev->name);
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
@@ -28,6 +28,7 @@
|
|
||||||
#include <linux/of.h>
|
|
||||||
#include <linux/of_net.h>
|
|
||||||
#include <linux/of_device.h>
|
|
||||||
+#include <linux/of_mdio.h>
|
|
||||||
|
|
||||||
#include "stmmac.h"
|
|
||||||
#include "stmmac_platform.h"
|
|
||||||
@@ -168,13 +169,16 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
/* Default to phy auto-detection */
|
|
||||||
plat->phy_addr = -1;
|
|
||||||
|
|
||||||
+ /* If we find a phy-handle property, use it as the PHY */
|
|
||||||
+ plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
|
||||||
+
|
|
||||||
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
|
|
||||||
* and warn of its use. Remove this when phy node support is added.
|
|
||||||
*/
|
|
||||||
if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
|
|
||||||
dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
|
|
||||||
|
|
||||||
- if (plat->phy_bus_name)
|
|
||||||
+ if (plat->phy_node || plat->phy_bus_name)
|
|
||||||
plat->mdio_bus_data = NULL;
|
|
||||||
else
|
|
||||||
plat->mdio_bus_data =
|
|
||||||
--- a/include/linux/stmmac.h
|
|
||||||
+++ b/include/linux/stmmac.h
|
|
||||||
@@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
|
|
||||||
int phy_addr;
|
|
||||||
int interface;
|
|
||||||
struct stmmac_mdio_bus_data *mdio_bus_data;
|
|
||||||
+ struct device_node *phy_node;
|
|
||||||
struct stmmac_dma_cfg *dma_cfg;
|
|
||||||
int clk_csr;
|
|
||||||
int has_gmac;
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,65 +0,0 @@
|
||||||
From 0149d275415cd1b2382ce94e5eb32641590097d0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 15:57:12 -0700
|
|
||||||
Subject: [PATCH 2/8] stmmac: move error path at the end of
|
|
||||||
stmmac_probe_config_dt()
|
|
||||||
|
|
||||||
We will want to do additional clean-up on certain errors. Therefore,
|
|
||||||
this change moves the error path at the end of the function for better
|
|
||||||
code readability.
|
|
||||||
|
|
||||||
This patch doesn't change anything functionally.
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 22 ++++++++++++++++------
|
|
||||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
@@ -130,13 +130,18 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
struct device_node *np = pdev->dev.of_node;
|
|
||||||
struct stmmac_dma_cfg *dma_cfg;
|
|
||||||
const struct of_device_id *device;
|
|
||||||
+ int ret;
|
|
||||||
|
|
||||||
- if (!np)
|
|
||||||
- return -ENODEV;
|
|
||||||
+ if (!np) {
|
|
||||||
+ ret = -ENODEV;
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
device = of_match_device(stmmac_dt_ids, &pdev->dev);
|
|
||||||
- if (!device)
|
|
||||||
- return -ENODEV;
|
|
||||||
+ if (!device) {
|
|
||||||
+ ret = -ENODEV;
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (device->data) {
|
|
||||||
const struct stmmac_of_data *data = device->data;
|
|
||||||
@@ -236,8 +241,10 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
if (of_find_property(np, "snps,pbl", NULL)) {
|
|
||||||
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
|
|
||||||
GFP_KERNEL);
|
|
||||||
- if (!dma_cfg)
|
|
||||||
- return -ENOMEM;
|
|
||||||
+ if (!dma_cfg) {
|
|
||||||
+ ret = -ENOMEM;
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
plat->dma_cfg = dma_cfg;
|
|
||||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
|
||||||
dma_cfg->fixed_burst =
|
|
||||||
@@ -255,6 +262,9 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
+
|
|
||||||
+err:
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static int stmmac_probe_config_dt(struct platform_device *pdev,
|
|
|
@ -1,64 +0,0 @@
|
||||||
From 3a95f75867be562cb919ff23a738f70357188fbd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 16:02:03 -0700
|
|
||||||
Subject: [PATCH 3/8] stmmac: add fixed-link device-tree support
|
|
||||||
|
|
||||||
In case DT is used, this change adds the ability to the stmmac driver to
|
|
||||||
detect a fixed-link PHY, instanciate it, and use it during
|
|
||||||
phy_connect().
|
|
||||||
|
|
||||||
Fixed link PHYs DT usage is described in:
|
|
||||||
Documentation/devicetree/bindings/net/fixed-link.txt
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 12 +++++++++++-
|
|
||||||
2 files changed, 12 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
||||||
@@ -859,7 +859,7 @@ static int stmmac_init_phy(struct net_de
|
|
||||||
* device as well.
|
|
||||||
* Note: phydev->phy_id is the result of reading the UID PHY registers.
|
|
||||||
*/
|
|
||||||
- if (phydev->phy_id == 0) {
|
|
||||||
+ if (!priv->plat->phy_node && phydev->phy_id == 0) {
|
|
||||||
phy_disconnect(phydev);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
@@ -177,6 +177,14 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
/* If we find a phy-handle property, use it as the PHY */
|
|
||||||
plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
|
||||||
|
|
||||||
+ /* If phy-handle is not specified, check if we have a fixed-phy */
|
|
||||||
+ if (!plat->phy_node && of_phy_is_fixed_link(np)) {
|
|
||||||
+ if ((of_phy_register_fixed_link(np) < 0))
|
|
||||||
+ return -ENODEV;
|
|
||||||
+
|
|
||||||
+ plat->phy_node = of_node_get(np);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
|
|
||||||
* and warn of its use. Remove this when phy node support is added.
|
|
||||||
*/
|
|
||||||
@@ -243,7 +251,7 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!dma_cfg) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
- goto err;
|
|
||||||
+ goto err2;
|
|
||||||
}
|
|
||||||
plat->dma_cfg = dma_cfg;
|
|
||||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
|
||||||
@@ -263,6 +271,8 @@ static int stmmac_probe_config_dt(struct
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
+err2:
|
|
||||||
+ of_node_put(np);
|
|
||||||
err:
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,407 +0,0 @@
|
||||||
From 69fb970ad3fe05af7cb99ea78230c69c7ca0d03b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 16:10:22 -0700
|
|
||||||
Subject: [PATCH 4/8] stmmac: add ipq806x glue layer
|
|
||||||
|
|
||||||
The ethernet controller available in IPQ806x is a Synopsys DesignWare
|
|
||||||
Gigabit MAC IP core, already supported by the stmmac driver.
|
|
||||||
|
|
||||||
This glue layer implements some platform specific settings required to
|
|
||||||
get the controller working on an IPQ806x based platform.
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 +
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
|
|
||||||
drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c | 324 +++++++++++++++++++++
|
|
||||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
|
|
||||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.h | 1 +
|
|
||||||
5 files changed, 328 insertions(+), 1 deletion(-)
|
|
||||||
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
|
||||||
@@ -16,6 +16,7 @@ if STMMAC_ETH
|
|
||||||
config STMMAC_PLATFORM
|
|
||||||
tristate "STMMAC Platform bus support"
|
|
||||||
depends on STMMAC_ETH
|
|
||||||
+ select MFD_SYSCON
|
|
||||||
default y
|
|
||||||
---help---
|
|
||||||
This selects the platform specific bus support for the stmmac driver.
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
|
|
||||||
@@ -6,7 +6,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethto
|
|
||||||
|
|
||||||
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
|
|
||||||
stmmac-platform-objs:= stmmac_platform.o dwmac-meson.o dwmac-sunxi.o \
|
|
||||||
- dwmac-sti.o dwmac-socfpga.o dwmac-rk.o
|
|
||||||
+ dwmac-sti.o dwmac-socfpga.o dwmac-rk.o dwmac-ipq806x.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
|
|
||||||
stmmac-pci-objs:= stmmac_pci.o
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
||||||
@@ -43,6 +43,7 @@ static const struct of_device_id stmmac_
|
|
||||||
{ .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
|
|
||||||
{ .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
|
|
||||||
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
|
|
||||||
+ { .compatible = "qcom,ipq806x-gmac", .data = &ipq806x_gmac_data },
|
|
||||||
{ .compatible = "st,spear600-gmac"},
|
|
||||||
{ .compatible = "snps,dwmac-3.610"},
|
|
||||||
{ .compatible = "snps,dwmac-3.70a"},
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
|
|
||||||
@@ -25,5 +25,6 @@ extern const struct stmmac_of_data stih4
|
|
||||||
extern const struct stmmac_of_data stid127_dwmac_data;
|
|
||||||
extern const struct stmmac_of_data socfpga_gmac_data;
|
|
||||||
extern const struct stmmac_of_data rk3288_gmac_data;
|
|
||||||
+extern const struct stmmac_of_data ipq806x_gmac_data;
|
|
||||||
|
|
||||||
#endif /* __STMMAC_PLATFORM_H__ */
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
|
|
||||||
@@ -0,0 +1,343 @@
|
|
||||||
+/*
|
|
||||||
+ * Qualcomm Atheros IPQ806x GMAC glue layer
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 2015 The Linux Foundation
|
|
||||||
+ *
|
|
||||||
+ * Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
+ * purpose with or without fee is hereby granted, provided that the above
|
|
||||||
+ * copyright notice and this permission notice appear in all copies.
|
|
||||||
+ *
|
|
||||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include <linux/device.h>
|
|
||||||
+#include <linux/platform_device.h>
|
|
||||||
+#include <linux/phy.h>
|
|
||||||
+#include <linux/regmap.h>
|
|
||||||
+#include <linux/clk.h>
|
|
||||||
+#include <linux/reset.h>
|
|
||||||
+#include <linux/of_net.h>
|
|
||||||
+#include <linux/mfd/syscon.h>
|
|
||||||
+#include <linux/stmmac.h>
|
|
||||||
+#include <linux/of_mdio.h>
|
|
||||||
+
|
|
||||||
+#include "stmmac_platform.h"
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_CLK_GATE 0x8
|
|
||||||
+#define NSS_COMMON_CLK_GATE_PTP_EN(x) BIT(0x10 + x)
|
|
||||||
+#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x) BIT(0x9 + (x * 2))
|
|
||||||
+#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x) BIT(0x8 + (x * 2))
|
|
||||||
+#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x) BIT(0x4 + x)
|
|
||||||
+#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x) BIT(0x0 + x)
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_CLK_DIV0 0xC
|
|
||||||
+#define NSS_COMMON_CLK_DIV_OFFSET(x) (x * 8)
|
|
||||||
+#define NSS_COMMON_CLK_DIV_MASK 0x7f
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_CLK_SRC_CTRL 0x14
|
|
||||||
+#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x) (1 << x)
|
|
||||||
+/* Mode is coded on 1 bit but is different depending on the MAC ID:
|
|
||||||
+ * MAC0: QSGMII=0 RGMII=1
|
|
||||||
+ * MAC1: QSGMII=0 SGMII=0 RGMII=1
|
|
||||||
+ * MAC2 & MAC3: QSGMII=0 SGMII=1
|
|
||||||
+ */
|
|
||||||
+#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x) 1
|
|
||||||
+#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x) ((x >= 2) ? 1 : 0)
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_MACSEC_CTL 0x28
|
|
||||||
+#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x) (1 << x)
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_GMAC_CTL(x) (0x30 + (x * 4))
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_CSYS_REQ BIT(19)
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL BIT(16)
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET 8
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_IFG_OFFSET 0
|
|
||||||
+#define NSS_COMMON_GMAC_CTL_IFG_MASK 0x3f
|
|
||||||
+
|
|
||||||
+#define NSS_COMMON_CLK_DIV_RGMII_1000 1
|
|
||||||
+#define NSS_COMMON_CLK_DIV_RGMII_100 9
|
|
||||||
+#define NSS_COMMON_CLK_DIV_RGMII_10 99
|
|
||||||
+#define NSS_COMMON_CLK_DIV_SGMII_1000 0
|
|
||||||
+#define NSS_COMMON_CLK_DIV_SGMII_100 4
|
|
||||||
+#define NSS_COMMON_CLK_DIV_SGMII_10 49
|
|
||||||
+
|
|
||||||
+#define QSGMII_PCS_MODE_CTL 0x68
|
|
||||||
+#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x) BIT((x * 8) + 7)
|
|
||||||
+
|
|
||||||
+#define QSGMII_PCS_CAL_LCKDT_CTL 0x120
|
|
||||||
+#define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
|
|
||||||
+
|
|
||||||
+/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
|
|
||||||
+#define QSGMII_PHY_SGMII_CTL(x) ((x == 1) ? 0x134 : \
|
|
||||||
+ (0x13c + (4 * (x - 2))))
|
|
||||||
+#define QSGMII_PHY_CDR_EN BIT(0)
|
|
||||||
+#define QSGMII_PHY_RX_FRONT_EN BIT(1)
|
|
||||||
+#define QSGMII_PHY_RX_SIGNAL_DETECT_EN BIT(2)
|
|
||||||
+#define QSGMII_PHY_TX_DRIVER_EN BIT(3)
|
|
||||||
+#define QSGMII_PHY_QSGMII_EN BIT(7)
|
|
||||||
+#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET 12
|
|
||||||
+#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK 0x7
|
|
||||||
+#define QSGMII_PHY_RX_DC_BIAS_OFFSET 18
|
|
||||||
+#define QSGMII_PHY_RX_DC_BIAS_MASK 0x3
|
|
||||||
+#define QSGMII_PHY_RX_INPUT_EQU_OFFSET 20
|
|
||||||
+#define QSGMII_PHY_RX_INPUT_EQU_MASK 0x3
|
|
||||||
+#define QSGMII_PHY_CDR_PI_SLEW_OFFSET 22
|
|
||||||
+#define QSGMII_PHY_CDR_PI_SLEW_MASK 0x3
|
|
||||||
+#define QSGMII_PHY_TX_DRV_AMP_OFFSET 28
|
|
||||||
+#define QSGMII_PHY_TX_DRV_AMP_MASK 0xf
|
|
||||||
+
|
|
||||||
+struct ipq806x_gmac {
|
|
||||||
+ struct platform_device *pdev;
|
|
||||||
+ struct regmap *nss_common;
|
|
||||||
+ struct regmap *qsgmii_csr;
|
|
||||||
+ uint32_t id;
|
|
||||||
+ struct clk *core_clk;
|
|
||||||
+ phy_interface_t phy_mode;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
|
|
||||||
+{
|
|
||||||
+ struct device *dev = &gmac->pdev->dev;
|
|
||||||
+ int div;
|
|
||||||
+
|
|
||||||
+ switch (speed) {
|
|
||||||
+ case SPEED_1000:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_SGMII_1000;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case SPEED_100:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_SGMII_100;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case SPEED_10:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_SGMII_10;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ default:
|
|
||||||
+ dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return div;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
|
|
||||||
+{
|
|
||||||
+ struct device *dev = &gmac->pdev->dev;
|
|
||||||
+ int div;
|
|
||||||
+
|
|
||||||
+ switch (speed) {
|
|
||||||
+ case SPEED_1000:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_RGMII_1000;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case SPEED_100:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_RGMII_100;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case SPEED_10:
|
|
||||||
+ div = NSS_COMMON_CLK_DIV_RGMII_10;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ default:
|
|
||||||
+ dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return div;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
|
|
||||||
+{
|
|
||||||
+ uint32_t clk_bits, val;
|
|
||||||
+ int div;
|
|
||||||
+
|
|
||||||
+ switch (gmac->phy_mode) {
|
|
||||||
+ case PHY_INTERFACE_MODE_RGMII:
|
|
||||||
+ div = get_clk_div_rgmii(gmac, speed);
|
|
||||||
+ clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
|
|
||||||
+ NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case PHY_INTERFACE_MODE_SGMII:
|
|
||||||
+ div = get_clk_div_sgmii(gmac, speed);
|
|
||||||
+ clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
|
|
||||||
+ NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ default:
|
|
||||||
+ dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
|
||||||
+ phy_modes(gmac->phy_mode));
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Disable the clocks */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
|
||||||
+ val &= ~clk_bits;
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
|
||||||
+
|
|
||||||
+ /* Set the divider */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
|
|
||||||
+ val &= ~(NSS_COMMON_CLK_DIV_MASK
|
|
||||||
+ << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
|
|
||||||
+ val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
|
|
||||||
+
|
|
||||||
+ /* Enable the clock back */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
|
||||||
+ val |= clk_bits;
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
|
|
||||||
+{
|
|
||||||
+ struct device *dev = &gmac->pdev->dev;
|
|
||||||
+
|
|
||||||
+ gmac->phy_mode = of_get_phy_mode(dev->of_node);
|
|
||||||
+ if (gmac->phy_mode < 0) {
|
|
||||||
+ dev_err(dev, "missing phy mode property\n");
|
|
||||||
+ return ERR_PTR(-EINVAL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
|
|
||||||
+ dev_err(dev, "missing qcom id property\n");
|
|
||||||
+ return ERR_PTR(-EINVAL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* The GMACs are called 1 to 4 in the documentation, but to simplify the
|
|
||||||
+ * code and keep it consistent with the Linux convention, we'll number
|
|
||||||
+ * them from 0 to 3 here.
|
|
||||||
+ */
|
|
||||||
+ if (gmac->id < 0 || gmac->id > 3) {
|
|
||||||
+ dev_err(dev, "invalid gmac id\n");
|
|
||||||
+ return ERR_PTR(-EINVAL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ gmac->core_clk = devm_clk_get(dev, "stmmaceth");
|
|
||||||
+ if (IS_ERR(gmac->core_clk)) {
|
|
||||||
+ dev_err(dev, "missing stmmaceth clk property\n");
|
|
||||||
+ return gmac->core_clk;
|
|
||||||
+ }
|
|
||||||
+ clk_set_rate(gmac->core_clk, 266000000);
|
|
||||||
+
|
|
||||||
+ /* Setup the register map for the nss common registers */
|
|
||||||
+ gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
|
|
||||||
+ "qcom,nss-common");
|
|
||||||
+ if (IS_ERR(gmac->nss_common)) {
|
|
||||||
+ dev_err(dev, "missing nss-common node\n");
|
|
||||||
+ return gmac->nss_common;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Setup the register map for the qsgmii csr registers */
|
|
||||||
+ gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
|
|
||||||
+ "qcom,qsgmii-csr");
|
|
||||||
+ if (IS_ERR(gmac->qsgmii_csr)) {
|
|
||||||
+ dev_err(dev, "missing qsgmii-csr node\n");
|
|
||||||
+ return gmac->qsgmii_csr;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void *ipq806x_gmac_setup(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct device *dev = &pdev->dev;
|
|
||||||
+ struct ipq806x_gmac *gmac;
|
|
||||||
+ int val;
|
|
||||||
+ void *err;
|
|
||||||
+
|
|
||||||
+ gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
|
|
||||||
+ if (!gmac)
|
|
||||||
+ return ERR_PTR(-ENOMEM);
|
|
||||||
+
|
|
||||||
+ gmac->pdev = pdev;
|
|
||||||
+
|
|
||||||
+ err = ipq806x_gmac_of_parse(gmac);
|
|
||||||
+ if (err) {
|
|
||||||
+ dev_err(dev, "device tree parsing error\n");
|
|
||||||
+ return err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
|
|
||||||
+ QSGMII_PCS_CAL_LCKDT_CTL_RST);
|
|
||||||
+
|
|
||||||
+ /* Inter frame gap is set to 12 */
|
|
||||||
+ val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
|
|
||||||
+ 12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
|
|
||||||
+ /* We also initiate an AXI low power exit request */
|
|
||||||
+ val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
|
|
||||||
+ switch (gmac->phy_mode) {
|
|
||||||
+ case PHY_INTERFACE_MODE_RGMII:
|
|
||||||
+ val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
|
|
||||||
+ break;
|
|
||||||
+ case PHY_INTERFACE_MODE_SGMII:
|
|
||||||
+ val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
|
||||||
+ phy_modes(gmac->phy_mode));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
|
|
||||||
+
|
|
||||||
+ /* Configure the clock src according to the mode */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
|
|
||||||
+ val &= ~NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
|
||||||
+ switch (gmac->phy_mode) {
|
|
||||||
+ case PHY_INTERFACE_MODE_RGMII:
|
|
||||||
+ val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
|
|
||||||
+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
|
||||||
+ break;
|
|
||||||
+ case PHY_INTERFACE_MODE_SGMII:
|
|
||||||
+ val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
|
|
||||||
+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
|
||||||
+ phy_modes(gmac->phy_mode));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
|
|
||||||
+
|
|
||||||
+ /* Enable PTP clock */
|
|
||||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
|
||||||
+ val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
|
|
||||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
|
||||||
+
|
|
||||||
+ if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
|
|
||||||
+ regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
|
|
||||||
+ QSGMII_PHY_CDR_EN |
|
|
||||||
+ QSGMII_PHY_RX_FRONT_EN |
|
|
||||||
+ QSGMII_PHY_RX_SIGNAL_DETECT_EN |
|
|
||||||
+ QSGMII_PHY_TX_DRIVER_EN |
|
|
||||||
+ QSGMII_PHY_QSGMII_EN |
|
|
||||||
+ 0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
|
|
||||||
+ 0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET |
|
|
||||||
+ 0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
|
|
||||||
+ 0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
|
|
||||||
+ 0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return gmac;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
|
|
||||||
+{
|
|
||||||
+ struct ipq806x_gmac *gmac = priv;
|
|
||||||
+
|
|
||||||
+ ipq806x_gmac_set_speed(gmac, speed);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+const struct stmmac_of_data ipq806x_gmac_data = {
|
|
||||||
+ .has_gmac = 1,
|
|
||||||
+ .setup = ipq806x_gmac_setup,
|
|
||||||
+ .fix_mac_speed = ipq806x_gmac_fix_mac_speed,
|
|
||||||
+};
|
|
|
@ -1,52 +0,0 @@
|
||||||
From 0f9605d9409b77a89daef91cc68239fc2ff50457 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
Date: Fri, 8 May 2015 16:51:25 -0700
|
|
||||||
Subject: [PATCH 5/8] net: stmmac: ipq806x: document device tree bindings
|
|
||||||
|
|
||||||
Add the device tree bindings documentation for the QCA IPQ806x
|
|
||||||
variant of the Synopsys DesignWare MAC.
|
|
||||||
|
|
||||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|
||||||
---
|
|
||||||
.../devicetree/bindings/net/ipq806x-dwmac.txt | 35 ++++++++++++++++++++++
|
|
||||||
1 file changed, 35 insertions(+)
|
|
||||||
create mode 100644 Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
|
|
||||||
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
|
|
||||||
@@ -0,0 +1,35 @@
|
|
||||||
+* IPQ806x DWMAC Ethernet controller
|
|
||||||
+
|
|
||||||
+The device inherits all the properties of the dwmac/stmmac devices
|
|
||||||
+described in the file net/stmmac.txt with the following changes.
|
|
||||||
+
|
|
||||||
+Required properties:
|
|
||||||
+
|
|
||||||
+- compatible: should be "qcom,ipq806x-gmac" along with "snps,dwmac"
|
|
||||||
+ and any applicable more detailed version number
|
|
||||||
+ described in net/stmmac.txt
|
|
||||||
+
|
|
||||||
+- qcom,nss-common: should contain a phandle to a syscon device mapping the
|
|
||||||
+ nss-common registers.
|
|
||||||
+
|
|
||||||
+- qcom,qsgmii-csr: should contain a phandle to a syscon device mapping the
|
|
||||||
+ qsgmii-csr registers.
|
|
||||||
+
|
|
||||||
+Example:
|
|
||||||
+
|
|
||||||
+ gmac: ethernet@37000000 {
|
|
||||||
+ device_type = "network";
|
|
||||||
+ compatible = "qcom,ipq806x-gmac";
|
|
||||||
+ reg = <0x37000000 0x200000>;
|
|
||||||
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
+ interrupt-names = "macirq";
|
|
||||||
+
|
|
||||||
+ qcom,nss-common = <&nss_common>;
|
|
||||||
+ qcom,qsgmii-csr = <&qsgmii_csr>;
|
|
||||||
+
|
|
||||||
+ clocks = <&gcc GMAC_CORE1_CLK>;
|
|
||||||
+ clock-names = "stmmaceth";
|
|
||||||
+
|
|
||||||
+ resets = <&gcc GMAC_CORE1_RESET>;
|
|
||||||
+ reset-names = "stmmaceth";
|
|
||||||
+ };
|
|
|
@ -9,27 +9,23 @@ Subject: [PATCH] stmac: platform: add support for retreiving mac from mtd
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||||
@@ -302,6 +302,7 @@ static int stmmac_pltfr_probe(struct pla
|
@@ -116,6 +116,19 @@ stmmac_probe_config_dt(struct platform_d
|
||||||
struct stmmac_priv *priv = NULL;
|
return ERR_PTR(-ENOMEM);
|
||||||
struct plat_stmmacenet_data *plat_dat = NULL;
|
|
||||||
const char *mac = NULL;
|
|
||||||
+ u8 mtd_mac[ETH_ALEN] = { };
|
|
||||||
int irq, wol_irq, lpi_irq;
|
|
||||||
|
|
||||||
/* Get IRQ information early to have an ability to ask for deferred
|
*mac = of_get_mac_address(np);
|
||||||
@@ -362,6 +363,15 @@ static int stmmac_pltfr_probe(struct pla
|
+ if (!*mac) {
|
||||||
pr_err("%s: main dt probe failed", __func__);
|
+ u8 mtd_mac[ETH_ALEN];
|
||||||
return ret;
|
+ int ret;
|
||||||
}
|
|
||||||
+
|
+
|
||||||
+ if (!mac) {
|
+ ret = of_get_mac_address_mtd(np, mtd_mac);
|
||||||
+ ret = of_get_mac_address_mtd(dev->of_node, &mtd_mac);
|
|
||||||
+ if (ret == -EPROBE_DEFER)
|
+ if (ret == -EPROBE_DEFER)
|
||||||
+ return ret;
|
+ return ERR_PTR(ret);
|
||||||
+
|
+
|
||||||
+ if (is_valid_ether_addr(&mtd_mac))
|
+ if (is_valid_ether_addr(mtd_mac))
|
||||||
+ mac = mtd_mac;
|
+ *mac = devm_kmemdup(&pdev->dev, mtd_mac, ETH_ALEN,
|
||||||
|
+ GFP_KERNEL);
|
||||||
+ }
|
+ }
|
||||||
}
|
+
|
||||||
|
plat->interface = of_get_phy_mode(np);
|
||||||
|
|
||||||
/* Custom setup (if needed) */
|
/* Get max speed of operation from device tree */
|
||||||
|
|
Loading…
Reference in New Issue