Modifications for Atmel AT91RM9200DK ARM920T based development kit - Add Atmel DataFlash support for reading and writing. - Add possibility to boot a Linux from DataFlash with BOOTM command. - Add Flash detection on Atmel AT91RM9200DK (between Atmel AT49BV1614 and AT49BV1614A flashes) - Replace old Ethernet PHY layer functions - Change link address * Patch by Frank Smith, 9 Jun 2003: use CRIT_EXCEPTION for machine check on 4xx * Patch by Detlev Zundel, 13 Jun 2003: added implementation of the "carinfo" command in cmd_immap.cmaster
parent
71f9511803
commit
2abbe07547
@ -1,2 +1,2 @@ |
||||
TEXT_BASE = 0x21fa0000
|
||||
TEXT_BASE = 0x21f00000
|
||||
|
||||
|
@ -0,0 +1,521 @@ |
||||
/* Driver for ATMEL DataFlash support
|
||||
* Author : Hamid Ikdoumi (Atmel) |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that 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., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
*/ |
||||
|
||||
#include <config.h> |
||||
#include <common.h> |
||||
#include <asm/hardware.h> |
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH |
||||
#include <dataflash.h> |
||||
|
||||
#define SPI_CLK 5000000 |
||||
#define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0 : NPCS0 %1110 */ |
||||
#define AT91C_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3 : NPCS3 %0111 */ |
||||
|
||||
void AT91F_SpiInit(void) { |
||||
|
||||
/*-------------------------------------------------------------------*/ |
||||
/* SPI DataFlash Init */ |
||||
/*-------------------------------------------------------------------*/ |
||||
/* Configure PIOs */ |
||||
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 | |
||||
AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK; |
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 | |
||||
AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK; |
||||
/* Enable CLock */ |
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI; |
||||
|
||||
/* Reset the SPI */ |
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; |
||||
|
||||
/* Configure SPI in Master Mode with No CS selected !!! */ |
||||
AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS; |
||||
|
||||
/* Configure CS0 and CS3 */ |
||||
*(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8); |
||||
|
||||
*(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8); |
||||
|
||||
} |
||||
|
||||
void AT91F_SpiEnable(int cs) { |
||||
switch(cs) { |
||||
case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */ |
||||
AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; |
||||
AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS); |
||||
break; |
||||
case 3: /* Configure SPI CS3 for Serial DataFlash Card */ |
||||
/* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */ |
||||
AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7; /* Set in PIO mode */ |
||||
AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7; /* Configure in output */ |
||||
/* Clear Output */ |
||||
AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7; |
||||
/* Configure PCS */ |
||||
AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; |
||||
AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS); |
||||
break; |
||||
} |
||||
|
||||
/* SPI_Enable */ |
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; |
||||
} |
||||
|
||||
/*----------------------------------------------------------------------------*/ |
||||
/* \fn AT91F_SpiWrite */ |
||||
/* \brief Set the PDC registers for a transfert */ |
||||
/*----------------------------------------------------------------------------*/ |
||||
unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc ) |
||||
{ |
||||
unsigned int timeout; |
||||
|
||||
pDesc->state = BUSY; |
||||
|
||||
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; |
||||
|
||||
/* Initialize the Transmit and Receive Pointer */ |
||||
AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ; |
||||
AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ; |
||||
|
||||
/* Intialize the Transmit and Receive Counters */ |
||||
AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size; |
||||
AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size; |
||||
|
||||
if ( pDesc->tx_data_size != 0 ) { |
||||
/* Initialize the Next Transmit and Next Receive Pointer */ |
||||
AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ; |
||||
AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ; |
||||
|
||||
/* Intialize the Next Transmit and Next Receive Counters */ |
||||
AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ; |
||||
AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ; |
||||
} |
||||
|
||||
/* arm simple, non interrupt dependent timer */ |
||||
reset_timer_masked(); |
||||
timeout = 0; |
||||
|
||||
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN; |
||||
while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) && ((timeout = get_timer_masked() ) < CFG_SPI_WRITE_TOUT)); |
||||
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; |
||||
pDesc->state = IDLE; |
||||
|
||||
if (timeout >= CFG_SPI_WRITE_TOUT){ |
||||
printf("Error Timeout\n\r"); |
||||
return DATAFLASH_ERROR; |
||||
} |
||||
|
||||
return DATAFLASH_OK; |
||||
} |
||||
|
||||
|
||||
/*----------------------------------------------------------------------*/ |
||||
/* \fn AT91F_DataFlashSendCommand */ |
||||
/* \brief Generic function to send a command to the dataflash */ |
||||
/*----------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_DataFlashSendCommand( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned char OpCode, |
||||
unsigned int CmdSize, |
||||
unsigned int DataflashAddress) |
||||
{ |
||||
unsigned int adr; |
||||
|
||||
if ( (pDataFlash->pDataFlashDesc->state) != IDLE) |
||||
return DATAFLASH_BUSY; |
||||
|
||||
/* process the address to obtain page address and byte address */ |
||||
adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << pDataFlash->pDevice->page_offset) + (DataflashAddress % (pDataFlash->pDevice->pages_size)); |
||||
|
||||
/* fill the command buffer */ |
||||
pDataFlash->pDataFlashDesc->command[0] = OpCode; |
||||
pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16); |
||||
pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8); |
||||
pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ; |
||||
pDataFlash->pDataFlashDesc->command[4] = 0; |
||||
pDataFlash->pDataFlashDesc->command[5] = 0; |
||||
pDataFlash->pDataFlashDesc->command[6] = 0; |
||||
pDataFlash->pDataFlashDesc->command[7] = 0; |
||||
|
||||
/* Initialize the SpiData structure for the spi write fuction */ |
||||
pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ; |
||||
pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize ; |
||||
pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ; |
||||
pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize ; |
||||
|
||||
/* send the command and read the data */ |
||||
return AT91F_SpiWrite (pDataFlash->pDataFlashDesc); |
||||
} |
||||
|
||||
|
||||
/*----------------------------------------------------------------------*/ |
||||
/* \fn AT91F_DataFlashGetStatus */ |
||||
/* \brief Read the status register of the dataflash */ |
||||
/*----------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc) |
||||
{ |
||||
AT91S_DataFlashStatus status; |
||||
|
||||
/* if a transfert is in progress ==> return 0 */ |
||||
if( (pDesc->state) != IDLE) |
||||
return DATAFLASH_BUSY; |
||||
|
||||
/* first send the read status command (D7H) */ |
||||
pDesc->command[0] = DB_STATUS; |
||||
pDesc->command[1] = 0; |
||||
|
||||
pDesc->DataFlash_state = GET_STATUS; |
||||
pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */ |
||||
pDesc->tx_cmd_pt = pDesc->command ; |
||||
pDesc->rx_cmd_pt = pDesc->command ; |
||||
pDesc->rx_cmd_size = 2 ; |
||||
pDesc->tx_cmd_size = 2 ; |
||||
status = AT91F_SpiWrite (pDesc); |
||||
|
||||
pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1); |
||||
|
||||
return status; |
||||
} |
||||
|
||||
|
||||
/*----------------------------------------------------------------------*/ |
||||
/* \fn AT91F_DataFlashWaitReady */ |
||||
/* \brief wait for dataflash ready (bit7 of the status register == 1) */ |
||||
/*----------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout) |
||||
{ |
||||
pDataFlashDesc->DataFlash_state = IDLE; |
||||
|
||||
do { |
||||
AT91F_DataFlashGetStatus(pDataFlashDesc); |
||||
timeout--; |
||||
} |
||||
while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0) ); |
||||
|
||||
if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) |
||||
return DATAFLASH_ERROR; |
||||
|
||||
return DATAFLASH_OK; |
||||
} |
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_DataFlashContinuousRead */ |
||||
/* Object : Continuous stream Read */ |
||||
/* Input Parameters : DataFlash Service */ |
||||
/* : <src> = dataflash address */ |
||||
/* : <*dataBuffer> = data buffer pointer */ |
||||
/* : <sizeToRead> = data buffer size */ |
||||
/* Return value : State of the dataflash */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_DataFlashContinuousRead ( |
||||
AT91PS_DataFlash pDataFlash, |
||||
int src, |
||||
unsigned char *dataBuffer, |
||||
int sizeToRead ) |
||||
{ |
||||
/* Test the size to read in the device */ |
||||
if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number))) |
||||
return DATAFLASH_MEMORY_OVERFLOW; |
||||
|
||||
pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer; |
||||
pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead; |
||||
pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer; |
||||
pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead; |
||||
|
||||
/* Send the command to the dataflash */ |
||||
return(AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src)); |
||||
} |
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_DataFlashPagePgmBuf */ |
||||
/* Object : Main memory page program through buffer 1 or buffer 2 */ |
||||
/* Input Parameters : DataFlash Service */ |
||||
/* : <*src> = Source buffer */ |
||||
/* : <dest> = dataflash destination address */ |
||||
/* : <SizeToWrite> = data buffer size */ |
||||
/* Return value : State of the dataflash */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned char *src, |
||||
unsigned int dest, |
||||
unsigned int SizeToWrite) |
||||
{ |
||||
pDataFlash->pDataFlashDesc->tx_data_pt = src ; |
||||
pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ; |
||||
pDataFlash->pDataFlashDesc->rx_data_pt = src; |
||||
pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite; |
||||
|
||||
/* Send the command to the dataflash */ |
||||
return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, 4, dest)); |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_MainMemoryToBufferTransfert */ |
||||
/* Object : Read a page in the SRAM Buffer 1 or 2 */ |
||||
/* Input Parameters : DataFlash Service */ |
||||
/* : Page concerned */ |
||||
/* : */ |
||||
/* Return value : State of the dataflash */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned char BufferCommand, |
||||
unsigned int page) |
||||
{ |
||||
/* Test if the buffer command is legal */ |
||||
if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF)) |
||||
return DATAFLASH_BAD_COMMAND; |
||||
|
||||
/* no data to transmit or receive */ |
||||
pDataFlash->pDataFlashDesc->tx_data_size = 0; |
||||
|
||||
return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, page*pDataFlash->pDevice->pages_size)); |
||||
} |
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------- */ |
||||
/* Function Name : AT91F_DataFlashWriteBuffer */ |
||||
/* Object : Write data to the internal sram buffer 1 or 2 */ |
||||
/* Input Parameters : DataFlash Service */ |
||||
/* : <BufferCommand> = command to write buffer1 or buffer2 */ |
||||
/* : <*dataBuffer> = data buffer to write */ |
||||
/* : <bufferAddress> = address in the internal buffer */ |
||||
/* : <SizeToWrite> = data buffer size */ |
||||
/* Return value : State of the dataflash */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer ( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned char BufferCommand, |
||||
unsigned char *dataBuffer, |
||||
unsigned int bufferAddress, |
||||
int SizeToWrite ) |
||||
{ |
||||
/* Test if the buffer command is legal */ |
||||
if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE)) |
||||
return DATAFLASH_BAD_COMMAND; |
||||
|
||||
/* buffer address must be lower than page size */ |
||||
if (bufferAddress > pDataFlash->pDevice->pages_size) |
||||
return DATAFLASH_BAD_ADDRESS; |
||||
|
||||
if ( (pDataFlash->pDataFlashDesc->state) != IDLE) |
||||
return DATAFLASH_BUSY; |
||||
|
||||
/* Send first Write Command */ |
||||
pDataFlash->pDataFlashDesc->command[0] = BufferCommand; |
||||
pDataFlash->pDataFlashDesc->command[1] = 0; |
||||
pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ; |
||||
pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ; |
||||
|
||||
|
||||
pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ; |
||||
pDataFlash->pDataFlashDesc->tx_cmd_size = 4 ; |
||||
pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ; |
||||
pDataFlash->pDataFlashDesc->rx_cmd_size = 4 ; |
||||
|
||||
pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ; |
||||
pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ; |
||||
pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite ; |
||||
pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ; |
||||
|
||||
return AT91F_SpiWrite(pDataFlash->pDataFlashDesc); |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_WriteBufferToMain */ |
||||
/* Object : Write buffer to the main memory */ |
||||
/* Input Parameters : DataFlash Service */ |
||||
/* : <BufferCommand> = command to send to buffer1 or buffer2 */ |
||||
/* : <dest> = main memory address */ |
||||
/* Return value : State of the dataflash */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_WriteBufferToMain ( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned char BufferCommand, |
||||
unsigned int dest ) |
||||
{ |
||||
/* Test if the buffer command is correct */ |
||||
if ((BufferCommand != DB_BUF1_PAGE_PGM) && |
||||
(BufferCommand != DB_BUF1_PAGE_ERASE_PGM) && |
||||
(BufferCommand != DB_BUF2_PAGE_PGM) && |
||||
(BufferCommand != DB_BUF2_PAGE_ERASE_PGM) ) |
||||
return DATAFLASH_BAD_COMMAND; |
||||
|
||||
/* no data to transmit or receive */ |
||||
pDataFlash->pDataFlashDesc->tx_data_size = 0; |
||||
|
||||
/* Send the command to the dataflash */ |
||||
return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, dest)); |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_PartialPageWrite */ |
||||
/* Object : Erase partielly a page */ |
||||
/* Input Parameters : <page> = page number */ |
||||
/* : <AdrInpage> = adr to begin the fading */ |
||||
/* : <length> = Number of bytes to erase */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_PartialPageWrite ( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned char *src, |
||||
unsigned int dest, |
||||
unsigned int size) |
||||
{ |
||||
unsigned int page; |
||||
unsigned int AdrInPage; |
||||
|
||||
page = dest / (pDataFlash->pDevice->pages_size); |
||||
AdrInPage = dest % (pDataFlash->pDevice->pages_size); |
||||
|
||||
/* Read the contents of the page in the Sram Buffer */ |
||||
AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page); |
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000); |
||||
/*Update the SRAM buffer */ |
||||
AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size); |
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000); |
||||
|
||||
/* Rewrite the modified Sram Buffer in the main memory */ |
||||
return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size))); |
||||
} |
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_DataFlashWrite_Overloaded */ |
||||
/* Object : */ |
||||
/* Input Parameters : <*src> = Source buffer */ |
||||
/* : <dest> = dataflash adress */ |
||||
/* : <size> = data buffer size */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_DataFlashWrite( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned char *src, |
||||
int dest, |
||||
int size ) |
||||
{ |
||||
unsigned int length; |
||||
|
||||
AT91F_SpiEnable(pDataFlash->pDevice->cs); |
||||
|
||||
if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number))) |
||||
return DATAFLASH_MEMORY_OVERFLOW; |
||||
|
||||
/* If destination does not fit a page start address */ |
||||
if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0 ) { |
||||
length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size))); |
||||
|
||||
if (size < length) |
||||
length = size; |
||||
|
||||
if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length)) |
||||
return DATAFLASH_ERROR; |
||||
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000); |
||||
|
||||
/* Update size, source and destination pointers */ |
||||
size -= length; |
||||
dest += length; |
||||
src += length; |
||||
} |
||||
|
||||
while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) { |
||||
/* program dataflash page */ |
||||
if(!AT91F_DataFlashPagePgmBuf(pDataFlash, src, dest, pDataFlash->pDevice->pages_size )) |
||||
return DATAFLASH_ERROR; |
||||
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000); |
||||
|
||||
/* Update size, source and destination pointers */ |
||||
size -= pDataFlash->pDevice->pages_size ; |
||||
dest += pDataFlash->pDevice->pages_size ; |
||||
src += pDataFlash->pDevice->pages_size ; |
||||
} |
||||
|
||||
/* If still some bytes to read */ |
||||
if ( size > 0 ) { |
||||
/* program dataflash page */ |
||||
if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) ) |
||||
return DATAFLASH_ERROR; |
||||
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000); |
||||
} |
||||
return DATAFLASH_OK; |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_DataFlashRead */ |
||||
/* Object : Read a block in dataflash */ |
||||
/* Input Parameters : */ |
||||
/* Return value : */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
int AT91F_DataFlashRead( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned long addr, |
||||
unsigned long size, |
||||
char *buffer) |
||||
{ |
||||
unsigned long SizeToRead; |
||||
|
||||
AT91F_SpiEnable(pDataFlash->pDevice->cs); |
||||
|
||||
if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK) |
||||
return -1; |
||||
|
||||
while (size) { |
||||
SizeToRead = (size < 0x8000)? size:0x8000; |
||||
|
||||
if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK) |
||||
return -1; |
||||
|
||||
if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK) |
||||
return -1; |
||||
|
||||
size -= SizeToRead; |
||||
addr += SizeToRead; |
||||
buffer += SizeToRead; |
||||
} |
||||
|
||||
return DATAFLASH_OK; |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_DataflashProbe */ |
||||
/* Object : */ |
||||
/* Input Parameters : */ |
||||
/* Return value : Dataflash status register */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc) |
||||
{ |
||||
AT91F_SpiEnable(cs); |
||||
AT91F_DataFlashGetStatus(pDesc); |
||||
return((pDesc->command[1] == 0xFF)? 0: pDesc->command[1] & 0x3C); |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,468 @@ |
||||
/*
|
||||
* (C) Copyright 2003 |
||||
* Author : Hamid Ikdoumi (Atmel) |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that 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., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
#include <at91rm9200_net.h> |
||||
#include <net.h> |
||||
|
||||
/* ----- Ethernet Buffer definitions ----- */ |
||||
|
||||
typedef struct { |
||||
unsigned long addr, size; |
||||
} rbf_t; |
||||
|
||||
#define RBF_ADDR 0xfffffffc |
||||
#define RBF_OWNER (1<<0) |
||||
#define RBF_WRAP (1<<1) |
||||
#define RBF_BROADCAST (1<<31) |
||||
#define RBF_MULTICAST (1<<30) |
||||
#define RBF_UNICAST (1<<29) |
||||
#define RBF_EXTERNAL (1<<28) |
||||
#define RBF_UNKOWN (1<<27) |
||||
#define RBF_SIZE 0x07ff |
||||
#define RBF_LOCAL4 (1<<26) |
||||
#define RBF_LOCAL3 (1<<25) |
||||
#define RBF_LOCAL2 (1<<24) |
||||
#define RBF_LOCAL1 (1<<23) |
||||
|
||||
/* Emac Buffers in last 512KBytes of SDRAM*/ |
||||
/* Be careful, buffer size is limited to 512KBytes !!! */ |
||||
#define RBF_FRAMEMAX 100 |
||||
/*#define RBF_FRAMEMEM 0x200000 */ |
||||
#define RBF_FRAMEMEM 0x21F80000 |
||||
#define RBF_FRAMELEN 0x600 |
||||
|
||||
#define RBF_FRAMEBTD RBF_FRAMEMEM |
||||
#define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t)) |
||||
|
||||
|
||||
#ifdef CONFIG_DRIVER_ETHER |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) |
||||
|
||||
/* structure to interface the PHY */ |
||||
AT91S_PhyOps AT91S_Dm9161Ops; |
||||
AT91PS_PhyOps pPhyOps; |
||||
|
||||
AT91PS_EMAC p_mac; |
||||
|
||||
/*************************** Phy layer functions ************************/ |
||||
/** functions to interface the DAVICOM 10/100Mbps ethernet phy **********/ |
||||
|
||||
/*
|
||||
* Name:
|
||||
* dm9161_IsPhyConnected |
||||
* Description:
|
||||
* Reads the 2 PHY ID registers |
||||
* Arguments:
|
||||
* p_mac - pointer to AT91S_EMAC struct |
||||
* Return value:
|
||||
* TRUE - if id read successfully |
||||
* FALSE- if error
|
||||
*/ |
||||
static unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac) |
||||
{ |
||||
unsigned short Id1, Id2; |
||||
|
||||
at91rm9200_EmacEnableMDIO (p_mac); |
||||
at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID1, &Id1); |
||||
at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID2, &Id2); |
||||
at91rm9200_EmacDisableMDIO (p_mac); |
||||
|
||||
if ((Id1 == (DM9161_PHYID1_OUI >> 6)) && |
||||
((Id2 >> 10) == (DM9161_PHYID1_OUI & DM9161_LSB_MASK))) |
||||
return TRUE; |
||||
|
||||
return FALSE; |
||||
} |
||||
|
||||
/*
|
||||
* Name:
|
||||
* dm9161_GetLinkSpeed |
||||
* Description:
|
||||
* Link parallel detection status of MAC is checked and set in the
|
||||
* MAC configuration registers |
||||
* Arguments:
|
||||
* p_mac - pointer to MAC
|
||||
* Return value:
|
||||
* TRUE - if link status set succesfully |
||||
* FALSE - if link status not set |
||||
*/ |
||||
static UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac) |
||||
{ |
||||
unsigned short stat1, stat2; |
||||
|
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1)) |
||||
return FALSE; |
||||
|
||||
if (!(stat1 & DM9161_LINK_STATUS)) /* link status up? */ |
||||
return FALSE; |
||||
|
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2)) |
||||
return FALSE; |
||||
|
||||
if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) { |
||||
/*set Emac for 100BaseTX and Full Duplex */ |
||||
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; |
||||
return TRUE; |
||||
} |
||||
|
||||
if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) { |
||||
/*set MII for 10BaseT and Full Duplex */ |
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & |
||||
~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) |
||||
| AT91C_EMAC_FD; |
||||
return TRUE; |
||||
} |
||||
|
||||
if ((stat1 & DM9161_100BASE_T4_HD) && (stat2 & DM9161_100HDX)) { |
||||
/*set MII for 100BaseTX and Half Duplex */ |
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & |
||||
~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) |
||||
| AT91C_EMAC_SPD; |
||||
return TRUE; |
||||
} |
||||
|
||||
if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) { |
||||
/*set MII for 10BaseT and Half Duplex */ |
||||
p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); |
||||
return TRUE; |
||||
} |
||||
return FALSE; |
||||
} |
||||
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* dm9161_InitPhy |
||||
* Description:
|
||||
* MAC starts checking its link by using parallel detection and
|
||||
* Autonegotiation and the same is set in the MAC configuration registers |
||||
* Arguments:
|
||||
* p_mac - pointer to struct AT91S_EMAC |
||||
* Return value:
|
||||
* TRUE - if link status set succesfully |
||||
* FALSE - if link status not set |
||||
*/ |
||||
static UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac) |
||||
{ |
||||
UCHAR ret = TRUE; |
||||
unsigned short IntValue; |
||||
|
||||
at91rm9200_EmacEnableMDIO (p_mac); |
||||
|
||||
if (!dm9161_GetLinkSpeed (p_mac)) { |
||||
/* Try another time */ |
||||
ret = dm9161_GetLinkSpeed (p_mac); |
||||
} |
||||
|
||||
/* Disable PHY Interrupts */ |
||||
at91rm9200_EmacReadPhy (p_mac, DM9161_MDINTR, &IntValue); |
||||
/* clear FDX, SPD, Link, INTR masks */ |
||||
IntValue &= ~(DM9161_FDX_MASK | DM9161_SPD_MASK | |
||||
DM9161_LINK_MASK | DM9161_INTR_MASK); |
||||
at91rm9200_EmacWritePhy (p_mac, DM9161_MDINTR, &IntValue); |
||||
at91rm9200_EmacDisableMDIO (p_mac); |
||||
|
||||
return (ret); |
||||
} |
||||
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* dm9161_AutoNegotiate |
||||
* Description:
|
||||
* MAC Autonegotiates with the partner status of same is set in the
|
||||
* MAC configuration registers |
||||
* Arguments:
|
||||
* dev - pointer to struct net_device |
||||
* Return value:
|
||||
* TRUE - if link status set successfully |
||||
* FALSE - if link status not set |
||||
*/ |
||||
static UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status) |
||||
{ |
||||
unsigned short value; |
||||
unsigned short PhyAnar; |
||||
unsigned short PhyAnalpar; |
||||
|
||||
/* Set dm9161 control register */ |
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value)) |
||||
return FALSE; |
||||
value &= ~DM9161_AUTONEG; /* remove autonegotiation enable */ |
||||
value |= DM9161_ISOLATE; /* Electrically isolate PHY */ |
||||
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value)) |
||||
return FALSE; |
||||
|
||||
/* Set the Auto_negotiation Advertisement Register */ |
||||
/* MII advertising for Next page, 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */ |
||||
PhyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX | |
||||
DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3; |
||||
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_ANAR, &PhyAnar)) |
||||
return FALSE; |
||||
|
||||
/* Read the Control Register */ |
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value)) |
||||
return FALSE; |
||||
|
||||
value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE; |
||||
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value)) |
||||
return FALSE; |
||||
/* Restart Auto_negotiation */ |
||||
value |= DM9161_RESTART_AUTONEG; |
||||
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value)) |
||||
return FALSE; |
||||
|
||||
/*check AutoNegotiate complete */ |
||||
udelay (10000); |
||||
at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &value); |
||||
if (!(value & DM9161_AUTONEG_COMP)) |
||||
return FALSE; |
||||
|
||||
/* Get the AutoNeg Link partner base page */ |
||||
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_ANLPAR, &PhyAnalpar)) |
||||
return FALSE; |
||||
|
||||
if ((PhyAnar & DM9161_TX_FDX) && (PhyAnalpar & DM9161_TX_FDX)) { |
||||
/*set MII for 100BaseTX and Full Duplex */ |
||||
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; |
||||
return TRUE; |
||||
} |
||||
|
||||
if ((PhyAnar & DM9161_10_FDX) && (PhyAnalpar & DM9161_10_FDX)) { |
||||
/*set MII for 10BaseT and Full Duplex */ |
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & |
||||
~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) |
||||
| AT91C_EMAC_FD; |
||||
return TRUE; |
||||
} |
||||
return FALSE; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
/*********** EMAC Phy layer Management functions *************************/ |
||||
/*
|
||||
* Name:
|
||||
* at91rm9200_EmacEnableMDIO |
||||
* Description:
|
||||
* Enables the MDIO bit in MAC control register |
||||
* Arguments:
|
||||
* p_mac - pointer to struct AT91S_EMAC |
||||
* Return value:
|
||||
* none |
||||
*/ |
||||
static void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac) |
||||
{ |
||||
/* Mac CTRL reg set for MDIO enable */ |
||||
p_mac->EMAC_CTL |= AT91C_EMAC_MPE; /* Management port enable */ |
||||
} |
||||
|
||||
/*
|
||||
* Name:
|
||||
* at91rm9200_EmacDisableMDIO |
||||
* Description:
|
||||
* Disables the MDIO bit in MAC control register |
||||
* Arguments:
|
||||
* p_mac - pointer to struct AT91S_EMAC |
||||
* Return value:
|
||||
* none |
||||
*/ |
||||
static void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac) |
||||
{ |
||||
/* Mac CTRL reg set for MDIO disable */ |
||||
p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE; /* Management port disable */ |
||||
} |
||||
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* at91rm9200_EmacReadPhy |
||||
* Description:
|
||||
* Reads data from the PHY register |
||||
* Arguments:
|
||||
* dev - pointer to struct net_device |
||||
* RegisterAddress - unsigned char |
||||
* pInput - pointer to value read from register
|
||||
* Return value:
|
||||
* TRUE - if data read successfully |
||||
*/ |
||||
static UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac, |
||||
unsigned char RegisterAddress, |
||||
unsigned short *pInput) |
||||
{ |
||||
p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) | |
||||
(AT91C_EMAC_CODE_802_3) | (AT91C_EMAC_RW_R) | |
||||
(RegisterAddress << 18); |
||||
|
||||
udelay (10000); |
||||
|
||||
*pInput = (unsigned short) p_mac->EMAC_MAN; |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* at91rm9200_EmacWritePhy |
||||
* Description:
|
||||
* Writes data to the PHY register |
||||
* Arguments:
|
||||
* dev - pointer to struct net_device |
||||
* RegisterAddress - unsigned char |
||||
* pOutput - pointer to value to be written in the register
|
||||
* Return value:
|
||||
* TRUE - if data read successfully |
||||
*/ |
||||
static UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac, |
||||
unsigned char RegisterAddress, |
||||
unsigned short *pOutput) |
||||
{ |
||||
p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) | |
||||
AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W | |
||||
(RegisterAddress << 18); |
||||
|
||||
udelay (10000); |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
/*
|
||||
* Name:
|
||||
* at91rm92000_GetPhyInterface |
||||
* Description:
|
||||
* Initialise the interface functions to the PHY
|
||||
* Arguments:
|
||||
* None |
||||
* Return value:
|
||||
* None |
||||
*/ |
||||
void at91rm92000_GetPhyInterface (void) |
||||
{ |
||||
AT91S_Dm9161Ops.Init = dm9161_InitPhy; |
||||
AT91S_Dm9161Ops.IsPhyConnected = dm9161_IsPhyConnected; |
||||
AT91S_Dm9161Ops.GetLinkSpeed = dm9161_GetLinkSpeed; |
||||
AT91S_Dm9161Ops.AutoNegotiate = dm9161_AutoNegotiate; |
||||
|
||||
pPhyOps = (AT91PS_PhyOps) & AT91S_Dm9161Ops; |
||||
} |
||||
|
||||
|
||||
rbf_t *rbfdt; |
||||
rbf_t *rbfp; |
||||
|
||||
int eth_init (bd_t * bd) |
||||
{ |
||||
int ret; |
||||
int i; |
||||
|
||||
p_mac = AT91C_BASE_EMAC; |
||||
|
||||
*AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | AT91C_PA7_ETXCK_EREFCK; /* PIO Disable Register */ |
||||
|
||||
*AT91C_PIOB_PDR = AT91C_PB25_EF100 | |
||||
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | |
||||
AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | |
||||
AT91C_PB13_ETX3 | AT91C_PB12_ETX2; |
||||
|
||||
*AT91C_PIOB_BSR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; /* Select B Register */ |
||||
|
||||
*AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */ |
||||
|
||||
p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */ |
||||
|
||||
/* Init Ehternet buffers */ |
||||
rbfdt = (rbf_t *) RBF_FRAMEBTD; |
||||
for (i = 0; i < RBF_FRAMEMAX; i++) { |
||||
rbfdt[i].addr = RBF_FRAMEBUF + RBF_FRAMELEN * i; |
||||
rbfdt[i].size = 0; |
||||
} |
||||
rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP; |
||||
rbfp = &rbfdt[0]; |
||||
|
||||
at91rm92000_GetPhyInterface (); |
||||
|
||||
if (!pPhyOps->IsPhyConnected (p_mac)) |
||||
printf ("PHY not connected!!\n\r"); |
||||
|
||||
/* MII management start from here */ |
||||
if (!(p_mac->EMAC_SR & AT91C_EMAC_LINK)) { |
||||
if (!(ret = pPhyOps->Init (p_mac))) { |
||||
printf ("MAC: error during MII initialization\n"); |
||||
return 0; |
||||
} |
||||
} else { |
||||
printf ("No link\n\r"); |
||||
return 0; |
||||
} |
||||
|
||||
p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16) |
||||
| (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]); |
||||
p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]); |
||||
|
||||
p_mac->EMAC_RBQP = (long) (&rbfdt[0]); |
||||
p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA); |
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII) |
||||
& ~AT91C_EMAC_CLK; |
||||
p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int eth_send (volatile void *packet, int length) |
||||
{ |
||||
while (!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ)); |
||||
p_mac->EMAC_TAR = (long) packet; |
||||
p_mac->EMAC_TCR = length; |
||||
while (p_mac->EMAC_TCR & 0x7ff); |
||||
p_mac->EMAC_TSR |= AT91C_EMAC_COMP; |
||||
return 0; |
||||
} |
||||
|
||||
int eth_rx (void) |
||||
{ |
||||
int size; |
||||
|
||||
if (!(rbfp->addr & RBF_OWNER)) |
||||
return 0; |
||||
|
||||
size = rbfp->size & RBF_SIZE; |
||||
NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size); |
||||
|
||||
rbfp->addr &= ~RBF_OWNER; |
||||
if (rbfp->addr & RBF_WRAP) |
||||
rbfp = &rbfdt[0]; |
||||
else |
||||
rbfp++; |
||||
|
||||
p_mac->EMAC_RSR |= AT91C_EMAC_REC; |
||||
|
||||
return size; |
||||
} |
||||
|
||||
void eth_halt (void) |
||||
{ |
||||
}; |
||||
#endif /* CONFIG_COMMANDS & CFG_CMD_NET */ |
||||
#endif /* CONFIG_DRIVER_ETHER */ |
@ -1,251 +0,0 @@ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <asm/io.h> |
||||
#include <net.h> |
||||
|
||||
/* ----- Ethernet Buffer definitions ----- */ |
||||
|
||||
typedef struct { |
||||
unsigned long addr,size; |
||||
} rbf_t; |
||||
|
||||
#define RBF_ADDR 0xfffffffc |
||||
#define RBF_OWNER (1<<0) |
||||
#define RBF_WRAP (1<<1) |
||||
#define RBF_BROADCAST (1<<31) |
||||
#define RBF_MULTICAST (1<<30) |
||||
#define RBF_UNICAST (1<<29) |
||||
#define RBF_EXTERNAL (1<<28) |
||||
#define RBF_UNKOWN (1<<27) |
||||
#define RBF_SIZE 0x07ff |
||||
#define RBF_LOCAL4 (1<<26) |
||||
#define RBF_LOCAL3 (1<<25) |
||||
#define RBF_LOCAL2 (1<<24) |
||||
#define RBF_LOCAL1 (1<<23) |
||||
|
||||
#define RBF_FRAMEMAX 10 |
||||
#define RBF_FRAMEMEM 0x200000 |
||||
#define RBF_FRAMELEN 0x600 |
||||
|
||||
#define RBF_FRAMEBTD RBF_FRAMEMEM |
||||
#define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t)) |
||||
|
||||
/* stolen from mii.h */ |
||||
/* Generic MII registers. */ |
||||
|
||||
#define MII_BMCR 0x00 /* Basic mode control register */ |
||||
#define MII_BMSR 0x01 /* Basic mode status register */ |
||||
#define BMSR_JCD 0x0002 /* Jabber detected */ |
||||
#define BMSR_LSTATUS 0x0004 /* Link status */ |
||||
#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ |
||||
#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ |
||||
#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ |
||||
#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ |
||||
|
||||
#define MII_STS2_REG 17 /* Davicom specific */ |
||||
#define MII_MDINTR_REG 21 /* Davicom specific */ |
||||
|
||||
#ifdef CONFIG_DRIVER_ETHER |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) |
||||
|
||||
AT91PS_EMAC p_mac; |
||||
|
||||
int MII_ReadPhy(unsigned char addr, unsigned short *ret) |
||||
{ |
||||
|
||||
p_mac->EMAC_MAN = 0x60020000 | (addr << 18); |
||||
udelay(10000); |
||||
*ret = (unsigned short)p_mac->EMAC_MAN; |
||||
return 1; |
||||
} |
||||
|
||||
|
||||
int MII_GetLinkSpeed(void) |
||||
{ |
||||
unsigned short stat1, stat2; |
||||
int ret; |
||||
|
||||
if (!(ret = MII_ReadPhy(MII_BMSR, &stat1))) |
||||
return 0; |
||||
|
||||
if (stat1 & BMSR_JCD) |
||||
{ |
||||
#ifdef DEBUG |
||||
printf("MII: jabber condition detected\n"); |
||||
#endif /*jabber detected re-read the register*/ |
||||
} |
||||
if (!(ret = MII_ReadPhy(MII_BMSR, &stat1))) |
||||
return 0; |
||||
if (!(stat1 & BMSR_LSTATUS)) /* link status up? */ |
||||
{ |
||||
printf("MII: no Link\n"); |
||||
return 0; |
||||
} |
||||
|
||||
if (!(ret = MII_ReadPhy(MII_STS2_REG, &stat2))) |
||||
return 0; |
||||
|
||||
if ((stat1 & BMSR_100FULL) && (stat2 & 0x8000) ) |
||||
{ |
||||
/* set MII for 100BaseTX and Full Duplex */ |
||||
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; |
||||
#ifdef DEBUG |
||||
printf("MII: 100BaseTX and Full Duplex detected\n"); |
||||
#endif |
||||
return 1; |
||||
} |
||||
|
||||
else |
||||
if ((stat1 & BMSR_10FULL) && (stat2 & 0x2000)) |
||||
{ |
||||
/* set MII for 10BaseT and Full Duplex */ |
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)); |
||||
#ifdef DEBUG |
||||
printf("MII: 10BaseT and Full Duplex detected\n"); |
||||
#endif |
||||
return 1; |
||||
} |
||||
else |
||||
if ((stat1 & BMSR_100HALF) && (stat2 & 0x4000)) |
||||
{ |
||||
/* set MII for 100BaseTX and Half Duplex */ |
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)); |
||||
#ifdef DEBUG |
||||
printf("MII: 100BaseTX and Hall Duplex detected\n"); |
||||
#endif |
||||
return 1; |
||||
} |
||||
else |
||||
if ((stat1 & BMSR_10HALF) && (stat2 & 0x1000)) |
||||
{ |
||||
/*set MII for 10BaseT and Half Duplex */ |
||||
p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); |
||||
#ifdef DEBUG |
||||
printf("MII: 10BaseT and Hall Duplex detected\n"); |
||||
#endif |
||||
return 1; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
int MDIO_StartupPhy(void) |
||||
{ |
||||
int ret; |
||||
|
||||
if(p_mac->EMAC_SR & AT91C_EMAC_LINK) |
||||
{ |
||||
printf("MDIO_StartupPhy: no link\n"); |
||||
return 0; |
||||
}; |
||||
|
||||
p_mac->EMAC_CTL |= AT91C_EMAC_MPE; |
||||
|
||||
ret = MII_GetLinkSpeed(); |
||||
if (ret == 0) |
||||
{ |
||||
printf("MDIO_StartupPhy: MII_GetLinkSpeed failed\n"); |
||||
ret = 0; |
||||
} |
||||
else |
||||
{ |
||||
ret = 1; |
||||
} |
||||
|
||||
p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE; |
||||
return ret; |
||||
|
||||
} |
||||
|
||||
|
||||
rbf_t* rbfdt; |
||||
rbf_t* rbfp; |
||||
|
||||
int eth_init( bd_t *bd ) |
||||
{ |
||||
int ret; |
||||
int i; |
||||
p_mac = AT91C_BASE_EMAC; |
||||
|
||||
*AT91C_PIOA_PDR = AT91C_PA16_EMDIO | |
||||
AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | |
||||
AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | |
||||
AT91C_PA7_ETXCK_EREFCK; /* PIO Disable Register */ |
||||
|
||||
*AT91C_PIOB_PDR = AT91C_PB25_EF100 | |
||||
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | |
||||
AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; |
||||
|
||||
*AT91C_PIOB_BSR = AT91C_PB25_EF100 | |
||||
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | |
||||
AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; /* Select B Register */ |
||||
*AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */ |
||||
p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */ |
||||
|
||||
rbfdt=(rbf_t *)RBF_FRAMEBTD; |
||||
for(i = 0; i < RBF_FRAMEMAX; i++) |
||||
{ |
||||
rbfdt[i].addr=RBF_FRAMEBUF+RBF_FRAMELEN*i; |
||||
rbfdt[i].size=0; |
||||
} |
||||
rbfdt[RBF_FRAMEMAX-1].addr|=RBF_WRAP; |
||||
rbfp=&rbfdt[0]; |
||||
|
||||
if (!(ret = MDIO_StartupPhy())) |
||||
{ |
||||
printf("MAC: error during MII initialization\n"); |
||||
return 0; |
||||
} |
||||
|
||||
p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16) |
||||
| (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]); |
||||
p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]); |
||||
|
||||
p_mac->EMAC_RBQP = (long)(&rbfdt[0]); |
||||
p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA); |
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII) & ~AT91C_EMAC_CLK; |
||||
p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE ; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int eth_send(volatile void *packet, int length) |
||||
{ |
||||
while(!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ)) |
||||
; |
||||
p_mac->EMAC_TAR = (long)packet; |
||||
p_mac->EMAC_TCR = length; |
||||
while(p_mac->EMAC_TCR & 0x7ff) |
||||
; |
||||
p_mac->EMAC_TSR |= AT91C_EMAC_COMP; |
||||
return 0; |
||||
} |
||||
|
||||
int eth_rx(void) |
||||
{ |
||||
int size; |
||||
|
||||
if(!(rbfp->addr & RBF_OWNER)) |
||||
return 0; |
||||
|
||||
size=rbfp->size & RBF_SIZE; |
||||
NetReceive((volatile uchar *) (rbfp->addr & RBF_ADDR), size); |
||||
|
||||
rbfp->addr &= ~RBF_OWNER; |
||||
if(rbfp->addr & RBF_WRAP) |
||||
rbfp = &rbfdt[0]; |
||||
else |
||||
rbfp++; |
||||
|
||||
p_mac->EMAC_RSR |= AT91C_EMAC_REC; |
||||
|
||||
return size; |
||||
} |
||||
|
||||
void eth_halt( void ) |
||||
{}; |
||||
#endif |
||||
#endif |
@ -0,0 +1,245 @@ |
||||
/* LowLevel function for ATMEL DataFlash support
|
||||
* Author : Hamid Ikdoumi (Atmel) |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that 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., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
*/ |
||||
#include <common.h> |
||||
#include <config.h> |
||||
#ifdef CONFIG_HAS_DATAFLASH |
||||
#include <asm/hardware.h> |
||||
#include <dataflash.h> |
||||
|
||||
AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS]; |
||||
static AT91S_DataFlash DataFlashInst; |
||||
|
||||
int cs[][CFG_MAX_DATAFLASH_BANKS] = { |
||||
{CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */ |
||||
{CFG_DATAFLASH_LOGIC_ADDR_CS3, 3} |
||||
}; |
||||
|
||||
extern void AT91F_SpiInit (void); |
||||
extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc); |
||||
extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash, |
||||
unsigned long addr, |
||||
unsigned long size, char *buffer); |
||||
|
||||
|
||||
int AT91F_DataflashInit (void) |
||||
{ |
||||
int i, j; |
||||
int dfcode; |
||||
|
||||
AT91F_SpiInit (); |
||||
|
||||
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { |
||||
|
||||
dataflash_info[i].id = 0; |
||||
dataflash_info[i].Device.pages_number = 0; |
||||
dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc); |
||||
|
||||
switch (dfcode) { |
||||
case AT45DB161: |
||||
dataflash_info[i].Device.pages_number = 4096; |
||||
dataflash_info[i].Device.pages_size = 528; |
||||
dataflash_info[i].Device.page_offset = 10; |
||||
dataflash_info[i].Device.byte_mask = 0x300; |
||||
dataflash_info[i].Device.cs = cs[i][1]; |
||||
dataflash_info[i].Desc.DataFlash_state = IDLE; |
||||
dataflash_info[i].logical_address = cs[i][0]; |
||||
dataflash_info[i].id = dfcode; |
||||
break; |
||||
|
||||
case AT45DB321: |
||||
dataflash_info[i].Device.pages_number = 8192; |
||||
dataflash_info[i].Device.pages_size = 528; |
||||
dataflash_info[i].Device.page_offset = 10; |
||||
dataflash_info[i].Device.byte_mask = 0x300; |
||||
dataflash_info[i].Device.cs = cs[i][1]; |
||||
dataflash_info[i].Desc.DataFlash_state = IDLE; |
||||
dataflash_info[i].logical_address = cs[i][0]; |
||||
dataflash_info[i].id = dfcode; |
||||
break; |
||||
|
||||
case AT45DB642: |
||||
dataflash_info[i].Device.pages_number = 8192; |
||||
dataflash_info[i].Device.pages_size = 1056; |
||||
dataflash_info[i].Device.page_offset = 11; |
||||
dataflash_info[i].Device.byte_mask = 0x700; |
||||
dataflash_info[i].Device.cs = cs[i][1]; |
||||
dataflash_info[i].Desc.DataFlash_state = IDLE; |
||||
dataflash_info[i].logical_address = cs[i][0]; |
||||
dataflash_info[i].id = dfcode; |
||||
break; |
||||
|
||||
default: |
||||
break; |
||||
} |
||||
|
||||
for (j = 0; j < dataflash_info[i].Device.pages_number; j++) |
||||
dataflash_info[i].protect[j] = FLAG_PROTECT_SET; |
||||
|
||||
} |
||||
return (1); |
||||
} |
||||
|
||||
|
||||
|
||||
void dataflash_print_info (void) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { |
||||
if (dataflash_info[i].id != 0) { |
||||
printf ("DataFlash:"); |
||||
switch (dataflash_info[i].id) { |
||||
case AT45DB161: |
||||
printf ("AT45DB161\n"); |
||||
break; |
||||
|
||||
case AT45DB321: |
||||
printf ("AT45DB321\n"); |
||||
break; |
||||
|
||||
case AT45DB642: |
||||
printf ("AT45DB642\n"); |
||||
break; |
||||
} |
||||
|
||||
printf ("Nb pages: %6d\n" |
||||
"Page Size: %6d\n" |
||||
"Size=%8d bytes\n" |
||||
"Logical address: 0x%08X\n", |
||||
(unsigned int) dataflash_info[i].Device.pages_number, |
||||
(unsigned int) dataflash_info[i].Device.pages_size, |
||||
(unsigned int) dataflash_info[i].Device.pages_number * |
||||
dataflash_info[i].Device.pages_size, |
||||
(unsigned int) dataflash_info[i].logical_address); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_DataflashSelect */ |
||||
/* Object : Select the correct device */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash, |
||||
unsigned int *addr) |
||||
{ |
||||
char addr_valid = 0; |
||||
int i; |
||||
|
||||
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) |
||||
if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) { |
||||
addr_valid = 1; |
||||
break; |
||||
} |
||||
if (!addr_valid) { |
||||
pFlash = (AT91PS_DataFlash) 0; |
||||
return pFlash; |
||||
} |
||||
pFlash->pDataFlashDesc = &(dataflash_info[i].Desc); |
||||
pFlash->pDevice = &(dataflash_info[i].Device); |
||||
*addr -= dataflash_info[i].logical_address; |
||||
return (pFlash); |
||||
} |
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : addr_dataflash */ |
||||
/* Object : Test if address is valid */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
int addr_dataflash (unsigned long addr) |
||||
{ |
||||
int addr_valid = 0; |
||||
int i; |
||||
|
||||
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { |
||||
if ((((int) addr) & 0xFF000000) == |
||||
dataflash_info[i].logical_address) { |
||||
addr_valid = 1; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return addr_valid; |
||||
} |
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : read_dataflash */ |
||||
/* Object : dataflash memory read */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
int read_dataflash (unsigned long addr, unsigned long size, char *result) |
||||
{ |
||||
int AddrToRead = addr; |
||||
AT91PS_DataFlash pFlash = &DataFlashInst; |
||||
|
||||
pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead); |
||||
if (pFlash == 0) |
||||
return -1; |
||||
|
||||
return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result)); |
||||
} |
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/ |
||||
/* Function Name : write_dataflash */ |
||||
/* Object : write a block in dataflash */ |
||||
/*-----------------------------------------------------------------------------*/ |
||||
int write_dataflash (unsigned long addr_dest, unsigned long addr_src, |
||||
unsigned long size) |
||||
{ |
||||
extern AT91S_DataFlashStatus AT91F_DataFlashWrite( |
||||
AT91PS_DataFlash, uchar *, int, int); |
||||
int AddrToWrite = addr_dest; |
||||
AT91PS_DataFlash pFlash = &DataFlashInst; |
||||
|
||||
pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite); |
||||
if (AddrToWrite == -1) |
||||
return -1; |
||||
|
||||
return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite, |
||||
size); |
||||
} |
||||
|
||||
|
||||
void dataflash_perror (int err) |
||||
{ |
||||
switch (err) { |
||||
case ERR_OK: |
||||
break; |
||||
case ERR_TIMOUT: |
||||
printf ("Timeout writing to DataFlash\n"); |
||||
break; |
||||
case ERR_PROTECTED: |
||||
printf ("Can't write to protected DataFlash sectors\n"); |
||||
break; |
||||
case ERR_INVAL: |
||||
printf ("Outside available DataFlash\n"); |
||||
break; |
||||
case ERR_UNKNOWN_FLASH_TYPE: |
||||
printf ("Unknown Type of DataFlash\n"); |
||||
break; |
||||
case ERR_PROG_ERROR: |
||||
printf ("General DataFlash Programming Error\n"); |
||||
break; |
||||
default: |
||||
printf ("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,59 @@ |
||||
/*
|
||||
* Ethernet: An implementation of the Ethernet Device Driver suite for the |
||||
* uClinux 2.0.38 operating system. This Driver has been developed |
||||
* for AT75C220 board.
|
||||
* |
||||
* NOTE: The driver is implemented for one MAC |
||||
* |
||||
* Version: @(#)at91rm9200_net.h 1.0.0 01/10/2001 |
||||
* |
||||
* Authors: Lineo Inc <www.lineo.com> |
||||
* |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License |
||||
* as published by the Free Software Foundation; either version |
||||
* 2 of the License, or (at your option) any later version. |
||||
*/ |
||||
|
||||
#ifndef AT91RM9200_ETHERNET |
||||
#define AT91RM9200_ETHERNET |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
#include <asm/arch/hardware.h> |
||||
#include "dm9161.h" |
||||
|
||||
#define FALSE 0 |
||||
#define TRUE 1 |
||||
|
||||
|
||||
#define ETHERNET_ADDRESS_SIZE 6 |
||||
|
||||
typedef unsigned char UCHAR; |
||||
|
||||
/* Interface to drive the physical layer */ |
||||
typedef struct _AT91S_PhyOps |
||||
{ |
||||
unsigned char (*Init)(AT91S_EMAC *pmac); |
||||
unsigned int (*IsPhyConnected)(AT91S_EMAC *pmac); |
||||
unsigned char (*GetLinkSpeed)(AT91S_EMAC *pmac); |
||||
unsigned char (*AutoNegotiate)(AT91S_EMAC *pmac, int *); |
||||
|
||||
} AT91S_PhyOps,*AT91PS_PhyOps; |
||||
|
||||
|
||||
#define EMAC_DESC_DONE 0x00000001 /* ownership bit */ |
||||
#define EMAC_DESC_WRAP 0x00000002 /* bit for wrap */ |
||||
|
||||
/****************** function prototypes **********************/ |
||||
|
||||
/* MII functions */ |
||||
static void at91rm9200_EmacEnableMDIO(AT91PS_EMAC p_mac); |
||||
static void at91rm9200_EmacDisableMDIO(AT91PS_EMAC p_mac); |
||||
static UCHAR at91rm9200_EmacReadPhy(AT91PS_EMAC p_mac, unsigned char RegisterAddress, unsigned short *pInput); |
||||
static UCHAR at91rm9200_EmacWritePhy(AT91PS_EMAC p_mac, unsigned char RegisterAddress, unsigned short *pOutput); |
||||
void at91rm92000_GetPhyInterface(void ); |
||||
|
||||
#endif /* AT91RM9200_ETHERNET */ |
||||
|
@ -0,0 +1,176 @@ |
||||
/*
|
||||
* (C) Copyright 2003 |
||||
* Data Flash Atmel Description File |
||||
* Author : Hamid Ikdoumi (Atmel) |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that 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., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
/* File Name : dataflash.h */ |
||||
/* Object : Data Flash Atmel Description File */ |
||||
/* Translator : */ |
||||
/* */ |
||||
/* 1.0 03/04/01 HI : Creation */ |
||||
/* 1.2 20/10/02 FB : Adapatation Service and Lib v3 */ |
||||
/*----------------------------------------------------------------------*/ |
||||
|
||||
#ifndef _DataFlash_h |
||||
#define _DataFlash_h |
||||
|
||||
|
||||
#include <asm/arch/hardware.h> |
||||
#include "config.h" |
||||
|
||||
|
||||
typedef struct { |
||||
unsigned long base; /* logical base address for a bank */ |
||||
unsigned long size; /* total bank size */ |
||||
unsigned long page_count; |
||||
unsigned long page_size; |
||||
unsigned long id; /* device id */ |
||||
unsigned char protect[CFG_MAX_DATAFLASH_PAGES]; /* page protection status */ |
||||
} dataflash_info_t; |
||||
|
||||
|
||||
typedef unsigned int AT91S_DataFlashStatus; |
||||
|
||||
/*----------------------------------------------------------------------*/ |
||||
/* DataFlash Structures */ |
||||
/*----------------------------------------------------------------------*/ |
||||
|
||||
/*---------------------------------------------*/ |
||||
/* DataFlash Descriptor Structure Definition */ |
||||
/*---------------------------------------------*/ |
||||
typedef struct _AT91S_DataflashDesc { |
||||
unsigned char *tx_cmd_pt; |
||||
unsigned int tx_cmd_size; |
||||
unsigned char *rx_cmd_pt; |
||||
unsigned int rx_cmd_size; |
||||
unsigned char *tx_data_pt; |
||||
unsigned int tx_data_size; |
||||
unsigned char *rx_data_pt; |
||||
unsigned int rx_data_size; |
||||
volatile unsigned char state; |
||||
volatile unsigned char DataFlash_state; |
||||
unsigned char command[8]; |
||||
} AT91S_DataflashDesc, *AT91PS_DataflashDesc; |
||||
|
||||
/*---------------------------------------------*/ |
||||
/* DataFlash device definition structure */ |
||||
/*---------------------------------------------*/ |
||||
typedef struct _AT91S_Dataflash { |
||||
int pages_number; /* dataflash page number */ |
||||
int pages_size; /* dataflash page size */ |
||||
int page_offset; /* page offset in command */ |
||||
int byte_mask; /* byte mask in command */ |
||||
int cs; |
||||
} AT91S_DataflashFeatures, *AT91PS_DataflashFeatures; |
||||
|
||||
/*---------------------------------------------*/ |
||||
/* DataFlash Structure Definition */ |
||||
/*---------------------------------------------*/ |
||||
typedef struct _AT91S_DataFlash { |
||||
AT91PS_DataflashDesc pDataFlashDesc; /* dataflash descriptor */ |
||||
AT91PS_DataflashFeatures pDevice; /* Pointer on a dataflash features array */ |
||||
} AT91S_DataFlash, *AT91PS_DataFlash; |
||||
|
||||
|
||||
|
||||
typedef struct _AT91S_DATAFLASH_INFO { |
||||
|
||||
AT91S_DataflashDesc Desc; |
||||
AT91S_DataflashFeatures Device; /* Pointer on a dataflash features array */ |
||||
unsigned long logical_address; |
||||
unsigned int id; /* device id */ |
||||
unsigned char protect[CFG_MAX_DATAFLASH_PAGES]; /* page protection status */ |
||||
} AT91S_DATAFLASH_INFO, *AT91PS_DATAFLASH_INFO; |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*/ |
||||
|
||||
#define AT45DB161 0x2c |
||||
#define AT45DB321 0x34 |
||||
#define AT45DB642 0x3c |
||||
|
||||
#define AT91C_DATAFLASH_TIMEOUT 10000 /* For AT91F_DataFlashWaitReady */ |
||||
|
||||
/* DataFlash return value */ |
||||
#define DATAFLASH_BUSY 0x00 |
||||
#define DATAFLASH_OK 0x01 |
||||
#define DATAFLASH_ERROR 0x02 |
||||
#define DATAFLASH_MEMORY_OVERFLOW 0x03 |
||||
#define DATAFLASH_BAD_COMMAND 0x04 |
||||
#define DATAFLASH_BAD_ADDRESS 0x05 |
||||
|
||||
|
||||
/* Driver State */ |
||||
#define IDLE 0x0 |
||||
#define BUSY 0x1 |
||||
#define ERROR 0x2 |
||||
|
||||
/* DataFlash Driver State */ |
||||
#define GET_STATUS 0x0F |
||||
|
||||
/*-------------------------------------------------------------------------------------------------*/ |
||||
/* Command Definition */ |
||||
/*-------------------------------------------------------------------------------------------------*/ |
||||
|
||||
/* READ COMMANDS */ |
||||
#define DB_CONTINUOUS_ARRAY_READ 0xE8 /* Continuous array read */ |
||||
#define DB_BURST_ARRAY_READ 0xE8 /* Burst array read */ |
||||
#define DB_PAGE_READ 0xD2 /* Main memory page read */ |
||||
#define DB_BUF1_READ 0xD4 /* Buffer 1 read */ |
||||
#define DB_BUF2_READ 0xD6 /* Buffer 2 read */ |
||||
#define DB_STATUS 0xD7 /* Status Register */ |
||||
|
||||
/* PROGRAM and ERASE COMMANDS */ |
||||
#define DB_BUF1_WRITE 0x84 /* Buffer 1 write */ |
||||
#define DB_BUF2_WRITE 0x87 /* Buffer 2 write */ |
||||
#define DB_BUF1_PAGE_ERASE_PGM 0x83 /* Buffer 1 to main memory page program with built-In erase */ |
||||
#define DB_BUF1_PAGE_ERASE_FASTPGM 0x93 /* Buffer 1 to main memory page program with built-In erase, Fast program */ |
||||
#define DB_BUF2_PAGE_ERASE_PGM 0x86 /* Buffer 2 to main memory page program with built-In erase */ |
||||
#define DB_BUF2_PAGE_ERASE_FASTPGM 0x96 /* Buffer 1 to main memory page program with built-In erase, Fast program */ |
||||
#define DB_BUF1_PAGE_PGM 0x88 /* Buffer 1 to main memory page program without built-In erase */ |
||||
#define DB_BUF1_PAGE_FASTPGM 0x98 /* Buffer 1 to main memory page program without built-In erase, Fast program */ |
||||
#define DB_BUF2_PAGE_PGM 0x89 /* Buffer 2 to main memory page program without built-In erase */ |
||||
#define DB_BUF2_PAGE_FASTPGM 0x99 /* Buffer 1 to main memory page program without built-In erase, Fast program */ |
||||
#define DB_PAGE_ERASE 0x81 /* Page Erase */ |
||||
#define DB_BLOCK_ERASE 0x50 /* Block Erase */ |
||||
#define DB_PAGE_PGM_BUF1 0x82 /* Main memory page through buffer 1 */ |
||||
#define DB_PAGE_FASTPGM_BUF1 0x92 /* Main memory page through buffer 1, Fast program */ |
||||
#define DB_PAGE_PGM_BUF2 0x85 /* Main memory page through buffer 2 */ |
||||
#define DB_PAGE_FastPGM_BUF2 0x95 /* Main memory page through buffer 2, Fast program */ |
||||
|
||||
/* ADDITIONAL COMMANDS */ |
||||
#define DB_PAGE_2_BUF1_TRF 0x53 /* Main memory page to buffer 1 transfert */ |
||||
#define DB_PAGE_2_BUF2_TRF 0x55 /* Main memory page to buffer 2 transfert */ |
||||
#define DB_PAGE_2_BUF1_CMP 0x60 /* Main memory page to buffer 1 compare */ |
||||
#define DB_PAGE_2_BUF2_CMP 0x61 /* Main memory page to buffer 2 compare */ |
||||
#define DB_AUTO_PAGE_PGM_BUF1 0x58 /* Auto page rewrite throught buffer 1 */ |
||||
#define DB_AUTO_PAGE_PGM_BUF2 0x59 /* Auto page rewrite throught buffer 2 */ |
||||
|
||||
/*-------------------------------------------------------------------------------------------------*/ |
||||
|
||||
extern int addr_dataflash (unsigned long addr); |
||||
extern int read_dataflash (unsigned long addr, unsigned long size, char *result); |
||||
extern int write_dataflash (unsigned long addr, unsigned long dest, unsigned long size); |
||||
extern void dataflash_print_info (void); |
||||
extern void dataflash_perror (int err); |
||||
|
||||
#endif |
@ -0,0 +1,130 @@ |
||||
/*
|
||||
* NOTE: DAVICOM ethernet Physical layer
|
||||
* |
||||
* Version: @(#)DM9161.h 1.0.0 01/10/2001 |
||||
* |
||||
* Authors: ATMEL Rousset |
||||
* |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License |
||||
* as published by the Free Software Foundation; either version |
||||
* 2 of the License, or (at your option) any later version. |
||||
*/ |
||||
|
||||
|
||||
// DAVICOM PHYSICAL LAYER TRANSCEIVER DM9161
|
||||
|
||||
#define DM9161_BMCR 0 // Basic Mode Control Register
|
||||
#define DM9161_BMSR 1 // Basic Mode Status Register
|
||||
#define DM9161_PHYID1 2 // PHY Idendifier Register 1
|
||||
#define DM9161_PHYID2 3 // PHY Idendifier Register 2
|
||||
#define DM9161_ANAR 4 // Auto_Negotiation Advertisement Register
|
||||
#define DM9161_ANLPAR 5 // Auto_negotiation Link Partner Ability Register
|
||||
#define DM9161_ANER 6 // Auto-negotiation Expansion Register
|
||||
#define DM9161_DSCR 16 // Specified Configuration Register
|
||||
#define DM9161_DSCSR 17 // Specified Configuration and Status Register
|
||||
#define DM9161_10BTCSR 18 // 10BASE-T Configuration and Satus Register
|
||||
#define DM9161_MDINTR 21 // Specified Interrupt Register
|
||||
#define DM9161_RECR 22 // Specified Receive Error Counter Register
|
||||
#define DM9161_DISCR 23 // Specified Disconnect Counter Register
|
||||
#define DM9161_RLSR 24 // Hardware Reset Latch State Register
|
||||
|
||||
|
||||
// --Bit definitions: DM9161_BMCR
|
||||
#define DM9161_RESET (1 << 15) // 1= Software Reset; 0=Normal Operation
|
||||
#define DM9161_LOOPBACK (1 << 14) // 1=loopback Enabled; 0=Normal Operation
|
||||
#define DM9161_SPEED_SELECT (1 << 13) // 1=100Mbps; 0=10Mbps
|
||||
#define DM9161_AUTONEG (1 << 12) |
||||
#define DM9161_POWER_DOWN (1 << 11) |
||||
#define DM9161_ISOLATE (1 << 10) |
||||
#define DM9161_RESTART_AUTONEG (1 << 9) |
||||
#define DM9161_DUPLEX_MODE (1 << 8) |
||||
#define DM9161_COLLISION_TEST (1 << 7) |
||||
|
||||
//--Bit definitions: DM9161_BMSR
|
||||
#define DM9161_100BASE_T4 (1 << 15) |
||||
#define DM9161_100BASE_TX_FD (1 << 14) |
||||
#define DM9161_100BASE_T4_HD (1 << 13) |
||||
#define DM9161_10BASE_T_FD (1 << 12) |
||||
#define DM9161_10BASE_T_HD (1 << 11) |
||||
#define DM9161_MF_PREAMB_SUPPR (1 << 6) |
||||
#define DM9161_AUTONEG_COMP (1 << 5) |
||||
#define DM9161_REMOTE_FAULT (1 << 4) |
||||
#define DM9161_AUTONEG_ABILITY (1 << 3) |
||||
#define DM9161_LINK_STATUS (1 << 2) |
||||
#define DM9161_JABBER_DETECT (1 << 1) |
||||
#define DM9161_EXTEND_CAPAB (1 << 0) |
||||
|
||||
//--definitions: DM9161_PHYID1
|
||||
#define DM9161_PHYID1_OUI 0x606E |
||||
#define DM9161_LSB_MASK 0x3F |
||||
|
||||
//--Bit definitions: DM9161_ANAR, DM9161_ANLPAR
|
||||
#define DM9161_NP (1 << 15) |
||||
#define DM9161_ACK (1 << 14) |
||||
#define DM9161_RF (1 << 13) |
||||
#define DM9161_FCS (1 << 10) |
||||
#define DM9161_T4 (1 << 9) |
||||
#define DM9161_TX_FDX (1 << 8) |
||||
#define DM9161_TX_HDX (1 << 7) |
||||
#define DM9161_10_FDX (1 << 6) |
||||
#define DM9161_10_HDX (1 << 5) |
||||
#define DM9161_AN_IEEE_802_3 0x0001 |
||||
|
||||
//--Bit definitions: DM9161_ANER
|
||||
#define DM9161_PDF (1 << 4) |
||||
#define DM9161_LP_NP_ABLE (1 << 3) |
||||
#define DM9161_NP_ABLE (1 << 2) |
||||
#define DM9161_PAGE_RX (1 << 1) |
||||
#define DM9161_LP_AN_ABLE (1 << 0) |
||||
|
||||
//--Bit definitions: DM9161_DSCR
|
||||
#define DM9161_BP4B5B (1 << 15) |
||||
#define DM9161_BP_SCR (1 << 14) |
||||
#define DM9161_BP_ALIGN (1 << 13) |
||||
#define DM9161_BP_ADPOK (1 << 12) |
||||
#define DM9161_REPEATER (1 << 11) |
||||
#define DM9161_TX (1 << 10) |
||||
#define DM9161_RMII_ENABLE (1 << 8) |
||||
#define DM9161_F_LINK_100 (1 << 7) |
||||
#define DM9161_SPLED_CTL (1 << 6) |
||||
#define DM9161_COLLED_CTL (1 << 5) |
||||
#define DM9161_RPDCTR_EN (1 << 4) |
||||
#define DM9161_SM_RST (1 << 3) |
||||
#define DM9161_MFP SC (1 << 2) |
||||
#define DM9161_SLEEP (1 << 1) |
||||
#define DM9161_RLOUT (1 << 0) |
||||
|
||||
//--Bit definitions: DM9161_DSCSR
|
||||
#define DM9161_100FDX (1 << 15) |
||||
#define DM9161_100HDX (1 << 14) |
||||
#define DM9161_10FDX (1 << 13) |
||||
#define DM9161_10HDX (1 << 12) |
||||
|
||||
//--Bit definitions: DM9161_10BTCSR
|
||||
#define DM9161_LP_EN (1 << 14) |
||||
#define DM9161_HBE (1 << 13) |
||||
#define DM9161_SQUELCH (1 << 12) |
||||
#define DM9161_JABEN (1 << 11) |
||||
#define DM9161_10BT_SER (1 << 10) |
||||
#define DM9161_POLR (1 << 0) |
||||
|
||||
|
||||
//--Bit definitions: DM9161_MDINTR
|
||||
#define DM9161_INTR_PEND (1 << 15) |
||||
#define DM9161_FDX_MASK (1 << 11) |
||||
#define DM9161_SPD_MASK (1 << 10) |
||||
#define DM9161_LINK_MASK (1 << 9) |
||||
#define DM9161_INTR_MASK (1 << 8) |
||||
#define DM9161_FDX_CHANGE (1 << 4) |
||||
#define DM9161_SPD_CHANGE (1 << 3) |
||||
#define DM9161_LINK_CHANGE (1 << 2) |
||||
#define DM9161_INTR_STATUS (1 << 0) |
||||
|
||||
|
||||
/****************** function prototypes **********************/ |
||||
static unsigned int dm9161_IsPhyConnected(AT91PS_EMAC p_mac); |
||||
static unsigned char dm9161_GetLinkSpeed(AT91PS_EMAC p_mac); |
||||
static unsigned char dm9161_AutoNegotiate(AT91PS_EMAC p_mac, int *status); |
||||
static unsigned char dm9161_InitPhy(AT91PS_EMAC p_mac); |
Loading…
Reference in new issue