From: Erik M. <er...@us...> - 2001-10-15 21:56:40
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv21169 Modified Files: nesa.c pleb.c shannon.c system3.c Log Message: Nesa flash functions. Not tested, but they should work. Please test, Russ. Index: nesa.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/nesa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- nesa.c 2001/10/14 22:36:11 1.1 +++ nesa.c 2001/10/15 21:56:37 1.2 @@ -26,4 +26,183 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + + + +#warning "Please fix NESA flash descriptor" + +/* flash descriptor for NESA flash */ +/* 2x AMD *whatever* flash (4MB) */ +flash_descriptor_t flash_descriptors[] = +{ + { + size: 2 * 8 * 1024, + num: 8, + }, + { + size: 2 * 64 * 1024, + num: 31, + }, + { + /* NULL block */ + }, +}; + + + + +/* flash commands for two 16 bit AMD flash chips */ +#define READ_ARRAY 0x00F000F0 +#define UNLOCK1 0x00AA00AA +#define UNLOCK2 0x00550055 +#define ERASE_SETUP 0x00800080 +#define ERASE_CONFIRM 0x00300030 +#define PGM_SETUP 0x00A000A0 +#define UNLOCK_BYPASS 0x00200020 +#define FLASH_ADDR1 (0x00000555 << 2) +#define FLASH_ADDR2 (0x000002AA << 2) +#define ERASE_DONE 0x00800080 +#define RDY_MASK 0x00800080 +#define STATUS_PGM_ERR 0x00200020 +#define STATUS_ERASE_ERR 0x00000001 + +#define READY 1 +#define ERR 2 + + + + +#warning "Please check NESA flash code" + +/* the next two functions should work for all 2x 16 bit AMD flashes */ + +int erase_flash(u32 *addr) +{ + u32 result; + int chip1, chip2; + + /* prepare for erase */ + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP); + barrier(); + + /* erase command */ + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *addr = data_to_flash(ERASE_CONFIRM); + + /* I just can't find clean ways of dealing with this flash... + * The error bit is a *set* bit, so if its read, and bit 7 is 0, + * but bit 5 is 1, its an error, however, after these status reads + * are done, erased flash goes to 0xff...sooo...each chip has to + * be caught where the bits are the status bits -- Russ */ + + /* Russ, why don't you do this like the LART does? Just check + * the status of chips with a single compare. -- Erik */ + chip1 = chip2 = 0; + + do { + result = data_from_flash(*addr); + barrier(); + + if (!chip1 && (result & 0xFFFF) & ERASE_DONE) + chip1 = READY; + if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) + chip1 = ERR; + + if (!chip2 && (result >> 16) & ERASE_DONE) + chip2 = READY; + + if (!chip2 && (result >> 16) & STATUS_PGM_ERR) + chip2 = ERR; + + } while(!chip1 || !chip2); + + /* put flash back into Read Array mode */ + *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); + barrier(); + + if (chip1 == ERR || chip2 == ERR) + return -EFLASHERASE; + + return 0; +} + + + + +int write_flash(u32 *dst, const u32* src) +{ + u32 result; + int chip1, chip2; + + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS); + barrier(); + + *dst = data_to_flash(PGM_SETUP); + barrier(); + *dst = *src; + barrier(); + + /* This is a pretty similar situation to the erasing status below + * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5 + * gets set before this happens, there is an error, but this could + * happen near the clock edge, and bit 5 could be the actual data + * before bit 7 changes, so we have to read again. -- Russ + */ + + chip1 = chip2 = 0; + do { + result = data_from_flash(*dst); + barrier(); + + if (!chip1 && ((result & 0x80) == (*src & 0x80))) + chip1 = READY; + + if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) { + result = data_from_flash(*dst); + barrier(); + + if ((result & 0x80) == (*src & 0x80)) + chip1 = READY; + else + chip1 = ERR; + } + + if (!chip2 && ((result & (0x80 << 16)) == (*src & (0x80 << 16)))) + chip2 = READY; + + if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) { + result = data_from_flash(*dst); + barrier(); + + if ((result & (0x80 << 16)) == (*src & (0x80 << 16))) + chip2 = READY; + else + chip2 = ERR; + } + + } while (!chip1 || !chip2); + + *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); + barrier(); + + if (chip1 == ERR || chip2 == ERR || *dst != *src) + return -EFLASHPGM; + + return 0; +} Index: pleb.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/pleb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- pleb.c 2001/10/14 22:36:11 1.1 +++ pleb.c 2001/10/15 21:56:37 1.2 @@ -26,4 +26,53 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/init.h> +#include <blob/led.h> +#include <blob/util.h> + +/* the LED should always be on or otherwise the serial transmitter + * doesn't work + */ +static void lock_pleb_led(void) +{ + led_unlock(); + led_on(); + led_lock(); +} + +/* do this just after the initial hardware has been initialised */ +__initlist(lock_pleb_led, INIT_LEVEL_INITIAL_HARDWARE + 1); + + + + +#warning "Please verify PLEB flash layout" + +/* flash descriptor for PLEB flash. */ +flash_descriptor_t flash_descriptors[] = +{ + { + /* NULL block */ + }, +}; + + + + +#warning "Please verify PLEB flash functions" + +int erase_flash(u32 *addr) +{ + return -EFLASHERASE; +} + + + +/* write a flash block at a given location */ +int write_flash(u32 *dst, const u32* src) +{ + return -EFLASHPGM; +} Index: shannon.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/shannon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- shannon.c 2001/10/14 22:36:11 1.1 +++ shannon.c 2001/10/15 21:56:37 1.2 @@ -26,4 +26,181 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + + +#warning "Please fix SHANNON flash descriptor" + +/* flash descriptor for SHANNON flash */ +/* 2x AMD *whatever* flash (4MB) */ +flash_descriptor_t flash_descriptors[] = +{ + { + size: 2 * 8 * 1024, + num: 8, + }, + { + size: 2 * 64 * 1024, + num: 31, + }, + { + /* NULL block */ + }, +}; + + + + +/* flash commands for two 16 bit AMD flash chips */ +#define READ_ARRAY 0x00F000F0 +#define UNLOCK1 0x00AA00AA +#define UNLOCK2 0x00550055 +#define ERASE_SETUP 0x00800080 +#define ERASE_CONFIRM 0x00300030 +#define PGM_SETUP 0x00A000A0 +#define UNLOCK_BYPASS 0x00200020 +#define FLASH_ADDR1 (0x00000555 << 2) +#define FLASH_ADDR2 (0x000002AA << 2) +#define ERASE_DONE 0x00800080 +#define RDY_MASK 0x00800080 +#define STATUS_PGM_ERR 0x00200020 +#define STATUS_ERASE_ERR 0x00000001 + +#define READY 1 +#define ERR 2 + + + + +#warning "Please check SHANNON flash code" + +int erase_flash(u32 *addr) +{ + u32 result; + int chip1, chip2; + + /* prepare for erase */ + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP); + barrier(); + + /* erase command */ + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *addr = data_to_flash(ERASE_CONFIRM); + + /* I just can't find clean ways of dealing with this flash... + * The error bit is a *set* bit, so if its read, and bit 7 is 0, + * but bit 5 is 1, its an error, however, after these status reads + * are done, erased flash goes to 0xff...sooo...each chip has to + * be caught where the bits are the status bits -- Russ */ + + /* Russ, why don't you do this like the LART does? Just check + * the status of chips with a single compare. -- Erik */ + chip1 = chip2 = 0; + + do { + result = data_from_flash(*addr); + barrier(); + + if (!chip1 && (result & 0xFFFF) & ERASE_DONE) + chip1 = READY; + + if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) + chip1 = ERR; + + if (!chip2 && (result >> 16) & ERASE_DONE) + chip2 = READY; + + if (!chip2 && (result >> 16) & STATUS_PGM_ERR) + chip2 = ERR; + + } while(!chip1 || !chip2); + + /* put flash back into Read Array mode */ + *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); + barrier(); + + if (chip1 == ERR || chip2 == ERR) + return -EFLASHERASE; + + return 0; +} + + + + +int write_flash(u32 *dst, const u32* src) +{ + u32 result; + int chip1, chip2; + + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS); + barrier(); + + *dst = data_to_flash(PGM_SETUP); + barrier(); + *dst = *src; + barrier(); + + /* This is a pretty similar situation to the erasing status below + * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5 + * gets set before this happens, there is an error, but this could + * happen near the clock edge, and bit 5 could be the actual data + * before bit 7 changes, so we have to read again. -- Russ + */ + + chip1 = chip2 = 0; + do { + result = data_from_flash(*dst); + barrier(); + + if (!chip1 && ((result & 0x80) == (*src & 0x80))) + chip1 = READY; + + if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) { + result = data_from_flash(*dst); + barrier(); + + if ((result & 0x80) == (*src & 0x80)) + chip1 = READY; + else + chip1 = ERR; + } + + if (!chip2 && ((result & (0x80 << 16)) == (*src & (0x80 << 16)))) + chip2 = READY; + + if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) { + result = data_from_flash(*dst); + barrier(); + + if ((result & (0x80 << 16)) == (*src & (0x80 << 16))) + chip2 = READY; + else + chip2 = ERR; + } + + } while (!chip1 || !chip2); + + *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); + barrier(); + + if (chip1 == ERR || chip2 == ERR || *dst != *src) + return -EFLASHPGM; + + return 0; +} Index: system3.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/system3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- system3.c 2001/10/14 22:36:11 1.1 +++ system3.c 2001/10/15 21:56:37 1.2 @@ -26,4 +26,38 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + + +#warning "Please verify System3 flash layout" + +/* flash descriptor for System3 flash. */ +/* I have *really* no idea what kind of flash System3 uses */ +flash_descriptor_t flash_descriptors[] = +{ + { + /* NULL block */ + }, +}; + + + +#warning "Please verify System3 flash functions" + +int erase_flash(u32 *addr) +{ + return -EFLASHERASE; +} + + + + +/* write a flash block at a given location */ +int write_flash(u32 *dst, const u32* src) +{ + return -EFLASHPGM; +} |
From: Russ D. <Rus...@as...> - 2001-10-15 22:02:36
|
On Mon, 2001-10-15 at 14:56, Erik Mouw wrote: > Update of /cvsroot/blob/blob/src/blob > In directory usw-pr-cvs1:/tmp/cvs-serv21169 > > Modified Files: > nesa.c pleb.c shannon.c system3.c > Log Message: > Nesa flash functions. Not tested, but they should work. Please test, Russ. You should really break this out a bit more, as both the nesa and shannon have identical flash (probably true with other platforms as well). Maybe there should be an amd.c, and an intel.c. Each would contain functions for erasing and writing the flash. <arch.c> would set the proper write function, as well as an optional read32/write32 (for plaiting). If no erase/write function was set, then flashing would barf. |
From: Erik M. <J.A...@IT...> - 2001-10-15 22:20:25
|
On Mon, Oct 15, 2001 at 03:05:52PM -0700, Russ Dill wrote: > You should really break this out a bit more, as both the nesa and > shannon have identical flash (probably true with other platforms as > well). Maybe there should be an amd.c, and an intel.c. Each would > contain functions for erasing and writing the flash. <arch.c> would set > the proper write function, as well as an optional read32/write32 (for > plaiting). If no erase/write function was set, then flashing would barf. Well, yes and no. The Intel flashes should be easy to do, because 1x 16 bit and 2x 16 bit flashes can be done with the same code (only the commands and error codes differ). Looking at your comments in the code, the AMD flashes are a bit more difficult to handle, so I doubt it's really worth it. I really want to avoid recreating the complete MTD functionality in blob. Anyway, at least it cleans up the flash code a lot, and I'll clean it up even more when I start implementing the flash partitioning. Erik -- J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department of Electrical Engineering, Faculty of Information Technology and Systems, Delft University of Technology, PO BOX 5031, 2600 GA Delft, The Netherlands Phone: +31-15-2783635 Fax: +31-15-2781843 Email: J.A...@it... WWW: http://www-ict.its.tudelft.nl/~erik/ |
From: Russ D. <Rus...@as...> - 2001-10-15 22:31:16
|
On Mon, 2001-10-15 at 15:20, Erik Mouw wrote: > On Mon, Oct 15, 2001 at 03:05:52PM -0700, Russ Dill wrote: > > You should really break this out a bit more, as both the nesa and > > shannon have identical flash (probably true with other platforms as > > well). Maybe there should be an amd.c, and an intel.c. Each would > > contain functions for erasing and writing the flash. <arch.c> would set > > the proper write function, as well as an optional read32/write32 (for > > plaiting). If no erase/write function was set, then flashing would barf. > > Well, yes and no. The Intel flashes should be easy to do, because 1x 16 > bit and 2x 16 bit flashes can be done with the same code (only the > commands and error codes differ). > > Looking at your comments in the code, the AMD flashes are a bit more > difficult to handle, so I doubt it's really worth it. I really want to > avoid recreating the complete MTD functionality in blob. > > Anyway, at least it cleans up the flash code a lot, and I'll clean it > up even more when I start implementing the flash partitioning. The code could probably be cleaned up to support 1x 16. The amount of code duplication involved in the current method just seems excessive. |
From: Erik M. <J.A...@IT...> - 2001-10-15 22:50:10
|
On Mon, Oct 15, 2001 at 03:34:20PM -0700, Russ Dill wrote: > On Mon, 2001-10-15 at 15:20, Erik Mouw wrote: > > Looking at your comments in the code, the AMD flashes are a bit more > > difficult to handle, so I doubt it's really worth it. I really want to > > avoid recreating the complete MTD functionality in blob. > > The code could probably be cleaned up to support 1x 16. The amount of > code duplication involved in the current method just seems excessive. Agreed. I'll look into this tomorrow. Erik [sleep(7*3600) or so] -- J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department of Electrical Engineering, Faculty of Information Technology and Systems, Delft University of Technology, PO BOX 5031, 2600 GA Delft, The Netherlands Phone: +31-15-2783635 Fax: +31-15-2781843 Email: J.A...@it... WWW: http://www-ict.its.tudelft.nl/~erik/ |
From: Erik M. <J.A...@IT...> - 2001-10-15 22:09:57
|
On Mon, Oct 15, 2001 at 02:56:39PM -0700, Erik Mouw wrote: > Modified Files: > nesa.c pleb.c shannon.c system3.c > Log Message: > Nesa flash functions. Not tested, but they should work. Please test, Russ. Grrrr, I hate following up to my own messages. My intention was to commit each file with a separate CVS commit. Anyway, here is the rest of the log: Pleb flash functions should still be fleshed out. Pleb turns the LED on and locks it early in the boot process, so the LED shouldn't go off anymore, and hence the serial port should remain working. Shannon flash functions are not tested but they should work. Please fill out the correct flash table. Please test, Russ and Tim. PT System3 flash functions should be fleshed out. Stefan? Note that the flash descriptions are currently not used in the erase and write functions, but I want to use them for the flash partitioning support (which should become easier right now). Erik -- J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department of Electrical Engineering, Faculty of Information Technology and Systems, Delft University of Technology, PO BOX 5031, 2600 GA Delft, The Netherlands Phone: +31-15-2783635 Fax: +31-15-2781843 Email: J.A...@it... WWW: http://www-ict.its.tudelft.nl/~erik/ |