#include <linux/platform_device.h>
#include <linux/ath9k_platform.h>
#include <linux/ar8216_platform.h>
+#include <linux/platform_data/phy-at803x.h>
#include <asm/mach-ath79/ar71xx_regs.h>
},
};
+static struct at803x_platform_data mynet_rext_at803x_data = {
+ .disable_smarteee = 0,
+ .enable_rgmii_rx_delay = 1,
+ .enable_rgmii_tx_delay = 0,
+ .fixup_rgmii_tx_delay = 1,
+};
+
+static struct mdio_board_info mynet_rext_mdio0_info[] = {
+ {
+ .bus_id = "ag71xx-mdio.0",
+ .phy_addr = 4,
+ .platform_data = &mynet_rext_at803x_data,
+ },
+};
+
static void mynet_rext_get_mac(const char *name, char *mac)
{
u8 *nvram = (u8 *) KSEG1ADDR(MYNET_REXT_NVRAM_ADDR);
ath79_register_mdio(0, 0x0);
+ mdiobus_register_board_info(mynet_rext_mdio0_info,
+ ARRAY_SIZE(mynet_rext_mdio0_info));
+
/* LAN */
mynet_rext_get_mac("et0macaddr=", ath79_eth0_data.mac_addr);
/* GMAC0 is connected to an external PHY on Port 4 */
ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
ath79_eth0_data.phy_mask = BIT(4);
+ ath79_eth0_pll_data.pll_10 = 0x00001313; /* athrs_mac.c */
ath79_eth0_pll_data.pll_1000 = 0x0e000000; /* athrs_mac.c */
ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
ath79_register_eth(0);
#define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05
#define AT803X_DEBUG_RGMII_TX_CLK_DLY BIT(8)
+@@ -50,6 +60,7 @@ MODULE_LICENSE("GPL");
+ struct at803x_priv {
+ bool phy_reset:1;
+ struct gpio_desc *gpiod_reset;
++ int prev_speed;
+ };
+
+ struct at803x_context {
@@ -61,6 +71,43 @@ struct at803x_context {
u16 led_control;
};
return 0;
}
+@@ -258,6 +334,8 @@ static int at803x_config_intr(struct phy
+ static void at803x_link_change_notify(struct phy_device *phydev)
+ {
+ struct at803x_priv *priv = phydev->priv;
++ struct at803x_platform_data *pdata;
++ pdata = dev_get_platdata(&phydev->dev);
+
+ /*
+ * Conduct a hardware reset for AT8030 every time a link loss is
+@@ -287,6 +365,26 @@ static void at803x_link_change_notify(st
+ } else {
+ priv->phy_reset = false;
+ }
++ }
++ if (pdata->fixup_rgmii_tx_delay &&
++ phydev->speed != priv->prev_speed) {
++ switch (phydev->speed) {
++ case SPEED_10:
++ case SPEED_100:
++ at803x_dbg_reg_set(phydev,
++ AT803X_DEBUG_SYSTEM_MODE_CTRL,
++ AT803X_DEBUG_RGMII_TX_CLK_DLY);
++ break;
++ case SPEED_1000:
++ at803x_dbg_reg_clr(phydev,
++ AT803X_DEBUG_SYSTEM_MODE_CTRL,
++ AT803X_DEBUG_RGMII_TX_CLK_DLY);
++ break;
++ default:
++ break;
++ }
++
++ priv->prev_speed = phydev->speed;
+ }
+ }
+
--- /dev/null
+++ b/include/linux/platform_data/phy-at803x.h
-@@ -0,0 +1,10 @@
+@@ -0,0 +1,11 @@
+#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;
++ int disable_smarteee:1;
++ int enable_rgmii_tx_delay:1;
++ int enable_rgmii_rx_delay:1;
++ int fixup_rgmii_tx_delay:1;
+};
+
+#endif /* _PHY_AT803X_PDATA_H */