
Hello Marco,
I am including the memory driver for the newer chip as well as the config file. The config file has been changed more than once, since I am trying to port the uboot 1.1.4 right. This is a current config file as of now.
/** * OUR FLASHY FLASH DRIVER **/
#include <common.h>
#define MEM_FLASH_BASE (*(volatile u16 *)(CFG_FLASH_BASE))
#define PRODUCT_ID_IN_CODE 0x90 #define COMMAND_READ 0xFF #define COMMAND_SECTOR_UNLOCK_I 0x60 #define COMMAND_SECTOR_UNLOCK_II 0xD0 #define COMMAND_SECTOR_ERASE_SETUP 0x20 #define COMMAND_GENERAL_ERASE_CONFIRM 0xD0 #define COMMAND_READ_STATUS_REGISTER 0x70 #define COMMAND_WORD_PROGRAM_40 0x40
#define ATM_ID_BV6416C 0xC5
#define READY 1 #define ERR 2 #define TMO 4
/** * CFG_FLASH_BASE comes from include/configs/at91rm9200dk.h * CFG_MAX_FLASH_BANKS comes from include/configs/at91rm9200dk.h * PHYS_FLASH_1 comes from include/configs/at91rm9200dk.h **/
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/* Flash Organization Structure */ typedef struct OrgDef { unsigned int sector_number; unsigned int sector_size; } OrgDef;
OrgDef OrgAT49BV6416C[] = { { 8, 8*1024 }, /* 8 * 8 kBytes sectors */ { 127, 64*1024 }, /* 127 * 64 kBytes sectors */ };
void flash_identification (flash_info_t * info) { volatile u16 manuf_code, device_code, add_device_code;
MEM_FLASH_BASE = PRODUCT_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));
/* Vendor type */ info->flash_id = ATM_MANUFACT & FLASH_VENDMASK; printf ("Atmel: ");
if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416C & FLASH_TYPEMASK)) { info->flash_id |= ATM_ID_BV6416C & FLASH_TYPEMASK; printf ("AT49BV6416C (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]); *addr = COMMAND_SECTOR_UNLOCK_I; *addr = COMMAND_SECTOR_UNLOCK_II; }
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_BV6416C & FLASH_TYPEMASK)) { /* AT49BV6416C Flash */
pOrgDef = OrgAT49BV6416C; flash_nb_blocks = sizeof (OrgAT49BV6416C) / sizeof (OrgDef); } else { flash_nb_blocks = 0; }
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 ("error: 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;
/* 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_BV6416C & FLASH_TYPEMASK): printf ("AT49BV6416 (64Mbit)\n"); break; default: printf ("Unknown Chip Type\n"); return; }
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"); }
int flash_erase (flash_info_t * info, int s_first, int s_last) { u16 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++; sect = s_last; /* BREAK */ } }
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]);
*addr = COMMAND_SECTOR_ERASE_SETUP; *addr = COMMAND_GENERAL_ERASE_CONFIRM;
/* wait until flash is ready */ chip1 = 0;
do { *addr = COMMAND_READ_STATUS_REGISTER; result = *addr;
/* check timeout */ if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { chip1 = TMO; break; }
if( result&0x0080 ) { chip1 = READY; }
} while (!chip1);
*addr = COMMAND_READ;
if (chip1 == ERR) { rc = ERR_PROG_ERROR; } else if (chip1 == TMO) { rc = ERR_TIMOUT; } else { printf ("ok.\n"); } } else { /* it was protected */ printf ("protected!\n"); } }
if (ctrlc ()) printf ("User Interrupt!\n");
/* 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 != 0xFF) 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 ();
*addr = COMMAND_WORD_PROGRAM_40; *addr = data;
/* arm simple, non interrupt dependent timer */ reset_timer_masked ();
/* wait until flash is ready */ chip1 = 0; do { *addr = COMMAND_READ_STATUS_REGISTER; result = *addr;
/* check timeout */ if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { chip1 = TMO; break; }
if( result&0x0080 ) { chip1 = READY; } } while (!chip);
*addr = COMMAND_READ;
if (chip1 == TMO || *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; }
------------------------------------------------------------------------
/* * 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 */ #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 */ #define CONFIG_BOOTBINFUNC 1
/* * 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 115200
#define CFG_AT91C_BRGR_DIVISOR 33 /* hardcode so no __divsi3 : AT91C_MASTER_CLOCK / baudrate / 16 */
/* * Hardware drivers */
/* define one of these to choose the DBGU, USART0 or USART1 as console */ #define CONFIG_DBGU #undef CONFIG_USART0 #undef CONFIG_USART1
#undef CONFIG_HWFLOW /* don't include RTS/CTS flow control support */
#undef CONFIG_MODEM_SUPPORT /* disable modem initialization stuff */
#define CONFIG_BOOTDELAY 3 /* #define CONFIG_ENV_OVERWRITE 1 */
#define CONFIG_COMMANDS \ ((CONFIG_CMD_DFL ) & \ ~(CFG_CMD_BDI | \ CFG_CMD_IMI | \ CFG_CMD_AUTOSCRIPT | \ CFG_CMD_FPGA | \ CFG_CMD_MISC | \ CFG_CMD_LOADS | \ CFG_CMD_NET))
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include <cmd_confdefs.h> #if 0 #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) #endif #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 #if 0 #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 */ #endif #define PHYS_FLASH_1 0x10000000 #define PHYS_FLASH_SIZE 0x800000 /* 8 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 #ifndef CONFIG_BOOTBINFUNC #define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x20000) /* after u-boot.bin */ #define CFG_ENV_SIZE 0x10000 /* sectors are 64K here */ #else #define CFG_ENV_ADDR (PHYS_FLASH_1 + 0xe000) /* between boot.bin and u-boot.bin.gz */ #define CFG_ENV_SIZE 0x2000 /* 0x8000 */ #endif #endif
#define CFG_LOAD_ADDR 0x21000000 /* default load address */
#ifndef CONFIG_BOOTBINFUNC #define CFG_BOOT_SIZE 0x00 /* 0 KBytes */ #define CFG_U_BOOT_BASE PHYS_FLASH_1 #define CFG_U_BOOT_SIZE 0x20000 /* 128 KBytes */ #else #define CFG_BOOT_SIZE 0x6000 /* 24 KBytes */ #define CFG_U_BOOT_BASE (PHYS_FLASH_1 + 0x10000) #define CFG_U_BOOT_SIZE 0x10000 /* 64 KBytes */ #endif
#define CFG_BAUDRATE_TABLE {115200 , 19200, 38400, 57600, 9600 }
#define CFG_PROMPT "U-Boot 1.1.2 w/boot.bin> " /* 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 1000 #define CFG_HZ_CLOCK 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
Marco Cavallini wrote:
Roman Kolesnikov ha scritto:
Hello everyone,
I found the difference (with the help of Koan) in the command list and cycles for the newer Atmel chip. I have a new driver now to access the flash, and it works ok. However, I still have problem with UBoot1.1.4. When I load UBoot originally into flash and run, everything works well. However, when I restart the uboot from flash again, I think uboot overwrites something in the environment variables. My environment variables become corrupt. For instance the very first sign is invalid input, output, and debug settigns on the second start up.
When I print the environment variables, I get about 8K of garbage data. I wonder what could be causing my corruption. It only occurs in the environment variables.
Hi Roman, Please show us your include/configs/at91rm9200dk.h
Ciao