--- /home/tschaefer/temp/u-boot/CHANGELOG 2005-04-22 17:09:09.000000000 +0200 +++ CHANGELOG 2005-04-25 17:37:14.000000000 +0200 @@ -2,6 +2,10 @@ Changes for U-Boot 1.1.3: ====================================================================== +* Patch by Thomas Schäfer, 25 Apr 2005: + drivers/cfi_flash.c: + - added write buffer programming support for AMD flash chips + * Fix INKA4x0: use CS1 as gpio_wkup_6 output * Fix bug in the SDRAM initialization code for canmb, IceCube and --- /home/tschaefer/temp/u-boot/drivers/cfi_flash.c 2005-04-13 12:02:47.000000000 +0200 +++ drivers/cfi_flash.c 2005-04-25 17:23:23.000000000 +0200 @@ -10,6 +10,10 @@ * Ed Okerson * Modified to work with little-endian systems. * + * Copyright (C) 2005 + * Thomas Schäfer, thomas.schaefer@kontron.com + * AMD write buffer programming support + * * See file CREDITS for list of people who contributed to this * project. * @@ -33,6 +37,7 @@ * 01/22/2004 - Write performance enhancements for parallel chips (Tolunay) * 01/23/2004 - Support for x8/x16 chips (Rune Raknerud) * 01/27/2004 - Little endian support Ed Okerson + * 04/25/2005 - AMD write buffer programming support Thomas Schäfer * * Tested Architectures * Port Width Chip Width # of banks Flash Chip Board @@ -105,6 +110,9 @@ #define AMD_CMD_ERASE_SECTOR 0x30 #define AMD_CMD_UNLOCK_START 0xAA #define AMD_CMD_UNLOCK_ACK 0x55 +#define AMD_CMD_BUFFER_LOAD 0x25 +#define AMD_CMD_BUFFER_PROG 0x29 +#define AMD_CMD_RESUME_PROG 0x30 #define AMD_STATUS_TOGGLE 0x40 #define AMD_STATUS_ERROR 0x20 @@ -536,7 +544,10 @@ buffered_size = (info->portwidth / info->chipwidth); buffered_size *= info->buffer_size; while (cnt >= info->portwidth) { - i = buffered_size > cnt ? cnt : buffered_size; + /* write buffer until next buffered_size aligned boundary */ + i = buffered_size - (wp % buffered_size); + if (i>cnt) + i = cnt; if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK) return rc; i -= (i % info->portwidth); @@ -1205,19 +1216,37 @@ int retcode; volatile cfiptr_t src; volatile cfiptr_t dst; - /* buffered writes in the AMD chip set is not supported yet */ - if((info->vendor == CFI_CMDSET_AMD_STANDARD) || - (info->vendor == CFI_CMDSET_AMD_EXTENDED)) - return ERR_INVAL; src.cp = cp; dst.cp = (uchar *) dest; sector = find_sector (info, dest); + + /* initialize write buffer programming for different flash vendors */ + switch (info->vendor) { + case CFI_CMDSET_AMD_STANDARD: + case CFI_CMDSET_AMD_EXTENDED: + /* AMD flash types supporting write buffering */ + flash_unlock_seq (info, sector); + flash_write_cmd (info, sector, 0, AMD_CMD_BUFFER_LOAD); + if ((retcode = + flash_status_check (info, sector, info->buffer_write_tout, + "write to buffer")) == ERR_TIMOUT ) + return ERR_TIMOUT; + break; + default: + /* Intel (and other?) flash types supporting write buffering */ flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS); flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER); if ((retcode = flash_status_check (info, sector, info->buffer_write_tout, - "write to buffer")) == ERR_OK) { + "write to buffer")) == ERR_TIMOUT ) { + flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS); + return ERR_TIMOUT; + } + break; + } + + /* write program data into flash buffer */ /* reduce the number of loops by the width of the port */ switch (info->portwidth) { case FLASH_CFI_8BIT: @@ -1256,14 +1285,29 @@ break; } } - flash_write_cmd (info, sector, 0, - FLASH_CMD_WRITE_BUFFER_CONFIRM); + + /* finish write buffer programming for different flash vendors */ + switch (info->vendor) { + case CFI_CMDSET_AMD_STANDARD: + case CFI_CMDSET_AMD_EXTENDED: + /* AMD flash types supporting write buffering */ + flash_write_cmd (info, sector, 0, AMD_CMD_BUFFER_PROG); + retcode = + flash_status_check (info, sector, + info->buffer_write_tout, + "buffer write"); + break; + default: + /* Intel (and other?) flash types supporting write buffering */ + flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM); retcode = flash_full_status_check (info, sector, info->buffer_write_tout, "buffer write"); - } flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS); + break; + } + return retcode; } #endif /* CFG_FLASH_USE_BUFFER_WRITE */