Browse Source

ramips: mt7620: add rgmii delays support

At this moment mt7620 ethernet driver doesn't support rgmii delays
configuration. SoC MT7620 have bits 2 and 3 in GPC1 an GPC2 to configure
delays for rx and tx rgmii interface.

This patch adds rx/tx rgmii delay configuration from dts.

Signed-off-by: Pawel Dembicki <[email protected]>
Pawel Dembicki 6 years ago
parent
commit
5410a8e295

+ 4 - 0
target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/gsw_mt7620.h

@@ -46,6 +46,10 @@
 #define GSW_REG_IMR		0x7008
 #define GSW_REG_ISR		0x700c
 #define GSW_REG_GPC1		0x7014
+#define GSW_REG_GPC2		0x701c
+
+#define GSW_REG_GPCx_TXDELAY	BIT(3)
+#define GSW_REG_GPCx_RXDELAY	BIT(2)
 
 #define GSW_REG_MAC_P0_MCR	0x100
 #define GSW_REG_MAC_P1_MCR	0x200

+ 34 - 0
target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/soc_mt7620.c

@@ -146,6 +146,8 @@ static void mt7620_port_init(struct fe_priv *priv, struct device_node *np)
 	int phy_mode, size, id;
 	int shift = 12;
 	u32 val, mask = 0;
+	u32 val_delay = 0;
+	u32 mask_delay = GSW_REG_GPCx_TXDELAY | GSW_REG_GPCx_RXDELAY;
 	int min = (gsw->port4 == PORT4_EPHY) ? (5) : (4);
 
 	if (!_id || (be32_to_cpu(*_id) < min) || (be32_to_cpu(*_id) > 5)) {
@@ -175,6 +177,25 @@ static void mt7620_port_init(struct fe_priv *priv, struct device_node *np)
 	switch (phy_mode) {
 	case PHY_INTERFACE_MODE_RGMII:
 		mask = 0;
+		/* Do not touch rx/tx delay in this state to avoid problems with
+		 * backward compability.
+		 */
+		mask_delay = 0;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		mask = 0;
+		val_delay |= GSW_REG_GPCx_TXDELAY;
+		val_delay &= ~GSW_REG_GPCx_RXDELAY;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		mask = 0;
+		val_delay &= ~GSW_REG_GPCx_TXDELAY;
+		val_delay &= ~GSW_REG_GPCx_RXDELAY;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		mask = 0;
+		val_delay &= ~GSW_REG_GPCx_TXDELAY;
+		val_delay |= GSW_REG_GPCx_RXDELAY;
 		break;
 	case PHY_INTERFACE_MODE_MII:
 		mask = 1;
@@ -196,6 +217,19 @@ static void mt7620_port_init(struct fe_priv *priv, struct device_node *np)
 	val |= mask << shift;
 	rt_sysc_w32(val, SYSC_REG_CFG1);
 
+	if (id == 4) {
+		val = mtk_switch_r32(gsw, GSW_REG_GPC2);
+		val &= ~(mask_delay);
+		val |= val_delay & mask_delay;
+		mtk_switch_w32(gsw, val, GSW_REG_GPC2);
+	}
+	else if (id == 5) {
+		val = mtk_switch_r32(gsw, GSW_REG_GPC1);
+		val &= ~(mask_delay);
+		val |= val_delay & mask_delay;
+		mtk_switch_w32(gsw, val, GSW_REG_GPC1);
+	}
+
 	if (priv->phy->phy_fixed[id]) {
 		const __be32 *link = priv->phy->phy_fixed[id];
 		int tx_fc, rx_fc;