#include <spi.h>
#include <spi_flash.h>
#include <watchdog.h>
+#include <asm/sizes.h>
#include "spi_flash_internal.h"
}
}
+static int spi_flash_check_bankaddr_access(struct spi_flash *flash, u32 *offset)
+{
+ int ret;
+
+ if (*offset >= SZ_16M) {
+ ret = spi_flash_bankaddr_access(flash, STATUS_BANKADDR_ENABLE);
+ if (ret) {
+ debug("SF: fail to %s bank addr bit\n",
+ STATUS_BANKADDR_ENABLE ? "set" : "reset");
+ return ret;
+ }
+ *offset -= SZ_16M;
+ } else {
+ ret = spi_flash_bankaddr_access(flash, STATUS_BANKADDR_DISABLE);
+ if (ret) {
+ debug("SF: fail to %s bank addr bit\n",
+ STATUS_BANKADDR_DISABLE ? "set" : "reset");
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
static int spi_flash_read_write(struct spi_slave *spi,
const u8 *cmd, size_t cmd_len,
const u8 *data_out, u8 *data_in,
int ret;
u8 cmd[flash->addr_width+1];
+ if ((flash->size > SZ_16M) && (flash->addr_width == 3)) {
+ ret = spi_flash_check_bankaddr_access(flash, &offset);
+ if (ret) {
+ debug("SF: fail to acess bank_addr\n");
+ return ret;
+ }
+ }
+
page_size = flash->page_size;
page_addr = offset / page_size;
byte_addr = offset % page_size;
unsigned long page_size;
unsigned long byte_addr;
u8 cmd[flash->addr_width+2];
+ int ret;
+
+ if ((flash->size > SZ_16M) && (flash->addr_width == 3)) {
+ ret = spi_flash_check_bankaddr_access(flash, &offset);
+ if (ret) {
+ debug("SF: fail to acess bank_addr\n");
+ return ret;
+ }
+ }
page_size = flash->page_size;
page_addr = offset / page_size;
unsigned long page_addr;
u8 cmd[flash->addr_width+1];
+ if ((flash->size > SZ_16M) && (flash->addr_width == 3)) {
+ ret = spi_flash_check_bankaddr_access(flash, &offset);
+ if (ret) {
+ debug("SF: fail to acess bank_addr\n");
+ return ret;
+ }
+ }
+
erase_size = flash->sector_size;
if (offset % erase_size || len % erase_size) {
debug("SF: Erase offset/length not multiple of erase size\n");
return spi_flash_read_common(flash, &cmd, 1, data, 1);
}
+int spi_flash_bankaddr_access(struct spi_flash *flash, u8 status)
+{
+ int ret, pass;
+ u8 data = 0, write_done = 0;
+
+ for (pass = 0; pass < 2; pass++) {
+ ret = spi_flash_cmd_bankaddr_read(flash, (void *)&data);
+ if (ret < 0) {
+ debug("SF: fail to read bank addr register\n");
+ return ret;
+ }
+
+ if ((data != status) & !write_done) {
+ debug("SF: need to %s bank addr bit\n",
+ status ? "set" : "reset");
+
+ write_done = 1;
+ ret = spi_flash_cmd_bankaddr_write(flash, status);
+ if (ret < 0) {
+ debug("SF: fail to write bank addr bit\n");
+ return ret;
+ }
+ } else {
+ debug("SF: bank addr bit is %s.\n",
+ status ? "set" : "reset");
+ return ret;
+ }
+ }
+
+ return -1;
+}
+
/*
* The following table holds all device probe functions
*
/* Common status */
#define STATUS_WIP 0x01
+#define STATUS_BANKADDR_ENABLE 0x01
+#define STATUS_BANKADDR_DISABLE 0x00
/* Send a single-byte command to the device and read the response */
int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len);
/* Read the bank address register */
int spi_flash_cmd_bankaddr_read(struct spi_flash *flash, void *data);
+/*
+ * Bank address access
+ * access 4th byte address in 3-byte addessing mode for flashes
+ * which has an actual size of > 16MB.
+ */
+int spi_flash_bankaddr_access(struct spi_flash *flash, u8 status);
+
/*
* Same as spi_flash_cmd_read() except it also claims/releases the SPI
* bus. Used as common part of the ->read() operation.