Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-sh

- Improvements to the Renesas Ethernet AVB MAC driver
diff --git a/arch/arm/mach-renesas/Kconfig b/arch/arm/mach-renesas/Kconfig
index aeb55da..d373ab5 100644
--- a/arch/arm/mach-renesas/Kconfig
+++ b/arch/arm/mach-renesas/Kconfig
@@ -76,6 +76,7 @@
 	imply MULTI_DTB_FIT
 	imply MULTI_DTB_FIT_USER_DEFINED_AREA
 	imply PINCTRL_RZG2L
+	imply RENESAS_RAVB
 	imply RENESAS_SDHI
 	imply RZG2L_GPIO
 	imply SCIF_CONSOLE
diff --git a/configs/renesas_rzg2l_smarc_defconfig b/configs/renesas_rzg2l_smarc_defconfig
index b1d970b..6ec1512 100644
--- a/configs/renesas_rzg2l_smarc_defconfig
+++ b/configs/renesas_rzg2l_smarc_defconfig
@@ -27,6 +27,9 @@
 CONFIG_CMD_MMC=y
 CONFIG_CMD_PART=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_EXT4=y
@@ -41,6 +44,7 @@
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_SYS_MMC_ENV_PART=2
 CONFIG_VERSION_VARIABLE=y
+CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_REGMAP=y
 CONFIG_CLK=y
 CONFIG_CLK_RENESAS=y
@@ -50,6 +54,8 @@
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_RAA215300=y
 CONFIG_DM_REGULATOR=y
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4434d36..950ed0f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -860,7 +860,7 @@
 	select PHY_ETHERNET_ID
 	help
 	  This driver implements support for the Ethernet AVB block in
-	  Renesas M3 and H3 SoCs.
+	  several Renesas R-Car and RZ SoCs.
 
 config MPC8XX_FEC
 	bool "Fast Ethernet Controller on MPC8XX"
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index 539fd37..6852886 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -23,6 +23,7 @@
 #include <asm/io.h>
 #include <asm/global_data.h>
 #include <asm/gpio.h>
+#include <reset.h>
 
 /* Registers */
 #define RAVB_REG_CCC		0x000
@@ -30,6 +31,7 @@
 #define RAVB_REG_CSR		0x00C
 #define RAVB_REG_APSR		0x08C
 #define RAVB_REG_RCR		0x090
+#define RAVB_REG_RTC		0x0B4
 #define RAVB_REG_TGC		0x300
 #define RAVB_REG_TCCR		0x304
 #define RAVB_REG_RIC0		0x360
@@ -43,6 +45,7 @@
 #define RAVB_REG_GECMR		0x5b0
 #define RAVB_REG_MAHR		0x5c0
 #define RAVB_REG_MALR		0x5c8
+#define RAVB_REG_CSR0		0x800
 
 #define CCC_OPC_CONFIG		BIT(0)
 #define CCC_OPC_OPERATION	BIT(1)
@@ -64,14 +67,24 @@
 #define PIR_MDC			BIT(0)
 
 #define ECMR_TRCCM		BIT(26)
+#define ECMR_RCPT		BIT(25)
 #define ECMR_RZPF		BIT(20)
 #define ECMR_PFR		BIT(18)
 #define ECMR_RXF		BIT(17)
+#define ECMR_TXF		BIT(16)
 #define ECMR_RE			BIT(6)
 #define ECMR_TE			BIT(5)
 #define ECMR_DM			BIT(1)
+#define ECMR_PRM		BIT(0)
 #define ECMR_CHG_DM		(ECMR_TRCCM | ECMR_RZPF | ECMR_PFR | ECMR_RXF)
 
+#define CSR0_RPE		BIT(5)
+#define CSR0_TPE		BIT(4)
+
+#define GECMR_SPEED_10M		(0 << 4)
+#define GECMR_SPEED_100M	(1 << 4)
+#define GECMR_SPEED_1G		(2 << 4)
+
 /* DMA Descriptors */
 #define RAVB_NUM_BASE_DESC		16
 #define RAVB_NUM_TX_DESC		8
@@ -107,6 +120,13 @@
 
 #define RAVB_TX_TIMEOUT_MS		1000
 
+struct ravb_device_ops {
+	void (*mac_init)(struct udevice *dev);
+	void (*dmac_init)(struct udevice *dev);
+	void (*config)(struct udevice *dev);
+	bool has_reset;
+};
+
 struct ravb_desc {
 	u32	ctrl;
 	u32	dptr;
@@ -130,6 +150,7 @@
 	struct mii_dev		*bus;
 	void __iomem		*iobase;
 	struct clk_bulk		clks;
+	struct reset_ctl	rst;
 };
 
 static inline void ravb_flush_dcache(u32 addr, u32 len)
