[PATCHv4 1/3] net: ethernet: mediatek: support MT7621 SoC ethernet hardware

2019-01-29 Thread gerg
From: Bjørn Mork 

The Mediatek MT7621 SoC contains the same ethernet hardware module as
used on a number of other MediaTek SoC parts. There are some minor
differences to deal with but we can use the same driver to support
them all.

This patch is based on work by Bjørn Mork , and his
original patch is at:

https://github.com/bmork/LEDE/commit/3293bc63f5461ca1eb0bbc4ed90145335e7e3404

There is an additional compatible devicetree type added, and the primary
change to the code required is to support a single interrupt (for both
RX and TX interrupts).

Signed-off-by: Bjørn Mork 
[g...@kernel.org: rebase to mainline and irq handler fix]
Signed-off-by: Greg Ungerer 
---
 drivers/net/ethernet/mediatek/Kconfig   |  2 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 48 ++---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  4 ++
 3 files changed, 46 insertions(+), 8 deletions(-)

v2: first in series for this change
v3: rebase onto 5.0-rc3
v4: rebase onto 5.0-rc4

diff --git a/drivers/net/ethernet/mediatek/Kconfig 
b/drivers/net/ethernet/mediatek/Kconfig
index f9149d2a4694..43656f961891 100644
--- a/drivers/net/ethernet/mediatek/Kconfig
+++ b/drivers/net/ethernet/mediatek/Kconfig
@@ -1,6 +1,6 @@
 config NET_VENDOR_MEDIATEK
bool "MediaTek ethernet driver"
-   depends on ARCH_MEDIATEK
+   depends on ARCH_MEDIATEK || SOC_MT7621
---help---
  If you have a Mediatek SoC with ethernet, say Y.
 
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c 
b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 49f926b7a91c..94d4663e3933 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1745,6 +1745,22 @@ static irqreturn_t mtk_handle_irq_tx(int irq, void *_eth)
return IRQ_HANDLED;
 }
 
