@ -263,6 +263,121 @@ static void altera_tse_stop_sgdma(struct udevice *dev)
& tx_sgdma - > control ) ;
}
static void msgdma_reset ( struct msgdma_csr * csr )
{
u32 status ;
ulong ctime ;
/* Reset mSGDMA */
writel ( MSGDMA_CSR_STAT_MASK , & csr - > status ) ;
writel ( MSGDMA_CSR_CTL_RESET , & csr - > control ) ;
ctime = get_timer ( 0 ) ;
while ( 1 ) {
status = readl ( & csr - > status ) ;
if ( ! ( status & MSGDMA_CSR_STAT_RESETTING ) )
break ;
if ( get_timer ( ctime ) > ALT_TSE_SW_RESET_TIMEOUT ) {
debug ( " Reset msgdma timeout \n " ) ;
break ;
}
}
/* Clear status */
writel ( MSGDMA_CSR_STAT_MASK , & csr - > status ) ;
}
static u32 msgdma_wait ( struct msgdma_csr * csr )
{
u32 status ;
ulong ctime ;
/* Wait for the descriptor to complete */
ctime = get_timer ( 0 ) ;
while ( 1 ) {
status = readl ( & csr - > status ) ;
if ( ! ( status & MSGDMA_CSR_STAT_BUSY ) )
break ;
if ( get_timer ( ctime ) > ALT_TSE_SGDMA_BUSY_TIMEOUT ) {
debug ( " sgdma timeout \n " ) ;
break ;
}
}
/* Clear status */
writel ( MSGDMA_CSR_STAT_MASK , & csr - > status ) ;
return status ;
}
static int altera_tse_send_msgdma ( struct udevice * dev , void * packet ,
int length )
{
struct altera_tse_priv * priv = dev_get_priv ( dev ) ;
struct msgdma_extended_desc * desc = priv - > tx_desc ;
u32 tx_buf = virt_to_phys ( packet ) ;
u32 status ;
writel ( tx_buf , & desc - > read_addr_lo ) ;
writel ( 0 , & desc - > read_addr_hi ) ;
writel ( 0 , & desc - > write_addr_lo ) ;
writel ( 0 , & desc - > write_addr_hi ) ;
writel ( length , & desc - > len ) ;
writel ( 0 , & desc - > burst_seq_num ) ;
writel ( MSGDMA_DESC_TX_STRIDE , & desc - > stride ) ;
writel ( MSGDMA_DESC_CTL_TX_SINGLE , & desc - > control ) ;
status = msgdma_wait ( priv - > sgdma_tx ) ;
debug ( " sent %d bytes, status %08x \n " , length , status ) ;
return 0 ;
}
static int altera_tse_recv_msgdma ( struct udevice * dev , int flags ,
uchar * * packetp )
{
struct altera_tse_priv * priv = dev_get_priv ( dev ) ;
struct msgdma_csr * csr = priv - > sgdma_rx ;
struct msgdma_response * resp = priv - > rx_resp ;
u32 level , length , status ;
level = readl ( & csr - > resp_fill_level ) ;
if ( level & 0xffff ) {
length = readl ( & resp - > bytes_transferred ) ;
status = readl ( & resp - > status ) ;
debug ( " recv %d bytes, status %08x \n " , length , status ) ;
* packetp = priv - > rx_buf ;
return length ;
}
return - EAGAIN ;
}
static int altera_tse_free_pkt_msgdma ( struct udevice * dev , uchar * packet ,
int length )
{
struct altera_tse_priv * priv = dev_get_priv ( dev ) ;
struct msgdma_extended_desc * desc = priv - > rx_desc ;
u32 rx_buf = virt_to_phys ( priv - > rx_buf ) ;
writel ( 0 , & desc - > read_addr_lo ) ;
writel ( 0 , & desc - > read_addr_hi ) ;
writel ( rx_buf , & desc - > write_addr_lo ) ;
writel ( 0 , & desc - > write_addr_hi ) ;
writel ( PKTSIZE_ALIGN , & desc - > len ) ;
writel ( 0 , & desc - > burst_seq_num ) ;
writel ( MSGDMA_DESC_RX_STRIDE , & desc - > stride ) ;
writel ( MSGDMA_DESC_CTL_RX_SINGLE , & desc - > control ) ;
debug ( " recv setup \n " ) ;
return 0 ;
}
static void altera_tse_stop_msgdma ( struct udevice * dev )
{
struct altera_tse_priv * priv = dev_get_priv ( dev ) ;
msgdma_reset ( priv - > sgdma_rx ) ;
msgdma_reset ( priv - > sgdma_tx ) ;
}
static int tse_mdio_read ( struct mii_dev * bus , int addr , int devad , int reg )
{
struct altera_tse_priv * priv = bus - > priv ;
@ -449,6 +564,13 @@ static const struct tse_ops tse_sgdma_ops = {
. stop = altera_tse_stop_sgdma ,
} ;
static const struct tse_ops tse_msgdma_ops = {
. send = altera_tse_send_msgdma ,
. recv = altera_tse_recv_msgdma ,
. free_pkt = altera_tse_free_pkt_msgdma ,
. stop = altera_tse_stop_msgdma ,
} ;
static int altera_tse_probe ( struct udevice * dev )
{
struct eth_pdata * pdata = dev_get_platdata ( dev ) ;
@ -466,6 +588,8 @@ static int altera_tse_probe(struct udevice *dev)
priv - > dma_type = dev_get_driver_data ( dev ) ;
if ( priv - > dma_type = = ALT_SGDMA )
priv - > ops = & tse_sgdma_ops ;
else
priv - > ops = & tse_msgdma_ops ;
/*
* decode regs . there are multiple reg tuples , and they need to
* match with reg - names .
@ -490,8 +614,14 @@ static int altera_tse_probe(struct udevice *dev)
priv - > mac_dev = base ;
else if ( strcmp ( list , " rx_csr " ) = = 0 )
priv - > sgdma_rx = base ;
else if ( strcmp ( list , " rx_desc " ) = = 0 )
priv - > rx_desc = base ;
else if ( strcmp ( list , " rx_resp " ) = = 0 )
priv - > rx_resp = base ;
else if ( strcmp ( list , " tx_csr " ) = = 0 )
priv - > sgdma_tx = base ;
else if ( strcmp ( list , " tx_desc " ) = = 0 )
priv - > tx_desc = base ;
else if ( strcmp ( list , " s1 " ) = = 0 )
desc_mem = base ;
idx + = addrc + sizec ;
@ -567,6 +697,7 @@ static const struct eth_ops altera_tse_ops = {
} ;
static const struct udevice_id altera_tse_ids [ ] = {
{ . compatible = " altr,tse-msgdma-1.0 " , . data = ALT_MSGDMA } ,
{ . compatible = " altr,tse-1.0 " , . data = ALT_SGDMA } ,
{ }
} ;