aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-10-10 03:48:05 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-10 15:35:13 -0400
commit1fadee0c364572f2b2e098b34001fbaa82ee2e00 (patch)
tree809996015492996af409f7458fd7ecf4419365ca /drivers/net/phy
parent5af7fb6e3e92c2797ee30d66138cf6aa6b29240d (diff)
net/phy: micrel: Add clock support for KSZ8021/KSZ8031
The KSZ8021 and KSZ8031 support RMII reference input clocks of 25MHz and 50MHz. Both PHYs differ in the default frequency they expect after reset. If this differs from the actual input clock, then register 0x1f bit 7 must be changed. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/micrel.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 011dbda2b2f1..492435fce1d4 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -26,6 +26,7 @@
26#include <linux/phy.h> 26#include <linux/phy.h>
27#include <linux/micrel_phy.h> 27#include <linux/micrel_phy.h>
28#include <linux/of.h> 28#include <linux/of.h>
29#include <linux/clk.h>
29 30
30/* Operation Mode Strap Override */ 31/* Operation Mode Strap Override */
31#define MII_KSZPHY_OMSO 0x16 32#define MII_KSZPHY_OMSO 0x16
@@ -72,9 +73,12 @@ static int ksz_config_flags(struct phy_device *phydev)
72{ 73{
73 int regval; 74 int regval;
74 75
75 if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { 76 if (phydev->dev_flags & (MICREL_PHY_50MHZ_CLK | MICREL_PHY_25MHZ_CLK)) {
76 regval = phy_read(phydev, MII_KSZPHY_CTRL); 77 regval = phy_read(phydev, MII_KSZPHY_CTRL);
77 regval |= KSZ8051_RMII_50MHZ_CLK; 78 if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK)
79 regval |= KSZ8051_RMII_50MHZ_CLK;
80 else
81 regval &= ~KSZ8051_RMII_50MHZ_CLK;
78 return phy_write(phydev, MII_KSZPHY_CTRL, regval); 82 return phy_write(phydev, MII_KSZPHY_CTRL, regval);
79 } 83 }
80 return 0; 84 return 0;
@@ -440,6 +444,27 @@ ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum,
440{ 444{
441} 445}
442 446
447static int ksz8021_probe(struct phy_device *phydev)
448{
449 struct clk *clk;
450
451 clk = devm_clk_get(&phydev->dev, "rmii-ref");
452 if (!IS_ERR(clk)) {
453 unsigned long rate = clk_get_rate(clk);
454
455 if (rate > 24500000 && rate < 25500000) {
456 phydev->dev_flags |= MICREL_PHY_25MHZ_CLK;
457 } else if (rate > 49500000 && rate < 50500000) {
458 phydev->dev_flags |= MICREL_PHY_50MHZ_CLK;
459 } else {
460 dev_err(&phydev->dev, "Clock rate out of range: %ld\n", rate);
461 return -EINVAL;
462 }
463 }
464
465 return 0;
466}
467
443static struct phy_driver ksphy_driver[] = { 468static struct phy_driver ksphy_driver[] = {
444{ 469{
445 .phy_id = PHY_ID_KS8737, 470 .phy_id = PHY_ID_KS8737,
@@ -462,6 +487,7 @@ static struct phy_driver ksphy_driver[] = {
462 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | 487 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
463 SUPPORTED_Asym_Pause), 488 SUPPORTED_Asym_Pause),
464 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 489 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
490 .probe = ksz8021_probe,
465 .config_init = ksz8021_config_init, 491 .config_init = ksz8021_config_init,
466 .config_aneg = genphy_config_aneg, 492 .config_aneg = genphy_config_aneg,
467 .read_status = genphy_read_status, 493 .read_status = genphy_read_status,
@@ -477,6 +503,7 @@ static struct phy_driver ksphy_driver[] = {
477 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | 503 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
478 SUPPORTED_Asym_Pause), 504 SUPPORTED_Asym_Pause),
479 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 505 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
506 .probe = ksz8021_probe,
480 .config_init = ksz8021_config_init, 507 .config_init = ksz8021_config_init,
481 .config_aneg = genphy_config_aneg, 508 .config_aneg = genphy_config_aneg,
482 .read_status = genphy_read_status, 509 .read_status = genphy_read_status,