From 40e80547b6bf9cce949202d08f64ef67a7957842 Mon Sep 17 00:00:00 2001 From: Merlijn Wajer Date: Mon, 16 Apr 2018 10:06:13 +0200 Subject: [PATCH] Forward port OLIMEX LIME2 Gbit ethernet patch Required for ethernet to work on some LIME2 revisions. --- board/sunxi/gmac.c | 2 -- drivers/net/phy/micrel_ksz90x1.c | 11 ++++++++++- drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++++ drivers/net/phy/smsc.c | 35 +++++++++++++++++++++++++++++++++-- include/configs/sunxi-common.h | 3 +++ 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c index 826650c..663bde1 100644 --- a/board/sunxi/gmac.c +++ b/board/sunxi/gmac.c @@ -24,8 +24,6 @@ void eth_init_board(void) #ifdef CONFIG_RGMII setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII | CCM_GMAC_CTRL_GPIT_RGMII); - setbits_le32(&ccm->gmac_clk_cfg, - CCM_GMAC_CTRL_TX_CLK_DELAY(CONFIG_GMAC_TX_DELAY)); #else setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_MII | CCM_GMAC_CTRL_GPIT_MII); diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c index b350a61..5005ee8 100644 --- a/drivers/net/phy/micrel_ksz90x1.c +++ b/drivers/net/phy/micrel_ksz90x1.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -103,7 +105,7 @@ static const struct ksz90x1_reg_field ksz9031_ctl_grp[] = { }; static const struct ksz90x1_reg_field ksz9031_clk_grp[] = { - { "rxc-skew-ps", 5, 0, 0xf }, { "txc-skew-ps", 5, 5, 0xf } + { "rxc-skew-ps", 5, 0, 0x7 }, { "txc-skew-ps", 5, 5, 0x17 } }; static int ksz90x1_of_config_group(struct phy_device *phydev, @@ -334,6 +336,13 @@ static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr, static int ksz9031_config(struct phy_device *phydev) { int ret; + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + +#ifdef CONFIG_RGMII + setbits_le32(&ccm->gmac_clk_cfg, + CCM_GMAC_CTRL_TX_CLK_DELAY(4)); +#endif ret = ksz9031_of_config(phydev); if (ret) diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index d5c2a46..8443aac 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #define PHY_RTL8211x_FORCE_MASTER BIT(1) #define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2) @@ -80,6 +82,9 @@ static int rtl8211e_probe(struct phy_device *phydev) /* RealTek RTL8211x */ static int rtl8211x_config(struct phy_device *phydev) { + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); /* mask interrupt at init; if the interrupt is @@ -88,6 +93,27 @@ static int rtl8211x_config(struct phy_device *phydev) phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER, MIIM_RTL8211x_PHY_INTR_DIS); + /* Check if device is RTL8211CL or RTL8211E */ + if(phydev->drv->uid == 0x1cc912) { + /* On RTL8211E TX delay must be 0 and + * phy must be forced to be master + */ + setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_DELAY(0)); + + unsigned int reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); + /* force manual master/slave configuration */ + reg |= MIIM_RTL8211x_CTRL1000T_MSCE; + /* force master mode */ + reg |= MIIM_RTL8211x_CTRL1000T_MASTER; + phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg); + + } else { + if(phydev->drv->uid == 0x1cc915) { + /* On RTL8211E make GMAC_TX_CLK_DELAY 2 */ + setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_DELAY(2)); + } + } + if (phydev->flags & PHY_RTL8211x_FORCE_MASTER) { unsigned int reg; @@ -114,6 +140,7 @@ static int rtl8211x_config(struct phy_device *phydev) phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0); } + /* read interrupt status just to clear it */ phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER); diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 73ed144..46ee3a8 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -11,6 +11,8 @@ * Copyright (c) 2006 Herbert Valerio Riedel */ #include +#include +#include /* This code does not check the partner abilities. */ static int smsc_parse_status(struct phy_device *phydev) @@ -43,6 +45,30 @@ static int smsc_startup(struct phy_device *phydev) return smsc_parse_status(phydev); } +#if 1 +static int olinuxino_smsc_startup(struct phy_device *phydev) +{ + int ret; + + ret = gpio_request(SUNXI_GPA(17), "lan8710-txerr"); + if(ret) + return ret; + gpio_direction_output(SUNXI_GPA(17), 0); + + ret = genphy_update_link(phydev); + if (ret) + return ret; + + return genphy_parse_link(phydev); +} + +static int olinuxino_smsc_shutdown(struct phy_device *phydev) +{ + sunxi_gpio_set_cfgpin(SUNXI_GPA(17), SUNXI_GPIO_INPUT); + return 0; +} +#endif + static struct phy_driver lan8700_driver = { .name = "SMSC LAN8700", .uid = 0x0007c0c0, @@ -69,8 +95,13 @@ static struct phy_driver lan8710_driver = { .mask = 0xffff0, .features = PHY_BASIC_FEATURES, .config = &genphy_config_aneg, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, +#if 1 + .startup = &olinuxino_smsc_startup, + .shutdown = &olinuxino_smsc_shutdown, +#else + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +#endif }; static struct phy_driver lan8740_driver = { diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 9d9e9ce..df9428b 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -294,6 +294,9 @@ extern int soft_i2c_gpio_scl; #ifdef CONFIG_SUN7I_GMAC #define CONFIG_MII /* MII PHY management */ #define CONFIG_PHY_REALTEK +#define CONFIG_PHY_MICREL +#define CONFIG_PHY_MICREL_KSZ9031 +#define CONFIG_PHY_SMSC #endif #ifdef CONFIG_USB_EHCI_HCD