summaryrefslogtreecommitdiff
path: root/board/bf537-stamp/spi_flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/bf537-stamp/spi_flash.c')
-rw-r--r--board/bf537-stamp/spi_flash.c107
1 files changed, 78 insertions, 29 deletions
diff --git a/board/bf537-stamp/spi_flash.c b/board/bf537-stamp/spi_flash.c
index 797daf2..a336894 100644
--- a/board/bf537-stamp/spi_flash.c
+++ b/board/bf537-stamp/spi_flash.c
@@ -59,6 +59,15 @@ static struct flash_info flash_st_serial_flash[] = {
{ NULL, 0, 0, 0 }
};
+/* SPI Speeds: 20 MHz / 40 MHz */
+static struct flash_info flash_sst_serial_flash[] = {
+ { "SST25WF512", 0x2501, 4 * 1024, 128 },
+ { "SST25WF010", 0x2502, 4 * 1024, 256 },
+ { "SST25WF020", 0x2503, 4 * 1024, 512 },
+ { "SST25WF040", 0x2504, 4 * 1024, 1024 },
+ { NULL, 0, 0, 0 }
+};
+
/* SPI Speeds: 66 MHz / 33 MHz */
static struct flash_info flash_atmel_dataflash[] = {
{ "AT45DB011x", 0x0c, 264, 512 },
@@ -98,6 +107,13 @@ static struct flash_ops flash_st_ops = {
.status = 0x05,
};
+static struct flash_ops flash_sst_ops = {
+ .read = OP_READ,
+ .write = 0x02,
+ .erase = 0x20,
+ .status = 0x05,
+};
+
static struct flash_ops flash_atmel_ops = {
.read = OP_READ,
.write = 0x82,
@@ -131,6 +147,7 @@ static struct {
enum {
JED_MANU_SPANSION = 0x01,
JED_MANU_ST = 0x20,
+ JED_MANU_SST = 0xBF,
JED_MANU_ATMEL = 0x1F,
JED_MANU_WINBOND = 0xEF,
};
@@ -149,6 +166,12 @@ static struct manufacturer_info flash_manufacturers[] = {
.ops = &flash_st_ops,
},
{
+ .name = "SST",
+ .id = JED_MANU_SST,
+ .flashes = flash_sst_serial_flash,
+ .ops = &flash_sst_ops,
+ },
+ {
.name = "Atmel",
.id = JED_MANU_ATMEL,
.flashes = flash_atmel_dataflash,
@@ -276,6 +299,7 @@ static int wait_for_ready_status(void)
switch (flash.manufacturer_id) {
case JED_MANU_SPANSION:
case JED_MANU_ST:
+ case JED_MANU_SST:
case JED_MANU_WINBOND:
if (!(read_status_register() & 0x01))
return 0;
@@ -297,6 +321,50 @@ static int wait_for_ready_status(void)
return -1;
}
+static int enable_writing(void)
+{
+ ulong start;
+
+ if (flash.manufacturer_id == JED_MANU_ATMEL)
+ return 0;
+
+ /* A write enable instruction must previously have been executed */
+ SPI_ON();
+ spi_write_read_byte(0x06);
+ SPI_OFF();
+
+ /* The status register will be polled to check the write enable latch "WREN" */
+ start = get_timer(0);
+ while (get_timer(0) - start < TIMEOUT) {
+ if (read_status_register() & 0x02)
+ return 0;
+
+ if (ctrlc()) {
+ puts("\nAbort\n");
+ return -1;
+ }
+ }
+
+ puts("Timeout\n");
+ return -1;
+}
+
+static void write_status_register(uint8_t val)
+{
+ if (flash.manufacturer_id != JED_MANU_SST)
+ hang();
+
+ if (enable_writing())
+ return;
+
+ /* send instruction to write status register */
+ SPI_ON();
+ spi_write_read_byte(0x01);
+ /* and clear it! */
+ spi_write_read_byte(val);
+ SPI_OFF();
+}
+
/* Request and read the manufacturer and device id of parts which
* are compatible with the JEDEC standard (JEP106) and use that to
* setup other operating conditions.
@@ -351,6 +419,7 @@ static int spi_detect_part(void)
switch (flash.manufacturer_id) {
case JED_MANU_SPANSION:
case JED_MANU_ST:
+ case JED_MANU_SST:
case JED_MANU_WINBOND:
for (i = 0; flash.manufacturer->flashes[i].name; ++i) {
if (dev_id == flash.manufacturer->flashes[i].id)
@@ -362,7 +431,11 @@ static int spi_detect_part(void)
flash.flash = &flash.manufacturer->flashes[i];
flash.sector_size = flash.flash->sector_size;
flash.num_sectors = flash.flash->num_sectors;
- flash.write_length = 256;
+
+ if (flash.manufacturer_id == JED_MANU_SST)
+ flash.write_length = 1; /* pwnt :( */
+ else
+ flash.write_length = 256;
break;
case JED_MANU_ATMEL: {
@@ -388,6 +461,10 @@ static int spi_detect_part(void)
}
}
+ /* the SST parts power up with software protection enabled by default */
+ if (flash.manufacturer_id == JED_MANU_SST)
+ write_status_register(0);
+
called_init = 1;
return 0;
@@ -572,34 +649,6 @@ static int read_flash(unsigned long address, long count, uchar *buffer)
return 0;
}
-static int enable_writing(void)
-{
- ulong start;
-
- if (flash.manufacturer_id == JED_MANU_ATMEL)
- return 0;
-
- /* A write enable instruction must previously have been executed */
- SPI_ON();
- spi_write_read_byte(0x06);
- SPI_OFF();
-
- /* The status register will be polled to check the write enable latch "WREN" */
- start = get_timer(0);
- while (get_timer(0) - start < TIMEOUT) {
- if (read_status_register() & 0x02)
- return 0;
-
- if (ctrlc()) {
- puts("\nAbort\n");
- return -1;
- }
- }
-
- puts("Timeout\n");
- return -1;
-}
-
static long address_to_sector(unsigned long address)
{
if (address > (flash.num_sectors * flash.sector_size) - 1)