aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ar71xx/patches-3.14/425-net-phy-at803x-allow-to-configure-via-pdata.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-08-07 12:40:53 +0000
committerFelix Fietkau <nbd@openwrt.org>2014-08-07 12:40:53 +0000
commite41a0cafff16f2443e587884782172c6d8478771 (patch)
tree2ab441d85607622857c5d7602918d24312daa7ab /target/linux/ar71xx/patches-3.14/425-net-phy-at803x-allow-to-configure-via-pdata.patch
parentf75f9606ad6af9f4c62acd45741a7e3880ad7dbb (diff)
downloadupstream-e41a0cafff16f2443e587884782172c6d8478771.tar.gz
upstream-e41a0cafff16f2443e587884782172c6d8478771.tar.bz2
upstream-e41a0cafff16f2443e587884782172c6d8478771.zip
ar71xx: add linux 3.14 support
Signed-off-by: Zhao, Gang <gang.zhao.42@gmail.com> Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 42038
Diffstat (limited to 'target/linux/ar71xx/patches-3.14/425-net-phy-at803x-allow-to-configure-via-pdata.patch')
-rw-r--r--target/linux/ar71xx/patches-3.14/425-net-phy-at803x-allow-to-configure-via-pdata.patch134
1 files changed, 134 insertions, 0 deletions
diff --git a/target/linux/ar71xx/patches-3.14/425-net-phy-at803x-allow-to-configure-via-pdata.patch b/target/linux/ar71xx/patches-3.14/425-net-phy-at803x-allow-to-configure-via-pdata.patch
new file mode 100644
index 0000000000..ffaceca5c7
--- /dev/null
+++ b/target/linux/ar71xx/patches-3.14/425-net-phy-at803x-allow-to-configure-via-pdata.patch
@@ -0,0 +1,134 @@
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -12,10 +12,12 @@
+ */
+
+ #include <linux/phy.h>
++#include <linux/mdio.h>
+ #include <linux/module.h>
+ #include <linux/string.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
++#include <linux/platform_data/phy-at803x.h>
+
+ #define AT803X_INTR_ENABLE 0x12
+ #define AT803X_INTR_STATUS 0x13
+@@ -32,10 +34,61 @@
+ #define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05
+ #define AT803X_DEBUG_RGMII_TX_CLK_DLY BIT(8)
+
++#define AT803X_PCS_SMART_EEE_CTRL3 0x805D
++
++#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3
++#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT 12
++#define AT803X_SMART_EEE_CTRL3_LPI_EN BIT(8)
++
++#define AT803X_DEBUG_PORT_ACCESS_OFFSET 0x1D
++#define AT803X_DEBUG_PORT_ACCESS_DATA 0x1E
++
++#define AT803X_DBG0_REG 0x00
++#define AT803X_DBG0_RGMII_RX_CLK_DELAY_EN BIT(8)
++
++#define AT803X_DBG5_REG 0x05
++#define AT803X_DBG5_RGMII_TX_CLK_DELAY_EN BIT(8)
++
+ MODULE_DESCRIPTION("Atheros 803x PHY driver");
+ MODULE_AUTHOR("Matus Ujhelyi");
+ MODULE_LICENSE("GPL");
+
++static u16
++at803x_dbg_reg_rmw(struct phy_device *phydev, u16 reg, u16 clear, u16 set)
++{
++ struct mii_bus *bus = phydev->bus;
++ int val;
++
++ mutex_lock(&bus->mdio_lock);
++
++ bus->write(bus, phydev->addr, AT803X_DEBUG_PORT_ACCESS_OFFSET, reg);
++ val = bus->read(bus, phydev->addr, AT803X_DEBUG_PORT_ACCESS_DATA);
++ if (val < 0) {
++ val = 0xffff;
++ goto out;
++ }
++
++ val &= ~clear;
++ val |= set;
++ bus->write(bus, phydev->addr, AT803X_DEBUG_PORT_ACCESS_DATA, val);
++
++out:
++ mutex_unlock(&bus->mdio_lock);
++ return val;
++}
++
++static inline void
++at803x_dbg_reg_set(struct phy_device *phydev, u16 reg, u16 set)
++{
++ at803x_dbg_reg_rmw(phydev, reg, 0, set);
++}
++
++static inline void
++at803x_dbg_reg_clr(struct phy_device *phydev, u16 reg, u16 clear)
++{
++ at803x_dbg_reg_rmw(phydev, reg, clear, 0);
++}
++
+ static int at803x_set_wol(struct phy_device *phydev,
+ struct ethtool_wolinfo *wol)
+ {
+@@ -139,8 +192,16 @@ static int at803x_resume(struct phy_devi
+ return 0;
+ }
+
++static void at803x_disable_smarteee(struct phy_device *phydev)
++{
++ phy_write_mmd(phydev, MDIO_MMD_PCS, AT803X_PCS_SMART_EEE_CTRL3,
++ 1 << AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT);
++ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
++}
++
+ static int at803x_config_init(struct phy_device *phydev)
+ {
++ struct at803x_platform_data *pdata;
+ int val;
+ int ret;
+ u32 features;
+@@ -188,6 +249,26 @@ static int at803x_config_init(struct phy
+ return ret;
+ }
+
++ pdata = dev_get_platdata(&phydev->dev);
++ if (pdata) {
++ if (pdata->disable_smarteee)
++ at803x_disable_smarteee(phydev);
++
++ if (pdata->enable_rgmii_rx_delay)
++ at803x_dbg_reg_set(phydev, AT803X_DBG0_REG,
++ AT803X_DBG0_RGMII_RX_CLK_DELAY_EN);
++ else
++ at803x_dbg_reg_clr(phydev, AT803X_DBG0_REG,
++ AT803X_DBG0_RGMII_RX_CLK_DELAY_EN);
++
++ if (pdata->enable_rgmii_tx_delay)
++ at803x_dbg_reg_set(phydev, AT803X_DBG5_REG,
++ AT803X_DBG5_RGMII_TX_CLK_DELAY_EN);
++ else
++ at803x_dbg_reg_clr(phydev, AT803X_DBG5_REG,
++ AT803X_DBG5_RGMII_TX_CLK_DELAY_EN);
++ }
++
+ return 0;
+ }
+
+--- /dev/null
++++ b/include/linux/platform_data/phy-at803x.h
+@@ -0,0 +1,10 @@
++#ifndef _PHY_AT803X_PDATA_H
++#define _PHY_AT803X_PDATA_H
++
++struct at803x_platform_data {
++ int disable_smarteee:1;
++ int enable_rgmii_tx_delay:1;
++ int enable_rgmii_rx_delay:1;
++};
++
++#endif /* _PHY_AT803X_PDATA_H */