aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/mtk_eth.c
diff options
context:
space:
mode:
authorMarkLee2020-01-21 19:31:57 +0800
committerTom Rini2020-02-07 13:59:58 -0500
commitb4ef49a905052f9f765d3e1b1e18244202de3083 (patch)
treecdba2eb1c7c73e7c32a62eda98f1efd30f751531 /drivers/net/mtk_eth.c
parenta54ece408582294217d5185dc40a950a3c2983ea (diff)
eth: mtk-eth: add sgmii mode support in mediatek eth driver
This patch add sgmii init part for the mediatek SoC that support sgmii mode. It is a must for mt7622. Signed-off-by: MarkLee <Mark-MC.Lee@mediatek.com>
Diffstat (limited to 'drivers/net/mtk_eth.c')
-rw-r--r--drivers/net/mtk_eth.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index c22e590387b..8354e82244e 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -151,6 +151,7 @@ struct mtk_eth_priv {
void __iomem *fe_base;
void __iomem *gmac_base;
void __iomem *ethsys_base;
+ void __iomem *sgmii_base;
struct mii_dev *mdio_bus;
int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg);
@@ -750,6 +751,24 @@ static int mtk_phy_probe(struct udevice *dev)
return 0;
}
+static void mtk_sgmii_init(struct mtk_eth_priv *priv)
+{
+ /* Set SGMII GEN2 speed(2.5G) */
+ clrsetbits_le32(priv->sgmii_base + SGMSYS_GEN2_SPEED,
+ SGMSYS_SPEED_2500, SGMSYS_SPEED_2500);
+
+ /* Disable SGMII AN */
+ clrsetbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1,
+ SGMII_AN_ENABLE, 0);
+
+ /* SGMII force mode setting */
+ writel(SGMII_FORCE_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE);
+
+ /* Release PHYA power down state */
+ clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL,
+ SGMII_PHYA_PWD, 0);
+}
+
static void mtk_mac_init(struct mtk_eth_priv *priv)
{
int i, ge_mode = 0;
@@ -758,8 +777,13 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
switch (priv->phy_interface) {
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII:
+ ge_mode = GE_MODE_RGMII;
+ break;
case PHY_INTERFACE_MODE_SGMII:
ge_mode = GE_MODE_RGMII;
+ mtk_ethsys_rmw(priv, ETHSYS_SYSCFG0_REG, SYSCFG0_SGMII_SEL_M,
+ SYSCFG0_SGMII_SEL(priv->gmac_id));
+ mtk_sgmii_init(priv);
break;
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
@@ -1104,6 +1128,26 @@ static int mtk_eth_ofdata_to_platdata(struct udevice *dev)
}
}
+ if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+ /* get corresponding sgmii phandle */
+ ret = dev_read_phandle_with_args(dev, "mediatek,sgmiisys",
+ NULL, 0, 0, &args);
+ if (ret)
+ return ret;
+
+ regmap = syscon_node_to_regmap(args.node);
+
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ priv->sgmii_base = regmap_get_range(regmap, 0);
+
+ if (!priv->sgmii_base) {
+ dev_err(dev, "Unable to find sgmii\n");
+ return -ENODEV;
+ }
+ }
+
/* check for switch first, otherwise phy will be used */
priv->sw = SW_NONE;
priv->switch_init = NULL;