@ -17,6 +17,7 @@
# include <asm/ti-common/keystone_serdes.h>
unsigned int emac_open ;
static struct mii_dev * mdio_bus ;
static unsigned int sys_has_mdio = 1 ;
# ifdef KEYSTONE2_EMAC_GIG_ENABLE
@ -42,10 +43,6 @@ static void keystone2_net_serdes_setup(void);
static int gen_get_link_speed ( int phy_addr ) ;
/* EMAC Addresses */
static volatile struct mdio_regs * adap_mdio =
( struct mdio_regs * ) EMAC_MDIO_BASE_ADDR ;
int keystone2_eth_read_mac_addr ( struct eth_device * dev )
{
struct eth_priv_t * eth_priv ;
@ -70,64 +67,67 @@ int keystone2_eth_read_mac_addr(struct eth_device *dev)
return 0 ;
}
static void keystone2_mdio_reset ( void )
/* MDIO */
static int keystone2_mdio_reset ( struct mii_dev * bus )
{
u_int32_t clkdiv ;
u_int32_t clkdiv ;
struct mdio_regs * adap_mdio = bus - > priv ;
clkdiv = ( EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ ) - 1 ;
writel ( ( clkdiv & 0xffff ) |
MDIO_CONTROL_ENABLE |
MDIO_CONTROL_FAULT |
MDIO_CONTROL_FAULT_ENABLE ,
writel ( ( clkdiv & 0xffff ) | MDIO_CONTROL_ENABLE |
MDIO_CONTROL_FAULT | MDIO_CONTROL_FAULT_ENABLE ,
& adap_mdio - > control ) ;
while ( readl ( & adap_mdio - > control ) & MDIO_CONTROL_IDLE )
;
return 0 ;
}
/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
int keystone2_eth_phy_read ( u_int8_t phy_addr , u_int8_t reg_num , u_int16_t * data )
/**
* keystone2_mdio_read - read a PHY register via MDIO interface .
* Blocks until operation is complete .
*/
static int keystone2_mdio_read ( struct mii_dev * bus ,
int addr , int devad , int reg )
{
int tmp ;
int tmp ;
struct mdio_regs * adap_mdio = bus - > priv ;
while ( readl ( & adap_mdio - > useraccess0 ) & MDIO_USERACCESS0_GO )
;
writel ( MDIO_USERACCESS0_GO |
MDIO_USERACCESS0_WRITE_READ |
( ( reg_num & 0x1f ) < < 21 ) |
( ( phy_addr & 0x1f ) < < 16 ) ,
writel ( MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_READ |
( ( reg & 0x1f ) < < 21 ) | ( ( addr & 0x1f ) < < 16 ) ,
& adap_mdio - > useraccess0 ) ;
/* Wait for command to complete */
while ( ( tmp = readl ( & adap_mdio - > useraccess0 ) ) & MDIO_USERACCESS0_GO )
;
if ( tmp & MDIO_USERACCESS0_ACK ) {
* data = tmp & 0xffff ;
return 0 ;
}
if ( tmp & MDIO_USERACCESS0_ACK )
return tmp & 0xffff ;
* data = - 1 ;
return - 1 ;
}
/*
* W rite to a PHY register via MDIO inteface .
/**
* keystone2_mdio_write - w rite to a PHY register via MDIO inter face .
* Blocks until operation is complete .
*/
int keystone2_eth_phy_write ( u_int8_t phy_addr , u_int8_t reg_num , u_int16_t data )
static int keystone2_mdio_write ( struct mii_dev * bus ,
int addr , int devad , int reg , u16 val )
{
struct mdio_regs * adap_mdio = bus - > priv ;
while ( readl ( & adap_mdio - > useraccess0 ) & MDIO_USERACCESS0_GO )
;
writel ( MDIO_USERACCESS0_GO |
MDIO_USERACCESS0_WRITE_WRITE |
( ( reg_num & 0x1f ) < < 21 ) |
( ( phy_addr & 0x1f ) < < 16 ) |
( data & 0xffff ) ,
& adap_mdio - > useraccess0 ) ;
writel ( MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_WRITE |
( ( reg & 0x1f ) < < 21 ) | ( ( addr & 0x1f ) < < 16 ) |
( val & 0xffff ) , & adap_mdio - > useraccess0 ) ;
/* Wait for command to complete */
while ( readl ( & adap_mdio - > useraccess0 ) & MDIO_USERACCESS0_GO )
@ -139,12 +139,12 @@ int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
/* PHY functions for a generic PHY */
static int gen_get_link_speed ( int phy_addr )
{
u_int16_t tmp ;
u_int16_t tmp ;
if ( ( ! keystone2_eth_phy_read ( phy_addr , MII_STATUS_REG , & tmp ) ) & &
( tmp & 0x04 ) ) {
tmp = mdio_bus - > read ( mdio_bus , phy_addr ,
MDIO_DEVAD_NONE , MII_STATUS_REG ) ;
if ( tmp & 0x04 )
return 0 ;
}
return - 1 ;
}
@ -156,8 +156,10 @@ static void __attribute__((unused))
struct eth_priv_t * eth_priv = ( struct eth_priv_t * ) dev - > priv ;
if ( sys_has_mdio ) {
if ( keystone2_eth_phy_read ( eth_priv - > phy_addr , 0 , & data ) | |
! ( data & ( 1 < < 6 ) ) ) /* speed selection MSB */
data = keystone2_mdio_read ( mdio_bus , eth_priv - > phy_addr ,
MDIO_DEVAD_NONE , 0 ) ;
/* speed selection MSB */
if ( ! ( data & ( 1 < < 6 ) ) )
return ;
}
@ -435,7 +437,7 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
hw_config_streaming_switch ( ) ;
if ( sys_has_mdio ) {
keystone2_mdio_reset ( ) ;
keystone2_mdio_reset ( mdio_bus ) ;
link = keystone_get_link_status ( dev ) ;
if ( link = = 0 ) {
@ -518,6 +520,7 @@ static int keystone2_eth_rcv_packet(struct eth_device *dev)
*/
int keystone2_emac_initialize ( struct eth_priv_t * eth_priv )
{
int res ;
struct eth_device * dev ;
dev = malloc ( sizeof ( struct eth_device ) ) ;
@ -539,6 +542,20 @@ int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
eth_register ( dev ) ;
/* Register MDIO bus if it's not registered yet */
if ( ! mdio_bus ) {
mdio_bus = mdio_alloc ( ) ;
mdio_bus - > read = keystone2_mdio_read ;
mdio_bus - > write = keystone2_mdio_write ;
mdio_bus - > reset = keystone2_mdio_reset ;
mdio_bus - > priv = ( void * ) EMAC_MDIO_BASE_ADDR ;
sprintf ( mdio_bus - > name , " ethernet-mdio " ) ;
res = mdio_register ( mdio_bus ) ;
if ( res )
return res ;
}
return 0 ;
}