2009-10-14 15:13:45 -07:00
/*******************************************************************************
This is the driver for the GMAC on - chip Ethernet controller for ST SoCs .
DWC Ether MAC 10 / 100 / 1000 Universal version 3.41 a has been used for
developing this code .
2010-04-13 20:21:12 +00:00
This contains the functions to handle the dma .
2010-01-06 23:07:20 +00:00
2009-10-14 15:13:45 -07:00
Copyright ( C ) 2007 - 2009 STMicroelectronics Ltd
This program is free software ; you can redistribute it and / or modify it
under the terms and conditions of the GNU General Public License ,
version 2 , as published by the Free Software Foundation .
This program is distributed in the hope it will be useful , but WITHOUT
ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
more details .
You should have received a copy of the GNU General Public License along with
this program ; if not , write to the Free Software Foundation , Inc . ,
51 Franklin St - Fifth Floor , Boston , MA 02110 - 1301 USA .
The full GNU General Public License is included in this distribution in
the file called " COPYING " .
Author : Giuseppe Cavallaro < peppe . cavallaro @ st . com >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-01-06 23:07:20 +00:00
# include "dwmac1000.h"
2010-01-06 23:07:18 +00:00
# include "dwmac_dma.h"
2009-10-14 15:13:45 -07:00
2010-01-06 23:07:20 +00:00
static int dwmac1000_dma_init ( unsigned long ioaddr , int pbl , u32 dma_tx ,
u32 dma_rx )
2009-10-14 15:13:45 -07:00
{
u32 value = readl ( ioaddr + DMA_BUS_MODE ) ;
/* DMA SW reset */
value | = DMA_BUS_MODE_SFT_RESET ;
writel ( value , ioaddr + DMA_BUS_MODE ) ;
do { } while ( ( readl ( ioaddr + DMA_BUS_MODE ) & DMA_BUS_MODE_SFT_RESET ) ) ;
value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
( ( pbl < < DMA_BUS_MODE_PBL_SHIFT ) |
( pbl < < DMA_BUS_MODE_RPBL_SHIFT ) ) ;
# ifdef CONFIG_STMMAC_DA
value | = DMA_BUS_MODE_DA ; /* Rx has priority over tx */
# endif
writel ( value , ioaddr + DMA_BUS_MODE ) ;
/* Mask interrupts by writing to CSR7 */
writel ( DMA_INTR_DEFAULT_MASK , ioaddr + DMA_INTR_ENA ) ;
/* The base address of the RX/TX descriptor lists must be written into
* DMA CSR3 and CSR4 , respectively . */
writel ( dma_tx , ioaddr + DMA_TX_BASE_ADDR ) ;
writel ( dma_rx , ioaddr + DMA_RCV_BASE_ADDR ) ;
return 0 ;
}
2010-01-06 23:07:20 +00:00
static void dwmac1000_dma_operation_mode ( unsigned long ioaddr , int txmode ,
2009-10-14 15:13:45 -07:00
int rxmode )
{
u32 csr6 = readl ( ioaddr + DMA_CONTROL ) ;
if ( txmode = = SF_DMA_MODE ) {
2010-04-13 20:21:12 +00:00
CHIP_DBG ( KERN_DEBUG " GMAC: enable TX store and forward mode \n " ) ;
2009-10-14 15:13:45 -07:00
/* Transmit COE type 2 cannot be done in cut-through mode. */
csr6 | = DMA_CONTROL_TSF ;
/* Operating on second frame increase the performance
* especially when transmit store - and - forward is used . */
csr6 | = DMA_CONTROL_OSF ;
} else {
2010-04-13 20:21:12 +00:00
CHIP_DBG ( KERN_DEBUG " GMAC: disabling TX store and forward mode "
2009-10-14 15:13:45 -07:00
" (threshold = %d) \n " , txmode ) ;
csr6 & = ~ DMA_CONTROL_TSF ;
csr6 & = DMA_CONTROL_TC_TX_MASK ;
tree-wide: fix assorted typos all over the place
That is "success", "unknown", "through", "performance", "[re|un]mapping"
, "access", "default", "reasonable", "[con]currently", "temperature"
, "channel", "[un]used", "application", "example","hierarchy", "therefore"
, "[over|under]flow", "contiguous", "threshold", "enough" and others.
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2009-11-14 13:09:05 -02:00
/* Set the transmit threshold */
2009-10-14 15:13:45 -07:00
if ( txmode < = 32 )
csr6 | = DMA_CONTROL_TTC_32 ;
else if ( txmode < = 64 )
csr6 | = DMA_CONTROL_TTC_64 ;
else if ( txmode < = 128 )
csr6 | = DMA_CONTROL_TTC_128 ;
else if ( txmode < = 192 )
csr6 | = DMA_CONTROL_TTC_192 ;
else
csr6 | = DMA_CONTROL_TTC_256 ;
}
if ( rxmode = = SF_DMA_MODE ) {
2010-04-13 20:21:12 +00:00
CHIP_DBG ( KERN_DEBUG " GMAC: enable RX store and forward mode \n " ) ;
2009-10-14 15:13:45 -07:00
csr6 | = DMA_CONTROL_RSF ;
} else {
2010-04-13 20:21:12 +00:00
CHIP_DBG ( KERN_DEBUG " GMAC: disabling RX store and forward mode "
2009-10-14 15:13:45 -07:00
" (threshold = %d) \n " , rxmode ) ;
csr6 & = ~ DMA_CONTROL_RSF ;
csr6 & = DMA_CONTROL_TC_RX_MASK ;
if ( rxmode < = 32 )
csr6 | = DMA_CONTROL_RTC_32 ;
else if ( rxmode < = 64 )
csr6 | = DMA_CONTROL_RTC_64 ;
else if ( rxmode < = 96 )
csr6 | = DMA_CONTROL_RTC_96 ;
else
csr6 | = DMA_CONTROL_RTC_128 ;
}
writel ( csr6 , ioaddr + DMA_CONTROL ) ;
}
/* Not yet implemented --- no RMON module */
2010-01-06 23:07:20 +00:00
static void dwmac1000_dma_diagnostic_fr ( void * data ,
struct stmmac_extra_stats * x , unsigned long ioaddr )
2009-10-14 15:13:45 -07:00
{
return ;
}
2010-01-06 23:07:20 +00:00
static void dwmac1000_dump_dma_regs ( unsigned long ioaddr )
2009-10-14 15:13:45 -07:00
{
int i ;
pr_info ( " DMA registers \n " ) ;
for ( i = 0 ; i < 22 ; i + + ) {
if ( ( i < 9 ) | | ( i > 17 ) ) {
int offset = i * 4 ;
pr_err ( " \t Reg No. %d (offset 0x%x): 0x%08x \n " , i ,
( DMA_BUS_MODE + offset ) ,
readl ( ioaddr + DMA_BUS_MODE + offset ) ) ;
}
}
}
2010-01-06 23:07:20 +00:00
struct stmmac_dma_ops dwmac1000_dma_ops = {
. init = dwmac1000_dma_init ,
. dump_regs = dwmac1000_dump_dma_regs ,
. dma_mode = dwmac1000_dma_operation_mode ,
. dma_diagnostic_fr = dwmac1000_dma_diagnostic_fr ,
2010-01-06 23:07:18 +00:00
. enable_dma_transmission = dwmac_enable_dma_transmission ,
. enable_dma_irq = dwmac_enable_dma_irq ,
. disable_dma_irq = dwmac_disable_dma_irq ,
. start_tx = dwmac_dma_start_tx ,
. stop_tx = dwmac_dma_stop_tx ,
. start_rx = dwmac_dma_start_rx ,
. stop_rx = dwmac_dma_stop_rx ,
. dma_interrupt = dwmac_dma_interrupt ,
2010-01-06 23:07:17 +00:00
} ;