Skip to contentSkip to conversation

sunxi: R40: add gigabit ethernet clocks

PATCH New Lothar Felten 3 participants 8 messages Jul 13, 2018 – Jul 16, 2018

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH v6 1/6 sunxi: R40: add gigabit ethernet clocks

Add clock control entries for the gigabit interface of the Allwinner R40/V40 CPU

---
Changelog:
new in v2
v2->v3->4->v5->v6: none

---
 arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
arch/arm/include/asm/arch-sunxi/clock_sun6i.h +9 -1
index 3a59016955..ee387127f3 100644
@@ -60,7 +60,11 @@ struct sunxi_ccm_reg {
 	u32 reserved11;
 	u32 sata_clk_cfg;	/* 0xc8 SATA clock control (R40 only) */
 	u32 usb_clk_cfg;	/* 0xcc USB clock control */
-	u32 gmac_clk_cfg;	/* 0xd0 GMAC clock control */
+#ifdef CONFIG_MACH_SUN8I_R40
+	u32 cir0_clk_cfg;	/* 0xd0 CIR0 clock control (R40 only) */
+#else
+	u32 gmac_clk_cfg;	/* 0xd0 GMAC clock control (not for R40) */
+#endif
 	u32 reserved12[7];
 	u32 mdfs_clk_cfg;	/* 0xf0 MDFS clock control */
 	u32 dram_clk_cfg;	/* 0xf4 DRAM configuration clock control */
@@ -103,7 +107,11 @@ struct sunxi_ccm_reg {
 	u32 mtc_clk_cfg;	/* 0x158 MTC module clock */
 	u32 mbus0_clk_cfg;	/* 0x15c MBUS0 module clock */
 	u32 mbus1_clk_cfg;	/* 0x160 MBUS1 module clock */
+#ifdef CONFIG_MACH_SUN8I_R40
+	u32 gmac_clk_cfg;	/* 0x164 GMAC clock control (R40 only) */
+#else
 	u32 reserved16;
+#endif
 	u32 mipi_dsi_clk_cfg;	/* 0x168 MIPI DSI clock control */
 	u32 mipi_csi_clk_cfg;	/* 0x16c MIPI CSI clock control */
 	u32 reserved17[4];
Signature · 1 line
2.14.1
#1 lore raw

PATCH v6 2/6 net: sun8i-emac: fix printing NULL character

If the variant is not set and therefore NULL, do not attempt to print the variant.

---
Changelog:
new in v4
v4->v5->v6 none

---
 drivers/net/sun8i_emac.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/sun8i_emac.c +1 -2
index 1f5c630e02..23c4d68f77 100644
@@ -843,8 +843,7 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
 	priv->variant = dev_get_driver_data(dev);
 
 	if (!priv->variant) {
-		printf("%s: Missing variant '%s'\n", __func__,
-		       (char *)priv->variant);
+		printf("%s: Missing variant\n", __func__);
 		return -EINVAL;
 	}
 
Signature · 1 line
2.14.1
#2 lore raw

PATCH v6 3/6 net: sun8i-emac: set mux and clock by driver data

In reply to Lothar Felten

Use driver data->variant information to select device specific pin mux and phy clock settings.

Suggested by Jagan Teki

---
Changelog:
new in v3
v3 -> v4 use driver data to distinguish between variants v4 -> v5 -> v6 none

---
 drivers/net/sun8i_emac.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)
drivers/net/sun8i_emac.c +20 -15
index 23c4d68f77..ee3b2aa7f4 100644
@@ -65,11 +65,9 @@
 
 #define AHB_GATE_OFFSET_EPHY	0
 
-#if defined(CONFIG_MACH_SUNXI_H3_H5)
-#define SUN8I_GPD8_GMAC		2
-#else
-#define SUN8I_GPD8_GMAC		4
-#endif
+/* IO mux settings */
+#define SUN8I_IOMUX_H3		2
+#define SUN8I_IOMUX		4
 
 /* H3/A64 EMAC Register's offset */
 #define EMAC_CTL0		0x00
@@ -453,6 +451,7 @@ static int _sun8i_emac_eth_init(struct emac_eth_dev *priv, u8 *enetaddr)
 
 static int parse_phy_pins(struct udevice *dev)
 {
+	struct emac_eth_dev *priv = dev_get_priv(dev);
 	int offset;
 	const char *pin_name;
 	int drive, pull = SUN4I_PINCTRL_NO_PULL, i;
@@ -494,7 +493,11 @@ static int parse_phy_pins(struct udevice *dev)
 		if (pin < 0)
 			continue;
 
-		sunxi_gpio_set_cfgpin(pin, SUN8I_GPD8_GMAC);
+		if (priv->variant == H3_EMAC)
+			sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX_H3);
+		else
+			sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX);
+
 		if (drive != ~0)
 			sunxi_gpio_set_drv(pin, drive);
 		if (pull != ~0)
