blob: cfa2a0ca04f53716213d301ce6384dd949749f24 [file] [log] [blame]
developer5d148cb2023-06-02 13:08:11 +08001From c816d165754d8fd002478cce6eb774b9390c795f Mon Sep 17 00:00:00 2001
2From: Sam Shih <sam.shih@mediatek.com>
3Date: Fri, 2 Jun 2023 13:06:01 +0800
4Subject: [PATCH]
5 [backport-networking-drivers][999-1707-add-mdio-bus-for-gphy-calibration.patch]
6
7---
8 drivers/net/dsa/mt7530.c | 115 +++++++++++++++++++++++++++++++++++++++
9 1 file changed, 115 insertions(+)
10
11diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
12index 2cd5dae9c..290a2e77a 100644
13--- a/drivers/net/dsa/mt7530.c
14+++ b/drivers/net/dsa/mt7530.c
15@@ -847,6 +847,117 @@ mt7531_ind_phy_write(struct dsa_switch *ds, int port, int regnum,
developer382dc9c2022-10-13 09:34:36 +080016 return ret;
17 }
developer5d148cb2023-06-02 13:08:11 +080018
developer382dc9c2022-10-13 09:34:36 +080019+static int mt753x_mdio_read(struct mii_bus *bus, int addr, int regnum)
20+{
21+ struct mt7530_priv *priv = bus->priv;
22+ struct mt7530_dummy_poll p;
23+ int ret;
24+ u32 val;
25+
26+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
27+
28+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
29+
30+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
31+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
32+ if (ret < 0) {
33+ dev_err(priv->dev, "poll timeout\n");
34+ goto out;
35+ }
36+
37+ val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(addr) |
38+ MT7531_MDIO_REG_ADDR(regnum);
39+
40+ mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
41+
42+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
43+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
44+ if (ret < 0) {
45+ dev_err(priv->dev, "poll timeout\n");
46+ goto out;
47+ }
48+
49+ ret = val & MT7531_MDIO_RW_DATA_MASK;
50+out:
51+ mutex_unlock(&priv->bus->mdio_lock);
52+
53+ return ret;
54+}
55+
56+static int mt753x_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
57+{
58+ struct mt7530_priv *priv = bus->priv;
59+ struct mt7530_dummy_poll p;
60+ int ret;
61+ u32 reg;
62+
63+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
64+
65+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
66+
67+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
68+ !(reg & MT7531_PHY_ACS_ST), 20, 100000);
69+ if (ret < 0) {
70+ dev_err(priv->dev, "poll timeout\n");
71+ goto out;
72+ }
73+
74+ reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(addr) |
75+ MT7531_MDIO_REG_ADDR(regnum) | val;
76+
77+ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
78+
79+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
80+ !(reg & MT7531_PHY_ACS_ST), 20, 100000);
81+ if (ret < 0) {
82+ dev_err(priv->dev, "poll timeout\n");
83+ goto out;
84+ }
85+
86+out:
87+ mutex_unlock(&priv->bus->mdio_lock);
88+
89+ return ret;
90+}
91+
92+static int mt753x_setup_mdio(struct dsa_switch *ds)
93+{
94+ struct mt7530_priv *priv = ds->priv;
95+ struct device_node *mdio_np;
96+ int ret;
97+
98+ mdio_np = of_get_compatible_child(priv->dev->of_node, "mediatek,dsa-slave-mdio");
99+ if (!mdio_np) {
100+ dev_err(priv->dev, "no MDIO bus node\n");
101+ return -ENODEV;
102+ }
103+
104+ priv->ds->slave_mii_bus = devm_mdiobus_alloc(priv->dev);
105+ if (!priv->ds->slave_mii_bus) {
106+ ret = -ENOMEM;
107+ goto err_put_node;
108+ }
109+ priv->ds->slave_mii_bus->name = "mediatek,dsa-slave-mdio";
110+ priv->ds->slave_mii_bus->priv = priv;
111+ priv->ds->slave_mii_bus->parent = priv->dev;
112+ priv->ds->slave_mii_bus->phy_mask = ~priv->ds->phys_mii_mask;
113+ priv->ds->slave_mii_bus->read = mt753x_mdio_read;
114+ priv->ds->slave_mii_bus->write = mt753x_mdio_write;
115+ snprintf(priv->ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d.%d",
116+ priv->ds->dst->index, priv->ds->index);
117+ priv->ds->slave_mii_bus->dev.of_node = mdio_np;
118+
119+ ret = of_mdiobus_register(priv->ds->slave_mii_bus, mdio_np);
120+ if (ret)
121+ dev_err(priv->dev, "unable to register MDIO bus %s\n",
122+ priv->ds->slave_mii_bus->id);
123+
124+err_put_node:
125+ of_node_put(mdio_np);
126+
127+ return ret;
128+}
129+
130 static void
131 mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,
132 uint8_t *data)
developer5d148cb2023-06-02 13:08:11 +0800133@@ -2695,6 +2806,10 @@ mt7988_setup(struct dsa_switch *ds)
developer382dc9c2022-10-13 09:34:36 +0800134 if (ret < 0)
135 return ret;
developer5d148cb2023-06-02 13:08:11 +0800136
developer382dc9c2022-10-13 09:34:36 +0800137+ ret = mt753x_setup_mdio(ds);
138+ if (ret < 0)
139+ dev_err(priv->dev, "mt753x_setup_mdio failed\n");
140+
141 return 0;
142 }
developer5d148cb2023-06-02 13:08:11 +0800143
144--
1452.34.1
developer382dc9c2022-10-13 09:34:36 +0800146