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; +} |