@@ -618,16 +621,18 @@ static void sun8i_emac_board_setup(struct emac_eth_dev *priv)
 {
 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 
-#ifdef CONFIG_MACH_SUNXI_H3_H5
-	/* Only H3/H5 have clock controls for internal EPHY */
-	if (priv->use_internal_phy) {
-		/* Set clock gating for ephy */
-		setbits_le32(&ccm->bus_gate4, BIT(AHB_GATE_OFFSET_EPHY));
-
-		/* Deassert EPHY */
-		setbits_le32(&ccm->ahb_reset2_cfg, BIT(AHB_RESET_OFFSET_EPHY));
+	if (priv->variant == H3_EMAC) {
+		/* Only H3/H5 have clock controls for internal EPHY */
+		if (priv->use_internal_phy) {
+			/* Set clock gating for ephy */
+			setbits_le32(&ccm->bus_gate4,
+				     BIT(AHB_GATE_OFFSET_EPHY));
+
+			/* Deassert EPHY */
+			setbits_le32(&ccm->ahb_reset2_cfg,
+				     BIT(AHB_RESET_OFFSET_EPHY));
+		}
 	}
-#endif
 
 	/* Set clock gating for emac */
 	setbits_le32(&ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_GMAC));
Signature · 1 line
2.14.1
#3 lore raw

PATCH v6 4/6 net: sun8i-emac: support R40 GMAC

In reply to Lothar Felten

Add support for the GMAC found in the Allwinner R40/V40 SoC.

The R40 GMAC interface is not controlled by the syscon register but has a separate configuration register in the CCU.
The clock gate and reset bits are in a different register compared to the other SoCs supported by this driver.
The driver uses the -gmac suffix for the R40 because the R40 also has a different 100 MBit MAC (EMAC).

---
Changelog:
new in v3
v3 -> v4 use driver data to distinguish between variants v4 -> v5 -> v6 none

---
 drivers/net/sun8i_emac.c | 79 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 53 insertions(+), 26 deletions(-)
drivers/net/sun8i_emac.c +53 -26
index ee3b2aa7f4..3ba3a1ff8b 100644
@@ -67,6 +67,7 @@
 
 /* IO mux settings */
 #define SUN8I_IOMUX_H3		2
+#define SUN8I_IOMUX_R40	5
 #define SUN8I_IOMUX		4
 
 /* H3/A64 EMAC Register's offset */
@@ -97,6 +98,7 @@ enum emac_variant {
 	A83T_EMAC = 1,
 	H3_EMAC,
 	A64_EMAC,
+	R40_GMAC,
 };
 
 struct emac_dma_desc {
@@ -278,6 +280,9 @@ static int sun8i_emac_set_syscon(struct emac_eth_dev *priv)
 
 	reg = readl(priv->sysctl_reg + 0x30);
 
+	if (priv->variant == R40_GMAC)
+		return 0;
+
 	if (priv->variant == H3_EMAC) {
 		ret = sun8i_emac_set_syscon_ephy(priv, &reg);
 		if (ret)
@@ -495,6 +500,8 @@ static int parse_phy_pins(struct udevice *dev)
 
 		if (priv->variant == H3_EMAC)
 			sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX_H3);
+		else if (priv->variant == R40_GMAC)
+			sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX_R40);
 		else
 			sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX);
 
@@ -634,11 +641,26 @@ static void sun8i_emac_board_setup(struct emac_eth_dev *priv)
 		}
 	}
 
