Commit 638c1152 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'adin-add-support-for-clock-output'

Josua Mayer says:

====================
adin: add support for clock output

This patch series adds support for configuring the two clock outputs of adin
1200 and 1300 PHYs. Certain network controllers require an external reference
clock which can be provided by the PHY.

One of the replies to v1 was asking why the common clock framework isn't used.
Currently no PHY driver has implemented providing a clock to the network
controller. Instead they rely on vendor extensions to make the appropriate
configuration. For example ar8035 uses qca,clk-out-frequency - this patchset
aimed to replicate the same functionality.

Finally the 125MHz free-running clock is enabled in the device-tree for
SolidRun i.MX6 SoMs, to support revisions 1.9 and later, where the original phy
has been replaced with an adin 1300.
To avoid introducing new warning messages during boot for SoMs before rev 1.9,
the status field of the new phy node is disabled by default, and will be
enabled by U-Boot on demand.
====================

Link: https://lore.kernel.org/r/20220517085143.3749-1-josua@solid-run.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a3641ca4 654cd222
...@@ -36,6 +36,21 @@ properties: ...@@ -36,6 +36,21 @@ properties:
enum: [ 4, 8, 12, 16, 20, 24 ] enum: [ 4, 8, 12, 16, 20, 24 ]
default: 8 default: 8
adi,phy-output-clock:
description: Select clock output on GP_CLK pin. Two clocks are available:
A 25MHz reference and a free-running 125MHz.
The phy can alternatively automatically switch between the reference and
the 125MHz clocks based on its internal state.
$ref: /schemas/types.yaml#/definitions/string
enum:
- 25mhz-reference
- 125mhz-free-running
- adaptive-free-running
adi,phy-output-reference-clock:
description: Enable 25MHz reference clock output on CLK25_REF pin.
type: boolean
unevaluatedProperties: false unevaluatedProperties: false
examples: examples:
......
...@@ -83,6 +83,16 @@ ethernet-phy@4 { ...@@ -83,6 +83,16 @@ ethernet-phy@4 {
qca,clk-out-frequency = <125000000>; qca,clk-out-frequency = <125000000>;
qca,smarteee-tw-us-1g = <24>; qca,smarteee-tw-us-1g = <24>;
}; };
/*
* ADIN1300 (som rev 1.9 or later) is always at address 1. It
* will be enabled automatically by U-Boot if detected.
*/
ethernet-phy@1 {
reg = <1>;
adi,phy-output-clock = "125mhz-free-running";
status = "disabled";
};
}; };
}; };
......
...@@ -99,6 +99,15 @@ ...@@ -99,6 +99,15 @@
#define ADIN1300_GE_SOFT_RESET_REG 0xff0c #define ADIN1300_GE_SOFT_RESET_REG 0xff0c
#define ADIN1300_GE_SOFT_RESET BIT(0) #define ADIN1300_GE_SOFT_RESET BIT(0)
#define ADIN1300_GE_CLK_CFG_REG 0xff1f
#define ADIN1300_GE_CLK_CFG_MASK GENMASK(5, 0)
#define ADIN1300_GE_CLK_CFG_RCVR_125 BIT(5)
#define ADIN1300_GE_CLK_CFG_FREE_125 BIT(4)
#define ADIN1300_GE_CLK_CFG_REF_EN BIT(3)
#define ADIN1300_GE_CLK_CFG_HRT_RCVR BIT(2)
#define ADIN1300_GE_CLK_CFG_HRT_FREE BIT(1)
#define ADIN1300_GE_CLK_CFG_25 BIT(0)
#define ADIN1300_GE_RGMII_CFG_REG 0xff23 #define ADIN1300_GE_RGMII_CFG_REG 0xff23
#define ADIN1300_GE_RGMII_RX_MSK GENMASK(8, 6) #define ADIN1300_GE_RGMII_RX_MSK GENMASK(8, 6)
#define ADIN1300_GE_RGMII_RX_SEL(x) \ #define ADIN1300_GE_RGMII_RX_SEL(x) \
...@@ -433,6 +442,33 @@ static int adin_set_tunable(struct phy_device *phydev, ...@@ -433,6 +442,33 @@ static int adin_set_tunable(struct phy_device *phydev,
} }
} }
static int adin_config_clk_out(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
const char *val = NULL;
u8 sel = 0;
device_property_read_string(dev, "adi,phy-output-clock", &val);
if (!val) {
/* property not present, do not enable GP_CLK pin */
} else if (strcmp(val, "25mhz-reference") == 0) {
sel |= ADIN1300_GE_CLK_CFG_25;
} else if (strcmp(val, "125mhz-free-running") == 0) {
sel |= ADIN1300_GE_CLK_CFG_FREE_125;
} else if (strcmp(val, "adaptive-free-running") == 0) {
sel |= ADIN1300_GE_CLK_CFG_HRT_FREE;
} else {
phydev_err(phydev, "invalid adi,phy-output-clock\n");
return -EINVAL;
}
if (device_property_read_bool(dev, "adi,phy-output-reference-clock"))
sel |= ADIN1300_GE_CLK_CFG_REF_EN;
return phy_modify_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_GE_CLK_CFG_REG,
ADIN1300_GE_CLK_CFG_MASK, sel);
}
static int adin_config_init(struct phy_device *phydev) static int adin_config_init(struct phy_device *phydev)
{ {
int rc; int rc;
...@@ -455,6 +491,10 @@ static int adin_config_init(struct phy_device *phydev) ...@@ -455,6 +491,10 @@ static int adin_config_init(struct phy_device *phydev)
if (rc < 0) if (rc < 0)
return rc; return rc;
rc = adin_config_clk_out(phydev);
if (rc < 0)
return rc;
phydev_dbg(phydev, "PHY is using mode '%s'\n", phydev_dbg(phydev, "PHY is using mode '%s'\n",
phy_modes(phydev->interface)); phy_modes(phydev->interface));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment