Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a82a3fe0 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-dsa-mt7530-support-MT7530-in-the-MT7621-SoC'



Greg Ungerer says:

====================
net: dsa: mt7530: support MT7530 in the MT7621 SoC

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.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 08c25fe8 9389b5e9
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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
+57 −39
Original line number Diff line number Diff line
@@ -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)) {
		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.
			/* 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,6 +1225,8 @@ mt7530_setup(struct dsa_switch *ds)
	 * as two netdev instances.
	 */
	dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent;

	if (priv->id == ID_MT7530) {
		priv->ethernet = syscon_node_to_regmap(dn);
		if (IS_ERR(priv->ethernet))
			return PTR_ERR(priv->ethernet);
@@ -1238,6 +1246,7 @@ mt7530_setup(struct dsa_switch *ds)
				ret);
			return ret;
		}
	}

	/* Reset whole chip through gpio pin or memory-mapped registers for
	 * different type of hardware
@@ -1326,6 +1335,13 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
	.port_vlan_del		= mt7530_port_vlan_del,
};

static const struct of_device_id mt7530_of_match[] = {
	{ .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, },
	{ .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mt7530_of_match);

static int
mt7530_probe(struct mdio_device *mdiodev)
{
@@ -1356,6 +1372,13 @@ mt7530_probe(struct mdio_device *mdiodev)
		}
	}

	/* Get the hardware identifier from the devicetree node.
	 * We will need it for some of the clock and regulator setup.
	 */
	priv->id = (unsigned int)(unsigned long)
		of_device_get_match_data(&mdiodev->dev);

	if (priv->id == ID_MT7530) {
		priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
		if (IS_ERR(priv->core_pwr))
			return PTR_ERR(priv->core_pwr);
@@ -1363,6 +1386,7 @@ mt7530_probe(struct mdio_device *mdiodev)
		priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
		if (IS_ERR(priv->io_pwr))
			return PTR_ERR(priv->io_pwr);
	}

	/* Not MCM that indicates switch works as the remote standalone
	 * integrated circuit so the GPIO pin would be used to complete
@@ -1408,12 +1432,6 @@ mt7530_remove(struct mdio_device *mdiodev)
	mutex_destroy(&priv->reg_mutex);
}

static const struct of_device_id mt7530_of_match[] = {
	{ .compatible = "mediatek,mt7530" },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mt7530_of_match);

static struct mdio_driver mt7530_mdio_driver = {
	.probe  = mt7530_probe,
	.remove = mt7530_remove,
+9 −0
Original line number Diff line number Diff line
@@ -19,6 +19,11 @@
#define MT7530_NUM_FDB_RECORDS		2048
#define MT7530_ALL_MEMBERS		0xff

enum {
	ID_MT7530 = 0,
	ID_MT7621 = 1,
};

#define	NUM_TRGMII_CTRL			5

#define TRGMII_BASE(x)			(0x10000 + (x))
@@ -36,6 +41,9 @@
#define  UNM_FFP(x)			(((x) & 0xff) << 16)
#define  UNU_FFP(x)			(((x) & 0xff) << 8)
#define  UNU_FFP_MASK			UNU_FFP(~0)
#define  CPU_EN				BIT(7)
#define  CPU_PORT(x)			((x) << 4)
#define  CPU_MASK			(0xf << 4)

/* Registers for address table access */
#define MT7530_ATA1			0x74
@@ -430,6 +438,7 @@ struct mt7530_priv {
	struct regulator	*core_pwr;
	struct regulator	*io_pwr;
	struct gpio_desc	*reset;
	unsigned int		id;
	bool			mcm;

	struct mt7530_port	ports[MT7530_NUM_PORTS];
+1 −1
Original line number Diff line number Diff line
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.

+41 −7
Original line number Diff line number Diff line
@@ -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,6 +2501,9 @@ static int mtk_probe(struct platform_device *pdev)
	}

	for (i = 0; i < 3; 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);
@@ -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,
	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,
		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", .data = &mt7623_data},
	{},
Loading