-	/* Set clock gating for emac */
-	setbits_le32(&ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_GMAC));
-
-	/* De-assert EMAC */
-	setbits_le32(&ccm->ahb_reset0_cfg, BIT(AHB_RESET_OFFSET_GMAC));
+	if (priv->variant == R40_GMAC) {
+		/* Set clock gating for emac */
+		setbits_le32(&ccm->ahb_reset1_cfg, BIT(AHB_RESET_OFFSET_GMAC));
+
+		/* De-assert EMAC */
+		setbits_le32(&ccm->ahb_gate1, BIT(AHB_GATE_OFFSET_GMAC));
+
+		/* Select RGMII for R40 */
+		setbits_le32(&ccm->gmac_clk_cfg,
+			     CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII |
+			     CCM_GMAC_CTRL_GPIT_RGMII);
+		setbits_le32(&ccm->gmac_clk_cfg,
+			     CCM_GMAC_CTRL_TX_CLK_DELAY(CONFIG_GMAC_TX_DELAY));
+	} else {
+		/* Set clock gating for emac */
+		setbits_le32(&ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_GMAC));
+
+		/* De-assert EMAC */
+		setbits_le32(&ccm->ahb_reset0_cfg, BIT(AHB_RESET_OFFSET_GMAC));
+	}
 }
 
 #if defined(CONFIG_DM_GPIO)
@@ -805,22 +827,32 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
 		return -EINVAL;
 	}
 
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "syscon");
-	if (offset < 0) {
-		debug("%s: cannot find syscon node\n", __func__);
-		return -EINVAL;
-	}
-	reg = fdt_getprop(gd->fdt_blob, offset, "reg", NULL);
-	if (!reg) {
-		debug("%s: cannot find reg property in syscon node\n",
-		      __func__);
+	priv->variant = dev_get_driver_data(dev);
+
+	if (!priv->variant) {
+		printf("%s: Missing variant\n", __func__);
 		return -EINVAL;
 	}
-	priv->sysctl_reg = fdt_translate_address((void *)gd->fdt_blob,
-						 offset, reg);
-	if (priv->sysctl_reg == FDT_ADDR_T_NONE) {
-		debug("%s: Cannot find syscon base address\n", __func__);
-		return -EINVAL;
+
+	if (priv->variant != R40_GMAC) {
+		offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "syscon");
+		if (offset < 0) {
+			debug("%s: cannot find syscon node\n", __func__);
+			return -EINVAL;
+		}
+		reg = fdt_getprop(gd->fdt_blob, offset, "reg", NULL);
+		if (!reg) {
+			debug("%s: cannot find reg property in syscon node\n",
+			      __func__);
+			return -EINVAL;
+		}
+		priv->sysctl_reg = fdt_translate_address((void *)gd->fdt_blob,
+							 offset, reg);
+		if (priv->sysctl_reg == FDT_ADDR_T_NONE) {
+			debug("%s: Cannot find syscon base address\n",
+			      __func__);
+			return -EINVAL;
+		}
 	}
 
 	pdata->phy_interface = -1;
@@ -845,13 +877,6 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
 		return -EINVAL;
 	}
 
-	priv->variant = dev_get_driver_data(dev);
-
-	if (!priv->variant) {
-		printf("%s: Missing variant\n", __func__);
-		return -EINVAL;
-	}
-
 	if (priv->variant == H3_EMAC) {
 		int parent = fdt_parent_offset(gd->fdt_blob, offset);
 
@@ -892,6 +917,8 @@ static const struct udevice_id sun8i_emac_eth_ids[] = {
 		.data = (uintptr_t)A64_EMAC },
 	{.compatible = "allwinner,sun8i-a83t-emac",
 		.data = (uintptr_t)A83T_EMAC },
+	{.compatible = "allwinner,sun8i-r40-gmac",
+		.data = (uintptr_t)R40_GMAC },
 	{ }
 };
 
Signature · 1 line
2.14.1
#4 lore raw

PATCH v6 5/6 sunxi: R40: add gigabit ethernet devicetree node

In reply to Lothar Felten

Add a device tree node for the Allwinner R40/V40 GMAC gigabit ethernet interface.
The R40 SoC does not use the syscon register for GMAC settings. The gigabit ethernet interface can only be routed to a fixed set of pins.
Updated to match the Linux kernel's device tree.

---
Changelog:
new in v2
v2 -> v3 omit syscon node for R40
v3 -> v4 remove phy-mode from gmac node
v4 -> v5 match Linux device tree suggested by Chen-Yu Tsai v5 -> v6 none