+static irqreturn_t mtk_handle_irq(int irq, void *_eth)
+{
+   struct mtk_eth *eth = _eth;
+
+   if (mtk_r32(eth, MTK_PDMA_INT_MASK) & MTK_RX_DONE_INT) {
+   if (mtk_r32(eth, MTK_PDMA_INT_STATUS) & MTK_RX_DONE_INT)
+   mtk_handle_irq_rx(irq, _eth);
+   }
+   if (mtk_r32(eth, MTK_QDMA_INT_MASK) & MTK_TX_DONE_INT) {
+   if (mtk_r32(eth, MTK_QMTK_INT_STATUS) & MTK_TX_DONE_INT)
+   mtk_handle_irq_tx(irq, _eth);
+   }
+
+   return IRQ_HANDLED;
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void mtk_poll_controller(struct net_device *dev)
 {
@@ -2485,7 +2501,10 @@ static int mtk_probe(struct platform_device *pdev)
}
 
for (i = 0; i < 3; i++) {
-   eth->irq[i] = platform_get_irq(pdev, i);
+   if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
+   eth->irq[i] = eth->irq[0];
+   else
+   eth->irq[i] = platform_get_irq(pdev, i);
if (eth->irq[i] < 0) {
dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
return -ENXIO;
@@ -2528,13 +2547,21 @@ static int mtk_probe(struct platform_device *pdev)
goto err_deinit_hw;
}
 
-   err = devm_request_irq(eth->dev, eth->irq[1], mtk_handle_irq_tx, 0,
-  dev_name(eth->dev), eth);
-   if (err)
-   goto err_free_dev;
+   if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
+   err = devm_request_irq(eth->dev, eth->irq[0],
+  mtk_handle_irq, 0,
+  dev_name(eth->dev), eth);
+   } else {
+   err = devm_request_irq(eth->dev, eth->irq[1],
+  mtk_handle_irq_tx, 0,
+  dev_name(eth->dev), eth);
+   if (err)
+   goto err_free_dev;
 
-   err = devm_request_irq(eth->dev, eth->irq[2], mtk_handle_irq_rx, 0,
-  dev_name(eth->dev), eth);
+   err = devm_request_irq(eth->dev, eth->irq[2],
+  mtk_handle_irq_rx, 0,
+  dev_name(eth->dev), eth);
+   }
if (err)
goto err_free_dev;
 
@@ -2607,6 +2634,12 @@ static const struct mtk_soc_data mt2701_data = {
.required_pctl = true,
 };
 
+static const struct mtk_soc_data mt7621_data = {
+   .caps = MTK_SHARED_INT,
+   .required_clks = MT7621_CLKS_BITMAP,
+   .required_pctl = false,
+};
+
 static const struct mtk_soc_data mt7622_data = {
.caps = MTK_DUAL_GMAC_SHARED_SGMII | MTK_GMAC1_ESW | MTK_HWLRO,
.required_clks = MT7622_CLKS_BITMAP,
@@ -2621,6 +2654,7 @@ static const struct mtk_soc_data mt7623_data = {
 
 const struct of_device_id of_mtk_match[] = {
{ .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
+   { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
{ .compatible 

[PATCHv4 2/3] net: dsa: mt7530: support the 7530 switch on the Mediatek MT7621 SoC

2019-01-29 Thread gerg
From: Greg Ungerer 

The MediaTek MT7621 SoC device contains a 7530 switch, and the existing
linux kernel 7530 DSA switch driver can be used with it.

The bulk of the changes required stem from the 7621 having different
regulator and pad setup. The existing setup of these in the 7530
driver appears to be very specific to its implemtation in the Mediatek
7623 SoC. (Not entirely surprising given the 7623 is a quad core ARM
based SoC, and the 7621 is a dual core, dual thread MIPS based SoC).

Create a new devicetree type, "mediatek,mt7621", to support the 7530
switch in the 7621 SoC. There appears to be no usable ID register to
distinguish it from a 7530 in other hardware at runtime. This is used
to carry out the appropriate configuration and setup.

Signed-off-by: Greg Ungerer 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/mt7530.c | 96 
 drivers/net/dsa/mt7530.h |  9 
 2 files changed, 66 insertions(+), 39 deletions(-)

v1: initial patch
v2: use separate devicetree binding  
v3: rebase onto 5.0-rc3
v4: simplify by using of_device_get_match_data()
fix casting for 7530/7621 ID to be 32 and 64 bit clean
rebase onto 5.0-rc4

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index a8a2c728afba..c2b61500f958 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -621,17 +621,19 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int 
port,
struct mt7530_priv *priv = ds->priv;
 
if (phy_is_pseudo_fixed_link(phydev)) {
-   dev_dbg(priv->dev, "phy-mode for master device = %x\n",
-   phydev->interface);
-
-   /* Setup TX circuit incluing relevant PAD and driving */
-   mt7530_pad_clk_setup(ds, phydev->interface);
-
-   /* Setup RX circuit, relevant PAD and driving on the host
-* which must be placed after the setup on the device side is
-* all finished.
-*/
-   mt7623_pad_clk_setup(ds);
+   if (priv->id == ID_MT7530) {
+   dev_dbg(priv->dev, "phy-mode for master device = %x\n",
+   phydev->interface);
+
+   /* Setup TX circuit incluing relevant PAD and driving */
+   mt7530_pad_clk_setup(ds, phydev->interface);
+
+   /* Setup RX circuit, relevant PAD and driving on the
+* host which must be placed after the setup on the
+* device side is all finished.
+*/
+   mt7623_pad_clk_setup(ds);
+   }
} else {
u16 lcl_adv = 0, rmt_adv = 0;
u8 flowctrl;
@@ -687,6 +689,10 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
/* Unknown unicast frame fordwarding to the cpu port */
mt7530_set(priv, MT7530_MFC, UNU_FFP(BIT(port)));
 
+   /* Set CPU port number */
+   if (priv->id == ID_MT7621)
+   mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
+
/* CPU port gets connected to all user ports of
 * the switch
 */
@@ -1219,24 +1225,27 @@ mt7530_setup(struct dsa_switch *ds)
 * as two netdev instances.
 */
dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent;
-   priv->ethernet = syscon_node_to_regmap(dn);
-   if (IS_ERR(priv->ethernet))
-   return PTR_ERR(priv->ethernet);
 
-   regulator_set_voltage(priv->core_pwr, 100, 100);
-   ret = regulator_enable(priv->core_pwr);
-   if (ret < 0) {
-   dev_err(priv->dev,
-   "Failed to enable core power: %d\n", ret);
-   return ret;
-   }
+   if (priv->id == ID_MT7530) {
+   priv->ethernet = syscon_node_to_regmap(dn);
+   if (IS_ERR(priv->ethernet))
+   return PTR_ERR(priv->ethernet);
+
+   regulator_set_voltage(priv->core_pwr, 100, 100);
+   ret = regulator_enable(priv->core_pwr);
+   if (ret < 0) {
+   dev_err(priv->dev,
+   "Failed to enable core power: %d\n", ret);
+   return ret;
+   }
 
-   regulator_set_voltage(priv->io_pwr, 330, 330);
-   ret = regulator_enable(priv->io_pwr);
-   if (ret < 0) {
-   dev_err(priv->dev, "Failed to enable io pwr: %d\n",
-   ret);
-   return ret;
+   regulator_set_voltage(priv->io_pwr, 330, 330);
+   ret = regulator_enable(priv->io_pwr);
+   if (ret < 0) {
+   dev_err(priv->dev, "Failed to enable io pwr: %d\n",
+   ret);
+   return ret;
+   }
}
 
/* Reset whole chip through gpio pin or memory-mapped registers for

[PATCHv4 3/3] dt-bindings: net: dsa: add new MT7530 binding to support MT7621

2019-01-29 Thread gerg
From: Greg Ungerer 

Add devicetree binding to support the compatible mt7530 switch as used
in the MediaTek MT7621 SoC.

Signed-off-by: Greg Ungerer 
Reviewed-by: Andrew Lunn 
---
 Documentation/devicetree/bindings/net/dsa/mt7530.txt | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

v1: initial patch
v2: use separate devicetree binding
v3: change text according to feedback, rebase onto 5.0-rc3
v4: rebase onto 5.0-rc4

diff --git a/Documentation/devicetree/bindings/net/dsa/mt7530.txt 
b/Documentation/devicetree/bindings/net/dsa/mt7530.txt
index aa3527f71fdc..47aa205ee0bd 100644
--- a/Documentation/devicetree/bindings/net/dsa/mt7530.txt
+++ b/Documentation/devicetree/bindings/net/dsa/mt7530.txt
@@ -3,12 +3,16 @@ Mediatek MT7530 Ethernet switch
 
 Required properties:
 
-- compatible: Must be compatible = "mediatek,mt7530";
+- compatible: may be compatible = "mediatek,mt7530"
+   or compatible = "mediatek,mt7621"
 - #address-cells: Must be 1.
 - #size-cells: Must be 0.
 - mediatek,mcm: Boolean; if defined, indicates that either MT7530 is the part
on multi-chip module belong to MT7623A has or the remotely standalone
chip as the function MT7623N reference board provided for.
+
+If compatible mediatek,mt7530 is set then the following properties are required
+
 - core-supply: Phandle to the regulator node necessary for the core power.
 - io-supply: Phandle to the regulator node necessary for the I/O power.
See Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
-- 
2.17.1



[PATCHv4 0/3]: net: dsa: mt7530: support MT7530 in the MT7621 SoC

2019-01-29 Thread gerg


This is the fourth version of a patch series supporting the MT7530 switch
as used in the MediaTek MT7621 SoC. Unlike the MediaTek MT7623 the MT7621
is built around a dual core MIPS CPU architecture. But inside it uses
basically the same 7530 switch.

This series resolves all issues I had with previous versions, and I can
now reliably use the driver on a 7621 SoC platform. These patches were
generated against linux-5.0-rc4.

The first patch enables support for the existing kernel mediatek ethernet
driver on the MT7621 SoC. This support is from Bjørn Mork, with an update
and fix by me. Using this driver fixed a number of problems I had
(TX checksums, large RX packet drop) over the staging driver
(drivers/staging/mt7621-eth).

Patch 2 modifies the mt7530 DSA driver to support the 7530 switch as
implemented in the Mediatek MT7621 SoC. The last patch updates the
devicetree bindings to reflect the new support in the mt7530 driver.

There is no real dependencies between the patches, so they can be taken
independantly.

Creating a new binding for the MT7621 seems like the only viable approach
to distinguish between a stand alone 7530 switch, the silicon module
in the MT7623 SoC and the silicon in the MT7621. Certainly the 7530 ID
register in the MT7623 and MT7621 returns the same value, "0x7530001".

Looking at the mt7530.c DSA driver it might make some sense to convert
the existing "mediatek,mcm" binding to something like "mediatek,mt7623"
to be consistent with this new MT7621 support. As far as I can tell
this is the intention of this binding.

 Documentation/devicetree/bindings/net/dsa/mt7530.txt |6 -
 drivers/net/dsa/mt7530.c |   96 +++
 drivers/net/dsa/mt7530.h |9 +
 drivers/net/ethernet/mediatek/Kconfig|2 
 drivers/net/ethernet/mediatek/mtk_eth_soc.c  |   48 -
 drivers/net/ethernet/mediatek/mtk_eth_soc.h  |4 
 6 files changed, 117 insertions(+), 48 deletions(-)

v1: initial patch series
v2: rebase to linux-5.0-rc2
include mediatek ethernet driver changes
use devicetree binding to identify platform
v3: dropped mediatek ethernet driver auto negotiate patch
change devicetree binding text as per feedback
rebase onto 5.0-rc3
v4: simplify by using of_device_get_match_data()
fix casting for 7530/7621 ID to be 32 and 64 bit clean
add review-by tag
rebase onto 5.0-rc4




[PATCHv3 2/3] net: dsa: mt7530: support the 7530 switch on the Mediatek MT7621 SoC

2019-01-20 Thread gerg
From: Greg Ungerer 

The MediaTek MT7621 SoC device contains a 7530 switch, and the existing
linux kernel 7530 DSA switch driver can be used with it.

The bulk of the changes required stem from the 7621 having different
regulator and pad setup. The existing setup of these in the 7530
driver appears to be very specific to its implemtation in the Mediatek
7623 SoC. (Not entirely surprising given the 7623 is a quad core ARM
based SoC, and the 7621 is a dual core, dual thread MIPS based SoC).

Create a new devicetree type, "mediatek,mt7621", to support the 7530
switch in the 7621 SoC. There appears to be no usable ID register to
distinguish it from a 7530 in other hardware at runtime. This is used
to carry out the appropriate configuration and setup.

Signed-off-by: Greg Ungerer 
---
 drivers/net/dsa/mt7530.c | 97 
 drivers/net/dsa/mt7530.h |  9 
 2 files changed, 67 insertions(+), 39 deletions(-)

v1: initial patch
v2: use separate devicetree binding  
v3: rebase onto 5.0-rc3

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index a8a2c728afba..350ce4c4fd52 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -621,17 +621,19 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int 
port,
struct mt7530_priv *priv = ds->priv;
 
if (phy_is_pseudo_fixed_link(phydev)) {
-   dev_dbg(priv->dev, "phy-mode for master device = %x\n",
-   phydev->interface);
-
-   /* Setup TX circuit incluing relevant PAD and driving */
-   mt7530_pad_clk_setup(ds, phydev->interface);
-
-   /* Setup RX circuit, relevant PAD and driving on the host
-* which must be placed after the setup on the device side is
-* all finished.
-*/
-   mt7623_pad_clk_setup(ds);
+   if (priv->id == ID_MT7530) {
+   dev_dbg(priv->dev, "phy-mode for master device = %x\n",
+   phydev->interface);
+
+   /* Setup TX circuit incluing relevant PAD and driving */
+   mt7530_pad_clk_setup(ds, phydev->interface);
+
+   /* Setup RX circuit, relevant PAD and driving on the
+* host which must be placed after the setup on the
+* device side is all finished.
+*/
+   mt7623_pad_clk_setup(ds);
+   }
} else {
u16 lcl_adv = 0, rmt_adv = 0;
u8 flowctrl;
@@ -687,6 +689,10 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
/* Unknown unicast frame fordwarding to the cpu port */
mt7530_set(priv, MT7530_MFC, UNU_FFP(BIT(port)));
 
+   /* Set CPU port number */
+   if (priv->id == ID_MT7621)
+   mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
+
/* CPU port gets connected to all user ports of
 * the switch
 */
@@ -1219,24 +1225,27 @@ mt7530_setup(struct dsa_switch *ds)
 * as two netdev instances.
 */
dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent;
-   priv->ethernet = syscon_node_to_regmap(dn);
-   if (IS_ERR(priv->ethernet))
-   return PTR_ERR(priv->ethernet);
 
-   regulator_set_voltage(priv->core_pwr, 100, 100);
-   ret = regulator_enable(priv->core_pwr);
-   if (ret < 0) {
-   dev_err(priv->dev,
-   "Failed to enable core power: %d\n", ret);
-   return ret;
-   }
+   if (priv->id == ID_MT7530) {
+   priv->ethernet = syscon_node_to_regmap(dn);
+   if (IS_ERR(priv->ethernet))
+   return PTR_ERR(priv->ethernet);
+
+   regulator_set_voltage(priv->core_pwr, 100, 100);
+   ret = regulator_enable(priv->core_pwr);
+   if (ret < 0) {
+   dev_err(priv->dev,
+   "Failed to enable core power: %d\n", ret);
+   return ret;
+   }
 
-   regulator_set_voltage(priv->io_pwr, 330, 330);
-   ret = regulator_enable(priv->io_pwr);
-   if (ret < 0) {
-   dev_err(priv->dev, "Failed to enable io pwr: %d\n",
-   ret);
-   return ret;
+   regulator_set_voltage(priv->io_pwr, 330, 330);
+   ret = regulator_enable(priv->io_pwr);
+   if (ret < 0) {
+   dev_err(priv->dev, "Failed to enable io pwr: %d\n",
+   ret);
+   return ret;
+   }
}
 
/* Reset whole chip through gpio pin or memory-mapped registers for
@@ -1326,9 +1335,17 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.port_vlan_del  = mt7530_port_vlan_del,
 };
 
+static const st

[PATCHv3 1/3] net: ethernet: mediatek: support MT7621 SoC ethernet hardware

2019-01-20 Thread gerg
From: Bjørn Mork 

The Mediatek MT7621 SoC contains the same ethernet hardware module as
used on a number of other MediaTek SoC parts. There are some minor
differences to deal with but we can use the same driver to support
them all.

This patch is based on work by Bjørn Mork , and his
original patch is at:

https://github.com/bmork/LEDE/commit/3293bc63f5461ca1eb0bbc4ed90145335e7e3404

There is an additional compatible devicetree type added, and the primary
change to the code required is to support a single interrupt (for both
RX and TX interrupts).

Signed-off-by: Bjørn Mork 
[g...@kernel.org: rebase to mainline and irq handler fix]
Signed-off-by: Greg Ungerer 
---
 drivers/net/ethernet/mediatek/Kconfig   |  2 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 48 ++---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  4 ++
 3 files changed, 46 insertions(+), 8 deletions(-)

v2: first in series for this change
v3: rebase onto 5.0-rc3

diff --git a/drivers/net/ethernet/mediatek/Kconfig 
b/drivers/net/ethernet/mediatek/Kconfig
index f9149d2a4694..43656f961891 100644
--- a/drivers/net/ethernet/mediatek/Kconfig
+++ b/drivers/net/ethernet/mediatek/Kconfig
@@ -1,6 +1,6 @@
 config NET_VENDOR_MEDIATEK
bool "MediaTek ethernet driver"
-   depends on ARCH_MEDIATEK
+   depends on ARCH_MEDIATEK || SOC_MT7621
---help---
  If you have a Mediatek SoC with ethernet, say Y.
 
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c 
b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 49f926b7a91c..94d4663e3933 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1745,6 +1745,22 @@ static irqreturn_t mtk_handle_irq_tx(int irq, void *_eth)
return IRQ_HANDLED;
 }
 
+static irqreturn_t mtk_handle_irq(int irq, void *_eth)
+{
+   struct mtk_eth *eth = _eth;
+
+   if (mtk_r32(eth, MTK_PDMA_INT_MASK) & MTK_RX_DONE_INT) {
+   if (mtk_r32(eth, MTK_PDMA_INT_STATUS) & MTK_RX_DONE_INT)
+   mtk_handle_irq_rx(irq, _eth);
+   }
+   if (mtk_r32(eth, MTK_QDMA_INT_MASK) & MTK_TX_DONE_INT) {
+   if (mtk_r32(eth, MTK_QMTK_INT_STATUS) & MTK_TX_DONE_INT)
+   mtk_handle_irq_tx(irq, _eth);
+   }
+
+   return IRQ_HANDLED;
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void mtk_poll_controller(struct net_device *dev)
 {
@@ -2485,7 +2501,10 @@ static int mtk_probe(struct platform_device *pdev)
}
 
for (i = 0; i < 3; i++) {
-   eth->irq[i] = platform_get_irq(pdev, i);
+   if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
+   eth->irq[i] = eth->irq[0];
+   else
+   eth->irq[i] = platform_get_irq(pdev, i);
if (eth->irq[i] < 0) {
dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
return -ENXIO;
@@ -2528,13 +2547,21 @@ static int mtk_probe(struct platform_device *pdev)
goto err_deinit_hw;
}
 
-   err = devm_request_irq(eth->dev, eth->irq[1], mtk_handle_irq_tx, 0,
-  dev_name(eth->dev), eth);
-   if (err)
-   goto err_free_dev;
+   if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
+   err = devm_request_irq(eth->dev, eth->irq[0],
+  mtk_handle_irq, 0,
+  dev_name(eth->dev), eth);
+   } else {
+   err = devm_request_irq(eth->dev, eth->irq[1],
+  mtk_handle_irq_tx, 0,
+  dev_name(eth->dev), eth);
+   if (err)
+   goto err_free_dev;
 
-   err = devm_request_irq(eth->dev, eth->irq[2], mtk_handle_irq_rx, 0,
-  dev_name(eth->dev), eth);
+   err = devm_request_irq(eth->dev, eth->irq[2],
+  mtk_handle_irq_rx, 0,
+  dev_name(eth->dev), eth);
+   }
if (err)
goto err_free_dev;
 
@@ -2607,6 +2634,12 @@ static const struct mtk_soc_data mt2701_data = {
.required_pctl = true,
 };
 
+static const struct mtk_soc_data mt7621_data = {
+   .caps = MTK_SHARED_INT,
+   .required_clks = MT7621_CLKS_BITMAP,
+   .required_pctl = false,
+};
+
 static const struct mtk_soc_data mt7622_data = {
.caps = MTK_DUAL_GMAC_SHARED_SGMII | MTK_GMAC1_ESW | MTK_HWLRO,
.required_clks = MT7622_CLKS_BITMAP,
@@ -2621,6 +2654,7 @@ static const struct mtk_soc_data mt7623_data = {
 
 const struct of_device_id of_mtk_match[] = {
{ .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
+   { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
{ .compatible = "mediatek,mt7623-eth",

[PATCHv3 3/3] dt-bindings: net: dsa: add new MT7530 binding to support MT7621

2019-01-20 Thread gerg
From: Greg Ungerer 

Add devicetree binding to support the compatible mt7530 switch as used
in the MediaTek MT7621 SoC.

Signed-off-by: Greg Ungerer 
---
 Documentation/devicetree/bindings/net/dsa/mt7530.txt | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

v1: initial patch
v2: use separate devicetree binding
v3: change text according to feedback, rebase onto 5.0-rc3

diff --git a/Documentation/devicetree/bindings/net/dsa/mt7530.txt 
b/Documentation/devicetree/bindings/net/dsa/mt7530.txt
index aa3527f71fdc..47aa205ee0bd 100644
--- a/Documentation/devicetree/bindings/net/dsa/mt7530.txt
+++ b/Documentation/devicetree/bindings/net/dsa/mt7530.txt
@@ -3,12 +3,16 @@ Mediatek MT7530 Ethernet switch
 
 Required properties:
 
-- compatible: Must be compatible = "mediatek,mt7530";
+- compatible: may be compatible = "mediatek,mt7530"
+   or compatible = "mediatek,mt7621"
 - #address-cells: Must be 1.
 - #size-cells: Must be 0.
 - mediatek,mcm: Boolean; if defined, indicates that either MT7530 is the part
on multi-chip module belong to MT7623A has or the remotely standalone
chip as the function MT7623N reference board provided for.
+
+If compatible mediatek,mt7530 is set then the following properties are required
+
 - core-supply: Phandle to the regulator node necessary for the core power.
 - io-supply: Phandle to the regulator node necessary for the I/O power.
See Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
-- 
2.17.1



[PATCHv3 0/3]: net: support MT7530 switch in the MT7621 SoC

2019-01-20 Thread gerg


This is the third version of a patch series supporting the MT7530 switch
as used in the MediaTek MT7621 SoC. Unlike the MediaTek MT7623 the MT7621
is built around a dual core MIPS CPU architecture. But inside it uses
basically the same 7530 switch.

This series resolves all issues I had with previous versions, and I can
now reliably use the driver on a 7621 SoC platform. These patches were
generated against linux-5.0-rc3.

The first patch enables support for the existing kernel mediatek ethernet
driver on the MT7621 SoC. This support is from Bjørn Mork, with an update
and fix by me. Using this driver fixed a number of problems I had
(TX checksums, large RX packet drop) over the staging driver
(drivers/staging/mt7621-eth).

Patch 2 modifies the mt7530 DSA driver to support the 7530 switch as
implemented in the Mediatek MT7621 SoC. The last patch updates the
devicetree bindings to reflect the new support in the mt7530 driver.

There is no real dependencies between the patches, so they can be taken
independantly.

Creating a new binding for the MT7621 seems like the only viable approach
to distinguish between a stand alone 7530 switch, the silicon module
in the MT7623 SoC and the silicon in the MT7621. Certainly the 7530 ID
register in the MT7623 and MT7621 returns the same value, "0x7530001".

Looking at the mt7530.c DSA driver it might make some sense to convert
the existing "mediatek,mcm" binding to something like "mediatek,mt7623"
to be consistent with this new MT7621 support. As far as I can tell
this is the intention of this binding.

 Documentation/devicetree/bindings/net/dsa/mt7530.txt |6 -
 drivers/net/dsa/mt7530.c |   97 +++
 drivers/net/dsa/mt7530.h |9 +
 drivers/net/ethernet/mediatek/Kconfig|2 
 drivers/net/ethernet/mediatek/mtk_eth_soc.c  |   48 -
 drivers/net/ethernet/mediatek/mtk_eth_soc.h  |4 
 6 files changed, 118 insertions(+), 48 deletions(-)

v1: initial patch series
v2: rebase to linux-5.0-rc2
include mediatek ethernet driver changes
use devicetree binding to identify platform
v3: dropped mediatek ethernet driver auto negotiate patch
change devicetree binding text as per feedback
rebase onto 5.0-rc3




[PATCHv2 3/4] net: dsa: mt7530: support the 7530 switch on the Mediatek MT7621 SoC

2019-01-13 Thread gerg
From: Greg Ungerer 

The MediaTek MT7621 SoC device contains a 7530 switch, and the existing
linux kernel 7530 DSA switch driver can be used with it.

The bulk of the changes required stem from the 7621 having different
regulator and pad setup. The existing setup of these in the 7530
driver appears to be very specific to its implemtation in the Mediatek
7623 SoC. (Not entirely surprising given the 7623 is a quad core ARM
based SoC, and the 7621 is a dual core, dual thread MIPS based SoC).

Create a new devicetree type, "mediatek,mt7621", to support the 7530
switch in the 7621 SoC. There appears to be no usable ID register to
distinguish it from a 7530 in other hardware at runtime. This is used
to carry out the appropriate configuration and setup.

Signed-off-by: Greg Ungerer 
---
 drivers/net/dsa/mt7530.c | 97 
 drivers/net/dsa/mt7530.h |  9 
 2 files changed, 67 insertions(+), 39 deletions(-)

v1: initial patch
v2: changed to use separate devicetree binding

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 74547f43b938..c396665e576c 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -622,17 +622,19 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int 
port,
struct mt7530_priv *priv = ds->priv;
 
if (phy_is_pseudo_fixed_link(phydev)) {
-   dev_dbg(priv->dev, "phy-mode for master device = %x\n",
-   phydev->interface);
-
-   /* Setup TX circuit incluing relevant PAD and driving */
-   mt7530_pad_clk_setup(ds, phydev->interface);
-
-   /* Setup RX circuit, relevant PAD and driving on the host
-* which must be placed after the setup on the device side is
-* all finished.
-*/
-   mt7623_pad_clk_setup(ds);
+   if (priv->id == ID_MT7530) {
+   dev_dbg(priv->dev, "phy-mode for master device = %x\n",
+   phydev->interface);
+
+   /* Setup TX circuit incluing relevant PAD and driving */
+   mt7530_pad_clk_setup(ds, phydev->interface);
+
+   /* Setup RX circuit, relevant PAD and driving on the
+* host which must be placed after the setup on the
+* device side is all finished.
+*/
+   mt7623_pad_clk_setup(ds);
+   }
} else {
u16 lcl_adv = 0, rmt_adv = 0;
u8 flowctrl;
@@ -688,6 +690,10 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
/* Unknown unicast frame fordwarding to the cpu port */
mt7530_set(priv, MT7530_MFC, UNU_FFP(BIT(port)));
 
+   /* Set CPU port number */
+   if (priv->id == ID_MT7621)
+   mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
+
/* CPU port gets connected to all user ports of
 * the switch
 */
@@ -1220,24 +1226,27 @@ mt7530_setup(struct dsa_switch *ds)
 * as two netdev instances.
 */
dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent;
-   priv->ethernet = syscon_node_to_regmap(dn);
-   if (IS_ERR(priv->ethernet))
-   return PTR_ERR(priv->ethernet);
 
-   regulator_set_voltage(priv->core_pwr, 100, 100);
-   ret = regulator_enable(priv->core_pwr);
-   if (ret < 0) {
-   dev_err(priv->dev,
-   "Failed to enable core power: %d\n", ret);
-   return ret;
-   }
+   if (priv->id == ID_MT7530) {
+   priv->ethernet = syscon_node_to_regmap(dn);
+   if (IS_ERR(priv->ethernet))
+   return PTR_ERR(priv->ethernet);
+
+   regulator_set_voltage(priv->core_pwr, 100, 100);
+   ret = regulator_enable(priv->core_pwr);
+   if (ret < 0) {
+   dev_err(priv->dev,
+   "Failed to enable core power: %d\n", ret);
+   return ret;
+   }
 
-   regulator_set_voltage(priv->io_pwr, 330, 330);
-   ret = regulator_enable(priv->io_pwr);
-   if (ret < 0) {
-   dev_err(priv->dev, "Failed to enable io pwr: %d\n",
-   ret);
-   return ret;
+   regulator_set_voltage(priv->io_pwr, 330, 330);
+   ret = regulator_enable(priv->io_pwr);
+   if (ret < 0) {
+   dev_err(priv->dev, "Failed to enable io pwr: %d\n",
+   ret);
+   return ret;
+   }
}
 
/* Reset whole chip through gpio pin or memory-mapped registers for
@@ -1327,9 +1336,17 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.port_vlan_del  = mt7530_port_vlan_del,
 };
 
+static const struct of_device_

[PATCHv2 4/4] dt-bindings: net: dsa: add new MT7530 binding to support MT7621

2019-01-13 Thread gerg
From: Greg Ungerer 

Add devicetree binding to support the compatible mt7530 switch as used
in the MediaTek MT7621 SoC.

Signed-off-by: Greg Ungerer 
---
 Documentation/devicetree/bindings/net/dsa/mt7530.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

v1: initial patch
v2: changed to use separate devicetree binding

diff --git a/Documentation/devicetree/bindings/net/dsa/mt7530.txt 
b/Documentation/devicetree/bindings/net/dsa/mt7530.txt
index aa3527f71fdc..b4e2af30776f 100644
--- a/Documentation/devicetree/bindings/net/dsa/mt7530.txt
+++ b/Documentation/devicetree/bindings/net/dsa/mt7530.txt
@@ -3,7 +3,8 @@ Mediatek MT7530 Ethernet switch
 
 Required properties:
 
-- compatible: Must be compatible = "mediatek,mt7530";
+- compatible: may be compatible = "mediatek,mt7530"
+   or compatible = "mediatek,mt7621"
 - #address-cells: Must be 1.
 - #size-cells: Must be 0.
 - mediatek,mcm: Boolean; if defined, indicates that either MT7530 is the part
-- 
2.17.1



[PATCHv2 2/4] net: ethernet: mediatek: do not force autonegiation at init

2019-01-13 Thread gerg
From: Greg Ungerer 

Do not attempt to force a port phy auto-ngeotiation during the driver
init phase. It is not necessary and results in a warning at system
boot up:

mtk_soc_eth 1e10.ethernet: generated random MAC address be:e7:d4:9d:7d:b0
mtk_soc_eth 1e10.ethernet: connected mac 0 to PHY at fixed-0:00 
[uid=, driver=Generic PHY]
[ cut here ]
WARNING: CPU: 1 PID: 1 at drivers/net/phy/phy.c:548 phy_start_aneg+0xf0/0x1c0
called from state READY
Modules linked in:
CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.0.0-rc1-5-ge3368ed2e336-dirty 
#11
Stack : 007a   807e 8071 8006fb04 8072db28 000b
  8072d368 87c3db74 8077 0001 87c3db08 2892b90e
  8082   2d36 007b 
2d316372    8077  80715e70 0009
0224 80716e38 87d6a800 80660334 0001 80340714 0004 807e0004
...
Call Trace:
[<8000cfe0>] show_stack+0x94/0x12c
[<8060de6c>] dump_stack+0x8c/0xd0
[<80028430>] __warn+0x10c/0x120
[<80028488>] warn_slowpath_fmt+0x44/0x68
[<803adf78>] phy_start_aneg+0xf0/0x1c0
[<807aed8c>] mtk_init+0x434/0x4a4
[<8047310c>] register_netdevice+0x94/0x6d0
[<8047376c>] register_netdev+0x24/0x40
[<803bf4c0>] mtk_probe+0x2a0/0x930
[<80352d24>] platform_drv_probe+0x40/0x9c
[<80350e48>] really_probe+0x1f0/0x35c
[<803513e4>] __driver_attach+0x10c/0x114
[<8034ec88>] bus_for_each_dev+0x70/0xd0
[<8035023c>] bus_add_driver+0x1f0/0x25c
[<80351c70>] driver_register+0x80/0x144
[<800015f4>] do_one_initcall+0x50/0x1ac
[<80795e48>] kernel_init_freeable+0x184/0x26c
[<8062bbd4>] kernel_init+0x14/0x110
[<80007198>] ret_from_kernel_thread+0x14/0x1c
---[ end trace 6e884e9f12ed14c0 ]---
mtk_soc_eth 1e10.ethernet eth0: mediatek frame engine at 0xbe10, irq 22

Signed-off-by: Greg Ungerer 
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 -
 1 file changed, 1 deletion(-)

v2: first patch in this series for this change

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c 
b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index c7763a189619..e5a32d43a71c 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -356,7 +356,6 @@ static int mtk_phy_connect(struct net_device *dev)
linkmode_copy(dev->phydev->advertising, dev->phydev->supported);
linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
 dev->phydev->advertising);
-   phy_start_aneg(dev->phydev);
 
of_node_put(np);
 
-- 
2.17.1



[PATCHv2 0/4]: net: dsa: mt7530: support MT7530 in the MT7621 So

2019-01-13 Thread gerg


This is the second version of a patch series supporting the MT7530
switch as used in the MediaTek MT7621 SoC. Unlike the MediaTek MT7623
the MT7621 is built around a dual core MIPS CPU architecture. But
inside it uses basically the same 7530 switch.

These patches resolves all issues I had with version 1, and I can now
reliably use the driver on a 7621 SoC platform. These patches were
generated against linux-5.0-rc2.

The first 2 patches are new to the series and enable support for the
existing kernel mediatek ethernet driver on the MT7621 SoC. This support
is from Bjørn Mork, with an update and fix by me. Using this driver
fixed a number of problems I had (TX checksums, large RX packet drop)
over the staging driver (drivers/staging/mt7621-eth).

Patch 3 modifies the mt7530 DSA driver to support the 7530 switch as
implemented in the Mediatek MT7621 SoC. The last patch updates the
devicetree bindings to reflect the new support in the mt7530 driver.

Creating a new binding for the MT7621 seems like the only viable approach
to distinguish between a stand alone 7530 switch, the silicon module
in the MT7623 SoC and the silicon in the MT7621. Certainly the 7530 ID
register in the MT7623 and MT7621 returns the same value, "0x7530001".

Looking at the mt7530.c DSA driver it might make seom sense to convert
the existing "mediatek,mcm" binding to something like "mediatek,mt7623"
to be consistent with this new MT7621 support. As far as I can tell
this is the intention of this binding.

Any thoughts greatly appreciated...

 Documentation/devicetree/bindings/net/dsa/mt7530.txt |3
 drivers/net/dsa/mt7530.c |   97 +++
 drivers/net/dsa/mt7530.h |9 +
 drivers/net/ethernet/mediatek/Kconfig|2
 drivers/net/ethernet/mediatek/mtk_eth_soc.c  |   49 -
 drivers/net/ethernet/mediatek/mtk_eth_soc.h  |4
 6 files changed, 115 insertions(+), 49 deletions(-)

v1: initial patch series
v2: rebase to linux-5.0-rc2
include mediatek ethernet driver changes
change to use devicetree binding to idenify platform




[PATCHv2 1/4] net: ethernet: mediatek: support MT7621 SoC ethernet hardware

2019-01-13 Thread gerg
From: Bjørn Mork 

The Mediatek MT7621 SoC contains the same ethernet hardware module as
used on a number of other MediaTek SoC parts. There are some minor
differences to deal with but we can use the same driver to support
them all.

This patch is based on work by Bjørn Mork , and his
original patch is at:

https://github.com/bmork/LEDE/commit/3293bc63f5461ca1eb0bbc4ed90145335e7e3404

There is an additional compatible devicetree type added, and the primary
change to the code required is to support a single interrupt (for both
RX and TX interrupts).

Signed-off-by: Bjørn Mork 
[g...@kernel.org: rebase to mainline and irq handler fix]
Signed-off-by: Greg Ungerer 
---
 drivers/net/ethernet/mediatek/Kconfig   |  2 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 48 ++---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  4 ++
 3 files changed, 46 insertions(+), 8 deletions(-)

v2: first patch in this series for this change

diff --git a/drivers/net/ethernet/mediatek/Kconfig 
b/drivers/net/ethernet/mediatek/Kconfig
index f9149d2a4694..43656f961891 100644
--- a/drivers/net/ethernet/mediatek/Kconfig
+++ b/drivers/net/ethernet/mediatek/Kconfig
@@ -1,6 +1,6 @@
 config NET_VENDOR_MEDIATEK
bool "MediaTek ethernet driver"
-   depends on ARCH_MEDIATEK
+   depends on ARCH_MEDIATEK || SOC_MT7621
---help---
  If you have a Mediatek SoC with ethernet, say Y.
 
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c 
b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index fe9653fa8aea..c7763a189619 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1761,6 +1761,22 @@ static irqreturn_t mtk_handle_irq_tx(int irq, void *_eth)
return IRQ_HANDLED;
 }
 
+static irqreturn_t mtk_handle_irq(int irq, void *_eth)
+{
+   struct mtk_eth *eth = _eth;
+
+   if (mtk_r32(eth, MTK_PDMA_INT_MASK) & MTK_RX_DONE_INT) {
+   if (mtk_r32(eth, MTK_PDMA_INT_STATUS) & MTK_RX_DONE_INT)
+   mtk_handle_irq_rx(irq, _eth);
+   }
+   if (mtk_r32(eth, MTK_QDMA_INT_MASK) & MTK_TX_DONE_INT) {
+   if (mtk_r32(eth, MTK_QMTK_INT_STATUS) & MTK_TX_DONE_INT)
+   mtk_handle_irq_tx(irq, _eth);
+   }
+
+   return IRQ_HANDLED;
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void mtk_poll_controller(struct net_device *dev)
 {
@@ -2501,7 +2517,10 @@ static int mtk_probe(struct platform_device *pdev)
}
 
for (i = 0; i < 3; i++) {
-   eth->irq[i] = platform_get_irq(pdev, i);
+   if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
+   eth->irq[i] = eth->irq[0];
+   else
+   eth->irq[i] = platform_get_irq(pdev, i);
if (eth->irq[i] < 0) {
dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
return -ENXIO;
@@ -2544,13 +2563,21 @@ static int mtk_probe(struct platform_device *pdev)
goto err_deinit_hw;
}
 
-   err = devm_request_irq(eth->dev, eth->irq[1], mtk_handle_irq_tx, 0,
-  dev_name(eth->dev), eth);
-   if (err)
-   goto err_free_dev;
+   if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
+   err = devm_request_irq(eth->dev, eth->irq[0],
+  mtk_handle_irq, 0,
+  dev_name(eth->dev), eth);
+   } else {
+   err = devm_request_irq(eth->dev, eth->irq[1],
+  mtk_handle_irq_tx, 0,
+  dev_name(eth->dev), eth);
+   if (err)
+   goto err_free_dev;
 
-   err = devm_request_irq(eth->dev, eth->irq[2], mtk_handle_irq_rx, 0,
-  dev_name(eth->dev), eth);
+   err = devm_request_irq(eth->dev, eth->irq[2],
+  mtk_handle_irq_rx, 0,
+  dev_name(eth->dev), eth);
+   }
if (err)
goto err_free_dev;
 
@@ -2623,6 +2650,12 @@ static const struct mtk_soc_data mt2701_data = {
.required_pctl = true,
 };
 
+static const struct mtk_soc_data mt7621_data = {
+   .caps = MTK_SHARED_INT,
+   .required_clks = MT7621_CLKS_BITMAP,
+   .required_pctl = false,
+};
+
 static const struct mtk_soc_data mt7622_data = {
.caps = MTK_DUAL_GMAC_SHARED_SGMII | MTK_GMAC1_ESW | MTK_HWLRO,
.required_clks = MT7622_CLKS_BITMAP,
@@ -2637,6 +2670,7 @@ static const struct mtk_soc_data mt7623_data = {
 
 const struct of_device_id of_mtk_match[] = {
{ .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
+   { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
{ .compatible = "mediatek,mt7623-eth", .data = &mt7

[PATCH 3/3] dt-bindings: net: dsa: add new bindings MT7530

2018-11-29 Thread gerg
From: Greg Ungerer 

Add descriptive entries for the new bindings introduced to support the
MT7530 implementation in the MediaTek MT7621 SoC.

New bindings added for:

  mediatek,no-clock-regulator
  mediatek,mfc-has-cpuport

Signed-off-by: Greg Ungerer 
---
 Documentation/devicetree/bindings/net/dsa/mt7530.txt | 5 +
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/dsa/mt7530.txt 
b/Documentation/devicetree/bindings/net/dsa/mt7530.txt
index aa3527f71fdc..549ad7c338ea 100644
--- a/Documentation/devicetree/bindings/net/dsa/mt7530.txt
+++ b/Documentation/devicetree/bindings/net/dsa/mt7530.txt
@@ -9,6 +9,11 @@ Required properties:
 - mediatek,mcm: Boolean; if defined, indicates that either MT7530 is the part
on multi-chip module belong to MT7623A has or the remotely standalone
chip as the function MT7623N reference board provided for.
+- mediatek,no-clock-regulator: Boolean; if defined, indicates that the MT7530
+   is in a system-on-chip that does not require clock or regulator
+   control setup (for example the MT7621).
+- mediatek,mfc-has-cpuport: Boolean; if defined, indicates that the MT7530
+   has an MFC register that has a CPU PORT field and ENABLE bit
 - core-supply: Phandle to the regulator node necessary for the core power.
 - io-supply: Phandle to the regulator node necessary for the I/O power.
See Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
-- 
2.17.1



[PATCH 1/3] net: dsa: mt7530: make clock/regulator setup optional

2018-11-29 Thread gerg
From: Greg Ungerer 

At least one device that contains the MediaTek MT7530 switch module
does not need the clock and regulator setup parts of the MT7530 DSA
driver. That setup looks to be very specific to the MT7623.

The MediaTek MT7621 SoC device contains a 7530 switch, but its MIPS CPU
cores and overall architecture do not have any of the same clock or
regulator setup as the MT7623.

Create a new devicetree tag, mediatek,no-clock-regulator, that controls
whether we should setup and use the clocks and regulators specific to
some uses of the 7530.

Signed-off-by: Greg Ungerer 
---
 drivers/net/dsa/mt7530.c | 86 
 drivers/net/dsa/mt7530.h |  1 +
 2 files changed, 52 insertions(+), 35 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index a5de9bffe5be..532240c4bef9 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -625,14 +625,16 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int 
port,
dev_dbg(priv->dev, "phy-mode for master device = %x\n",
phydev->interface);
 
-   /* Setup TX circuit incluing relevant PAD and driving */
-   mt7530_pad_clk_setup(ds, phydev->interface);
-
-   /* Setup RX circuit, relevant PAD and driving on the host
-* which must be placed after the setup on the device side is
-* all finished.
-*/
-   mt7623_pad_clk_setup(ds);
+   if (priv->clkreg) {
+   /* Setup TX circuit incluing relevant PAD and driving */
+   mt7530_pad_clk_setup(ds, phydev->interface);
+
+   /* Setup RX circuit, relevant PAD and driving on the
+* host which must be placed after the setup on the
+* device side is all finished.
+*/
+   mt7623_pad_clk_setup(ds);
+   }
} else {
u16 lcl_adv = 0, rmt_adv = 0;
u8 flowctrl;
@@ -1219,24 +1221,27 @@ mt7530_setup(struct dsa_switch *ds)
 * as two netdev instances.
 */
dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent;
-   priv->ethernet = syscon_node_to_regmap(dn);
-   if (IS_ERR(priv->ethernet))
-   return PTR_ERR(priv->ethernet);
 
-   regulator_set_voltage(priv->core_pwr, 100, 100);
-   ret = regulator_enable(priv->core_pwr);
-   if (ret < 0) {
-   dev_err(priv->dev,
-   "Failed to enable core power: %d\n", ret);
-   return ret;
-   }
+   if (priv->clkreg) {
+   priv->ethernet = syscon_node_to_regmap(dn);
+   if (IS_ERR(priv->ethernet))
+   return PTR_ERR(priv->ethernet);
+
+   regulator_set_voltage(priv->core_pwr, 100, 100);
+   ret = regulator_enable(priv->core_pwr);
+   if (ret < 0) {
+   dev_err(priv->dev,
+   "Failed to enable core power: %d\n", ret);
+   return ret;
+   }
 
-   regulator_set_voltage(priv->io_pwr, 330, 330);
-   ret = regulator_enable(priv->io_pwr);
-   if (ret < 0) {
-   dev_err(priv->dev, "Failed to enable io pwr: %d\n",
-   ret);
-   return ret;
+   regulator_set_voltage(priv->io_pwr, 330, 330);
+   ret = regulator_enable(priv->io_pwr);
+   if (ret < 0) {
+   dev_err(priv->dev, "Failed to enable io pwr: %d\n",
+   ret);
+   return ret;
+   }
}
 
/* Reset whole chip through gpio pin or memory-mapped registers for
@@ -1268,10 +1273,12 @@ mt7530_setup(struct dsa_switch *ds)
return -ENODEV;
}
 
-   /* Reset the switch through internal reset */
-   mt7530_write(priv, MT7530_SYS_CTRL,
-SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
-SYS_CTRL_REG_RST);
+   if (priv->clkreg) {
+   /* Reset the switch through internal reset */
+   mt7530_write(priv, MT7530_SYS_CTRL,
+SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
+SYS_CTRL_REG_RST);
+   }
 
/* Enable Port 6 only; P5 as GMAC5 which currently is not supported */
val = mt7530_read(priv, MT7530_MHWTRAP);
@@ -1356,13 +1363,22 @@ mt7530_probe(struct mdio_device *mdiodev)
}
}
 
-   priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-   if (IS_ERR(priv->core_pwr))
-   return PTR_ERR(priv->core_pwr);
-
-   priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-   if (IS_ERR(priv->io_pwr))
-   return PTR_ERR(priv->io_pwr);
+   /* Use mediatek,no-clock-regu

[PATCH 2/3] net: dsa: mt7530: optional setting CPU field in MFC register

2018-11-29 Thread gerg
From: Greg Ungerer 

Some versions of the MediaTek MT7530 switch have a CPU port number and
enable bit in their MFC register. The MT7530 instance on the MediaTek
MT7621 SoC is one that does for example. The switch will not work
without these fields being correctly setup on these devices.

Create a new devicetree tag, mediatek,mfc-has-cpuport, that signifies
that this device needs the CPU port field and enable bit set when the
port is enabled.

Signed-off-by: Greg Ungerer 
---
 drivers/net/dsa/mt7530.c | 9 +
 drivers/net/dsa/mt7530.h | 4 
 2 files changed, 13 insertions(+)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 532240c4bef9..e41ada47233a 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -689,6 +689,10 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
/* Unknown unicast frame fordwarding to the cpu port */
mt7530_set(priv, MT7530_MFC, UNU_FFP(BIT(port)));
 
+   /* Set CPU port number */
+   if (priv->mfccpu)
+   mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
+
/* CPU port gets connected to all user ports of
 * the switch
 */
@@ -1380,6 +1384,11 @@ mt7530_probe(struct mdio_device *mdiodev)
 "MT7530 with no CLOCK or REGULATOR control\n");
}
 
+   /* Use mediatek,mfc-has-cpuport to distinguish hardware where the MFC
+* register has a CPU port number field setting.
+*/
+   priv->mfccpu = of_property_read_bool(dn, "mediatek,mfc-has-cpuport");
+
/* Not MCM that indicates switch works as the remote standalone
 * integrated circuit so the GPIO pin would be used to complete
 * the reset, otherwise memory-mapped register accessing used
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index ee97944c4507..cbc0725c4258 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -36,6 +36,9 @@
 #define  UNM_FFP(x)(((x) & 0xff) << 16)
 #define  UNU_FFP(x)(((x) & 0xff) << 8)
 #define  UNU_FFP_MASK  UNU_FFP(~0)
+#define  CPU_ENBIT(7)
+#define  CPU_PORT(x)   ((x) << 4)
+#define  CPU_MASK  (0xf << 4)
 
 /* Registers for address table access */
 #define MT7530_ATA10x74
@@ -432,6 +435,7 @@ struct mt7530_priv {
struct gpio_desc*reset;
boolmcm;
boolclkreg;
+   boolmfccpu;
 
struct mt7530_port  ports[MT7530_NUM_PORTS];
/* protect among processes for registers access*/
-- 
2.17.1



[PATCH 0/3]: net: dsa: mt7530: support MT7530 in the MT7621 SoC

2018-11-29 Thread gerg
I have been working towards supporting the MT7530 switch as used in the
MediaTek MT7621 SoC. Unlike the MediaTek MT7623 the MT7621 is built around
a dual core MIPS CPU architecture. But underneath it is what appears to
be the same 7530 switch.

The following 3 patches are more of an RFC than anything. They allow
use of the mt7530 dsa driver on this device - though with some issues
still to resolve. The primary change required is to not use the 7623
specific clock and regulator setup - none of that applies when using
the 7621 (and maybe other devices?). The other change required is to
set the 7530 MFC register CPU port number and enable bit.

The unresolved issues I still have appear to be more related to the
MT7621 ethernet driver (drivers/staging/mt7621-eth/*). I am hoping
someone might have some ideas on these. I don't really have any good
documentation on the ethernet devices on the 7621, so I am kind of
working in the dark here.

1. TX packets are not getting an IP header checksum via the normal
   off-loaded checksumming when in DSA mode. I have to switch off
   NETIF_F_IP_CSUM, so the software stack generates the checksum.
   That checksum offloading works ok when not using the 7530 DSA driver.

2. Maximal sized RX packets get silently dropped. So receive side packets
   that are large (perfect case is the all-but-last packets in a fragemented
   larger packet) appear to be dropped at the mt7621 ethernet MAC level.
   The 7530 MIB switch register counters show receive packets at the physical
   switch port side and at the CPU switch port - but I get no packets
   received or errors in the 7621 ethernet MAC. If I set the mtu of the
   server at the other end a little smaller (a few bytes is enough) then
   I get all the packets through. It seems like the DSA/VLAN tag bytes
   are causing a too large packet to get silently dropped somewhere.

Any thoughts greatly appreciated...

 Documentation/devicetree/bindings/net/dsa/mt7530.txt |5 +
 drivers/net/dsa/mt7530.c |   95 ---
 drivers/net/dsa/mt7530.h |5 +
 3 files changed, 70 insertions(+), 35 deletions(-)