const u8 *data_out, u8 *data_in,
size_t data_len)
{
- unsigned long flags = SPI_XFER_BEGIN;
+ unsigned long flags = 0;
int ret;
#ifdef CONFIG_SF_DUAL_FLASH
if (spi->flags & SPI_XFER_U_PAGE)
flags |= SPI_XFER_U_PAGE;
+#ifdef CONFIG_SPI_GENERIC
+ if (spi->flags & SPI_XFER_LOWER)
+ flags |= SPI_XFER_LOWER;
+ if (spi->flags & SPI_XFER_UPPER)
+ flags |= SPI_XFER_UPPER;
+ if (spi->flags & SPI_XFER_STRIPE)
+ flags |= SPI_XFER_STRIPE;
+#endif
#endif
if (data_len == 0)
flags |= SPI_XFER_END;
- ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags);
+ ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags | SPI_XFER_BEGIN);
if (ret) {
debug("SF: Failed to send command (%zu bytes): %d\n",
cmd_len, ret);
} else if (data_len != 0) {
ret = spi_xfer(spi, data_len * 8, data_out, data_in,
- SPI_XFER_END);
+ flags | SPI_XFER_END);
if (ret)
debug("SF: Failed to transfer %zu bytes of data: %d\n",
data_len, ret);
}
-
+#ifdef CONFIG_SPI_GENERIC
+ spi->flags &= ~SPI_XFER_MASK;
+#endif
return ret;
}
int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc)
{
u8 data[2];
+#ifdef CONFIG_SPI_GENERIC
+ u8 dataup[2];
+#endif
u8 cmd;
int ret;
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash & SF_DUAL_PARALLEL_FLASH)
+ flash->spi->flags |= SPI_XFER_LOWER;
+#endif
ret = spi_flash_cmd_read_status(flash, &data[0]);
if (ret < 0)
return ret;
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) {
+ flash->spi->flags |= SPI_XFER_UPPER;
+ ret = spi_flash_cmd_read_status(flash, &dataup[0]);
+ if (ret < 0)
+ return ret;
+ }
+#endif
+
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash & SF_DUAL_PARALLEL_FLASH)
+ flash->spi->flags |= SPI_XFER_LOWER;
+#endif
+
cmd = CMD_WRITE_STATUS;
data[1] = wc;
ret = spi_flash_write_common(flash, &cmd, 1, &data, 2);
return ret;
}
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) {
+ flash->spi->flags |= SPI_XFER_UPPER;
+ dataup[1] = wc;
+ ret = spi_flash_write_common(flash, &cmd, 1, &dataup, 2);
+ if (ret) {
+ debug("SF: fail to write config register\n");
+ return ret;
+ }
+ }
+#endif
+
return 0;
}
#endif
}
#endif
-static int spi_flash_poll_status(struct spi_slave *spi, unsigned long timeout,
+static int spi_flash_poll_status(struct spi_flash *flash, unsigned long timeout,
u8 cmd, u8 poll_bit)
{
+ struct spi_slave *spi = flash->spi;
unsigned long timebase;
- unsigned long flags = SPI_XFER_BEGIN;
+ unsigned long flags = 0;
int ret;
u8 status;
u8 check_status = 0x0;
+#ifdef CONFIG_SPI_GENERIC
+ u8 status_up;
+#endif
if (cmd == CMD_FLAG_STATUS)
check_status = poll_bit;
if (spi->flags & SPI_XFER_U_PAGE)
flags |= SPI_XFER_U_PAGE;
#endif
- ret = spi_xfer(spi, 8, &cmd, NULL, flags);
+ ret = spi_xfer(spi, 8, &cmd, NULL, flags | SPI_XFER_BEGIN);
if (ret) {
debug("SF: fail to read %s status register\n",
cmd == CMD_READ_STATUS ? "read" : "flag");
do {
WATCHDOG_RESET();
- ret = spi_xfer(spi, 8, NULL, &status, 0);
- if (ret)
- return -1;
-
- if ((status & poll_bit) == check_status)
- break;
-
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash == SF_DUAL_PARALLEL_FLASH) {
+ ret = spi_xfer(spi, 8, NULL, &status,
+ flags | SPI_XFER_LOWER);
+ if (ret)
+ return -1;
+ ret = spi_xfer(spi, 8, NULL, &status_up,
+ flags | SPI_XFER_UPPER);
+ if (ret)
+ return -1;
+ debug("Poll Status:0x%x, Status_up:0x%x\n", status,
+ status_up);
+
+ if (((status & poll_bit) == check_status) &&
+ ((status_up & poll_bit) == check_status))
+ break;
+ } else {
+#endif
+ ret = spi_xfer(spi, 8, NULL, &status, flags);
+ if (ret)
+ return -1;
+
+ debug("Poll Status:0x%x\n", status);
+ if ((status & poll_bit) == check_status)
+ break;
+#ifdef CONFIG_SPI_GENERIC
+ }
+#endif
} while (get_timer(timebase) < timeout);
- spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
+ spi_xfer(spi, 0, NULL, NULL, flags | SPI_XFER_END);
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash == SF_DUAL_PARALLEL_FLASH) {
+ if (((status & poll_bit) == check_status) &&
+ ((status_up & poll_bit) == check_status))
+ return 0;
+ } else {
+#endif
if ((status & poll_bit) == check_status)
return 0;
-
+#ifdef CONFIG_SPI_GENERIC
+ }
+#endif
/* Timed out */
debug("SF: time out!\n");
return -1;
int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
{
- struct spi_slave *spi = flash->spi;
int ret;
u8 poll_bit = STATUS_WIP;
u8 cmd = CMD_READ_STATUS;
- ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit);
+ ret = spi_flash_poll_status(flash, timeout, cmd, poll_bit);
if (ret < 0)
return ret;
if (flash->poll_cmd == CMD_FLAG_STATUS) {
poll_bit = STATUS_PEC;
cmd = CMD_FLAG_STATUS;
- ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit);
+ ret = spi_flash_poll_status(flash, timeout, cmd, poll_bit);
if (ret < 0)
return ret;
}
debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash == SF_DUAL_PARALLEL_FLASH)
+ flash->spi->flags |= SPI_XFER_STRIPE;
+#endif
ret = spi_flash_write_common(flash, cmd, sizeof(cmd),
buf + actual, chunk_len);
if (ret < 0) {
spi_flash_addr(read_addr, cmd);
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash == SF_DUAL_PARALLEL_FLASH)
+ flash->spi->flags |= SPI_XFER_STRIPE;
+#endif
+
ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);
if (ret < 0) {
debug("SF: read failed\n");
static int spi_flash_set_qeb_mxic(struct spi_flash *flash)
{
u8 qeb_status;
+#ifdef CONFIG_SPI_GENERIC
+ u8 qeb_status_up;
+#endif
int ret;
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash & SF_DUAL_PARALLEL_FLASH)
+ flash->spi->flags |= SPI_XFER_LOWER;
+#endif
+
ret = spi_flash_cmd_read_status(flash, &qeb_status);
if (ret < 0)
return ret;
- if (qeb_status & STATUS_QEB_MXIC) {
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) {
+ flash->spi->flags |= SPI_XFER_UPPER;
+ spi_flash_cmd_read_status(flash, &qeb_status_up);
+ }
+#endif
+ if ((qeb_status & STATUS_QEB_MXIC)
+#ifdef CONFIG_SPI_GENERIC
+ && (qeb_status_up & STATUS_QEB_MXIC)
+#endif
+ ) {
debug("SF: mxic: QEB is already set\n");
} else {
ret = spi_flash_cmd_write_status(flash, STATUS_QEB_MXIC);
static int spi_flash_set_qeb_winspan(struct spi_flash *flash)
{
u8 qeb_status;
+#ifdef CONFIG_SPI_GENERIC
+ u8 qeb_status_up;
+#endif
int ret;
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash & SF_DUAL_PARALLEL_FLASH)
+ flash->spi->flags |= SPI_XFER_LOWER;
+#endif
+
ret = spi_flash_cmd_read_config(flash, &qeb_status);
if (ret < 0)
return ret;
- if (qeb_status & STATUS_QEB_WINSPAN) {
+#ifdef CONFIG_SPI_GENERIC
+ if (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) {
+ flash->spi->flags |= SPI_XFER_UPPER;
+ ret = spi_flash_cmd_read_config(flash, &qeb_status_up);
+ }
+#endif
+ if ((qeb_status & STATUS_QEB_WINSPAN)
+#ifdef CONFIG_SPI_GENERIC
+ && (qeb_status_up & STATUS_QEB_WINSPAN)
+#endif
+ ) {
debug("SF: winspan: QEB is already set\n");
} else {
ret = spi_flash_cmd_write_config(flash, STATUS_QEB_WINSPAN);
flash->bank_write_cmd = (idcode[0] == 0x01) ?
CMD_BANKADDR_BRWR : CMD_EXTNADDR_WREAR;
- ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1,
- &curr_bank, 1);
- if (ret) {
- debug("SF: fail to read bank addr register\n");
- return ret;
+ if (flash->dual_flash == SF_DUAL_PARALLEL_FLASH) {
+ spi->flags |= SPI_XFER_LOWER;
+ ret = spi_flash_read_common(flash,
+ &flash->bank_read_cmd,
+ 1, &curr_bank, 1);
+ if (ret) {
+ debug("SF: fail to read bank addr register\n");
+ return ret;
+ }
}
flash->bank_curr = curr_bank;
} else {
int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash)
{
u8 idcode[5];
+#ifdef CONFIG_SPI_GENERIC
+ u8 idcode_up[5];
+ u8 i;
+#endif
int ret;
/* Setup spi_slave */
return ret;
}
+ if (spi->option == SF_DUAL_PARALLEL_FLASH)
+ spi->flags |= SPI_XFER_LOWER;
/* Read the ID codes */
ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
if (ret) {
goto err_read_id;
}
+#ifdef CONFIG_SPI_GENERIC
+ if (spi->option == SF_DUAL_PARALLEL_FLASH) {
+ spi->flags |= SPI_XFER_UPPER;
+ ret = spi_flash_cmd(spi, CMD_READ_ID, idcode_up,
+ sizeof(idcode_up));
+ if (ret) {
+ printf("SF: Failed to get idcodes\n");
+ goto err_read_id;
+ }
+ for (i = 0; i < sizeof(idcode); i++) {
+ if (idcode[i] != idcode_up[i]) {
+ printf("SF: Failed to get same idcodes\n");
+ goto err_read_id;
+ }
+ }
+ }
+#endif
#ifdef DEBUG
printf("SF: Got idcodes\n");
print_buffer(0, idcode, 1, sizeof(idcode), 0);