Commit 5befa5e8 authored by David S. Miller's avatar David S. Miller

Merge branch 'stmmac-IPQ806x'

Mathieu Olivari says:

====================
Add support for QCA IPQ806x Ethernet GMAC controller

This patch set adds support for the integrated Ethernet GMAC controller
on QCA IPQ806x SoC. This controller is based on a Gigabit Synopsys
DesignWare IP, already supported in the stmmac driver located in
drivers/net/ethernet/stmicro/stmmac.

This change is done as a follow-up to the following thread:
*http://www.spinics.net/lists/netdev/msg311265.html
While previous attempt was creating a new driver to drive this controller,
this new post leverages the existing stmmac driver by implementing the
SoC specific glue to it.

Aside from the pure stmmac glue layer, we have a couple of related
patches:
*IPQ806x NSS clock addition is cherry-picked and refreshed from the
 following thread: https://lkml.org/lkml/2014/8/6/390
*phy-handle and fixed-link support are also added in this change set so the
 driver can be fully functional on platforms using device-trees as well as
 ethernet switches.

V2:
 *Fix MODULE_LICENSE to "Dual BSD/GPL" as the dwmac-ipq806x.c is using
  ISC license.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a74eab63 95e130af
* 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";
};
This diff is collapsed.
...@@ -16,6 +16,7 @@ if STMMAC_ETH ...@@ -16,6 +16,7 @@ if STMMAC_ETH
config STMMAC_PLATFORM config STMMAC_PLATFORM
tristate "STMMAC Platform bus support" tristate "STMMAC Platform bus support"
depends on STMMAC_ETH depends on STMMAC_ETH
select MFD_SYSCON
default y default y
---help--- ---help---
This selects the platform specific bus support for the stmmac driver. This selects the platform specific bus support for the stmmac driver.
...@@ -36,6 +37,19 @@ config DWMAC_GENERIC ...@@ -36,6 +37,19 @@ config DWMAC_GENERIC
platform specific code to function or is using platform platform specific code to function or is using platform
data for setup. data for setup.
config DWMAC_IPQ806X
tristate "QCA IPQ806x DWMAC support"
default ARCH_QCOM
depends on OF
select MFD_SYSCON
help
Support for QCA IPQ806X DWMAC Ethernet.
This selects the IPQ806x SoC glue layer support for the stmmac
device driver. This driver does not use any of the hardware
acceleration features available on this SoC. Network devices
will behave like standard non-accelerated ethernet interfaces.
config DWMAC_LPC18XX config DWMAC_LPC18XX
tristate "NXP LPC18xx/43xx DWMAC support" tristate "NXP LPC18xx/43xx DWMAC support"
default ARCH_LPC18XX default ARCH_LPC18XX
......
...@@ -6,6 +6,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ ...@@ -6,6 +6,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
# Ordering matters. Generic driver must be last. # Ordering matters. Generic driver must be last.
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
obj-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o
obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o
obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o
obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
......
This diff is collapsed.
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "stmmac_ptp.h" #include "stmmac_ptp.h"
#include "stmmac.h" #include "stmmac.h"
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/of_mdio.h>
#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
...@@ -816,6 +817,10 @@ static int stmmac_init_phy(struct net_device *dev) ...@@ -816,6 +817,10 @@ static int stmmac_init_phy(struct net_device *dev)
priv->speed = 0; priv->speed = 0;
priv->oldduplex = -1; priv->oldduplex = -1;
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) if (priv->plat->phy_bus_name)
snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x", snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
priv->plat->phy_bus_name, priv->plat->bus_id); priv->plat->phy_bus_name, priv->plat->bus_id);
...@@ -825,9 +830,12 @@ static int stmmac_init_phy(struct net_device *dev) ...@@ -825,9 +830,12 @@ static int stmmac_init_phy(struct net_device *dev)
snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
priv->plat->phy_addr); priv->plat->phy_addr);
pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt); 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)) { if (IS_ERR(phydev)) {
pr_err("%s: Could not attach to PHY\n", dev->name); pr_err("%s: Could not attach to PHY\n", dev->name);
...@@ -848,7 +856,7 @@ static int stmmac_init_phy(struct net_device *dev) ...@@ -848,7 +856,7 @@ static int stmmac_init_phy(struct net_device *dev)
* device as well. * device as well.
* Note: phydev->phy_id is the result of reading the UID PHY registers. * 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); phy_disconnect(phydev);
return -ENODEV; return -ENODEV;
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_mdio.h>
#include "stmmac.h" #include "stmmac.h"
#include "stmmac_platform.h" #include "stmmac_platform.h"
...@@ -144,13 +145,24 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, ...@@ -144,13 +145,24 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
/* Default to phy auto-detection */ /* Default to phy auto-detection */
plat->phy_addr = -1; 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);
/* 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 /* "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. * 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) if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); 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; plat->mdio_bus_data = NULL;
else else
plat->mdio_bus_data = plat->mdio_bus_data =
...@@ -208,8 +220,10 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, ...@@ -208,8 +220,10 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
if (of_find_property(np, "snps,pbl", NULL)) { if (of_find_property(np, "snps,pbl", NULL)) {
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
GFP_KERNEL); GFP_KERNEL);
if (!dma_cfg) if (!dma_cfg) {
of_node_put(np);
return -ENOMEM; return -ENOMEM;
}
plat->dma_cfg = dma_cfg; plat->dma_cfg = dma_cfg;
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
dma_cfg->fixed_burst = dma_cfg->fixed_burst =
......
...@@ -289,5 +289,7 @@ ...@@ -289,5 +289,7 @@
#define UBI32_CORE1_CLK 279 #define UBI32_CORE1_CLK 279
#define UBI32_CORE2_CLK 280 #define UBI32_CORE2_CLK 280
#define EBI2_AON_CLK 281 #define EBI2_AON_CLK 281
#define NSSTCM_CLK_SRC 282
#define NSSTCM_CLK 283
#endif #endif
...@@ -129,4 +129,47 @@ ...@@ -129,4 +129,47 @@
#define USB30_1_PHY_RESET 112 #define USB30_1_PHY_RESET 112
#define NSSFB0_RESET 113 #define NSSFB0_RESET 113
#define NSSFB1_RESET 114 #define NSSFB1_RESET 114
#define UBI32_CORE1_CLKRST_CLAMP_RESET 115
#define UBI32_CORE1_CLAMP_RESET 116
#define UBI32_CORE1_AHB_RESET 117
#define UBI32_CORE1_AXI_RESET 118
#define UBI32_CORE2_CLKRST_CLAMP_RESET 119
#define UBI32_CORE2_CLAMP_RESET 120
#define UBI32_CORE2_AHB_RESET 121
#define UBI32_CORE2_AXI_RESET 122
#define GMAC_CORE1_RESET 123
#define GMAC_CORE2_RESET 124
#define GMAC_CORE3_RESET 125
#define GMAC_CORE4_RESET 126
#define GMAC_AHB_RESET 127
#define NSS_CH0_RST_RX_CLK_N_RESET 128
#define NSS_CH0_RST_TX_CLK_N_RESET 129
#define NSS_CH0_RST_RX_125M_N_RESET 130
#define NSS_CH0_HW_RST_RX_125M_N_RESET 131
#define NSS_CH0_RST_TX_125M_N_RESET 132
#define NSS_CH1_RST_RX_CLK_N_RESET 133
#define NSS_CH1_RST_TX_CLK_N_RESET 134
#define NSS_CH1_RST_RX_125M_N_RESET 135
#define NSS_CH1_HW_RST_RX_125M_N_RESET 136
#define NSS_CH1_RST_TX_125M_N_RESET 137
#define NSS_CH2_RST_RX_CLK_N_RESET 138
#define NSS_CH2_RST_TX_CLK_N_RESET 139
#define NSS_CH2_RST_RX_125M_N_RESET 140
#define NSS_CH2_HW_RST_RX_125M_N_RESET 141
#define NSS_CH2_RST_TX_125M_N_RESET 142
#define NSS_CH3_RST_RX_CLK_N_RESET 143
#define NSS_CH3_RST_TX_CLK_N_RESET 144
#define NSS_CH3_RST_RX_125M_N_RESET 145
#define NSS_CH3_HW_RST_RX_125M_N_RESET 146
#define NSS_CH3_RST_TX_125M_N_RESET 147
#define NSS_RST_RX_250M_125M_N_RESET 148
#define NSS_RST_TX_250M_125M_N_RESET 149
#define NSS_QSGMII_TXPI_RST_N_RESET 150
#define NSS_QSGMII_CDR_RST_N_RESET 151
#define NSS_SGMII2_CDR_RST_N_RESET 152
#define NSS_SGMII3_CDR_RST_N_RESET 153
#define NSS_CAL_PRBS_RST_N_RESET 154
#define NSS_LCKDT_RST_N_RESET 155
#define NSS_SRDS_N_RESET 156
#endif #endif
...@@ -99,6 +99,7 @@ struct plat_stmmacenet_data { ...@@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
int phy_addr; int phy_addr;
int interface; int interface;
struct stmmac_mdio_bus_data *mdio_bus_data; struct stmmac_mdio_bus_data *mdio_bus_data;
struct device_node *phy_node;
struct stmmac_dma_cfg *dma_cfg; struct stmmac_dma_cfg *dma_cfg;
int clk_csr; int clk_csr;
int has_gmac; int has_gmac;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment