History

net: phy: mscc-miim: add support to set MDIO bus frequency

Until now, the MDIO bus will have the hardware default bus frequency. Read the desired frequency of the bus from the device tree and configure it.

Michael Walle committed 4 years ago

Commit bb2a1931 parent b0385d41 file · +56 −2Browse files

Unified · Split

drivers/net/mdio/mdio-mscc-miim.c+56−2
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 */
88
99 #include <linux/bitops.h>
10+#include <linux/clk.h>
1011 #include <linux/io.h>
1112 #include <linux/iopoll.h>
1213 #include <linux/kernel.h>
@@ -30,6 +31,8 @@ · 17 unmodified lines
3031 #define MSCC_MIIM_CMD_VLD BIT(31)
3132 #define MSCC_MIIM_REG_DATA 0xC
3233 #define MSCC_MIIM_DATA_ERROR (BIT(16) | BIT(17))
34+#define MSCC_MIIM_REG_CFG 0x10
35+#define MSCC_MIIM_CFG_PRESCALE_MASK GENMASK(7, 0)
3336
3437 #define MSCC_PHY_REG_PHY_CFG 0x0
3538 #define PHY_CFG_PHY_ENA (BIT(0) | BIT(1) | BIT(2) | BIT(3))
@@ -50,6 +53,8 @@ struct mscc_miim_dev { · 14 unmodified lines
5053 int mii_status_offset;
5154 struct regmap *phy_regs;
5255 const struct mscc_miim_info *info;
56+ struct clk *clk;
57+ u32 bus_freq;
5358 };
5459
5560 /* When high resolution timers aren't built-in: we can't use usleep_range() as
@@ -235,9 +240,32 @@ int mscc_miim_setup(struct device *dev, struct mii_bus **pbus, const char *name, · 179 unmodified lines
235240 }
236241 EXPORT_SYMBOL(mscc_miim_setup);
237242
243+static int mscc_miim_clk_set(struct mii_bus *bus)
244+{
245+ struct mscc_miim_dev *miim = bus->priv;
246+ unsigned long rate;
247+ u32 div;
248+
249+ /* Keep the current settings */
250+ if (!miim->bus_freq)
251+ return 0;
252+
253+ rate = clk_get_rate(miim->clk);
254+
255+ div = DIV_ROUND_UP(rate, 2 * miim->bus_freq) - 1;
256+ if (div == 0 || div & ~MSCC_MIIM_CFG_PRESCALE_MASK) {
257+ dev_err(&bus->dev, "Incorrect MDIO clock frequency\n");
258+ return -EINVAL;
259+ }
260+
261+ return regmap_update_bits(miim->regs, MSCC_MIIM_REG_CFG,
262+ MSCC_MIIM_CFG_PRESCALE_MASK, div);
263+}
264+
238265 static int mscc_miim_probe(struct platform_device *pdev)
239266 {
240267 struct regmap *mii_regmap, *phy_regmap = NULL;
268+ struct device_node *np = pdev->dev.of_node;
241269 void __iomem *regs, *phy_regs;
242270 struct mscc_miim_dev *miim;
243271 struct resource *res;
@@ -288,21 +316,47 @@ static int mscc_miim_probe(struct platform_device *pdev) · 44 unmodified lines
288316 if (!miim->info)
289317 return -EINVAL;
290318
291− ret = of_mdiobus_register(bus, pdev->dev.of_node);
319+ miim->clk = devm_clk_get_optional(&pdev->dev, NULL);
320+ if (IS_ERR(miim->clk))
321+ return PTR_ERR(miim->clk);
322+
323+ of_property_read_u32(np, "clock-frequency", &miim->bus_freq);
324+
325+ if (miim->bus_freq && !miim->clk) {
326+ dev_err(&pdev->dev,
327+ "cannot use clock-frequency without a clock\n");
328+ return -EINVAL;
329+ }
330+
331+ ret = clk_prepare_enable(miim->clk);
332+ if (ret)
333+ return ret;
334+
335+ ret = mscc_miim_clk_set(bus);
336+ if (ret)
337+ goto out_disable_clk;
338+
339+ ret = of_mdiobus_register(bus, np);
292340 if (ret < 0) {
293341 dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
294− return ret;
342+ goto out_disable_clk;
295343 }
296344
297345 platform_set_drvdata(pdev, bus);
298346
299347 return 0;
348+
349+out_disable_clk:
350+ clk_disable_unprepare(miim->clk);
351+ return ret;
300352 }
301353
302354 static int mscc_miim_remove(struct platform_device *pdev)
303355 {
304356 struct mii_bus *bus = platform_get_drvdata(pdev);
357+ struct mscc_miim_dev *miim = bus->priv;
305358
359+ clk_disable_unprepare(miim->clk);
306360 mdiobus_unregister(bus);
307361
308362 return 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t