---
 arch/arm/dts/sun8i-r40.dtsi | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
arch/arm/dts/sun8i-r40.dtsi +34 -0
index 0aa76a2f10..2cdfb54282 100644
@@ -161,6 +161,19 @@
 			#interrupt-cells = <3>;
 			#gpio-cells = <3>;
 
+			gmac_rgmii_pins: gmac-rgmii-pins {
+				pins = "PA0", "PA1", "PA2", "PA3",
+				       "PA4", "PA5", "PA6", "PA7",
+				       "PA8", "PA10", "PA11", "PA12",
+				       "PA13", "PA15", "PA16";
+				function = "gmac";
+				/*
+				 * data lines in RGMII mode use DDR mode
+				 * and need a higher signal drive strength
+				 */
+				drive-strength = <40>;
+			};
+
 			i2c0_pins: i2c0_pins {
 				pins = "PB0", "PB1";
 				function = "i2c0";
@@ -202,6 +215,27 @@
 			#size-cells = <0>;
 		};
 
+		gmac: ethernet at 1c50000 {
+			compatible = "allwinner,sun8i-r40-gmac";
+			syscon = <&ccu>;
+			reg = <0x01c50000 0x10000>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+			resets = <&ccu RST_BUS_GMAC>;
+			reset-names = "stmmaceth";
+			clocks = <&ccu CLK_BUS_GMAC>;
+			clock-names = "stmmaceth";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+
+			gmac_mdio: mdio {
+				compatible = "snps,dwmac-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
 		gic: interrupt-controller at 1c81000 {
 			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
 			reg = <0x01c81000 0x1000>,
Signature · 1 line
2.14.1
#5 lore raw

PATCH v6 6/6 configs: Bananapi_M2_Ultra: enable gigabit ethernet

In reply to Lothar Felten

Enable the gigabit ethernet for the Bananapi M2 Ultra board. Tested on BananaPi M2 Berry (R40), custom board (V40)

---
Changelog:
new in v2
v2 -> v3 remove unused CONFIG_SUN7I_GMAC
v3 -> v4 include device tree node, enable ALDO2
v4 -> v5 match Linux kernel device tree
v5 -> v6 remove unused CONFIG_DM_GPIO

---
 arch/arm/dts/sun8i-r40-bananapi-m2-ultra.dts | 16 ++++++++++++++++
 configs/Bananapi_M2_Ultra_defconfig          |  4 ++++
 2 files changed, 20 insertions(+)
arch/arm/dts/sun8i-r40-bananapi-m2-ultra.dts +16 -0
index ab471ab0bf..28c9158302 100644
@@ -48,6 +48,7 @@
 	compatible = "sinovoip,bpi-m2-ultra", "allwinner,sun8i-r40";
 
 	aliases {
+		ethernet0 = &gmac;
 		serial0 = &uart0;
 	};
 
@@ -67,3 +68,18 @@
 	pinctrl-0 = <&uart0_pb_pins>;
 	status = "okay";
 };
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_rgmii_pins>;
+	phy-handle = <&phy1>;
+	phy-mode = "rgmii";
+	status = "okay";
+};
+
+&gmac_mdio {
+	phy1: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <1>;
+	};
+};
configs/Bananapi_M2_Ultra_defconfig +4 -0
index 37cc2df5dc..edcbb16cf6 100644
@@ -14,6 +14,10 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_SCSI_AHCI=y
 CONFIG_AXP_DLDO4_VOLT=2500
+CONFIG_AXP_ALDO2_VOLT=2500
 CONFIG_AXP_ELDO3_VOLT=1200
 CONFIG_SCSI=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
+CONFIG_SUN8I_EMAC=y
+CONFIG_RGMII=y
+CONFIG_MACPWR="PA17"
Signature · 1 line
2.14.1
#6 lore raw

PATCH v6 6/6 configs: Bananapi_M2_Ultra: enable gigabit ethernet

Quoted 5 lines · Lothar Felten

Enable the gigabit ethernet for the Bananapi M2 Ultra board. Tested on BananaPi M2 Berry (R40), custom board (V40)

Maxime

Signature · 10 lines
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180713/a09d29dd/attachment.sig>