diff options
Diffstat (limited to 'board/cmc_pu2')
-rw-r--r-- | board/cmc_pu2/Makefile | 2 | ||||
-rw-r--r-- | board/cmc_pu2/at91rm9200dk.c | 118 | ||||
-rw-r--r-- | board/cmc_pu2/cmc_pu2.c | 67 | ||||
-rw-r--r-- | board/cmc_pu2/config.mk | 2 | ||||
-rw-r--r-- | board/cmc_pu2/flash.c | 672 | ||||
-rw-r--r-- | board/cmc_pu2/memsetup.S | 25 |
6 files changed, 394 insertions, 492 deletions
diff --git a/board/cmc_pu2/Makefile b/board/cmc_pu2/Makefile index f94bd99..a939bbb 100644 --- a/board/cmc_pu2/Makefile +++ b/board/cmc_pu2/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = lib$(BOARD).a -OBJS := at91rm9200dk.o at45.o dm9161.o flash.o +OBJS := cmc_pu2.o at45.o dm9161.o flash.o SOBJS := memsetup.o $(LIB): $(OBJS) $(SOBJS) diff --git a/board/cmc_pu2/at91rm9200dk.c b/board/cmc_pu2/at91rm9200dk.c deleted file mode 100644 index 606ea48..0000000 --- a/board/cmc_pu2/at91rm9200dk.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * (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 diff --git a/board/cmc_pu2/cmc_pu2.c b/board/cmc_pu2/cmc_pu2.c new file mode 100644 index 0000000..f914d42 --- /dev/null +++ b/board/cmc_pu2/cmc_pu2.c @@ -0,0 +1,67 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * Modified for CMC_PU2 (removed Smart Media support) by Gary Jennejohn + * (2004) garyj@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 <common.h> +#include <asm/mach-types.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 CMC_PU2-Board */ + /* gd->bd->bi_arch_number = MACH_TYPE_CMC_PU2; */ + 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; +} diff --git a/board/cmc_pu2/config.mk b/board/cmc_pu2/config.mk index 9ce161e..9fef739 100644 --- a/board/cmc_pu2/config.mk +++ b/board/cmc_pu2/config.mk @@ -1 +1 @@ -TEXT_BASE = 0x21f00000 +TEXT_BASE = 0x20f00000 diff --git a/board/cmc_pu2/flash.c b/board/cmc_pu2/flash.c index 5220fcf..9baa473 100644 --- a/board/cmc_pu2/flash.c +++ b/board/cmc_pu2/flash.c @@ -1,11 +1,12 @@ /* - * (C) Copyright 2002 - * Lineo, Inc. <www.lineo.com> - * Bernhard Kuhn <bkuhn@lineo.com> + * (C) Copyright 2003-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Alex Zuepke <azu@sysgo.de> + * (C) Copyright 2004 + * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de + * + * Modified for the CMC PU2 by (C) Copyright 2004 Gary Jennejohn + * garyj@denx.de * * See file CREDITS for list of people who contributed to this * project. @@ -28,444 +29,339 @@ #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 +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ -#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00005555<<1))) -#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00002AAA<<1))) +/* + * CPU to flash interface is 32-bit, so make declaration accordingly + */ +typedef unsigned short FLASH_PORT_WIDTH; +typedef volatile unsigned short FLASH_PORT_WIDTHV; -#define BIT_ERASE_DONE 0x0080 -#define BIT_RDY_MASK 0x0080 -#define BIT_PROGRAM_ERROR 0x0020 -#define BIT_TIMEOUT 0x80000000 /* our flag */ +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV -#define READY 1 -#define ERR 2 -#define TMO 4 +#define FLASH_CYCLE1 0x0555 +#define FLASH_CYCLE2 0x02aa /*----------------------------------------------------------------------- + * Functions */ -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)); +static ulong flash_get_size(FPWV *addr, flash_info_t *info); +static void flash_reset(flash_info_t *info); +static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data); +static flash_info_t *flash_get_info(ulong base); - 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) +/*----------------------------------------------------------------------- + * flash_init() + * + * sets up flash_info and returns size of FLASH (bytes) + */ +unsigned long flash_init (void) { - int i, nb_sectors = 0; - - for (i=0; i<nb_blocks; i++){ - nb_sectors += pOrgDef[i].sector_number; - } - - return nb_sectors; + unsigned long size = 0; + ulong flashbase = CFG_FLASH_BASE; + + /* Init: no FLASHes known */ + memset(&flash_info[0], 0, sizeof(flash_info_t)); + + flash_info[0].size = + flash_get_size((FPW *)flashbase, &flash_info[0]); + + size = flash_info[0].size; + +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + /* monitor protection ON by default */ + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE+monitor_flash_len-1, + flash_get_info(CFG_MONITOR_BASE)); +#endif + +#ifdef CFG_ENV_IS_IN_FLASH + /* ENV protection ON by default */ + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR+CFG_ENV_SIZE-1, + flash_get_info(CFG_ENV_ADDR)); +#endif + + return size ? size : 1; } -void flash_unlock_sector(flash_info_t * info, unsigned int sector) +/*----------------------------------------------------------------------- + */ +static void flash_reset(flash_info_t *info) { - volatile u16 *addr = (volatile u16 *) (info->start[sector]); + FPWV *base = (FPWV *)(info->start[0]); - MEM_FLASH_ADDR1 = CMD_UNLOCK1; - *addr = CMD_SECTOR_UNLOCK; + /* Put FLASH back in read mode */ + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) + *base = (FPW)0x00FF00FF; /* Intel Read Mode */ + else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) + *base = (FPW)0x00F000F0; /* AMD Read Mode */ } +/*----------------------------------------------------------------------- + */ -ulong flash_init (void) +static flash_info_t *flash_get_info(ulong base) { - 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 */ + int i; + flash_info_t * info; - /* Unlock all sectors at reset */ - for (j=0; j<flash_info[i].sector_count; j++){ - flash_unlock_sector(&flash_info[i], j); - } - } + info = NULL; + for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) { + info = & flash_info[i]; + if (info->size && info->start[0] <= base && + base <= info->start[0] + info->size - 1) + break; } - /* 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; + return i == CFG_MAX_FLASH_BANKS ? 0 : info; } /*----------------------------------------------------------------------- */ -void flash_print_info (flash_info_t * info) + +void flash_print_info (flash_info_t *info) { int i; + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + switch (info->flash_id & FLASH_VENDMASK) { - case (ATM_MANUFACT & FLASH_VENDMASK): - printf ("Atmel: "); - break; - default: - printf ("Unknown Vendor "); - break; + case FLASH_MAN_AMD: printf ("AMD "); break; + case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break; + case FLASH_MAN_FUJ: printf ("FUJITSU "); break; + case FLASH_MAN_SST: printf ("SST "); break; + case FLASH_MAN_STM: printf ("STM "); break; + case FLASH_MAN_INTEL: printf ("INTEL "); 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"); + case FLASH_S29GL064M: + printf ("S29GL064M-R6 (64Mbit, uniform sector size)\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); + info->size >> 20, + info->sector_count); printf (" Sector Start Addresses:"); - for (i = 0; i < info->sector_count; i++) { + + for (i=0; i<info->sector_count; ++i) { if ((i % 5) == 0) { printf ("\n "); } - printf (" %08lX%s", info->start[i], + printf (" %08lX%s", + info->start[i], info->protect[i] ? " (RO)" : " "); } printf ("\n"); - -Done: ; + return; } /*----------------------------------------------------------------------- */ -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; - } +/* + * The following code cannot be run from FLASH! + */ - if ((info->flash_id & FLASH_VENDMASK) != - (ATM_MANUFACT & FLASH_VENDMASK)) { - return ERR_UNKNOWN_FLASH_VENDOR; - } +ulong flash_get_size (FPWV *addr, flash_info_t *info) +{ + int i; + ulong base = (ulong)addr; - prot = 0; - for (sect = s_first; sect <= s_last; ++sect) { - if (info->protect[sect]) { - prot++; - } - } - if (prot) - return ERR_PROTECTED; + /* Write auto select command: read Manufacturer ID */ + /* Write auto select command sequence and test FLASH answer */ + addr[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* for AMD, Intel ignores this */ + addr[FLASH_CYCLE2] = (FPW)0x00550055; /* for AMD, Intel ignores this */ + addr[FLASH_CYCLE1] = (FPW)0x00900090; /* selects Intel or AMD */ - /* - * 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. + /* The manufacturer codes are only 1 byte, so just use 1 byte. + * This works for any bus width and any FLASH device width. */ - cflag = icache_status (); - icache_disable (); - iflag = disable_interrupts (); + udelay(100); + switch (addr[0] & 0xff) { - /* 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 (); + case (uchar)AMD_MANUFACT: + printf ("Manufacturer: AMD (Spansion)\n"); + info->flash_id = FLASH_MAN_AMD; + break; - if (info->protect[sect] == 0) { /* not protected */ - volatile u16 *addr = (volatile u16 *) (info->start[sect]); + case (uchar)INTEL_MANUFACT: + printf ("Manufacturer: Intel (not supported yet)\n"); + info->flash_id = FLASH_MAN_INTEL; + break; - MEM_FLASH_ADDR1 = CMD_UNLOCK1; - MEM_FLASH_ADDR2 = CMD_UNLOCK2; - MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + break; + } - MEM_FLASH_ADDR1 = CMD_UNLOCK1; - MEM_FLASH_ADDR2 = CMD_UNLOCK2; - *addr = CMD_ERASE_CONFIRM; + /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */ + if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[1]) { + + case AMD_ID_MIRROR: + printf ("Mirror Bit flash: addr[14] = %08X addr[15] = %08X\n", + addr[14], addr[15]); + + switch(addr[14] & 0xffff) { + case (AMD_ID_GL064M_2 & 0xffff): + if (addr[15] != (AMD_ID_GL064M_3 & 0xffff)) { + printf ("Chip: S29GLxxxM -> unknown\n"); + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + } else { + printf ("Chip: S29GL064M-R6\n"); + info->flash_id += FLASH_S29GL064M; + info->sector_count = 128; + info->size = 0x00800000; + for (i = 0; i < info->sector_count; i++) { + info->start[i] = base; + base += 0x10000; + } + } + break; /* => 16 MB */ + default: + printf ("Chip: *** unknown ***\n"); + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + break; + } + break; - /* wait until flash is ready */ - chip1 = 0; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + } - do { - result = *addr; + /* Put FLASH back in read mode */ + flash_reset(info); - /* check timeout */ - if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { - MEM_FLASH_ADDR1 = CMD_READ_ARRAY; - chip1 = TMO; - break; - } + return (info->size); +} - if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE) - chip1 = READY; +/*----------------------------------------------------------------------- + */ - } while (!chip1); +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + FPWV *addr = (FPWV *)(info->start[0]); + int flag, prot, sect, l_sect; + ulong start, now, last; - MEM_FLASH_ADDR1 = CMD_READ_ARRAY; + printf ("flash_erase: first: %d last: %d\n", s_first, s_last); - if (chip1 == ERR) { - rc = ERR_PROG_ERROR; - goto outahere; + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); } - if (chip1 == TMO) { - rc = ERR_TIMOUT; - goto outahere; + return 1; } - printf ("ok.\n"); - } else { /* it was protected */ - printf ("protected!\n"); - } + if ((info->flash_id == FLASH_UNKNOWN) || + (info->flash_id > FLASH_AMD_COMP)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; } - if (ctrlc ()) - printf ("User Interrupt!\n"); - -outahere: - /* allow flash to settle - wait 10 ms */ - udelay_masked (10000); + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } - if (iflag) - enable_interrupts (); + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } - if (cflag) - icache_enable (); + l_sect = -1; - return rc; -} + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); -/*----------------------------------------------------------------------- - * Copy memory to flash - */ + addr[0x0555] = 0x00AA; + addr[0x02AA] = 0x0055; + addr[0x0555] = 0x0080; + addr[0x0555] = 0x00AA; + addr[0x02AA] = 0x0055; -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; + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr = (FPWV *)(info->start[sect]); + addr[0] = 0x0030; + l_sect = sect; + } + } - /* - * Check if Flash is (sufficiently) erased - */ - result = *addr; - if ((result & data) != data) - return ERR_NOT_ERASED; + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); /* - * 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. + * We wait for the last triggered sector */ - 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 (l_sect < 0) + goto DONE; + + start = get_timer (0); + last = start; + addr = (FPWV *)(info->start[l_sect]); + while ((addr[0] & 0x00000080) != 0x00000080) { + if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + return 1; + } + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } } - 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 (); +DONE: + /* reset to read mode */ + addr = (FPWV *)info->start[0]; + addr[0] = 0x000000F0; /* reset bank */ - return rc; + printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- - * Copy memory to flash. + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased */ -int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) { ulong wp, data; int rc; @@ -483,8 +379,8 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) wp = addr; while (cnt >= 2) { - data = *((volatile u16 *) src); - if ((rc = write_word (info, wp, data)) != 0) { + data = *((FPWV *)src); + if ((rc = write_word_amd(info, (FPW *)wp, data)) != 0) { return (rc); } src += 2; @@ -492,16 +388,68 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) cnt -= 2; } + if (cnt == 0) { + return (0); + } + if (cnt == 1) { - data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1)) << - 8); - if ((rc = write_word (info, wp, data)) != 0) { + data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1)) + << 8); + if ((rc = write_word_amd(info, (FPW *)wp, data)) != 0) { return (rc); } src += 1; wp += 1; cnt -= 1; - }; + } return ERR_OK; } + +/*----------------------------------------------------------------------- + * Write a word to Flash for AMD FLASH + * A word is 16 or 32 bits, whichever the bus width of the flash bank + * (not an individual chip) is. + * + * returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data) +{ + ulong start; + int flag; + FPWV *base; /* first address in flash bank */ + + /* Check if Flash is (sufficiently) erased */ + if ((*dest & data) != data) { + return (2); + } + + base = (FPWV *)(info->start[0]); + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */ + base[FLASH_CYCLE1] = (FPW)0x00A000A0; /* selects program mode */ + + *dest = data; /* start programming the data */ + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + start = get_timer (0); + + /* data polling for D7 */ + while ((*dest & (FPW)0x00000080) != (data & (FPW)0x00000080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + *dest = (FPW)0x000000F0; /* reset bank */ + return (1); + } + } + return (0); +} diff --git a/board/cmc_pu2/memsetup.S b/board/cmc_pu2/memsetup.S index 2d0e1d7..b0c8d4c 100644 --- a/board/cmc_pu2/memsetup.S +++ b/board/cmc_pu2/memsetup.S @@ -6,7 +6,7 @@ * * Modified for the at91rm9200dk board by * (C) Copyright 2004 - * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> * * See file CREDITS for list of people who contributed to this * project. @@ -35,7 +35,7 @@ * 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 + * turn is based on the boot.bin code from ATMEL * */ @@ -53,7 +53,7 @@ #define EBI_CFGR 0xFFFFFF64 #define EBI_CFGR_VAL 0x00000000 #define SMC2_CSR 0xFFFFFF70 -#define SMC2_CSR_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ +#define SMC2_CSR_VAL 0x100032ad /* 16bit, 2 TDF, 4 WS */ /* clocks */ #define PLLAR 0xFFFFFC28 @@ -73,7 +73,7 @@ #define EBI_CSA 0xFFFFFF60 #define EBI_CSA_VAL 0x00000002 /* CS1=SDRAM */ #define SDRC_CR 0xFFFFFF98 -#define SDRC_CR_VAL 0x2188c155 +#define SDRC_CR_VAL 0x3399c1d4 /* set up the SDRAM */ #define SDRAM 0x20000000 /* address of the SDRAM */ #define SDRAM1 0x20000080 /* address of the SDRAM */ #define SDRAM_VAL 0x00000000 /* value written to SDRAM */ @@ -86,15 +86,20 @@ #define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ -_TEXT_BASE: +_MTEXT_BASE: +#undef START_FROM_MEM +#ifdef START_FROM_MEM + .word TEXT_BASE-PHYS_FLASH_1 +#else .word TEXT_BASE +#endif -.globl memsetup -memsetup: +.globl lowlevelinit +lowlevelinit: /* memory control configuration */ /* this isn't very elegant, but what the heck */ ldr r0, =SMRDATA - ldr r1, _TEXT_BASE + ldr r1, _MTEXT_BASE sub r0, r0, r1 add r2, r0, #80 0: @@ -106,12 +111,12 @@ memsetup: cmp r2, r0 bne 0b /* delay - this is all done by guess */ - ldr r0, =0x00001000 + ldr r0, =0x00010000 1: subs r0, r0, #1 bhi 1b ldr r0, =SMRDATA1 - ldr r1, _TEXT_BASE + ldr r1, _MTEXT_BASE sub r0, r0, r1 add r2, r0, #176 2: |