From 2abbe0754759f94c79125a2534fbc4be74f416bc Mon Sep 17 00:00:00 2001 From: wdenk Date: Mon, 16 Jun 2003 23:50:08 +0000 Subject: * Patch by Nicolas Lacressonniere, 11 Jun 2003: 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.c --- drivers/Makefile | 6 +- drivers/at91rm9200_ether.c | 251 --------------------------------------------- drivers/dataflash.c | 245 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+), 254 deletions(-) delete mode 100644 drivers/at91rm9200_ether.c create mode 100644 drivers/dataflash.c (limited to 'drivers') diff --git a/drivers/Makefile b/drivers/Makefile index c1fa4193e8..50fc75ae07 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -27,9 +27,9 @@ include $(TOPDIR)/config.mk LIB = libdrivers.a -OBJS = 3c589.o 5701rls.o ali512x.o at91rm9200_ether.o \ +OBJS = 3c589.o 5701rls.o ali512x.o \ bcm570x.o bcm570x_autoneg.o cfb_console.o \ - cs8900.o ct69000.o dc2114x.o \ + cs8900.o ct69000.o dataflash.o dc2114x.o \ e1000.o eepro100.o \ i8042.o i82365.o inca-ip_sw.o \ lan91c96.o natsemi.o \ @@ -41,7 +41,7 @@ OBJS = 3c589.o 5701rls.o ali512x.o at91rm9200_ether.o \ ti_pci1410a.o tigon3.o w83c553f.o ## Disabled for now: -## cs8900.o ct69000.o dc2114x.o ds1722.o \ +## cs8900.o ct69000.o dataflash.o dc2114x.o ds1722.o \ ## lan91c96.o mw_eeprom.o natsemi.o \ ## smc91111.o smiLynxEM.o spi_eeprom.o sym53c8xx.o \ ## diff --git a/drivers/at91rm9200_ether.c b/drivers/at91rm9200_ether.c deleted file mode 100644 index f92008e34f..0000000000 --- a/drivers/at91rm9200_ether.c +++ /dev/null @@ -1,251 +0,0 @@ - -#include -#include -#include -#include - -/* ----- 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 diff --git a/drivers/dataflash.c b/drivers/dataflash.c new file mode 100644 index 0000000000..a0a4b62a4f --- /dev/null +++ b/drivers/dataflash.c @@ -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 +#include +#ifdef CONFIG_HAS_DATAFLASH +#include +#include + +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 -- cgit v1.2.1