@ -13,6 +13,7 @@
# include <phy.h>
# include <phy.h>
# define PHY_RTL8211x_FORCE_MASTER BIT(1)
# define PHY_RTL8211x_FORCE_MASTER BIT(1)
# define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2)
# define PHY_AUTONEGOTIATE_TIMEOUT 5000
# define PHY_AUTONEGOTIATE_TIMEOUT 5000
@ -47,6 +48,13 @@
# define MIIM_RTL8211F_PHYSTAT_SPDDONE 0x0800
# define MIIM_RTL8211F_PHYSTAT_SPDDONE 0x0800
# define MIIM_RTL8211F_PHYSTAT_LINK 0x0004
# define MIIM_RTL8211F_PHYSTAT_LINK 0x0004
# define MIIM_RTL8211E_CONFREG 0x1c
# define MIIM_RTL8211E_CONFREG_TXD 0x0002
# define MIIM_RTL8211E_CONFREG_RXD 0x0004
# define MIIM_RTL8211E_CONFREG_MAGIC 0xb400 /* Undocumented */
# define MIIM_RTL8211E_EXT_PAGE_SELECT 0x1e
# define MIIM_RTL8211F_PAGE_SELECT 0x1f
# define MIIM_RTL8211F_PAGE_SELECT 0x1f
# define MIIM_RTL8211F_TX_DELAY 0x100
# define MIIM_RTL8211F_TX_DELAY 0x100
# define MIIM_RTL8211F_LCR 0x10
# define MIIM_RTL8211F_LCR 0x10
@ -60,6 +68,15 @@ static int rtl8211b_probe(struct phy_device *phydev)
return 0 ;
return 0 ;
}
}
static int rtl8211e_probe ( struct phy_device * phydev )
{
# ifdef CONFIG_RTL8211E_PINE64_GIGABIT_FIX
phydev - > flags | = PHY_RTL8211E_PINE64_GIGABIT_FIX ;
# endif
return 0 ;
}
/* RealTek RTL8211x */
/* RealTek RTL8211x */
static int rtl8211x_config ( struct phy_device * phydev )
static int rtl8211x_config ( struct phy_device * phydev )
{
{
@ -81,6 +98,22 @@ static int rtl8211x_config(struct phy_device *phydev)
reg | = MIIM_RTL8211x_CTRL1000T_MASTER ;
reg | = MIIM_RTL8211x_CTRL1000T_MASTER ;
phy_write ( phydev , MDIO_DEVAD_NONE , MII_CTRL1000 , reg ) ;
phy_write ( phydev , MDIO_DEVAD_NONE , MII_CTRL1000 , reg ) ;
}
}
if ( phydev - > flags & PHY_RTL8211E_PINE64_GIGABIT_FIX ) {
unsigned int reg ;
phy_write ( phydev , MDIO_DEVAD_NONE , MIIM_RTL8211F_PAGE_SELECT ,
7 ) ;
phy_write ( phydev , MDIO_DEVAD_NONE ,
MIIM_RTL8211E_EXT_PAGE_SELECT , 0xa4 ) ;
reg = phy_read ( phydev , MDIO_DEVAD_NONE , MIIM_RTL8211E_CONFREG ) ;
/* Ensure both internal delays are turned off */
reg & = ~ ( MIIM_RTL8211E_CONFREG_TXD | MIIM_RTL8211E_CONFREG_RXD ) ;
/* Flip the magic undocumented bits */
reg | = MIIM_RTL8211E_CONFREG_MAGIC ;
phy_write ( phydev , MDIO_DEVAD_NONE , MIIM_RTL8211E_CONFREG , reg ) ;
phy_write ( phydev , MDIO_DEVAD_NONE , MIIM_RTL8211F_PAGE_SELECT ,
0 ) ;
}
/* read interrupt status just to clear it */
/* read interrupt status just to clear it */
phy_read ( phydev , MDIO_DEVAD_NONE , MIIM_RTL8211x_PHY_INER ) ;
phy_read ( phydev , MDIO_DEVAD_NONE , MIIM_RTL8211x_PHY_INER ) ;
@ -279,6 +312,7 @@ static struct phy_driver RTL8211E_driver = {
. uid = 0x1cc915 ,
. uid = 0x1cc915 ,
. mask = 0xffffff ,
. mask = 0xffffff ,
. features = PHY_GBIT_FEATURES ,
. features = PHY_GBIT_FEATURES ,
. probe = & rtl8211e_probe ,
. config = & rtl8211x_config ,
. config = & rtl8211x_config ,
. startup = & rtl8211e_startup ,
. startup = & rtl8211e_startup ,
. shutdown = & genphy_shutdown ,
. shutdown = & genphy_shutdown ,