Merge "qca: psci: Added support to enable secondary cores"
diff --git a/board/qca/arm/ipq40xx/ipq40xx.c b/board/qca/arm/ipq40xx/ipq40xx.c
index 985038b..19df3ad 100644
--- a/board/qca/arm/ipq40xx/ipq40xx.c
+++ b/board/qca/arm/ipq40xx/ipq40xx.c
@@ -135,6 +135,11 @@
qca_gpio_init(gpio_node);
ipq_spi_init(CONFIG_IPQ_SPI_NOR_INFO_IDX);
}
+
+#ifdef CONFIG_SPI_NAND
+ if (fdtdec_get_uint(gd->fdt_blob, 0, "spi_nand_available", 0))
+ spi_nand_init();
+#endif
}
static void ipq40xx_edma_common_init(void)
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index c665836..a93d7ac 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -16,3 +16,4 @@
obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o
obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o
obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
+obj-$(CONFIG_SPI_NAND) += spi_nand.o
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 42ebb1b..82f8aa2 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -957,6 +957,14 @@
}
if (!params->name) {
+#ifdef CONFIG_SPI_NAND
+ ret = spi_nand_flash_probe(spi, flash, idcode);
+
+ if (!ret) {
+ flash->addr_width = flash->size > 0x1000000 ? 4 : 3;
+ goto print_sf_info;
+ }
+#endif
printf("SF: Unsupported flash IDs: ");
printf("manuf %02x, jedec %04x, ext_jedec %04x\n",
idcode[0], jedec, ext_jedec);
@@ -1120,6 +1128,7 @@
}
#endif
+print_sf_info:
#ifndef CONFIG_SPL_BUILD
printf("SF: Detected %s with page size ", flash->name);
print_size(flash->page_size, ", erase size ");
diff --git a/drivers/mtd/spi/spi_nand.c b/drivers/mtd/spi/spi_nand.c
index 7a11161..2620fa2 100644
--- a/drivers/mtd/spi/spi_nand.c
+++ b/drivers/mtd/spi/spi_nand.c
@@ -16,9 +16,10 @@
#include <linux/mtd/nand.h>
#include <spi_flash.h>
#include <asm/errno.h>
-#include "spi_flash_internal.h"
#include "spi_nand_dev.h"
#include <malloc.h>
+#include "spi.h"
+#include <watchdog.h>
#define CONFIG_SF_DEFAULT_SPEED (48 * 1000 * 1000)
#define TIMEOUT 5000
@@ -172,6 +173,41 @@
cmd[3] = 0;
}
+int spi_nand_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
+ u8 cmd, u8 poll_bit, u8 *status)
+{
+ struct spi_slave *spi = flash->spi;
+ unsigned long timebase;
+ u8 cmd_buf[2];
+
+ cmd_buf[0] = 0x0F;
+ cmd_buf[1] = cmd;
+
+ timebase = get_timer(0);
+ do {
+ WATCHDOG_RESET();
+
+ spi_flash_cmd_read(spi, cmd_buf, 2, status, 1);
+ if ((*status & poll_bit) == 0)
+ break;
+
+ } while (get_timer(timebase) < timeout);
+
+ if ((*status & poll_bit) == 0)
+ return 0;
+
+ /* Timed out */
+ debug("SF: time out!\n");
+ return -1;
+}
+
+int spi_nand_flash_cmd_wait_ready(struct spi_flash *flash, u8 status_bit, u8 *status,
+ unsigned long timeout)
+{
+ return spi_nand_flash_cmd_poll_bit(flash, timeout,
+ 0xC0, status_bit, status);
+}
+
static int spinand_waitfunc(struct mtd_info *mtd, u8 val, u8 *status)
{
struct ipq40xx_spinand_info *info = mtd_to_ipq_info(mtd);
@@ -644,7 +680,7 @@
struct mtd_oob_ops ops = {0};
u32 ret;
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.len = len;
ops.datbuf = (uint8_t *)buf;
ret = spi_nand_read_std(mtd, from, &ops);
@@ -748,6 +784,8 @@
}
if (ops->ooblen)
ret = spi_nand_write_oob_data(mtd, to, ops);
+
+ ops->retlen += bytes;
write_len -= bytes;
if (!write_len)
break;
@@ -771,6 +809,7 @@
ops.len = len;
ops.datbuf = (uint8_t *)buf;
ret = spi_nand_write_std(mtd, to, &ops);
+ *retlen = ops.retlen;
return ret;
}
@@ -789,10 +828,9 @@
return ret;
}
-struct spi_flash *spi_nand_flash_probe(struct spi_slave *spi,
- u8 *idcode)
+int spi_nand_flash_probe(struct spi_slave *spi, struct spi_flash *flash,
+ u8 *idcode)
{
- struct spi_flash *flash;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(spi_nand_flash_tbl); i++) {
@@ -809,25 +847,16 @@
}
if (i == ARRAY_SIZE(spi_nand_flash_tbl)) {
- printf("SF NAND unsupported id:%x:%x:%x:%x",
- idcode[0], idcode[1], idcode[2], idcode[3]);
- return NULL;
+ return -EINVAL;
}
- flash = (struct spi_flash *)malloc(sizeof (*flash));
- if (!flash) {
- printf ("SF Failed to allocate memeory\n");
- return NULL;
- }
-
- flash->spi = spi;
-
flash->name = params->name;
flash->page_size = params->page_size;
flash->sector_size = params->page_size;
+ flash->erase_size = params->erase_size;
flash->size = (params->page_size * params->nr_sectors * params->pages_per_sector);
- return flash;
+ return 0;
}
static int spinand_unlock_protect(struct mtd_info *mtd)
@@ -962,20 +991,19 @@
mtd->priv = chip;
mtd->writesize = flash->page_size;
+ mtd->writebufsize = mtd->writesize;
mtd->erasesize = params->erase_size;
mtd->oobsize = params->oob_size;
mtd->size = flash->size;
mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH;
- mtd->point = NULL;
- mtd->unpoint = NULL;
- mtd->read = spi_nand_read;
- mtd->write = spi_nand_write;
- mtd->erase = spi_nand_erase;
- mtd->read_oob = spi_nand_read_oob;
- mtd->write_oob = spi_nand_write_oob;
- mtd->block_isbad = spi_nand_block_isbad;
- mtd->block_markbad = spi_nand_block_markbad;
+ mtd->_read = spi_nand_read;
+ mtd->_write = spi_nand_write;
+ mtd->_erase = spi_nand_erase;
+ mtd->_read_oob = spi_nand_read_oob;
+ mtd->_write_oob = spi_nand_write_oob;
+ mtd->_block_isbad = spi_nand_block_isbad;
+ mtd->_block_markbad = spi_nand_block_markbad;
chip->page_shift = ffs(mtd->writesize) - 1;
chip->phys_erase_shift = ffs(mtd->erasesize) - 1;