From: Johan Hovold <johan@kernel.org>
To: Florian Fainelli <f.fainelli@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Johan Hovold <johan@kernel.org>
Subject: [PATCH 17/22] net: phy: micrel: add generic rmii-ref-clk-sel support
Date: Tue, 11 Nov 2014 18:37:35 +0100 [thread overview]
Message-ID: <1415727460-20417-18-git-send-email-johan@kernel.org> (raw)
In-Reply-To: <1415727460-20417-1-git-send-email-johan@kernel.org>
Add generic RMII-reference-clock-select support.
Several Micrel PHY have a RMII-reference-clock-select bit to select
25 MHz or 50 MHz clock mode. Recently, support for configuring this
through device tree for KSZ8021 and KSZ8031 was added.
Generalise this support so that it can be configured for other PHY types
as well.
Note that some PHY revisions (of the same type) has this bit inverted.
This should be either configurable through a new device-tree property,
or preferably, determined based on PHY ID if possible.
Also note that this removes support for setting 25 MHz mode from board
files which was also added by the above mentioned commit 45f56cb82e45
("net/phy: micrel: Add clock support for KSZ8021/KSZ8031").
Signed-off-by: Johan Hovold <johan@kernel.org>
---
drivers/net/phy/micrel.c | 94 +++++++++++++++++++++++++---------------------
include/linux/micrel_phy.h | 1 -
2 files changed, 51 insertions(+), 44 deletions(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 6467bcc5a39d..d2e790cd3651 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -57,7 +57,7 @@
#define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9)
#define KSZ9021_CTRL_INT_ACTIVE_HIGH BIT(14)
#define KS8737_CTRL_INT_ACTIVE_HIGH BIT(14)
-#define KSZ8051_RMII_50MHZ_CLK BIT(7)
+#define KSZPHY_RMII_REF_CLK_SEL BIT(7)
/* Write/read to/from extended registers */
#define MII_KSZPHY_EXTREG 0x0b
@@ -76,15 +76,19 @@
struct kszphy_type {
u32 led_mode_reg;
bool has_broadcast_disable;
+ bool has_rmii_ref_clk_sel;
};
struct kszphy_priv {
const struct kszphy_type *type;
int led_mode;
+ bool rmii_ref_clk_sel;
+ bool rmii_ref_clk_sel_val;
};
static const struct kszphy_type ksz8021_type = {
.led_mode_reg = MII_KSZPHY_CTRL_2,
+ .has_rmii_ref_clk_sel = true,
};
static const struct kszphy_type ksz8041_type = {
@@ -100,21 +104,6 @@ static const struct kszphy_type ksz8081_type = {
.has_broadcast_disable = true,
};
-static int ksz_config_flags(struct phy_device *phydev)
-{
- int regval;
-
- if (phydev->dev_flags & (MICREL_PHY_50MHZ_CLK | MICREL_PHY_25MHZ_CLK)) {
- regval = phy_read(phydev, MII_KSZPHY_CTRL);
- if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK)
- regval |= KSZ8051_RMII_50MHZ_CLK;
- else
- regval &= ~KSZ8051_RMII_50MHZ_CLK;
- return phy_write(phydev, MII_KSZPHY_CTRL, regval);
- }
- return 0;
-}
-
static int kszphy_extended_write(struct phy_device *phydev,
u32 regnum, u16 val)
{
@@ -189,6 +178,22 @@ static int ks8737_config_intr(struct phy_device *phydev)
return rc < 0 ? rc : 0;
}
+static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val)
+{
+ int ctrl;
+
+ ctrl = phy_read(phydev, MII_KSZPHY_CTRL);
+ if (ctrl < 0)
+ return ctrl;
+
+ if (val)
+ ctrl |= KSZPHY_RMII_REF_CLK_SEL;
+ else
+ ctrl &= ~KSZPHY_RMII_REF_CLK_SEL;
+
+ return phy_write(phydev, MII_KSZPHY_CTRL, ctrl);
+}
+
static int kszphy_setup_led(struct phy_device *phydev, u32 reg, int val)
{
int rc, temp, shift;
@@ -243,6 +248,7 @@ static int kszphy_config_init(struct phy_device *phydev)
{
struct kszphy_priv *priv = phydev->priv;
const struct kszphy_type *type;
+ int ret;
if (!priv)
return 0;
@@ -252,6 +258,14 @@ static int kszphy_config_init(struct phy_device *phydev)
if (type->has_broadcast_disable)
kszphy_broadcast_disable(phydev);
+ if (priv->rmii_ref_clk_sel) {
+ ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
+ if (ret) {
+ dev_err(&phydev->dev, "failed to set rmii reference clock\n");
+ return ret;
+ }
+ }
+
if (priv->led_mode >= 0)
kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);
@@ -262,10 +276,8 @@ static int ksz8021_config_init(struct phy_device *phydev)
{
int rc;
- kszphy_config_init(phydev);
-
- rc = ksz_config_flags(phydev);
- if (rc < 0)
+ rc = kszphy_config_init(phydev);
+ if (rc)
return rc;
rc = kszphy_broadcast_disable(phydev);
@@ -273,16 +285,6 @@ static int ksz8021_config_init(struct phy_device *phydev)
return rc < 0 ? rc : 0;
}
-static int ks8051_config_init(struct phy_device *phydev)
-{
- int rc;
-
- kszphy_config_init(phydev);
-
- rc = ksz_config_flags(phydev);
- return rc < 0 ? rc : 0;
-}
-
static int ksz9021_load_values_from_of(struct phy_device *phydev,
struct device_node *of_node, u16 reg,
char *field1, char *field2,
@@ -517,6 +519,7 @@ static int kszphy_probe(struct phy_device *phydev)
const struct kszphy_type *type = phydev->drv->driver_data;
struct device_node *np = phydev->dev.of_node;
struct kszphy_priv *priv;
+ struct clk *clk;
int ret;
priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL);
@@ -542,28 +545,32 @@ static int kszphy_probe(struct phy_device *phydev)
priv->led_mode = -1;
}
- return 0;
-}
-
-static int ksz8021_probe(struct phy_device *phydev)
-{
- struct clk *clk;
-
clk = devm_clk_get(&phydev->dev, "rmii-ref");
if (!IS_ERR(clk)) {
unsigned long rate = clk_get_rate(clk);
+ priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel;
+
+ /* FIXME: add support for PHY revisions that have this bit
+ * inverted (e.g. through new property or based on PHY ID).
+ */
if (rate > 24500000 && rate < 25500000) {
- phydev->dev_flags |= MICREL_PHY_25MHZ_CLK;
+ priv->rmii_ref_clk_sel_val = false;
} else if (rate > 49500000 && rate < 50500000) {
- phydev->dev_flags |= MICREL_PHY_50MHZ_CLK;
+ priv->rmii_ref_clk_sel_val = true;
} else {
dev_err(&phydev->dev, "Clock rate out of range: %ld\n", rate);
return -EINVAL;
}
}
- return kszphy_probe(phydev);
+ /* Support legacy board-file configuration */
+ if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) {
+ priv->rmii_ref_clk_sel = true;
+ priv->rmii_ref_clk_sel_val = true;
+ }
+
+ return 0;
}
static struct phy_driver ksphy_driver[] = {
@@ -589,7 +596,7 @@ static struct phy_driver ksphy_driver[] = {
SUPPORTED_Asym_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
.driver_data = &ksz8021_type,
- .probe = ksz8021_probe,
+ .probe = kszphy_probe,
.config_init = ksz8021_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
@@ -606,7 +613,7 @@ static struct phy_driver ksphy_driver[] = {
SUPPORTED_Asym_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
.driver_data = &ksz8021_type,
- .probe = ksz8021_probe,
+ .probe = kszphy_probe,
.config_init = ksz8021_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
@@ -657,7 +664,8 @@ static struct phy_driver ksphy_driver[] = {
| SUPPORTED_Asym_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
.driver_data = &ksz8051_type,
- .config_init = ks8051_config_init,
+ .probe = kszphy_probe,
+ .config_init = kszphy_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.ack_interrupt = kszphy_ack_interrupt,
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index 53d33dee70e1..2e5b194b9b19 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h
@@ -37,7 +37,6 @@
/* struct phy_device dev_flags definitions */
#define MICREL_PHY_50MHZ_CLK 0x00000001
-#define MICREL_PHY_25MHZ_CLK 0x00000002
#define MICREL_KSZ9021_EXTREG_CTRL 0xB
#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC
--
2.0.4
next prev parent reply other threads:[~2014-11-11 17:37 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-11 17:37 [PATCH 00/22] net: phy: refactoring and Micrel features Johan Hovold
[not found] ` <1415727460-20417-1-git-send-email-johan-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2014-11-11 17:37 ` [PATCH 01/22] dt/bindings: fix documentation of ethernet-phy compatible property Johan Hovold
2014-11-11 17:37 ` [PATCH 02/22] net: phy: add module_phy_driver macro Johan Hovold
2014-11-11 17:37 ` [PATCH 03/22] net: phy: replace phy_driver_register calls Johan Hovold
2014-11-11 17:37 ` [PATCH 04/22] net: phy: replace phy_drivers_register calls Johan Hovold
2014-11-11 17:37 ` [PATCH 05/22] net: phy: micrel: fix config_intr error handling Johan Hovold
2014-11-11 17:37 ` [PATCH 06/22] net: phy: micrel: use BIT macro Johan Hovold
2014-11-11 17:37 ` [PATCH 07/22] net: phy: micrel: refactor broadcast disable Johan Hovold
2014-11-11 17:37 ` [PATCH 08/22] net: phy: micrel: disable broadcast for KSZ8081/KSZ8091 Johan Hovold
2014-11-11 17:37 ` [PATCH 09/22] net: phy: micrel: add led-mode sanity check Johan Hovold
2014-11-11 17:37 ` [PATCH 10/22] net: phy: micrel: refactor led-mode error handling Johan Hovold
2014-11-11 17:37 ` [PATCH 11/22] net: phy: micrel: clean up led-mode setup Johan Hovold
2014-11-11 17:37 ` [PATCH 12/22] net: phy: micrel: enable led-mode for KSZ8081/KSZ8091 Johan Hovold
2014-11-11 17:37 ` [PATCH 13/22] net: phy: add static data field to struct phy_driver Johan Hovold
2014-11-11 17:37 ` [PATCH 14/22] net: phy: micrel: add device-type abstraction Johan Hovold
2014-11-11 17:37 ` [PATCH 15/22] net: phy: micrel: parse of nodes at probe Johan Hovold
2014-11-11 17:37 ` [PATCH 16/22] net: phy: micrel: add has-broadcast-disable flag to type data Johan Hovold
2014-11-11 17:37 ` Johan Hovold [this message]
2014-11-11 17:37 ` [PATCH 18/22] net: phy: micrel: add support for rmii_ref_clk_sel to KSZ8081/KSZ8091 Johan Hovold
2014-11-11 17:37 ` [PATCH 19/22] dt/bindings: add micrel,rmii_ref_clk_sel_25_mhz to eth-phy binding Johan Hovold
2014-11-11 17:57 ` Mark Rutland
2014-11-11 18:18 ` Johan Hovold
2014-11-12 7:01 ` Sascha Hauer
2014-11-12 9:19 ` Johan Hovold
2014-11-13 8:09 ` Sascha Hauer
2014-11-14 11:21 ` Johan Hovold
2014-11-11 17:37 ` [PATCH 20/22] net: phy: micrel: refactor interrupt config Johan Hovold
2014-11-11 17:37 ` [PATCH 21/22] net: phy: micrel: add copyright entry Johan Hovold
2014-11-11 17:37 ` [RFC 22/22] net: phy: micrel: use generic config_init for KSZ8021/KSZ8031 Johan Hovold
2014-11-11 17:49 ` [PATCH 00/22] net: phy: refactoring and Micrel features David Miller
2014-11-11 18:00 ` Johan Hovold
2014-11-11 18:01 ` Florian Fainelli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1415727460-20417-18-git-send-email-johan@kernel.org \
--to=johan@kernel.org \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).