[][kernel][common][eth][Add MDC divider support]

[Description]
Add MDC divider support.

User can specify MDC speed by adding mdc-max-frequency property
to the mdio nodes.

================================================================
mdio: mdio-bus {
	#address-cells = <1>;
	#size-cells = <0>;
	mdc-max-frequency = <10500000>;

	phy0: ethernet-phy@0 {
		reg = <0>;
		compatible = "ethernet-phy-ieee802.3-c45";
		...
	};
	...
};
================================================================

Example: PHY device support 10.5MHz Maximum MDC clock.
User just need to declare this information in the DTS, driver will
find out a proper MDC divider(25MHz/3=8.33MHz) and setup
controller automatically.

If without this patch, MDC always running on 2.5MHz.

[Release-log]
N/A


Change-Id: If9171730373692243f02ceb9077bb496a774c8d0
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6756759
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 080e53e..6015127 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -814,7 +814,9 @@
 static int mtk_mdio_init(struct mtk_eth *eth)
 {
 	struct device_node *mii_np;
+	int clk = 25000000, max_clk = 2500000, divider = 1;
 	int ret;
+	u32 val;
 
 	mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
 	if (!mii_np) {
@@ -844,6 +846,36 @@
 		ret = -ENOMEM;
 		goto err_put_node;
 	}
+
+	if (!of_property_read_u32(mii_np, "mdc-max-frequency", &val))
+		max_clk = val;
+
+	while (clk / divider > max_clk) {
+		if (divider >= 63)
+			break;
+
+		divider++;
+	};
+
+	/* Configure MDC Turbo Mode */
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+		val = mtk_r32(eth, MTK_MAC_MISC);
+		val |= MISC_MDC_TURBO;
+		mtk_w32(eth, val, MTK_MAC_MISC);
+	} else {
+		val = mtk_r32(eth, MTK_PPSC);
+		val |= PPSC_MDC_TURBO;
+		mtk_w32(eth, val, MTK_PPSC);
+	}
+
+	/* Configure MDC Divider */
+	val = mtk_r32(eth, MTK_PPSC);
+	val &= ~PPSC_MDC_CFG;
+	val |= FIELD_PREP(PPSC_MDC_CFG, divider);
+	mtk_w32(eth, val, MTK_PPSC);
+
+	dev_info(eth->dev, "MDC is running on %d Hz\n", clk / divider);
+
 	ret = of_mdiobus_register(eth->mii_bus, mii_np);
 
 err_put_node:
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index a961042..d1e1d65 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -602,6 +602,11 @@
 #define RX_DMA_GET_AGG_CNT_V2(_x)	(((_x) >> 16) & 0xff)
 #define RX_DMA_GET_TOPS_CRSN(_x)	(((_x) >> 24) & 0xff)
 
+/* PHY Polling and SMI Master Control registers */
+#define MTK_PPSC		0x10000
+#define PPSC_MDC_CFG		GENMASK(29, 24)
+#define PPSC_MDC_TURBO		BIT(20)
+
 /* PHY Indirect Access Control registers */
 #define MTK_PHY_IAC		0x10004
 #define PHY_IAC_ACCESS		BIT(31)
@@ -615,7 +620,12 @@
 #define PHY_IAC_REG_SHIFT	25
 #define PHY_IAC_TIMEOUT		HZ
 
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+#define MTK_MAC_MISC		0x10010
+#else
 #define MTK_MAC_MISC		0x1000c
+#endif
+#define MISC_MDC_TURBO		BIT(4)
 #define MTK_MUX_TO_ESW		BIT(0)
 
 /* XMAC status registers */