Commit 56431e38 authored by David S. Miller's avatar David S. Miller

Merge branch 'Qualcomm-ethqos'

Vinod Koul says:

====================
net: Add support for Qualcomm ethqos

Some Qualcomm SoCs sport a ethqos controller which use DW ip, so add
the glue driver which uses stmmac driver along with DT bindings for
this device.

This controller supports rgmii mode and doesn't work with existing
phy drivers as they do not remove the phy delay delay in this mode,
so fix the two phy drivers tested with this.

Changes in v3:
 - Add description in DT and rename the file and compatible as suggested by
   Rob
 - Update changelog for QCA8K driver
 - Update AT803x phy disable delay for all RGMxx modes

Changes in v2:
 - Fix the example in dt-binding
 - Remove DT property for disable the delay and disable delay for RGMII mode
   in AT803x and QCA8K PHY drivers
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d6228b7c 5ecdd77c
Qualcomm Ethernet ETHQOS device
This documents dwmmac based ethernet device which supports Gigabit
ethernet for version v2.3.0 onwards.
This device has following properties:
Required properties:
- compatible: Should be qcom,qcs404-ethqos"
- reg: Address and length of the register set for the device
- reg-names: Should contain register names "stmmaceth", "rgmii"
- clocks: Should contain phandle to clocks
- clock-names: Should contain clock names "stmmaceth", "pclk",
"ptp_ref", "rgmii"
- interrupts: Should contain phandle to interrupts
- interrupt-names: Should contain interrupt names "macirq", "eth_lpi"
Rest of the properties are defined in stmmac.txt file in same directory
Example:
ethernet: ethernet@7a80000 {
compatible = "qcom,qcs404-ethqos";
reg = <0x07a80000 0x10000>,
<0x07a96000 0x100>;
reg-names = "stmmaceth", "rgmii";
clock-names = "stmmaceth", "pclk", "ptp_ref", "rgmii";
clocks = <&gcc GCC_ETH_AXI_CLK>,
<&gcc GCC_ETH_SLAVE_AHB_CLK>,
<&gcc GCC_ETH_PTP_CLK>,
<&gcc GCC_ETH_RGMII_CLK>;
interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_lpi";
snps,reset-gpio = <&tlmm 60 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,txpbl = <8>;
snps,rxpbl = <2>;
snps,aal;
snps,tso;
phy-handle = <&phy1>;
phy-mode = "rgmii";
mdio {
#address-cells = <0x1>;
#size-cells = <0x0>;
compatible = "snps,dwmac-mdio";
phy1: phy@4 {
device_type = "ethernet-phy";
reg = <0x4>;
};
};
};
...@@ -12608,6 +12608,14 @@ L: netdev@vger.kernel.org ...@@ -12608,6 +12608,14 @@ L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: drivers/net/ethernet/qualcomm/emac/ F: drivers/net/ethernet/qualcomm/emac/
QUALCOMM ETHQOS ETHERNET DRIVER
M: Vinod Koul <vkoul@kernel.org>
M: Niklas Cassel <niklas.cassel@linaro.org>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
F: Documentation/devicetree/bindings/net/qcom,dwmac.txt
QUALCOMM GENERIC INTERFACE I2C DRIVER QUALCOMM GENERIC INTERFACE I2C DRIVER
M: Alok Chauhan <alokc@codeaurora.org> M: Alok Chauhan <alokc@codeaurora.org>
M: Karthikeyan Ramasubramanian <kramasub@codeaurora.org> M: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
......
...@@ -420,7 +420,7 @@ qca8k_mib_init(struct qca8k_priv *priv) ...@@ -420,7 +420,7 @@ qca8k_mib_init(struct qca8k_priv *priv)
static int static int
qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode) qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode)
{ {
u32 reg; u32 reg, val;
switch (port) { switch (port) {
case 0: case 0:
...@@ -439,17 +439,9 @@ qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode) ...@@ -439,17 +439,9 @@ qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode)
*/ */
switch (mode) { switch (mode) {
case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII:
qca8k_write(priv, reg, /* RGMII mode means no delay so don't enable the delay */
QCA8K_PORT_PAD_RGMII_EN | val = QCA8K_PORT_PAD_RGMII_EN;
QCA8K_PORT_PAD_RGMII_TX_DELAY(3) | qca8k_write(priv, reg, val);
QCA8K_PORT_PAD_RGMII_RX_DELAY(3));
/* According to the datasheet, RGMII delay is enabled through
* PORT5_PAD_CTRL for all ports, rather than individual port
* registers
*/
qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
break; break;
case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_SGMII:
qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
......
...@@ -105,6 +105,16 @@ config DWMAC_OXNAS ...@@ -105,6 +105,16 @@ config DWMAC_OXNAS
This selects the Oxford Semiconductor OXNASSoC glue layer support for This selects the Oxford Semiconductor OXNASSoC glue layer support for
the stmmac device driver. This driver is used for OX820. the stmmac device driver. This driver is used for OX820.
config DWMAC_QCOM_ETHQOS
tristate "Qualcomm ETHQOS support"
default ARCH_QCOM
depends on OF && (ARCH_QCOM || COMPILE_TEST)
help
Support for the Qualcomm ETHQOS core.
This selects the Qualcomm ETHQOS glue layer support for the
stmmac device driver.
config DWMAC_ROCKCHIP config DWMAC_ROCKCHIP
tristate "Rockchip dwmac support" tristate "Rockchip dwmac support"
default ARCH_ROCKCHIP default ARCH_ROCKCHIP
......
...@@ -16,6 +16,7 @@ obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o ...@@ -16,6 +16,7 @@ obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o
obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o
obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o
obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o
obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
......
This diff is collapsed.
...@@ -110,16 +110,16 @@ static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, ...@@ -110,16 +110,16 @@ static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
return phy_write(phydev, AT803X_DEBUG_DATA, val); return phy_write(phydev, AT803X_DEBUG_DATA, val);
} }
static inline int at803x_enable_rx_delay(struct phy_device *phydev) static inline int at803x_disable_rx_delay(struct phy_device *phydev)
{ {
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0, return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
AT803X_DEBUG_RX_CLK_DLY_EN); AT803X_DEBUG_RX_CLK_DLY_EN, 0);
} }
static inline int at803x_enable_tx_delay(struct phy_device *phydev) static inline int at803x_disable_tx_delay(struct phy_device *phydev)
{ {
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0, return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
AT803X_DEBUG_TX_CLK_DLY_EN); AT803X_DEBUG_TX_CLK_DLY_EN, 0);
} }
/* save relevant PHY registers to private copy */ /* save relevant PHY registers to private copy */
...@@ -256,15 +256,17 @@ static int at803x_config_init(struct phy_device *phydev) ...@@ -256,15 +256,17 @@ static int at803x_config_init(struct phy_device *phydev)
return ret; return ret;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID || if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
ret = at803x_enable_rx_delay(phydev); phydev->interface == PHY_INTERFACE_MODE_RGMII) {
ret = at803x_disable_rx_delay(phydev);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID || if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
ret = at803x_enable_tx_delay(phydev); phydev->interface == PHY_INTERFACE_MODE_RGMII) {
ret = at803x_disable_tx_delay(phydev);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
......
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