Skip to content

Commit

Permalink
Merge branch 'add-further-dt-configuration-for-at803x-phys'
Browse files Browse the repository at this point in the history
Russell King says:

====================
Add further DT configuration for AT803x PHYs

This patch series adds the ability to configure the SmartEEE feature
in AT803x PHYs. SmartEEE defaults to enabled on these PHYs, and has
a history of causing random sporadic link drops at Gigabit speeds.

There appears to be two solutions to this. There is the approach that
Freescale adopted early on, which is to disable the SmartEEE feature.
However, this loses the power saving provided by EEE. Another solution
was found by Jon Nettleton is to increase the Tw parameter for Gigabit
links.

This patch series adds support for both approaches, by adding a boolean:

	qca,disable-smarteee

if one wishes to disable SmartEEE, and two properties to configure the
SmartEEE Tw parameters:

	qca,smarteee-tw-us-100m
	qca,smarteee-tw-us-1g

Sadly, the PHY quirk I merged a while back for AT8035 on iMX6 is broken
- rather than disabling SmartEEE mode, it enables it.

The addition of these properties will be sent to the appropriate
platform maintainers - although for SolidRun platforms, we only make use
of "qca,smarteee-tw-us-1g".
====================

Link: https://lore.kernel.org/r/20210114104455.GP1551@shell.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Jan 15, 2021
2 parents 1d9f03c + 390b4ca commit e7fa5c8
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
16 changes: 16 additions & 0 deletions Documentation/devicetree/bindings/net/qca,ar803x.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ properties:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2]

qca,disable-smarteee:
description: Disable Atheros SmartEEE feature.
type: boolean

qca,keep-pll-enabled:
description: |
If set, keep the PLL enabled even if there is no link. Useful if you
Expand All @@ -36,6 +40,18 @@ properties:
Only supported on the AR8031.
type: boolean

qca,smarteee-tw-us-100m:
description: EEE Tw parameter for 100M links.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 1
maximum: 255

qca,smarteee-tw-us-1g:
description: EEE Tw parameter for gigabit links.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 1
maximum: 255

vddio-supply:
description: |
RGMII I/O voltage regulator (see regulator/regulator.yaml).
Expand Down
65 changes: 64 additions & 1 deletion drivers/net/phy/at803x.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@
#define AT803X_MIN_DOWNSHIFT 2
#define AT803X_MAX_DOWNSHIFT 9

#define AT803X_MMD3_SMARTEEE_CTL1 0x805b
#define AT803X_MMD3_SMARTEEE_CTL2 0x805c
#define AT803X_MMD3_SMARTEEE_CTL3 0x805d
#define AT803X_MMD3_SMARTEEE_CTL3_LPI_EN BIT(8)

#define ATH9331_PHY_ID 0x004dd041
#define ATH8030_PHY_ID 0x004dd076
#define ATH8031_PHY_ID 0x004dd074
Expand All @@ -146,8 +151,11 @@ MODULE_LICENSE("GPL");
struct at803x_priv {
int flags;
#define AT803X_KEEP_PLL_ENABLED BIT(0) /* don't turn off internal PLL */
#define AT803X_DISABLE_SMARTEEE BIT(1)
u16 clk_25m_reg;
u16 clk_25m_mask;
u8 smarteee_lpi_tw_1g;
u8 smarteee_lpi_tw_100m;
struct regulator_dev *vddio_rdev;
struct regulator_dev *vddh_rdev;
struct regulator *vddio;
Expand Down Expand Up @@ -411,13 +419,32 @@ static int at803x_parse_dt(struct phy_device *phydev)
{
struct device_node *node = phydev->mdio.dev.of_node;
struct at803x_priv *priv = phydev->priv;
u32 freq, strength;
u32 freq, strength, tw;
unsigned int sel;
int ret;

if (!IS_ENABLED(CONFIG_OF_MDIO))
return 0;

if (of_property_read_bool(node, "qca,disable-smarteee"))
priv->flags |= AT803X_DISABLE_SMARTEEE;

if (!of_property_read_u32(node, "qca,smarteee-tw-us-1g", &tw)) {
if (!tw || tw > 255) {
phydev_err(phydev, "invalid qca,smarteee-tw-us-1g\n");
return -EINVAL;
}
priv->smarteee_lpi_tw_1g = tw;
}

if (!of_property_read_u32(node, "qca,smarteee-tw-us-100m", &tw)) {
if (!tw || tw > 255) {
phydev_err(phydev, "invalid qca,smarteee-tw-us-100m\n");
return -EINVAL;
}
priv->smarteee_lpi_tw_100m = tw;
}

ret = of_property_read_u32(node, "qca,clk-out-frequency", &freq);
if (!ret) {
switch (freq) {
Expand Down Expand Up @@ -526,6 +553,38 @@ static void at803x_remove(struct phy_device *phydev)
regulator_disable(priv->vddio);
}

static int at803x_smarteee_config(struct phy_device *phydev)
{
struct at803x_priv *priv = phydev->priv;
u16 mask = 0, val = 0;
int ret;

if (priv->flags & AT803X_DISABLE_SMARTEEE)
return phy_modify_mmd(phydev, MDIO_MMD_PCS,
AT803X_MMD3_SMARTEEE_CTL3,
AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, 0);

if (priv->smarteee_lpi_tw_1g) {
mask |= 0xff00;
val |= priv->smarteee_lpi_tw_1g << 8;
}
if (priv->smarteee_lpi_tw_100m) {
mask |= 0x00ff;
val |= priv->smarteee_lpi_tw_100m;
}
if (!mask)
return 0;

ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL1,
mask, val);
if (ret)
return ret;

return phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL3,
AT803X_MMD3_SMARTEEE_CTL3_LPI_EN,
AT803X_MMD3_SMARTEEE_CTL3_LPI_EN);
}

static int at803x_clk_out_config(struct phy_device *phydev)
{
struct at803x_priv *priv = phydev->priv;
Expand Down Expand Up @@ -577,6 +636,10 @@ static int at803x_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;

ret = at803x_smarteee_config(phydev);
if (ret < 0)
return ret;

ret = at803x_clk_out_config(phydev);
if (ret < 0)
return ret;
Expand Down

0 comments on commit e7fa5c8

Please sign in to comment.