@@ -181,7 +202,7 @@
 {
 	struct ravb_priv *eth = dev_get_priv(dev);
 	struct ravb_rxdesc *desc = &eth->rx_desc[eth->rx_desc_idx];
-	int len;
+	int len = 0;
 	u8 *packet;
 
 	/* Check if the rx descriptor is ready */
@@ -190,12 +211,11 @@
 		return -EAGAIN;
 
 	/* Check for errors */
-	if (desc->data.ctrl & RAVB_RX_DESC_MSC_RX_ERR_MASK) {
+	if (desc->data.ctrl & RAVB_RX_DESC_MSC_RX_ERR_MASK)
 		desc->data.ctrl &= ~RAVB_RX_DESC_MSC_MASK;
-		return -EAGAIN;
-	}
+	else
+		len = desc->data.ctrl & RAVB_DESC_DS_MASK;
 
-	len = desc->data.ctrl & RAVB_DESC_DS_MASK;
 	packet = (u8 *)(uintptr_t)desc->data.dptr;
 	ravb_invalidate_dcache((uintptr_t)packet, len);
 
@@ -349,10 +369,13 @@
 }
 
 /* E-MAC init function */
-static int ravb_mac_init(struct ravb_priv *eth)
+static void ravb_mac_init(struct udevice *dev)
 {
-	/* Disable MAC Interrupt */
-	writel(0, eth->iobase + RAVB_REG_ECSIPR);
+	struct ravb_device_ops *device_ops =
+		(struct ravb_device_ops *)dev_get_driver_data(dev);
+	struct ravb_priv *eth = dev_get_priv(dev);
+
+	device_ops->mac_init(dev);
 
 	/*
 	 * Set receive frame length
@@ -363,19 +386,33 @@
 	 * largest frames add the CRC length to the maximum Rx descriptor size.
 	 */
 	writel(RFLR_RFL_MIN + ETH_FCS_LEN, eth->iobase + RAVB_REG_RFLR);
+}
 
-	return 0;
+static void ravb_mac_init_rcar(struct udevice *dev)
+{
+	struct ravb_priv *eth = dev_get_priv(dev);
+
+	/* Disable MAC Interrupt */
+	writel(0, eth->iobase + RAVB_REG_ECSIPR);
 }
 
+static void ravb_mac_init_rzg2l(struct udevice *dev)
+{
+	struct ravb_priv *eth = dev_get_priv(dev);
+
+	setbits_32(eth->iobase + RAVB_REG_ECMR,
+		   ECMR_PRM | ECMR_RXF | ECMR_TXF | ECMR_RCPT |
+		   ECMR_TE | ECMR_RE | ECMR_RZPF |
+		   (eth->phydev->duplex ? ECMR_DM : 0));
+}
+
 /* AVB-DMAC init function */
 static int ravb_dmac_init(struct udevice *dev)
 {
+	struct ravb_device_ops *device_ops =
+		(struct ravb_device_ops *)dev_get_driver_data(dev);
 	struct ravb_priv *eth = dev_get_priv(dev);
-	struct eth_pdata *pdata = dev_get_plat(dev);
-	int ret = 0;
-	int mode = 0;
-	unsigned int delay;
-	bool explicit_delay = false;
+	int ret;
 
 	/* Set CONFIG mode */
 	ret = ravb_reset(dev);
@@ -391,6 +428,18 @@
 	/* Set little endian */
 	clrbits_le32(eth->iobase + RAVB_REG_CCC, CCC_BOC);
 
+	device_ops->dmac_init(dev);
+	return 0;
+}
+
+static void ravb_dmac_init_rcar(struct udevice *dev)
+{
+	struct ravb_priv *eth = dev_get_priv(dev);
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	int mode = 0;
+	unsigned int delay;
+	bool explicit_delay = false;
+
 	/* AVB rx set */
 	writel(0x18000001, eth->iobase + RAVB_REG_RCR);
 
@@ -400,7 +449,7 @@
 	/* Delay CLK: 2ns (not applicable on R-Car E3/D3) */
 	if ((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77990) ||
 	    (renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77995))
-		return 0;
+		return;
 
 	if (!dev_read_u32(dev, "rx-internal-delay-ps", &delay)) {
 		/* Valid values are 0 and 1800, according to DT bindings */
@@ -429,28 +478,45 @@
 	}
 
 	writel(mode, eth->iobase + RAVB_REG_APSR);
+}
 
