From e54e051c0adbe86116ab81c09a208f3a62c84f92 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Wed, 5 Jun 2019 18:38:51 +0800 Subject: [PATCH] net: phy: at803x: add vddio-1v8 and eee disable support Add new property "at803x,vddio-1p8v" and "at803x,eee-disabled" support. Signed-off-by: Fugang Duan [ Aisheng: fix small merge conflict ] Signed-off-by: Dong Aisheng [rebase] Signed-off-by: Yangbo Lu --- drivers/net/phy/at803x.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -44,8 +44,13 @@ #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A +#define AT803X_SMARTEEE_CTL3_OFFSET 0x805D +#define AT803X_MMD_ACCESS_CONTROL 0x0D +#define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E +#define AT803X_FUNC_DATA 0x4003 #define AT803X_REG_CHIP_CONFIG 0x1f #define AT803X_BT_BX_REG_SEL 0x8000 +#define AT803X_SMARTEEE_DISABLED_VAL 0x1000 #define AT803X_DEBUG_ADDR 0x1D #define AT803X_DEBUG_DATA 0x1E @@ -64,6 +69,9 @@ #define AT803X_LPI_EN BIT(8) +#define AT803X_DEBUG_REG_31 0x1f +#define AT803X_VDDIO_1P8V_EN 0x8 + #define ATH8030_PHY_ID 0x004dd076 #define ATH8031_PHY_ID 0x004dd074 #define ATH8032_PHY_ID 0x004dd023 @@ -74,12 +82,16 @@ #define AT803X_PAGE_FIBER 0 #define AT803X_PAGE_COPPER 1 +#define AT803X_EEE_FEATURE_DISABLE (1 << 1) +#define AT803X_VDDIO_1P8V (1 << 2) + MODULE_DESCRIPTION("Atheros 803x PHY driver"); MODULE_AUTHOR("Matus Ujhelyi"); MODULE_LICENSE("GPL"); struct at803x_priv { bool phy_reset:1; + u32 quirks; }; struct at803x_context { @@ -172,6 +184,39 @@ static int at803x_disable_tx_delay(struc AT803X_DEBUG_TX_CLK_DLY_EN, 0); } +static inline int at803x_set_vddio_1p8v(struct phy_device *phydev) +{ + return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_31, 0, + AT803X_VDDIO_1P8V_EN); +} + +static int at803x_disable_eee(struct phy_device *phydev) +{ + int ret; + + ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL, + AT803X_DEVICE_ADDR); + if (ret < 0) + return ret; + + ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA, + AT803X_SMARTEEE_CTL3_OFFSET); + if (ret < 0) + return ret; + + ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL, + AT803X_FUNC_DATA); + if (ret < 0) + return ret; + + ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA, + AT803X_SMARTEEE_DISABLED_VAL); + if (ret < 0) + return ret; + + return 0; +} + /* save relevant PHY registers to private copy */ static void at803x_context_save(struct phy_device *phydev, struct at803x_context *context) @@ -286,6 +331,12 @@ static int at803x_probe(struct phy_devic if (!priv) return -ENOMEM; + if (of_property_read_bool(dev->of_node, "at803x,eee-disabled")) + priv->quirks |= AT803X_EEE_FEATURE_DISABLE; + + if (of_property_read_bool(dev->of_node, "at803x,vddio-1p8v")) + priv->quirks |= AT803X_VDDIO_1P8V; + phydev->priv = priv; /* Some bootloaders leave the fiber page selected. @@ -316,6 +367,7 @@ static void at803x_enable_smart_eee(stru static int at803x_config_init(struct phy_device *phydev) { + struct at803x_priv *priv = phydev->priv; int ret; @@ -344,6 +396,18 @@ static int at803x_config_init(struct phy else ret = at803x_disable_tx_delay(phydev); + if (priv->quirks & AT803X_VDDIO_1P8V) { + ret = at803x_set_vddio_1p8v(phydev); + if (ret < 0) + return ret; + } + + if (priv->quirks & AT803X_EEE_FEATURE_DISABLE) { + ret = at803x_disable_eee(phydev); + if (ret < 0) + return ret; + } + return ret; }