aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/devicetree/bindings/net/micrel.txt6
-rw-r--r--drivers/net/phy/micrel.c31
-rw-r--r--include/linux/micrel_phy.h1
3 files changed, 36 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/net/micrel.txt b/Documentation/devicetree/bindings/net/micrel.txt
index 98a3e61f9ee8..e1d99b95c4ec 100644
--- a/Documentation/devicetree/bindings/net/micrel.txt
+++ b/Documentation/devicetree/bindings/net/micrel.txt
@@ -16,3 +16,9 @@ Optional properties:
16 KSZ8051: register 0x1f, bits 5..4 16 KSZ8051: register 0x1f, bits 5..4
17 17
18 See the respective PHY datasheet for the mode values. 18 See the respective PHY datasheet for the mode values.
19
20 - clocks, clock-names: contains clocks according to the common clock bindings.
21
22 supported clocks:
23 - KSZ8021, KSZ8031: "rmii-ref": The RMII refence input clock. Used
24 to determine the XI input clock.
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,
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index 2e5b194b9b19..53d33dee70e1 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h
@@ -37,6 +37,7 @@
37 37
38/* struct phy_device dev_flags definitions */ 38/* struct phy_device dev_flags definitions */
39#define MICREL_PHY_50MHZ_CLK 0x00000001 39#define MICREL_PHY_50MHZ_CLK 0x00000001
40#define MICREL_PHY_25MHZ_CLK 0x00000002
40 41
41#define MICREL_KSZ9021_EXTREG_CTRL 0xB 42#define MICREL_KSZ9021_EXTREG_CTRL 0xB
42#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC 43#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC