net: mediatek: add support for adjusting MDIO clock
User can assign a specific MDC speed to the eth node as follow:
ð {
...
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>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user