]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
net: mediatek: add support for adjusting MDIO clock
authorWeijie Gao <weijie.gao@mediatek.com>
Mon, 22 Jan 2024 02:08:11 +0000 (10:08 +0800)
committerTom Rini <trini@konsulko.com>
Fri, 1 Mar 2024 21:35:52 +0000 (16:35 -0500)
User can assign a specific MDC speed to the eth node as follow:

&eth {
...
phy-mode = "usxgmii";
phy-handle = <&phy8>;

mdio {
clock-frequency = <10500000>;
};

phy8: eth-phy@8 {
      compatible = "ethernet-phy-id31c3.1c12";
...
};

Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
drivers/net/mtk_eth.c
drivers/net/mtk_eth.h

index 3cfce058451d4210b9d784ff4c40c052c135ae81..726aedad3fae16bfa785ff120bf46bc7f1a0a595 100644 (file)
@@ -137,6 +137,7 @@ struct mtk_eth_priv {
        int force_mode;
        int speed;
        int duplex;
+       int mdc;
        bool pn_swap;
 
        struct phy_device *phydev;
@@ -1607,6 +1608,26 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
        mtk_pdma_write(priv, PDMA_RST_IDX_REG, RST_DTX_IDX0 | RST_DRX_IDX0);
 }
 
+static void mtk_eth_mdc_init(struct mtk_eth_priv *priv)
+{
+       u32 divider;
+
+       if (priv->mdc == 0)
+               return;
+
+       divider = min_t(u32, DIV_ROUND_UP(MDC_MAX_FREQ, priv->mdc), MDC_MAX_DIVIDER);
+
+       /* Configure MDC turbo mode */
+       if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
+               mtk_gmac_rmw(priv, GMAC_MAC_MISC_REG, 0, MISC_MDC_TURBO);
+       else
+               mtk_gmac_rmw(priv, GMAC_PPSC_REG, 0, MISC_MDC_TURBO);
+
+       /* Configure MDC divider */
+       mtk_gmac_rmw(priv, GMAC_PPSC_REG, PHY_MDC_CFG,
+                    FIELD_PREP(PHY_MDC_CFG, divider));
+}
+
 static int mtk_eth_start(struct udevice *dev)
 {
        struct mtk_eth_priv *priv = dev_get_priv(dev);
@@ -1803,6 +1824,9 @@ static int mtk_eth_probe(struct udevice *dev)
                noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC,
                                ARCH_DMA_MINALIGN);
 
+       /* Set MDC divider */
+       mtk_eth_mdc_init(priv);
+
        /* Set MAC mode */
        if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII)
                mtk_xmac_init(priv);
@@ -1881,6 +1905,17 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
 
        priv->gmac_id = dev_read_u32_default(dev, "mediatek,gmac-id", 0);
 
+       priv->mdc = 0;
+       subnode = ofnode_find_subnode(dev_ofnode(dev), "mdio");
+       if (ofnode_valid(subnode)) {
+               priv->mdc = ofnode_read_u32_default(subnode, "clock-frequency", 2500000);
+               if (priv->mdc > MDC_MAX_FREQ ||
+                   priv->mdc < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
+                       printf("error: MDIO clock frequency out of range\n");
+                       return -EINVAL;
+               }
+       }
+
        /* Interface mode is required */
        pdata->phy_interface = dev_read_phy_mode(dev);
        priv->phy_interface = pdata->phy_interface;
index 491cac56a81a04f9576e926a045909f0a61dc1f2..45229c0f9a963452f765a4708410016d9c700c93 100644 (file)
@@ -180,6 +180,12 @@ enum mkt_eth_capabilities {
 
 /* GMAC Registers */
 
+#define GMAC_PPSC_REG                  0x0000
+#define PHY_MDC_CFG                    GENMASK(29, 24)
+#define MDC_TURBO                      BIT(20)
+#define MDC_MAX_FREQ                   25000000
+#define MDC_MAX_DIVIDER                        63
+
 #define GMAC_PIAC_REG                  0x0004
 #define PHY_ACS_ST                     BIT(31)
 #define MDIO_REG_ADDR_S                        25
@@ -197,6 +203,7 @@ enum mkt_eth_capabilities {
 #define P1_XGMAC_FORCE_LINK            BIT(15)
 
 #define GMAC_MAC_MISC_REG              0x0010
+#define MISC_MDC_TURBO                 BIT(4)
 
 #define GMAC_GSW_CFG_REG               0x0080
 #define GSWTX_IPG_M                    0xF0000