kernel: split patches folder up into backport, pending and hack folders
[openwrt/openwrt.git] / target / linux / generic / pending-4.9 / 734-net-phy-at803x-allow-to-configure-via-pdata.patch
1 From: Gabor Juhos <juhosg@openwrt.org>
2 Subject: net: phy: allow to configure AR803x PHYs via platform data
3
4 Add a patch for the at803x phy driver, in order to be able
5 to configure some register settings via platform data.
6
7 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
8 ---
9 drivers/net/phy/at803x.c | 56 ++++++++++++++++++++++++++++++++
10 include/linux/platform_data/phy-at803x.h | 11 +++++++
11 2 files changed, 67 insertions(+)
12 create mode 100644 include/linux/platform_data/phy-at803x.h
13
14 diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
15 index c0f45dde60aa..4a55130dcb1c 100644
16 --- a/drivers/net/phy/at803x.c
17 +++ b/drivers/net/phy/at803x.c
18 @@ -12,12 +12,14 @@
19 */
20
21 #include <linux/phy.h>
22 +#include <linux/mdio.h>
23 #include <linux/module.h>
24 #include <linux/string.h>
25 #include <linux/netdevice.h>
26 #include <linux/etherdevice.h>
27 #include <linux/of_gpio.h>
28 #include <linux/gpio/consumer.h>
29 +#include <linux/platform_data/phy-at803x.h>
30
31 #define AT803X_INTR_ENABLE 0x12
32 #define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
33 @@ -45,6 +47,11 @@
34 #define AT803X_REG_CHIP_CONFIG 0x1f
35 #define AT803X_BT_BX_REG_SEL 0x8000
36
37 +#define AT803X_PCS_SMART_EEE_CTRL3 0x805D
38 +#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3
39 +#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT 12
40 +#define AT803X_SMART_EEE_CTRL3_LPI_EN BIT(8)
41 +
42 #define AT803X_DEBUG_ADDR 0x1D
43 #define AT803X_DEBUG_DATA 0x1E
44
45 @@ -72,6 +79,7 @@ MODULE_LICENSE("GPL");
46 struct at803x_priv {
47 bool phy_reset:1;
48 struct gpio_desc *gpiod_reset;
49 + int prev_speed;
50 };
51
52 struct at803x_context {
53 @@ -276,8 +284,16 @@ static int at803x_probe(struct phy_device *phydev)
54 return 0;
55 }
56
57 +static void at803x_disable_smarteee(struct phy_device *phydev)
58 +{
59 + phy_write_mmd(phydev, MDIO_MMD_PCS, AT803X_PCS_SMART_EEE_CTRL3,
60 + 1 << AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT);
61 + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
62 +}
63 +
64 static int at803x_config_init(struct phy_device *phydev)
65 {
66 + struct at803x_platform_data *pdata;
67 int ret;
68
69 ret = genphy_config_init(phydev);
70 @@ -298,6 +314,26 @@ static int at803x_config_init(struct phy_device *phydev)
71 return ret;
72 }
73
74 + pdata = dev_get_platdata(&phydev->mdio.dev);
75 + if (pdata) {
76 + if (pdata->disable_smarteee)
77 + at803x_disable_smarteee(phydev);
78 +
79 + if (pdata->enable_rgmii_rx_delay)
80 + at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
81 + AT803X_DEBUG_RX_CLK_DLY_EN);
82 + else
83 + at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
84 + AT803X_DEBUG_RX_CLK_DLY_EN, 0);
85 +
86 + if (pdata->enable_rgmii_tx_delay)
87 + at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
88 + AT803X_DEBUG_TX_CLK_DLY_EN);
89 + else
90 + at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
91 + AT803X_DEBUG_TX_CLK_DLY_EN, 0);
92 + }
93 +
94 return 0;
95 }
96
97 @@ -335,6 +371,8 @@ static int at803x_config_intr(struct phy_device *phydev)
98 static void at803x_link_change_notify(struct phy_device *phydev)
99 {
100 struct at803x_priv *priv = phydev->priv;
101 + struct at803x_platform_data *pdata;
102 + pdata = dev_get_platdata(&phydev->mdio.dev);
103
104 /*
105 * Conduct a hardware reset for AT8030/2 every time a link loss is
106 @@ -363,6 +401,24 @@ static void at803x_link_change_notify(struct phy_device *phydev)
107 } else {
108 priv->phy_reset = false;
109 }
110 + if (pdata && pdata->fixup_rgmii_tx_delay &&
111 + phydev->speed != priv->prev_speed) {
112 + switch (phydev->speed) {
113 + case SPEED_10:
114 + case SPEED_100:
115 + at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
116 + AT803X_DEBUG_TX_CLK_DLY_EN);
117 + break;
118 + case SPEED_1000:
119 + at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
120 + AT803X_DEBUG_TX_CLK_DLY_EN, 0);
121 + break;
122 + default:
123 + break;
124 + }
125 +
126 + priv->prev_speed = phydev->speed;
127 + }
128 }
129
130 static int at803x_aneg_done(struct phy_device *phydev)
131 diff --git a/include/linux/platform_data/phy-at803x.h b/include/linux/platform_data/phy-at803x.h
132 new file mode 100644
133 index 000000000000..a5df74b4f38d
134 --- /dev/null
135 +++ b/include/linux/platform_data/phy-at803x.h
136 @@ -0,0 +1,11 @@
137 +#ifndef _PHY_AT803X_PDATA_H
138 +#define _PHY_AT803X_PDATA_H
139 +
140 +struct at803x_platform_data {
141 + int disable_smarteee:1;
142 + int enable_rgmii_tx_delay:1;
143 + int enable_rgmii_rx_delay:1;
144 + int fixup_rgmii_tx_delay:1;
145 +};
146 +
147 +#endif /* _PHY_AT803X_PDATA_H */
148 --
149 2.11.0
150