Skip to content

Commit 23a890d

Browse files
Luo Jiedavem330
authored andcommitted
net: mdio: Add the reset function for IPQ MDIO driver
1. configure the MDIO clock source frequency. 2. the LDO resource is needed to configure the ethernet LDO available for CMN_PLL. Signed-off-by: Luo Jie <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e4637f6 commit 23a890d

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

drivers/net/mdio/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ config MDIO_OCTEON
169169
config MDIO_IPQ4019
170170
tristate "Qualcomm IPQ4019 MDIO interface support"
171171
depends on HAS_IOMEM && OF_MDIO
172+
depends on COMMON_CLK
172173
help
173174
This driver supports the MDIO interface found in Qualcomm
174175
IPQ40xx series Soc-s.

drivers/net/mdio/mdio-ipq4019.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/of_mdio.h>
1212
#include <linux/phy.h>
1313
#include <linux/platform_device.h>
14+
#include <linux/clk.h>
1415

1516
#define MDIO_MODE_REG 0x40
1617
#define MDIO_ADDR_REG 0x44
@@ -31,8 +32,15 @@
3132
#define IPQ4019_MDIO_TIMEOUT 10000
3233
#define IPQ4019_MDIO_SLEEP 10
3334

35+
/* MDIO clock source frequency is fixed to 100M */
36+
#define IPQ_MDIO_CLK_RATE 100000000
37+
38+
#define IPQ_PHY_SET_DELAY_US 100000
39+
3440
struct ipq4019_mdio_data {
3541
void __iomem *membase;
42+
void __iomem *eth_ldo_rdy;
43+
struct clk *mdio_clk;
3644
};
3745

3846
static int ipq4019_mdio_wait_busy(struct mii_bus *bus)
@@ -171,10 +179,35 @@ static int ipq4019_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
171179
return 0;
172180
}
173181

182+
static int ipq_mdio_reset(struct mii_bus *bus)
183+
{
184+
struct ipq4019_mdio_data *priv = bus->priv;
185+
u32 val;
186+
int ret;
187+
188+
/* To indicate CMN_PLL that ethernet_ldo has been ready if platform resource 1
189+
* is specified in the device tree.
190+
*/
191+
if (priv->eth_ldo_rdy) {
192+
val = readl(priv->eth_ldo_rdy);
193+
val |= BIT(0);
194+
writel(val, priv->eth_ldo_rdy);
195+
fsleep(IPQ_PHY_SET_DELAY_US);
196+
}
197+
198+
/* Configure MDIO clock source frequency if clock is specified in the device tree */
199+
ret = clk_set_rate(priv->mdio_clk, IPQ_MDIO_CLK_RATE);
200+
if (ret)
201+
return ret;
202+
203+
return clk_prepare_enable(priv->mdio_clk);
204+
}
205+
174206
static int ipq4019_mdio_probe(struct platform_device *pdev)
175207
{
176208
struct ipq4019_mdio_data *priv;
177209
struct mii_bus *bus;
210+
struct resource *res;
178211
int ret;
179212

180213
bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*priv));
@@ -187,9 +220,19 @@ static int ipq4019_mdio_probe(struct platform_device *pdev)
187220
if (IS_ERR(priv->membase))
188221
return PTR_ERR(priv->membase);
189222

223+
priv->mdio_clk = devm_clk_get_optional(&pdev->dev, "gcc_mdio_ahb_clk");
224+
if (IS_ERR(priv->mdio_clk))
225+
return PTR_ERR(priv->mdio_clk);
226+
227+
/* The platform resource is provided on the chipset IPQ5018 */
228+
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
229+
if (res)
230+
priv->eth_ldo_rdy = devm_ioremap_resource(&pdev->dev, res);
231+
190232
bus->name = "ipq4019_mdio";
191233
bus->read = ipq4019_mdio_read;
192234
bus->write = ipq4019_mdio_write;
235+
bus->reset = ipq_mdio_reset;
193236
bus->parent = &pdev->dev;
194237
snprintf(bus->id, MII_BUS_ID_SIZE, "%s%d", pdev->name, pdev->id);
195238

0 commit comments

Comments
 (0)