- add support for CMC PU2 board - add support for I2C on at91rm9200 * Patch by Gary Jennejohn, 28 Sep 2004: fix baudrate handling on at91rm9200master
parent
659883c298
commit
2cbe571a56
@ -0,0 +1,47 @@ |
||||
#
|
||||
# (C) Copyright 2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# 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 $(TOPDIR)/config.mk |
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := at91rm9200dk.o at45.o dm9161.o flash.o
|
||||
SOBJS := memsetup.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS) |
||||
$(AR) crv $@ $(OBJS) $(SOBJS)
|
||||
|
||||
clean: |
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean |
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) |
||||
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
-include .depend |
||||
|
||||
#########################################################################
|
@ -0,0 +1,621 @@ |
||||
/* 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 AT91C_SPI_CLK 10000000 /* Max Value = 10MHz to be compliant to |
||||
the Continuous Array Read function */ |
||||
|
||||
/* AC Characteristics */ |
||||
/* DLYBS = tCSS = 250ns min and DLYBCT = tCSH = 250ns */ |
||||
#define DATAFLASH_TCSS (0xC << 16) |
||||
#define DATAFLASH_TCHS (0x1 << 24) |
||||
|
||||
#define AT91C_TIMEOUT_WRDY 200000 |
||||
#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 & DATAFLASH_TCSS) | (AT91C_SPI_DLYBCT & |
||||
DATAFLASH_TCHS) | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8); |
||||
|
||||
*(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | (AT91C_SPI_DLYBCT & |
||||
DATAFLASH_TCHS) | ((AT91C_MASTER_CLOCK / (2*AT91C_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; |
||||
if (pDataFlash->pDevice->pages_number >= 16384) { |
||||
pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24); |
||||
pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16); |
||||
pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8); |
||||
pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF); |
||||
} else { |
||||
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 ) |
||||
{ |
||||
AT91S_DataFlashStatus status; |
||||
/* 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; |
||||
|
||||
status = AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src); |
||||
/* Send the command to the dataflash */ |
||||
return(status); |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* 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) |
||||
{ |
||||
int cmdsize; |
||||
pDataFlash->pDataFlashDesc->tx_data_pt = src ; |
||||
pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ; |
||||
pDataFlash->pDataFlashDesc->rx_data_pt = src; |
||||
pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite; |
||||
|
||||
cmdsize = 4; |
||||
/* Send the command to the dataflash */ |
||||
if (pDataFlash->pDevice->pages_number >= 16384) |
||||
cmdsize = 5; |
||||
return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, 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) |
||||
{ |
||||
int cmdsize; |
||||
/* 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; |
||||
cmdsize = 4; |
||||
if (pDataFlash->pDevice->pages_number >= 16384) |
||||
cmdsize = 5; |
||||
return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, 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 ) |
||||
{ |
||||
int cmdsize; |
||||
/* 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; |
||||
if (pDataFlash->pDevice->pages_number >= 16384) { |
||||
pDataFlash->pDataFlashDesc->command[2] = 0; |
||||
pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ; |
||||
pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ; |
||||
cmdsize = 5; |
||||
} else { |
||||
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->command[4] = 0; |
||||
cmdsize = 4; |
||||
} |
||||
|
||||
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 ; |
||||
|
||||
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_PageErase */ |
||||
/* Object : Erase a page */ |
||||
/* Input Parameters : DataFlash Service */ |
||||
/* : Page concerned */ |
||||
/* : */ |
||||
/* Return value : State of the dataflash */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_PageErase( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned int page) |
||||
{ |
||||
int cmdsize; |
||||
/* Test if the buffer command is legal */ |
||||
/* no data to transmit or receive */ |
||||
pDataFlash->pDataFlashDesc->tx_data_size = 0; |
||||
|
||||
cmdsize = 4; |
||||
if (pDataFlash->pDevice->pages_number >= 16384) |
||||
cmdsize = 5; |
||||
return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_ERASE, cmdsize, page*pDataFlash->pDevice->pages_size)); |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* Function Name : AT91F_BlockErase */ |
||||
/* Object : Erase a Block */ |
||||
/* Input Parameters : DataFlash Service */ |
||||
/* : Page concerned */ |
||||
/* : */ |
||||
/* Return value : State of the dataflash */ |
||||
/*------------------------------------------------------------------------------*/ |
||||
AT91S_DataFlashStatus AT91F_BlockErase( |
||||
AT91PS_DataFlash pDataFlash, |
||||
unsigned int block) |
||||
{ |
||||
int cmdsize; |
||||
/* Test if the buffer command is legal */ |
||||
/* no data to transmit or receive */ |
||||
pDataFlash->pDataFlashDesc->tx_data_size = 0; |
||||
cmdsize = 4; |
||||
if (pDataFlash->pDevice->pages_number >= 16384) |
||||
cmdsize = 5; |
||||
return(AT91F_DataFlashSendCommand (pDataFlash, DB_BLOCK_ERASE,cmdsize, block*8*pDataFlash->pDevice->pages_size)); |
||||
} |
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
/* 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 ) |
||||
{ |
||||
int cmdsize; |
||||
/* 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; |
||||
|
||||
cmdsize = 4; |
||||
if (pDataFlash->pDevice->pages_number >= 16384) |
||||
cmdsize = 5; |
||||
/* Send the command to the dataflash */ |
||||
return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, 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, AT91C_TIMEOUT_WRDY); |
||||
/*Update the SRAM buffer */ |
||||
AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size); |
||||
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY); |
||||
|
||||
/* Erase page if a 128 Mbits device */ |
||||
if (pDataFlash->pDevice->pages_number >= 16384) { |
||||
AT91F_PageErase(pDataFlash, page); |
||||
/* Rewrite the modified Sram Buffer in the main memory */ |
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY); |
||||
} |
||||
|
||||
/* 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 */ |
||||
/* 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; |
||||
unsigned int page; |
||||
unsigned int status; |
||||
|
||||
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, AT91C_TIMEOUT_WRDY); |
||||
|
||||
/* Update size, source and destination pointers */ |
||||
size -= length; |
||||
dest += length; |
||||
src += length; |
||||
} |
||||
|
||||
while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) { |
||||
/* program dataflash page */ |
||||
page = (unsigned int)dest / (pDataFlash->pDevice->pages_size); |
||||
|
||||
status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, 0, pDataFlash->pDevice->pages_size); |
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY); |
||||
|
||||
status = AT91F_PageErase(pDataFlash, page); |
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY); |
||||
if (!status) |
||||
return DATAFLASH_ERROR; |
||||
|
||||
status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest); |
||||
if(!status) |
||||
return DATAFLASH_ERROR; |
||||
|
||||
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY); |
||||
|
||||
/* 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, AT91C_TIMEOUT_WRDY); |
||||
} |
||||
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, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK) |
||||
return -1; |
||||
|
||||
while (size) { |
||||
SizeToRead = (size < 0x8000)? size:0x8000; |
||||
|
||||
if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != 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,118 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com> |
||||
* Marius Groeger <mgroeger@sysgo.de> |
||||
* |
||||
* 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 <common.h> |
||||
#include <asm/arch/AT91RM9200.h> |
||||
|
||||
/* ------------------------------------------------------------------------- */ |
||||
/*
|
||||
* Miscelaneous platform dependent initialisations |
||||
*/ |
||||
|
||||
int board_init (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
/* Enable Ctrlc */ |
||||
console_init_f (); |
||||
|
||||
/* Correct IRDA resistor problem */ |
||||
/* Set PA23_TXD in Output */ |
||||
(AT91PS_PIO) AT91C_BASE_PIOA->PIO_OER = AT91C_PA23_TXD2; |
||||
|
||||
/* memory and cpu-speed are setup before relocation */ |
||||
/* so we do _nothing_ here */ |
||||
|
||||
/* arch number of AT91RM9200DK-Board */ |
||||
gd->bd->bi_arch_number = 251; |
||||
/* adress of boot parameters */ |
||||
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int dram_init (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM; |
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE; |
||||
return 0; |
||||
} |
||||
|
||||
/*
|
||||
* Disk On Chip (NAND) Millenium initialization. |
||||
* The NAND lives in the CS2* space |
||||
*/ |
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND) |
||||
extern ulong nand_probe (ulong physadr); |
||||
|
||||
#define AT91_SMARTMEDIA_BASE 0x40000000 /* physical address to access memory on NCS3 */ |
||||
void nand_init (void) |
||||
{ |
||||
/* Setup Smart Media, fitst enable the address range of CS3 */ |
||||
*AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia; |
||||
/* set the bus interface characteristics based on
|
||||
tDS Data Set up Time 30 - ns |
||||
tDH Data Hold Time 20 - ns |
||||
tALS ALE Set up Time 20 - ns |
||||
16ns at 60 MHz ~= 3 */ |
||||
/*memory mapping structures */ |
||||
#define SM_ID_RWH (5 << 28) |
||||
#define SM_RWH (1 << 28) |
||||
#define SM_RWS (0 << 24) |
||||
#define SM_TDF (1 << 8) |
||||
#define SM_NWS (3) |
||||
AT91C_BASE_SMC2->SMC2_CSR[3] = (SM_RWH | SM_RWS | |
||||
AT91C_SMC2_ACSS_STANDARD | AT91C_SMC2_DBW_8 | |
||||
SM_TDF | AT91C_SMC2_WSEN | SM_NWS); |
||||
|
||||
/* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */ |
||||
*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | |
||||
AT91C_PC3_BFBAA_SMWE; |
||||
*AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | |
||||
AT91C_PC3_BFBAA_SMWE; |
||||
|
||||
/* Configure PC2 as input (signal READY of the SmartMedia) */ |
||||
*AT91C_PIOC_PER = AT91C_PC2_BFAVD; /* enable direct output enable */ |
||||
*AT91C_PIOC_ODR = AT91C_PC2_BFAVD; /* disable output */ |
||||
|
||||
/* Configure PB1 as input (signal Card Detect of the SmartMedia) */ |
||||
*AT91C_PIOB_PER = AT91C_PIO_PB1; /* enable direct output enable */ |
||||
*AT91C_PIOB_ODR = AT91C_PIO_PB1; /* disable output */ |
||||
|
||||
/* PIOB and PIOC clock enabling */ |
||||
*AT91C_PMC_PCER = 1 << AT91C_ID_PIOB; |
||||
*AT91C_PMC_PCER = 1 << AT91C_ID_PIOC; |
||||
|
||||
if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1) |
||||
printf (" No SmartMedia card inserted\n"); |
||||
#ifdef DEBUG |
||||
printf (" SmartMedia card inserted\n"); |
||||
|
||||
printf ("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE); |
||||
#endif |
||||
printf ("%4lu MB\n", nand_probe(AT91_SMARTMEDIA_BASE) >> 20); |
||||
} |
||||
#endif |
@ -0,0 +1 @@ |
||||
TEXT_BASE = 0x21f00000
|
@ -0,0 +1,243 @@ |
||||
/*
|
||||
* (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> |
||||
#include <dm9161.h> |
||||
|
||||
#ifdef CONFIG_DRIVER_ETHER |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) |
||||
|
||||
/*
|
||||
* 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; |
||||
} |
||||
|
||||
|
||||
/*
|
||||
* Name: |
||||
* at91rm92000_GetPhyInterface |
||||
* Description: |
||||
* Initialise the interface functions to the PHY |
||||
* Arguments: |
||||
* None |
||||
* Return value: |
||||
* None |
||||
*/ |
||||
void at91rm92000_GetPhyInterface(AT91PS_PhyOps p_phyops) |
||||
{ |
||||
p_phyops->Init = dm9161_InitPhy; |
||||
p_phyops->IsPhyConnected = dm9161_IsPhyConnected; |
||||
p_phyops->GetLinkSpeed = dm9161_GetLinkSpeed; |
||||
p_phyops->AutoNegotiate = dm9161_AutoNegotiate; |
||||
} |
||||
|
||||
#endif /* CONFIG_COMMANDS & CFG_CMD_NET */ |
||||
|
||||
#endif /* CONFIG_DRIVER_ETHER */ |
@ -0,0 +1,507 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Lineo, Inc. <www.lineo.com> |
||||
* Bernhard Kuhn <bkuhn@lineo.com> |
||||
* |
||||
* (C) Copyright 2002 |
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com> |
||||
* Alex Zuepke <azu@sysgo.de> |
||||
* |
||||
* 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 <common.h> |
||||
|
||||
ulong myflush(void); |
||||
|
||||
|
||||
/* Flash Organization Structure */ |
||||
typedef struct OrgDef |
||||
{ |
||||
unsigned int sector_number; |
||||
unsigned int sector_size; |
||||
} OrgDef; |
||||
|
||||
|
||||
/* Flash Organizations */ |
||||
OrgDef OrgAT49BV16x4[] = |
||||
{ |
||||
{ 8, 8*1024 }, /* 8 * 8 kBytes sectors */ |
||||
{ 2, 32*1024 }, /* 2 * 32 kBytes sectors */ |
||||
{ 30, 64*1024 }, /* 30 * 64 kBytes sectors */ |
||||
}; |
||||
|
||||
OrgDef OrgAT49BV16x4A[] = |
||||
{ |
||||
{ 8, 8*1024 }, /* 8 * 8 kBytes sectors */ |
||||
{ 31, 64*1024 }, /* 31 * 64 kBytes sectors */ |
||||
}; |
||||
|
||||
OrgDef OrgAT49BV6416[] = |
||||
{ |
||||
{ 8, 8*1024 }, /* 8 * 8 kBytes sectors */ |
||||
{ 127, 64*1024 }, /* 127 * 64 kBytes sectors */ |
||||
}; |
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; |
||||
|
||||
/* AT49BV1614A Codes */ |
||||
#define FLASH_CODE1 0xAA |
||||
#define FLASH_CODE2 0x55 |
||||
#define ID_IN_CODE 0x90 |
||||
#define ID_OUT_CODE 0xF0 |
||||
|
||||
|
||||
#define CMD_READ_ARRAY 0x00F0 |
||||
#define CMD_UNLOCK1 0x00AA |
||||
#define CMD_UNLOCK2 0x0055 |
||||
#define CMD_ERASE_SETUP 0x0080 |
||||
#define CMD_ERASE_CONFIRM 0x0030 |
||||
#define CMD_PROGRAM 0x00A0 |
||||
#define CMD_UNLOCK_BYPASS 0x0020 |
||||
#define CMD_SECTOR_UNLOCK 0x0070 |
||||
|
||||
#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00005555<<1))) |
||||
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00002AAA<<1))) |
||||
|
||||
#define BIT_ERASE_DONE 0x0080 |
||||
#define BIT_RDY_MASK 0x0080 |
||||
#define BIT_PROGRAM_ERROR 0x0020 |
||||
#define BIT_TIMEOUT 0x80000000 /* our flag */ |
||||
|
||||
#define READY 1 |
||||
#define ERR 2 |
||||
#define TMO 4 |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
void flash_identification (flash_info_t * info) |
||||
{ |
||||
volatile u16 manuf_code, device_code, add_device_code; |
||||
|
||||
MEM_FLASH_ADDR1 = FLASH_CODE1; |
||||
MEM_FLASH_ADDR2 = FLASH_CODE2; |
||||
MEM_FLASH_ADDR1 = ID_IN_CODE; |
||||
|
||||
manuf_code = *(volatile u16 *) CFG_FLASH_BASE; |
||||
device_code = *(volatile u16 *) (CFG_FLASH_BASE + 2); |
||||
add_device_code = *(volatile u16 *) (CFG_FLASH_BASE + (3 << 1)); |
||||
|
||||
MEM_FLASH_ADDR1 = FLASH_CODE1; |
||||
MEM_FLASH_ADDR2 = FLASH_CODE2; |
||||
MEM_FLASH_ADDR1 = ID_OUT_CODE; |
||||
|
||||
/* Vendor type */ |
||||
info->flash_id = ATM_MANUFACT & FLASH_VENDMASK; |
||||
printf ("Atmel: "); |
||||
|
||||
if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV1614 & FLASH_TYPEMASK)) { |
||||
|
||||
if ((add_device_code & FLASH_TYPEMASK) == |
||||
(ATM_ID_BV1614A & FLASH_TYPEMASK)) { |
||||
info->flash_id |= ATM_ID_BV1614A & FLASH_TYPEMASK; |
||||
printf ("AT49BV1614A (16Mbit)\n"); |
||||
} else { /* AT49BV1614 Flash */ |
||||
info->flash_id |= ATM_ID_BV1614 & FLASH_TYPEMASK; |
||||
printf ("AT49BV1614 (16Mbit)\n"); |
||||
} |
||||
|
||||
} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416 & FLASH_TYPEMASK)) { |
||||
info->flash_id |= ATM_ID_BV6416 & FLASH_TYPEMASK; |
||||
printf ("AT49BV6416 (64Mbit)\n"); |
||||
} |
||||
} |
||||
|
||||
ushort flash_number_sector(OrgDef *pOrgDef, unsigned int nb_blocks) |
||||
{ |
||||
int i, nb_sectors = 0; |
||||
|
||||
for (i=0; i<nb_blocks; i++){ |
||||
nb_sectors += pOrgDef[i].sector_number; |
||||
} |
||||
|
||||
return nb_sectors; |
||||
} |
||||
|
||||
void flash_unlock_sector(flash_info_t * info, unsigned int sector) |
||||
{ |
||||
volatile u16 *addr = (volatile u16 *) (info->start[sector]); |
||||
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1; |
||||
*addr = CMD_SECTOR_UNLOCK; |
||||
} |
||||
|
||||
|
||||
ulong flash_init (void) |
||||
{ |
||||
int i, j, k; |
||||
unsigned int flash_nb_blocks, sector; |
||||
unsigned int start_address; |
||||
OrgDef *pOrgDef; |
||||
|
||||
ulong size = 0; |
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { |
||||
ulong flashbase = 0; |
||||
|
||||
flash_identification (&flash_info[i]); |
||||
|
||||
if ((flash_info[i].flash_id & FLASH_TYPEMASK) == |
||||
(ATM_ID_BV1614 & FLASH_TYPEMASK)) { |
||||
|
||||
pOrgDef = OrgAT49BV16x4; |
||||
flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef); |
||||
} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) == |
||||
(ATM_ID_BV1614A & FLASH_TYPEMASK)){ /* AT49BV1614A Flash */ |
||||
|
||||
pOrgDef = OrgAT49BV16x4A; |
||||
flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef); |
||||
} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) == |
||||
(ATM_ID_BV6416 & FLASH_TYPEMASK)){ /* AT49BV6416 Flash */ |
||||
|
||||
pOrgDef = OrgAT49BV6416; |
||||
flash_nb_blocks = sizeof (OrgAT49BV6416) / sizeof (OrgDef); |
||||
} else { |
||||
flash_nb_blocks = 0; |
||||
pOrgDef = OrgAT49BV16x4; |
||||
} |
||||
|
||||
flash_info[i].sector_count = flash_number_sector(pOrgDef, flash_nb_blocks); |
||||
memset (flash_info[i].protect, 0, flash_info[i].sector_count); |
||||
|
||||
if (i == 0) |
||||
flashbase = PHYS_FLASH_1; |
||||
else |
||||
panic ("configured too many flash banks!\n"); |
||||
|
||||
sector = 0; |
||||
start_address = flashbase; |
||||
flash_info[i].size = 0; |
||||
|
||||
for (j = 0; j < flash_nb_blocks; j++) { |
||||
for (k = 0; k < pOrgDef[j].sector_number; k++) { |
||||
flash_info[i].start[sector++] = start_address; |
||||
start_address += pOrgDef[j].sector_size; |
||||
flash_info[i].size += pOrgDef[j].sector_size; |
||||
} |
||||
} |
||||
|
||||
size += flash_info[i].size; |
||||
|
||||
if ((flash_info[i].flash_id & FLASH_TYPEMASK) == |
||||
(ATM_ID_BV6416 & FLASH_TYPEMASK)){ /* AT49BV6416 Flash */ |
||||
|
||||
/* Unlock all sectors at reset */ |
||||
for (j=0; j<flash_info[i].sector_count; j++){ |
||||
flash_unlock_sector(&flash_info[i], j); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* Protect binary boot image */ |
||||
flash_protect (FLAG_PROTECT_SET, |
||||
CFG_FLASH_BASE, |
||||
CFG_FLASH_BASE + CFG_BOOT_SIZE - 1, &flash_info[0]); |
||||
|
||||
/* Protect environment variables */ |
||||
flash_protect (FLAG_PROTECT_SET, |
||||
CFG_ENV_ADDR, |
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); |
||||
|
||||
/* Protect U-Boot gzipped image */ |
||||
flash_protect (FLAG_PROTECT_SET, |
||||
CFG_U_BOOT_BASE, |
||||
CFG_U_BOOT_BASE + CFG_U_BOOT_SIZE - 1, &flash_info[0]); |
||||
|
||||
return size; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
void flash_print_info (flash_info_t * info) |
||||
{ |
||||
int i; |
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) { |
||||
case (ATM_MANUFACT & FLASH_VENDMASK): |
||||
printf ("Atmel: "); |
||||
break; |
||||
default: |
||||
printf ("Unknown Vendor "); |
||||
break; |
||||
} |
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) { |
||||
case (ATM_ID_BV1614 & FLASH_TYPEMASK): |
||||
printf ("AT49BV1614 (16Mbit)\n"); |
||||
break; |
||||
case (ATM_ID_BV1614A & FLASH_TYPEMASK): |
||||
printf ("AT49BV1614A (16Mbit)\n"); |
||||
break; |
||||
case (ATM_ID_BV6416 & FLASH_TYPEMASK): |
||||
printf ("AT49BV6416 (64Mbit)\n"); |
||||
break; |
||||
default: |
||||
printf ("Unknown Chip Type\n"); |
||||
goto Done; |
||||
break; |
||||
} |
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n", |
||||
info->size >> 20, info->sector_count); |
||||
|
||||
printf (" Sector Start Addresses:"); |
||||
for (i = 0; i < info->sector_count; i++) { |
||||
if ((i % 5) == 0) { |
||||
printf ("\n "); |
||||
} |
||||
printf (" %08lX%s", info->start[i], |
||||
info->protect[i] ? " (RO)" : " "); |
||||
} |
||||
printf ("\n"); |
||||
|
||||
Done: ; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
|
||||
int flash_erase (flash_info_t * info, int s_first, int s_last) |
||||
{ |
||||
ulong result; |
||||
int iflag, cflag, prot, sect; |
||||
int rc = ERR_OK; |
||||
int chip1; |
||||
|
||||
/* first look for protection bits */ |
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) |
||||
return ERR_UNKNOWN_FLASH_TYPE; |
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) { |
||||
return ERR_INVAL; |
||||
} |
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) != |
||||
(ATM_MANUFACT & FLASH_VENDMASK)) { |
||||
return ERR_UNKNOWN_FLASH_VENDOR; |
||||
} |
||||
|
||||
prot = 0; |
||||
for (sect = s_first; sect <= s_last; ++sect) { |
||||
if (info->protect[sect]) { |
||||
prot++; |
||||
} |
||||
} |
||||
if (prot) |
||||
return ERR_PROTECTED; |
||||
|
||||
/*
|
||||
* Disable interrupts which might cause a timeout |
||||
* here. Remember that our exception vectors are |
||||
* at address 0 in the flash, and we don't want a |
||||
* (ticker) exception to happen while the flash |
||||
* chip is in programming mode. |
||||
*/ |
||||
cflag = icache_status (); |
||||
icache_disable (); |
||||
iflag = disable_interrupts (); |
||||
|
||||
/* Start erase on unprotected sectors */ |
||||
for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { |
||||
printf ("Erasing sector %2d ... ", sect); |
||||
|
||||
/* arm simple, non interrupt dependent timer */ |
||||
reset_timer_masked (); |
||||
|
||||
if (info->protect[sect] == 0) { /* not protected */ |
||||
volatile u16 *addr = (volatile u16 *) (info->start[sect]); |
||||
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1; |
||||
MEM_FLASH_ADDR2 = CMD_UNLOCK2; |
||||
MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; |
||||
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1; |
||||
MEM_FLASH_ADDR2 = CMD_UNLOCK2; |
||||
*addr = CMD_ERASE_CONFIRM; |
||||
|
||||
/* wait until flash is ready */ |
||||
chip1 = 0; |
||||
|
||||
do { |
||||
result = *addr; |
||||
|
||||
/* check timeout */ |
||||
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { |
||||
MEM_FLASH_ADDR1 = CMD_READ_ARRAY; |
||||
chip1 = TMO; |
||||
break; |
||||
} |
||||
|
||||
if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE) |
||||
chip1 = READY; |
||||
|
||||
} while (!chip1); |
||||
|
||||
MEM_FLASH_ADDR1 = CMD_READ_ARRAY; |
||||
|
||||
if (chip1 == ERR) { |
||||
rc = ERR_PROG_ERROR; |
||||
goto outahere; |
||||
} |
||||
if (chip1 == TMO) { |
||||
rc = ERR_TIMOUT; |
||||
goto outahere; |
||||
} |
||||
|
||||
printf ("ok.\n"); |
||||
} else { /* it was protected */ |
||||
printf ("protected!\n"); |
||||
} |
||||
} |
||||
|
||||
if (ctrlc ()) |
||||
printf ("User Interrupt!\n"); |
||||
|
||||
outahere: |
||||
/* allow flash to settle - wait 10 ms */ |
||||
udelay_masked (10000); |
||||
|
||||
if (iflag) |
||||
enable_interrupts (); |
||||
|
||||
if (cflag) |
||||
icache_enable (); |
||||
|
||||
return rc; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash |
||||
*/ |
||||
|
||||
volatile static int write_word (flash_info_t * info, ulong dest, |
||||
ulong data) |
||||
{ |
||||
volatile u16 *addr = (volatile u16 *) dest; |
||||
ulong result; |
||||
int rc = ERR_OK; |
||||
int cflag, iflag; |
||||
int chip1; |
||||
|
||||
/*
|
||||
* Check if Flash is (sufficiently) erased |
||||
*/ |
||||
result = *addr; |
||||
if ((result & data) != data) |
||||
return ERR_NOT_ERASED; |
||||
|
||||
|
||||
/*
|
||||
* Disable interrupts which might cause a timeout |
||||
* here. Remember that our exception vectors are |
||||
* at address 0 in the flash, and we don't want a |
||||
* (ticker) exception to happen while the flash |
||||
* chip is in programming mode. |
||||
*/ |
||||
cflag = icache_status (); |
||||
icache_disable (); |
||||
iflag = disable_interrupts (); |
||||
|
||||
MEM_FLASH_ADDR1 = CMD_UNLOCK1; |
||||
MEM_FLASH_ADDR2 = CMD_UNLOCK2; |
||||
MEM_FLASH_ADDR1 = CMD_PROGRAM; |
||||
*addr = data; |
||||
|
||||
/* arm simple, non interrupt dependent timer */ |
||||
reset_timer_masked (); |
||||
|
||||
/* wait until flash is ready */ |
||||
chip1 = 0; |
||||
do { |
||||
result = *addr; |
||||
|
||||
/* check timeout */ |
||||
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { |
||||
chip1 = ERR | TMO; |
||||
break; |
||||
} |
||||
if (!chip1 && ((result & 0x80) == (data & 0x80))) |
||||
chip1 = READY; |
||||
|
||||
} while (!chip1); |
||||
|
||||
*addr = CMD_READ_ARRAY; |
||||
|
||||
if (chip1 == ERR || *addr != data) |
||||
rc = ERR_PROG_ERROR; |
||||
|
||||
if (iflag) |
||||
enable_interrupts (); |
||||
|
||||
if (cflag) |
||||
icache_enable (); |
||||
|
||||
return rc; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash. |
||||
*/ |
||||
|
||||
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) |
||||
{ |
||||
ulong wp, data; |
||||
int rc; |
||||
|
||||
if (addr & 1) { |
||||
printf ("unaligned destination not supported\n"); |
||||
return ERR_ALIGN; |
||||
}; |
||||
|
||||
if ((int) src & 1) { |
||||
printf ("unaligned source not supported\n"); |
||||
return ERR_ALIGN; |
||||
}; |
||||
|
||||
wp = addr; |
||||
|
||||
while (cnt >= 2) { |
||||
data = *((volatile u16 *) src); |
||||
if ((rc = write_word (info, wp, data)) != 0) { |
||||
return (rc); |
||||
} |
||||
src += 2; |
||||
wp += 2; |
||||
cnt -= 2; |
||||
} |
||||
|
||||
if (cnt == 1) { |
||||
data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1)) << |
||||
8); |
||||
if ((rc = write_word (info, wp, data)) != 0) { |
||||
return (rc); |
||||
} |
||||
src += 1; |
||||
wp += 1; |
||||
cnt -= 1; |
||||
}; |
||||
|
||||
return ERR_OK; |
||||
} |
@ -0,0 +1,200 @@ |
||||
/* |
||||
* Memory Setup stuff - taken from blob memsetup.S |
||||
* |
||||
* Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
|
||||
* Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
|
||||
* |
||||
* Modified for the at91rm9200dk board by |
||||
* (C) Copyright 2004 |
||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
* |
||||
* 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 <config.h> |
||||
#include <version.h> |
||||
|
||||
#ifdef CONFIG_BOOTBINFUNC |
||||
/* |
||||
* some parameters for the board |
||||
* |
||||
* This is based on rm9200dk.cfg for the BDI2000 from ABATRON which in |
||||
* turn is based on the boot.bin code from ATMMEL |
||||
* |
||||
*/ |
||||
|
||||
/* flash */ |
||||
#define MC_PUIA 0xFFFFFF10 |
||||
#define MC_PUIA_VAL 0x00000000 |
||||
#define MC_PUP 0xFFFFFF50 |
||||
#define MC_PUP_VAL 0x00000000 |
||||
#define MC_PUER 0xFFFFFF54 |
||||
#define MC_PUER_VAL 0x00000000 |
||||
#define MC_ASR 0xFFFFFF04 |
||||
#define MC_ASR_VAL 0x00000000 |
||||
#define MC_AASR 0xFFFFFF08 |
||||
#define MC_AASR_VAL 0x00000000 |
||||
#define EBI_CFGR 0xFFFFFF64 |
||||
#define EBI_CFGR_VAL 0x00000000 |
||||
#define SMC2_CSR 0xFFFFFF70 |
||||
#define SMC2_CSR_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ |
||||
|
||||
/* clocks */ |
||||
#define PLLAR 0xFFFFFC28 |
||||
#define PLLAR_VAL 0x20263E04 /* 179.712000 MHz for PCK */ |
||||
#define PLLBR 0xFFFFFC2C |
||||
#define PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */ |
||||
#define MCKR 0xFFFFFC30 |
||||
#define MCKR_VAL 0x00000202 /* PCK/3 = MCK Master Clock = 59.904000MHz from PLLA */ |
||||
|
||||
/* sdram */ |
||||
#define PIOC_ASR 0xFFFFF870 |
||||
#define PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ |
||||
#define PIOC_BSR 0xFFFFF804 |
||||
#define PIOC_BSR_VAL 0x00000000 |
||||
#define PIOC_PDR 0xFFFFF804 |
||||
#define PIOC_PDR_VAL 0xFFFF0000 |
||||
#define EBI_CSA 0xFFFFFF60 |
||||
#define EBI_CSA_VAL 0x00000002 /* CS1=SDRAM */ |
||||
#define SDRC_CR 0xFFFFFF98 |
||||
#define SDRC_CR_VAL 0x2188c155 |
||||
#define SDRAM 0x20000000 /* address of the SDRAM */ |
||||
#define SDRAM1 0x20000080 /* address of the SDRAM */ |
||||
#define SDRAM_VAL 0x00000000 /* value written to SDRAM */ |
||||
#define SDRC_MR 0xFFFFFF90 |
||||
#define SDRC_MR_VAL 0x00000002 /* Precharge All */ |
||||
#define SDRC_MR_VAL1 0x00000004 /* refresh */ |
||||
#define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ |
||||
#define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ |
||||
#define SDRC_TR 0xFFFFFF94 |
||||
#define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ |
||||
|
||||
|
||||
_TEXT_BASE: |
||||
.word TEXT_BASE
|
||||
|
||||
.globl memsetup
|
||||
memsetup: |
||||
/* memory control configuration */ |
||||
/* this isn't very elegant, but what the heck */ |
||||
ldr r0, =SMRDATA |
||||
ldr r1, _TEXT_BASE |
||||
sub r0, r0, r1 |
||||
add r2, r0, #80 |
||||
0: |
||||
/* the address */ |
||||
ldr r1, [r0], #4 |
||||
/* the value */ |
||||
ldr r3, [r0], #4 |
||||
str r3, [r1] |
||||
cmp r2, r0 |
||||
bne 0b |
||||
/* delay - this is all done by guess */ |
||||
ldr r0, =0x00001000 |
||||
1: |
||||
subs r0, r0, #1
|
||||
bhi 1b |
||||
ldr r0, =SMRDATA1 |
||||
ldr r1, _TEXT_BASE |
||||
sub r0, r0, r1 |
||||
add r2, r0, #176 |
||||
2: |
||||
/* the address */ |
||||
ldr r1, [r0], #4 |
||||
/* the value */ |
||||
ldr r3, [r0], #4 |
||||
str r3, [r1] |
||||
cmp r2, r0 |
||||
bne 2b |
||||
|
||||
/* everything is fine now */ |
||||
mov pc, lr |
||||
|
||||
.ltorg |
||||
|
||||
SMRDATA: |
||||
.word MC_PUIA
|
||||
.word MC_PUIA_VAL
|
||||
.word MC_PUP
|
||||
.word MC_PUP_VAL
|
||||
.word MC_PUER
|
||||
.word MC_PUER_VAL
|
||||
.word MC_ASR
|
||||
.word MC_ASR_VAL
|
||||
.word MC_AASR
|
||||
.word MC_AASR_VAL
|
||||
.word EBI_CFGR
|
||||
.word EBI_CFGR_VAL
|
||||
.word SMC2_CSR
|
||||
.word SMC2_CSR_VAL
|
||||
.word PLLAR
|
||||
.word PLLAR_VAL
|
||||
.word PLLBR
|
||||
.word PLLBR_VAL
|
||||
.word MCKR
|
||||
.word MCKR_VAL
|
||||
/* SMRDATA is 80 bytes long */ |
||||
/* here there's a delay of 100 */ |
||||
SMRDATA1: |
||||
.word PIOC_ASR
|
||||
.word PIOC_ASR_VAL
|
||||
.word PIOC_BSR
|
||||
.word PIOC_BSR_VAL
|
||||
.word PIOC_PDR
|
||||
.word PIOC_PDR_VAL
|
||||
.word EBI_CSA
|
||||
.word EBI_CSA_VAL
|
||||
.word SDRC_CR
|
||||
.word SDRC_CR_VAL
|
||||
.word SDRC_MR
|
||||
.word SDRC_MR_VAL
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRC_MR
|
||||
.word SDRC_MR_VAL1
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRC_MR
|
||||
.word SDRC_MR_VAL2
|
||||
.word SDRAM1
|
||||
.word SDRAM_VAL
|
||||
.word SDRC_TR
|
||||
.word SDRC_TR_VAL
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
.word SDRC_MR
|
||||
.word SDRC_MR_VAL3
|
||||
.word SDRAM
|
||||
.word SDRAM_VAL
|
||||
/* SMRDATA1 is 176 bytes long */ |
||||
#endif /* CONFIG_BOOTBINFUNC */ |
@ -0,0 +1,56 @@ |
||||
/* |
||||
* (C) Copyright 2002 |
||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de> |
||||
* |
||||
* 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 |
||||
*/ |
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") |
||||
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/ |
||||
OUTPUT_ARCH(arm) |
||||
ENTRY(_start) |
||||
SECTIONS |
||||
{ |
||||
. = 0x00000000; |
||||
|
||||
. = ALIGN(4); |
||||
.text : |
||||
{ |
||||
cpu/at91rm9200/start.o (.text) |
||||
*(.text) |
||||
} |
||||
|
||||
. = ALIGN(4); |
||||
.rodata : { *(.rodata) } |
||||
|
||||
. = ALIGN(4); |
||||
.data : { *(.data) } |
||||
|
||||
. = ALIGN(4); |
||||
.got : { *(.got) } |
||||
|
||||
__u_boot_cmd_start = .; |
||||
.u_boot_cmd : { *(.u_boot_cmd) } |
||||
__u_boot_cmd_end = .; |
||||
|
||||
. = ALIGN(4); |
||||
__bss_start = .; |
||||
.bss : { *(.bss) } |
||||
_end = .; |
||||
} |
@ -0,0 +1,192 @@ |
||||
/*
|
||||
* i2c Support for Atmel's AT91RM9200 Two-Wire Interface |
||||
* |
||||
* (c) Rick Bronson |
||||
* |
||||
* Borrowed heavily from original work by: |
||||
* Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> |
||||
* |
||||
* Modified to work with u-boot by (C) 2004 Gary Jennejohn garyj@denx.de |
||||
* |
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA. |
||||
* |
||||
*/ |
||||
#include <common.h> |
||||
|
||||
#ifdef CONFIG_HARD_I2C |
||||
|
||||
#include <i2c.h> |
||||
#include <asm/io.h> |
||||
#include <asm/arch/hardware.h> |
||||
|
||||
#include <at91rm9200_i2c.h> |
||||
|
||||
static int debug = 0; |
||||
|
||||
/*
|
||||
* Poll the i2c status register until the specified bit is set. |
||||
* Returns 0 if timed out (100 msec) |
||||
*/ |
||||
static short at91_poll_status(AT91PS_TWI twi, unsigned long bit) { |
||||
int loop_cntr = 10000; |
||||
do { |
||||
udelay(100); |
||||
} while (!(twi->TWI_SR & bit) && (--loop_cntr > 0)); |
||||
|
||||
return (loop_cntr > 0); |
||||
} |
||||
|
||||
/*
|
||||
* Generic i2c master transfer entrypoint |
||||
* |
||||
* rw == 1 means that this is a read |
||||
*/ |
||||
static int |
||||
at91_xfer(unsigned char chip, unsigned int addr, int alen, |
||||
unsigned char *buffer, int len, int rw) |
||||
{ |
||||
AT91PS_TWI twi = (AT91PS_TWI) AT91_TWI_BASE; |
||||
int length; |
||||
unsigned char *buf; |
||||
|
||||
/* Set the TWI Master Mode Register */ |
||||
twi->TWI_MMR = (chip << 16) | (alen << 8) |
||||
| ((rw == 1) ? AT91C_TWI_MREAD : 0); |
||||
|
||||
/* Set TWI Internal Address Register with first messages data field */ |
||||
/* only one address byte is supported */ |
||||
if (alen > 0) |
||||
twi->TWI_IADR = addr & 0xff; |
||||
|
||||
length = len; |
||||
buf = buffer; |
||||
if (length && buf) { /* sanity check */ |
||||
if (rw) { |
||||
twi->TWI_CR = AT91C_TWI_START; |
||||
while (length--) { |
||||
if (!length) |
||||
twi->TWI_CR = AT91C_TWI_STOP; |
||||
/* Wait until transfer is finished */ |
||||
if (!at91_poll_status(twi, AT91C_TWI_RXRDY)) { |
||||
if (debug) |
||||
printf("at91_i2c: timeout 1\n"); |
||||
return 1; |
||||
} |
||||
*buf++ = twi->TWI_RHR; |
||||
} |
||||
if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) { |
||||
if (debug) |
||||
printf("at91_i2c: timeout 2\n"); |
||||
return 1; |
||||
} |
||||
} else { |
||||
twi->TWI_CR = AT91C_TWI_START; |
||||
while (length--) { |
||||
twi->TWI_THR = *buf++; |
||||
if (!length) |
||||
twi->TWI_CR = AT91C_TWI_STOP; |
||||
if (!at91_poll_status(twi, AT91C_TWI_TXRDY)) { |
||||
if (debug) |
||||
printf("at91_i2c: timeout 3\n"); |
||||
return 1; |
||||
} |
||||
} |
||||
/* Wait until transfer is finished */ |
||||
if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) { |
||||
if (debug) |
||||
printf("at91_i2c: timeout 4\n"); |
||||
return 1; |
||||
} |
||||
} |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
int |
||||
i2c_probe(unsigned char chip) |
||||
{ |
||||
char buffer[1]; |
||||
|
||||
return at91_xfer(chip, 0, 0, buffer, 1, 1); |
||||
} |
||||
|
||||
int |
||||
i2c_read(unsigned char chip, unsigned int addr, int alen, |
||||
unsigned char *buffer, int len) |
||||
{ |
||||
/* we only allow one address byte */ |
||||
if (alen > 1) |
||||
return 1; |
||||
#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW |
||||
/* XXX assume an ATMEL AT24C16 */ |
||||
if (alen == 1) { |
||||
chip |= (addr >> 8) & 0xff; |
||||
addr = addr & 0xff; |
||||
} |
||||
#endif |
||||
return at91_xfer(chip, addr, alen, buffer, len, 1); |
||||
} |
||||
|
||||
int |
||||
i2c_write(unsigned char chip, unsigned int addr, int alen, |
||||
unsigned char *buffer, int len) |
||||
{ |
||||
int i; |
||||
unsigned char *buf; |
||||
|
||||
/* we only allow one address byte */ |
||||
if (alen > 1) |
||||
return 1; |
||||
#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW |
||||
/* XXX assume an ATMEL AT24C16 */ |
||||
if (alen == 1) { |
||||
buf = buffer; |
||||
/* do single byte writes */ |
||||
for (i = 0; i < len; i++) { |
||||
chip |= (addr >> 8) & 0xff; |
||||
addr = addr & 0xff; |
||||
if (at91_xfer(chip, addr, alen, buf++, 1, 0)) |
||||
return 1; |
||||
} |
||||
} |
||||
return 0; |
||||
#endif |
||||
return at91_xfer(chip, addr, alen, buffer, len, 0); |
||||
} |
||||
|
||||
/*
|
||||
* Main initialization routine |
||||
*/ |
||||
void |
||||
i2c_init(int speed, int slaveaddr) |
||||
{ |
||||
AT91PS_TWI twi = (AT91PS_TWI) AT91_TWI_BASE; |
||||
|
||||
*AT91C_PIOA_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK; |
||||
*AT91C_PIOA_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK; |
||||
*AT91C_PIOA_MDER = AT91C_PA25_TWD | AT91C_PA26_TWCK; |
||||
*AT91C_PMC_PCER = 1 << AT91C_ID_TWI; /* enable peripheral clock */ |
||||
|
||||
twi->TWI_IDR = 0x3ff; /* Disable all interrupts */ |
||||
twi->TWI_CR = AT91C_TWI_SWRST; /* Reset peripheral */ |
||||
twi->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS; /* Set Master mode */ |
||||
|
||||
/* Here, CKDIV = 1 and CHDIV=CLDIV ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6) */ |
||||
twi->TWI_CWGR = AT91C_TWI_CKDIV1 | AT91C_TWI_CLDIV3 | (AT91C_TWI_CLDIV3 << 8); |
||||
|
||||
printf("Found AT91 i2c\n"); |
||||
return; |
||||
} |
||||
#endif /* CONFIG_HARD_I2C */ |
@ -0,0 +1,126 @@ |
||||
// ----------------------------------------------------------------------------
|
||||
// ATMEL Microcontroller Software Support - ROUSSET -
|
||||
// ----------------------------------------------------------------------------
|
||||
// The software is delivered "AS IS" without warranty or condition of any
|
||||
// kind, either express, implied or statutory. This includes without
|
||||
// limitation any warranty or condition with respect to merchantability or
|
||||
// fitness for any particular purpose, or against the infringements of
|
||||
// intellectual property rights of others.
|
||||
// ----------------------------------------------------------------------------
|
||||
// File Name : at91rm9200_i2c.h
|
||||
// Object : AT91RM9200 / TWI definitions
|
||||
// Generated : AT91 SW Application Group 12/03/2002 (10:48:02)
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AT91RM9200_TWI_H |
||||
#define AT91RM9200_TWI_H |
||||
|
||||
// *****************************************************************************
|
||||
// SOFTWARE API DEFINITION FOR Two-wire Interface
|
||||
// *****************************************************************************
|
||||
#ifndef __ASSEMBLY__ |
||||
|
||||
typedef struct _AT91S_TWI { |
||||
AT91_REG TWI_CR; // Control Register
|
||||
AT91_REG TWI_MMR; // Master Mode Register
|
||||
AT91_REG TWI_SMR; // Slave Mode Register
|
||||
AT91_REG TWI_IADR; // Internal Address Register
|
||||
AT91_REG TWI_CWGR; // Clock Waveform Generator Register
|
||||
AT91_REG Reserved0[3]; //
|
||||
AT91_REG TWI_SR; // Status Register
|
||||
AT91_REG TWI_IER; // Interrupt Enable Register
|
||||
AT91_REG TWI_IDR; // Interrupt Disable Register
|
||||
AT91_REG TWI_IMR; // Interrupt Mask Register
|
||||
AT91_REG TWI_RHR; // Receive Holding Register
|
||||
AT91_REG TWI_THR; // Transmit Holding Register
|
||||
AT91_REG Reserved1[50]; //
|
||||
AT91_REG TWI_RPR; // Receive Pointer Register
|
||||
AT91_REG TWI_RCR; // Receive Counter Register
|
||||
AT91_REG TWI_TPR; // Transmit Pointer Register
|
||||
AT91_REG TWI_TCR; // Transmit Counter Register
|
||||
AT91_REG TWI_RNPR; // Receive Next Pointer Register
|
||||
AT91_REG TWI_RNCR; // Receive Next Counter Register
|
||||
AT91_REG TWI_TNPR; // Transmit Next Pointer Register
|
||||
AT91_REG TWI_TNCR; // Transmit Next Counter Register
|
||||
AT91_REG TWI_PTCR; // PDC Transfer Control Register
|
||||
AT91_REG TWI_PTSR; // PDC Transfer Status Register
|
||||
} AT91S_TWI, *AT91PS_TWI; |
||||
|
||||
#endif |
||||
|
||||
// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register --------
|
||||
#define AT91C_TWI_START ( 0x1 << 0) // (TWI) Send a START Condition
|
||||
#define AT91C_TWI_STOP ( 0x1 << 1) // (TWI) Send a STOP Condition
|
||||
#define AT91C_TWI_MSEN ( 0x1 << 2) // (TWI) TWI Master Transfer Enabled
|
||||
#define AT91C_TWI_MSDIS ( 0x1 << 3) // (TWI) TWI Master Transfer Disabled
|
||||
#define AT91C_TWI_SVEN ( 0x1 << 4) // (TWI) TWI Slave Transfer Enabled
|
||||
#define AT91C_TWI_SVDIS ( 0x1 << 5) // (TWI) TWI Slave Transfer Disabled
|
||||
#define AT91C_TWI_SWRST ( 0x1 << 7) // (TWI) Software Reset
|
||||
// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register --------
|
||||
#define AT91C_TWI_IADRSZ ( 0x3 << 8) // (TWI) Internal Device Address Size
|
||||
#define AT91C_TWI_IADRSZ_NO ( 0x0 << 8) // (TWI) No internal device address
|
||||
#define AT91C_TWI_IADRSZ_1_BYTE ( 0x1 << 8) // (TWI) One-byte internal device address
|
||||
#define AT91C_TWI_IADRSZ_2_BYTE ( 0x2 << 8) // (TWI) Two-byte internal device address
|
||||
#define AT91C_TWI_IADRSZ_3_BYTE ( 0x3 << 8) // (TWI) Three-byte internal device address
|
||||
#define AT91C_TWI_MREAD ( 0x1 << 12) // (TWI) Master Read Direction
|
||||
#define AT91C_TWI_DADR ( 0x7F << 6) // (TWI) Device Address
|
||||
// -------- TWI_SMR : (TWI Offset: 0x8) TWI Slave Mode Register --------
|
||||
#define AT91C_TWI_SADR ( 0x7F << 16) // (TWI) Slave Device Address
|
||||
// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register --------
|
||||
#define AT91C_TWI_CLDIV ( 0xFF << 0) // (TWI) Clock Low Divider
|
||||
#define AT91C_TWI_CHDIV ( 0xFF << 8) // (TWI) Clock High Divider
|
||||
#define AT91C_TWI_CKDIV ( 0x7 << 16) // (TWI) Clock Divider
|
||||
// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register --------
|
||||
#define AT91C_TWI_TXCOMP ( 0x1 << 0) // (TWI) Transmission Completed
|
||||
#define AT91C_TWI_RXRDY ( 0x1 << 1) // (TWI) Receive holding register ReaDY
|
||||
#define AT91C_TWI_TXRDY ( 0x1 << 2) // (TWI) Transmit holding register ReaDY
|
||||
#define AT91C_TWI_SVREAD ( 0x1 << 3) // (TWI) Slave Read
|
||||
#define AT91C_TWI_SVACC ( 0x1 << 4) // (TWI) Slave Access
|
||||
#define AT91C_TWI_GCACC ( 0x1 << 5) // (TWI) General Call Access
|
||||
#define AT91C_TWI_OVRE ( 0x1 << 6) // (TWI) Overrun Error
|
||||
#define AT91C_TWI_UNRE ( 0x1 << 7) // (TWI) Underrun Error
|
||||
#define AT91C_TWI_NACK ( 0x1 << 8) // (TWI) Not Acknowledged
|
||||
#define AT91C_TWI_ARBLST ( 0x1 << 9) // (TWI) Arbitration Lost
|
||||
// -------- TWI_IER : (TWI Offset: 0x24) TWI Interrupt Enable Register --------
|
||||
// -------- TWI_IDR : (TWI Offset: 0x28) TWI Interrupt Disable Register --------
|
||||
// -------- TWI_IMR : (TWI Offset: 0x2c) TWI Interrupt Mask Register --------
|
||||
|
||||
/*
|
||||
i2c Support for Atmel's AT91RM9200 Two-Wire Interface |
||||
|
||||
(c) Rick Bronson |
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA. |
||||
*/ |
||||
|
||||
#ifndef AT91_I2C_H |
||||
#define AT91_I2C_H |
||||
|
||||
#define AT91C_TWI_CLOCK 100000 |
||||
#define AT91C_TWI_SCLOCK (10 * AT91C_MASTER_CLOCK / AT91C_TWI_CLOCK) |
||||
#define AT91C_TWI_CKDIV1 (2 << 16) /* TWI clock divider. NOTE: see Errata #22 */ |
||||
|
||||
#if (AT91C_TWI_SCLOCK % 10) >= 5 |
||||
#define AT91C_TWI_CLDIV2 ((AT91C_TWI_SCLOCK / 10) - 5) |
||||
#else |
||||
#define AT91C_TWI_CLDIV2 ((AT91C_TWI_SCLOCK / 10) - 6) |
||||
#endif |
||||
#define AT91C_TWI_CLDIV3 ((AT91C_TWI_CLDIV2 + (4 - AT91C_TWI_CLDIV2 % 4)) >> 2) |
||||
|
||||
#define AT91C_EEPROM_I2C_ADDRESS (0x50 << 16) |
||||
|
||||
#endif |
||||
#endif |
@ -0,0 +1,225 @@ |
||||
/*
|
||||
* Rick Bronson <rick@efn.org> |
||||
* |
||||
* Configuation settings for the AT91RM9200DK board. |
||||
* |
||||
* 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 |
||||
*/ |
||||
|
||||
#ifndef __CONFIG_H |
||||
#define __CONFIG_H |
||||
|
||||
/*
|
||||
* If we are developing, we might want to start armboot from ram |
||||
* so we MUST NOT initialize critical regs like mem-timing ... |
||||
*/ |
||||
#define CONFIG_INIT_CRITICAL /* undef for developing */ |
||||
|
||||
/* ARM asynchronous clock */ |
||||
#define AT91C_MAIN_CLOCK 179712000 /* from 18.432 MHz crystal (18432000 / 4 * 39) */ |
||||
#define AT91C_MASTER_CLOCK 59904000 /* peripheral clock (AT91C_MASTER_CLOCK / 3) */ |
||||
/* #define AT91C_MASTER_CLOCK 44928000 */ /* peripheral clock (AT91C_MASTER_CLOCK / 4) */ |
||||
|
||||
#define AT91_SLOW_CLOCK 32768 /* slow clock */ |
||||
|
||||
#define CONFIG_AT91RM9200DK 1 /* on an AT91RM9200DK Board */ |
||||
#define CONFIG_CMC_PU2 1 /* on an CMC_PU2 Board */ |
||||
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ |
||||
#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ |
||||
#define CONFIG_SETUP_MEMORY_TAGS 1 |
||||
#define CONFIG_INITRD_TAG 1 |
||||
|
||||
/* define this to include the functionality of boot.bin in u-boot */ |
||||
#undef CONFIG_BOOTBINFUNC |
||||
|
||||
/*
|
||||
* Size of malloc() pool |
||||
*/ |
||||
#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) |
||||
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ |
||||
|
||||
#define CONFIG_BAUDRATE 9600 |
||||
|
||||
#define CFG_AT91C_BRGR_DIVISOR 390 /* hardcode so no __divsi3 : AT91C_MASTER_CLOCK /(baudrate * 16) */ |
||||
|
||||
/*
|
||||
* Hardware drivers |
||||
*/ |
||||
|
||||
/* define one of these to choose the DBGU, USART0 or USART1 as console */ |
||||
#undef CONFIG_DBGU |
||||
#undef CONFIG_USART0 |
||||
#define CONFIG_USART1 |
||||
|
||||
#undef CONFIG_HWFLOW /* don't include RTS/CTS flow control support */ |
||||
|
||||
#undef CONFIG_MODEM_SUPPORT /* disable modem initialization stuff */ |
||||
|
||||
#define CONFIG_HARD_I2C |
||||
|
||||
#ifdef CONFIG_HARD_I2C |
||||
#define CFG_I2C_SPEED 0 /* not used */ |
||||
#define CFG_I2C_SLAVE 0 /* not used */ |
||||
#define CONFIG_RTC_RS5C372A /* RICOH I2C RTC */ |
||||
#define CFG_I2C_RTC_ADDR 0x32 |
||||
#define CFG_I2C_EEPROM_ADDR 0x50 |
||||
#define CFG_I2C_EEPROM_ADDR_LEN 1 |
||||
#define CFG_I2C_EEPROM_ADDR_OVERFLOW |
||||
#endif |
||||
|
||||
#define CONFIG_BOOTDELAY 3 |
||||
/* #define CONFIG_ENV_OVERWRITE 1 */ |
||||
|
||||
#ifdef CONFIG_HARD_I2C |
||||
#define CONFIG_COMMANDS \ |
||||
((CONFIG_CMD_DFL | \
|
||||
CFG_CMD_I2C | \
|
||||
CFG_CMD_EEPROM | \
|
||||
CFG_CMD_DHCP ) & \
|
||||
~(CFG_CMD_BDI | \
|
||||
CFG_CMD_IMI | \
|
||||
CFG_CMD_AUTOSCRIPT | \
|
||||
CFG_CMD_FPGA | \
|
||||
CFG_CMD_MISC | \
|
||||
CFG_CMD_LOADS )) |
||||
#else |
||||
#define CONFIG_COMMANDS \ |
||||
((CONFIG_CMD_DFL | \
|
||||
CFG_CMD_DHCP ) & \
|
||||
~(CFG_CMD_BDI | \
|
||||
CFG_CMD_IMI | \
|
||||
CFG_CMD_AUTOSCRIPT | \
|
||||
CFG_CMD_FPGA | \
|
||||
CFG_CMD_MISC | \
|
||||
CFG_CMD_LOADS )) |
||||
#endif |
||||
|
||||
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ |
||||
#include <cmd_confdefs.h> |
||||
|
||||
#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ |
||||
#define SECTORSIZE 512 |
||||
|
||||
#define ADDR_COLUMN 1 |
||||
#define ADDR_PAGE 2 |
||||
#define ADDR_COLUMN_PAGE 3 |
||||
|
||||
#define NAND_ChipID_UNKNOWN 0x00 |
||||
#define NAND_MAX_FLOORS 1 |
||||
#define NAND_MAX_CHIPS 1 |
||||
|
||||
#define AT91_SMART_MEDIA_ALE (1 << 22) /* our ALE is AD22 */ |
||||
#define AT91_SMART_MEDIA_CLE (1 << 21) /* our CLE is AD21 */ |
||||
|
||||
#define NAND_DISABLE_CE(nand) do { *AT91C_PIOC_SODR = AT91C_PIO_PC0;} while(0) |
||||
#define NAND_ENABLE_CE(nand) do { *AT91C_PIOC_CODR = AT91C_PIO_PC0;} while(0) |
||||
|
||||
#define NAND_WAIT_READY(nand) while (!(*AT91C_PIOC_PDSR & AT91C_PIO_PC2)) |
||||
|
||||
#define WRITE_NAND_COMMAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | AT91_SMART_MEDIA_CLE) = (__u8)(d); } while(0) |
||||
#define WRITE_NAND_ADDRESS(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | AT91_SMART_MEDIA_ALE) = (__u8)(d); } while(0) |
||||
#define WRITE_NAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr) = (__u8)d; } while(0) |
||||
#define READ_NAND(adr) ((volatile unsigned char)(*(volatile __u8 *)(unsigned long)adr)) |
||||
/* the following are NOP's in our implementation */ |
||||
#define NAND_CTL_CLRALE(nandptr) |
||||
#define NAND_CTL_SETALE(nandptr) |
||||
#define NAND_CTL_CLRCLE(nandptr) |
||||
#define NAND_CTL_SETCLE(nandptr) |
||||
|
||||
#define CONFIG_NR_DRAM_BANKS 1 |
||||
#define PHYS_SDRAM 0x20000000 |
||||
#define PHYS_SDRAM_SIZE 0x2000000 /* 32 megs */ |
||||
|
||||
#define CFG_MEMTEST_START PHYS_SDRAM |
||||
#define CFG_MEMTEST_END CFG_MEMTEST_START + PHYS_SDRAM_SIZE - 262144 |
||||
|
||||
#define CONFIG_DRIVER_ETHER |
||||
#define CONFIG_NET_RETRY_COUNT 20 |
||||
#define CONFIG_AT91C_USE_RMII |
||||
|
||||
#define CONFIG_HAS_DATAFLASH 1 |
||||
#define CFG_SPI_WRITE_TOUT (5*CFG_HZ) |
||||
#define CFG_MAX_DATAFLASH_BANKS 2 |
||||
#define CFG_MAX_DATAFLASH_PAGES 16384 |
||||
#define CFG_DATAFLASH_LOGIC_ADDR_CS0 0xC0000000 /* Logical adress for CS0 */ |
||||
#define CFG_DATAFLASH_LOGIC_ADDR_CS3 0xD0000000 /* Logical adress for CS3 */ |
||||
|
||||
#define PHYS_FLASH_1 0x10000000 |
||||
#define PHYS_FLASH_SIZE 0x200000 /* 2 megs main flash */ |
||||
#define CFG_FLASH_BASE PHYS_FLASH_1 |
||||
#define CFG_MAX_FLASH_BANKS 1 |
||||
#define CFG_MAX_FLASH_SECT 256 |
||||
#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */ |
||||
#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */ |
||||
|
||||
#undef CFG_ENV_IS_IN_DATAFLASH |
||||
|
||||
#ifdef CFG_ENV_IS_IN_DATAFLASH |
||||
#define CFG_ENV_OFFSET 0x20000 |
||||
#define CFG_ENV_ADDR (CFG_DATAFLASH_LOGIC_ADDR_CS0 + CFG_ENV_OFFSET) |
||||
#define CFG_ENV_SIZE 0x2000 /* 0x8000 */ |
||||
#else |
||||
#define CFG_ENV_IS_IN_FLASH 1 |
||||
#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0xe000) /* 0x10000 */ |
||||
#define CFG_ENV_SIZE 0x2000 /* 0x8000 */ |
||||
#endif |
||||
|
||||
|
||||
#define CFG_LOAD_ADDR 0x21000000 /* default load address */ |
||||
|
||||
#define CFG_BOOT_SIZE 0x6000 /* 24 KBytes */ |
||||
#define CFG_U_BOOT_BASE (PHYS_FLASH_1 + 0x10000) |
||||
#define CFG_U_BOOT_SIZE 0x10000 /* 64 KBytes */ |
||||
|
||||
#define CFG_BAUDRATE_TABLE {115200 , 19200, 38400, 57600, 9600 } |
||||
|
||||
#define CFG_PROMPT "U-Boot> " /* Monitor Command Prompt */ |
||||
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ |
||||
#define CFG_MAXARGS 16 /* max number of command args */ |
||||
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ |
||||
|
||||
#ifndef __ASSEMBLY__ |
||||
/*-----------------------------------------------------------------------
|
||||
* Board specific extension for bd_info |
||||
* |
||||
* This structure is embedded in the global bd_info (bd_t) structure |
||||
* and can be used by the board specific code (eg board/...) |
||||
*/ |
||||
|
||||
struct bd_info_ext { |
||||
/* helper variable for board environment handling
|
||||
* |
||||
* env_crc_valid == 0 => uninitialised |
||||
* env_crc_valid > 0 => environment crc in flash is valid |
||||
* env_crc_valid < 0 => environment crc in flash is invalid |
||||
*/ |
||||
int env_crc_valid; |
||||
}; |
||||
#endif |
||||
|
||||
#define CFG_HZ AT91C_MASTER_CLOCK/2 /* AT91C_TC0_CMR is implicitly set to */ |
||||
/* AT91C_TC_TIMER_DIV1_CLOCK */ |
||||
|
||||
#define CONFIG_STACKSIZE (32*1024) /* regular stack */ |
||||
|
||||
#ifdef CONFIG_USE_IRQ |
||||
#error CONFIG_USE_IRQ not supported |
||||
#endif |
||||
|
||||
#endif |
Loading…
Reference in new issue