-	return 0;
+static void ravb_dmac_init_rzg2l(struct udevice *dev)
+{
+	struct ravb_priv *eth = dev_get_priv(dev);
+
+	/* Set Max Frame Length (RTC) */
+	writel(0x7ffc0000 | RFLR_RFL_MIN, eth->iobase + RAVB_REG_RTC);
 }
 
 static int ravb_config(struct udevice *dev)
 {
+	struct ravb_device_ops *device_ops =
+		(struct ravb_device_ops *)dev_get_driver_data(dev);
 	struct ravb_priv *eth = dev_get_priv(dev);
 	struct phy_device *phy = eth->phydev;
-	u32 mask = ECMR_CHG_DM | ECMR_RE | ECMR_TE;
 	int ret;
 
 	/* Configure AVB-DMAC register */
 	ravb_dmac_init(dev);
 
 	/* Configure E-MAC registers */
-	ravb_mac_init(eth);
+	ravb_mac_init(dev);
 	ravb_write_hwaddr(dev);
 
 	ret = phy_startup(phy);
 	if (ret)
 		return ret;
 
+	device_ops->config(dev);
+	return 0;
+}
+
+static void ravb_config_rcar(struct udevice *dev)
+{
+	struct ravb_priv *eth = dev_get_priv(dev);
+	struct phy_device *phy = eth->phydev;
+	u32 mask = ECMR_CHG_DM | ECMR_RE | ECMR_TE;
+
 	/* Set the transfer speed */
 	if (phy->speed == 100)
 		writel(0, eth->iobase + RAVB_REG_GECMR);
@@ -462,8 +528,22 @@
 		mask |= ECMR_DM;
 
 	writel(mask, eth->iobase + RAVB_REG_ECMR);
+}
 
-	return 0;
+static void ravb_config_rzg2l(struct udevice *dev)
+{
+	struct ravb_priv *eth = dev_get_priv(dev);
+	struct phy_device *phy = eth->phydev;
+
+	writel(CSR0_TPE | CSR0_RPE, eth->iobase + RAVB_REG_CSR0);
+
+	/* Set the transfer speed */
+	if (phy->speed == 10)
+		writel(GECMR_SPEED_10M, eth->iobase + RAVB_REG_GECMR);
+	else if (phy->speed == 100)
+		writel(GECMR_SPEED_100M, eth->iobase + RAVB_REG_GECMR);
+	else if (phy->speed == 1000)
+		writel(GECMR_SPEED_1G, eth->iobase + RAVB_REG_GECMR);
 }
 
 static int ravb_start(struct udevice *dev)
@@ -581,6 +661,8 @@
 
 static int ravb_probe(struct udevice *dev)
 {
+	struct ravb_device_ops *device_ops =
+		(struct ravb_device_ops *)dev_get_driver_data(dev);
 	struct eth_pdata *pdata = dev_get_plat(dev);
 	struct ravb_priv *eth = dev_get_priv(dev);
 	struct mii_dev *mdiodev;
@@ -616,16 +698,32 @@
 	if (ret)
 		goto err_clk_enable;
 
+	if (device_ops->has_reset) {
+		ret = reset_get_by_index(dev, 0, &eth->rst);
+		if (ret < 0)
+			goto err_clk_enable;
+
+		ret = reset_deassert(&eth->rst);
+		if (ret < 0)
+			goto err_reset_deassert;
+	}
+
 	ret = ravb_reset(dev);
 	if (ret)
-		goto err_clk_enable;
+		goto err_ravb_reset;
 
 	ret = ravb_phy_config(dev);
 	if (ret)
-		goto err_clk_enable;
+		goto err_ravb_reset;
 
 	return 0;
 
+err_ravb_reset:
+	if (device_ops->has_reset)
+		reset_assert(&eth->rst);
+err_reset_deassert:
+	if (device_ops->has_reset)
+		reset_free(&eth->rst);
 err_clk_enable:
 	mdio_unregister(mdiodev);
 err_mdio_register:
@@ -639,8 +737,14 @@
 
 static int ravb_remove(struct udevice *dev)
 {
+	struct ravb_device_ops *device_ops =
+		(struct ravb_device_ops *)dev_get_driver_data(dev);
 	struct ravb_priv *eth = dev_get_priv(dev);
 
+	if (device_ops->has_reset) {
+		reset_assert(&eth->rst);
+		reset_free(&eth->rst);
+	}
 	clk_release_bulk(&eth->clks);
 
 	free(eth->phydev);
@@ -675,9 +779,32 @@
 	return 0;
 }
 
+static const struct ravb_device_ops ravb_device_ops_rcar = {
+	.mac_init = ravb_mac_init_rcar,
+	.dmac_init = ravb_dmac_init_rcar,
+	.config = ravb_config_rcar,
+};
+
+static const struct ravb_device_ops ravb_device_ops_rzg2l = {
+	.mac_init = ravb_mac_init_rzg2l,
+	.dmac_init = ravb_dmac_init_rzg2l,
+	.config = ravb_config_rzg2l,
+	.has_reset = true,
+};
+
 static const struct udevice_id ravb_ids[] = {
-	{ .compatible = "renesas,etheravb-rcar-gen3" },
-	{ .compatible = "renesas,etheravb-rcar-gen4" },
+	{
+		.compatible = "renesas,etheravb-rcar-gen3",
+		.data = (ulong)&ravb_device_ops_rcar,
+	},
+	{
+		.compatible = "renesas,etheravb-rcar-gen4",
+		.data = (ulong)&ravb_device_ops_rcar,
+	},
+	{
+		.compatible = "renesas,rzg2l-gbeth",
+		.data = (ulong)&ravb_device_ops_rzg2l,
+	},
 	{ }
 };