* complete by checking the INT bit of config2 register.
*/
static void wait_op_done(struct mxc_nand_host *host, int max_retries,
- uint16_t param, int useirq)
+ int useirq)
{
uint32_t tmp;
udelay(1);
}
if (max_retries < 0)
- DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n",
- __func__, param);
+ DEBUG(MTD_DEBUG_LEVEL0, "%s: INT not set\n",
+ __func__);
}
}
writew(NFC_CMD, host->regs + NFC_CONFIG2);
/* Wait for operation to complete */
- wait_op_done(host, TROP_US_DELAY, cmd, useirq);
+ wait_op_done(host, TROP_US_DELAY, useirq);
}
/* This function sends an address (or partial address) to the
writew(NFC_ADDR, host->regs + NFC_CONFIG2);
/* Wait for operation to complete */
- wait_op_done(host, TROP_US_DELAY, addr, islast);
+ wait_op_done(host, TROP_US_DELAY, islast);
}
-/* This function requests the NANDFC to initate the transfer
- * of data currently in the NANDFC RAM buffer to the NAND device. */
-static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id,
- int spare_only)
+static void send_page(struct mxc_nand_host *host, uint8_t buf_id,
+ int spare_only, unsigned int ops)
{
- DEBUG(MTD_DEBUG_LEVEL3, "send_prog_page (%d)\n", spare_only);
+ DEBUG(MTD_DEBUG_LEVEL3, "send_page (%d)\n", spare_only);
/* NANDFC buffer 0 is used for page read/write */
writew(buf_id, host->regs + NFC_BUF_ADDR);
writew(config1, host->regs + NFC_CONFIG1);
}
- writew(NFC_INPUT, host->regs + NFC_CONFIG2);
+ writew(ops, host->regs + NFC_CONFIG2);
/* Wait for operation to complete */
- wait_op_done(host, TROP_US_DELAY, spare_only, true);
-}
-
-/* Requests NANDFC to initated the transfer of data from the
- * NAND device into in the NANDFC ram buffer. */
-static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id,
- int spare_only)
-{
- DEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only);
-
- /* NANDFC buffer 0 is used for page read/write */
- writew(buf_id, host->regs + NFC_BUF_ADDR);
-
- /* Configure spare or page+spare access */
- if (!host->pagesize_2k) {
- uint32_t config1 = readw(host->regs + NFC_CONFIG1);
- if (spare_only)
- config1 |= NFC_SP_EN;
- else
- config1 &= ~NFC_SP_EN;
- writew(config1, host->regs + NFC_CONFIG1);
- }
-
- writew(NFC_OUTPUT, host->regs + NFC_CONFIG2);
-
- /* Wait for operation to complete */
- wait_op_done(host, TROP_US_DELAY, spare_only, true);
+ wait_op_done(host, TROP_US_DELAY, true);
}
/* Request the NANDFC to perform a read of the NAND device ID. */
writew(NFC_ID, host->regs + NFC_CONFIG2);
/* Wait for operation to complete */
- wait_op_done(host, TROP_US_DELAY, 0, true);
+ wait_op_done(host, TROP_US_DELAY, true);
if (this->options & NAND_BUSWIDTH_16) {
void __iomem *main_buf = host->regs + MAIN_AREA0;
writew(NFC_STATUS, host->regs + NFC_CONFIG2);
/* Wait for operation to complete */
- wait_op_done(host, TROP_US_DELAY, 0, true);
+ wait_op_done(host, TROP_US_DELAY, true);
/* Status is placed in first word of main buffer */
/* get status, then recovery area 1 data */
struct nand_chip *nand_chip = mtd->priv;
struct mxc_nand_host *host = nand_chip->priv;
-#ifdef CONFIG_MTD_NAND_MXC_FORCE_CE
- if (chip > 0) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "ERROR: Illegal chip select (chip = %d)\n", chip);
- return;
- }
-
- if (chip == -1) {
- writew(readw(host->regs + NFC_CONFIG1) & ~NFC_CE,
- host->regs + NFC_CONFIG1);
- return;
- }
-
- writew(readw(host->regs + NFC_CONFIG1) | NFC_CE,
- host->regs + NFC_CONFIG1);
-#endif
-
switch (chip) {
case -1:
/* Disable the NFC clock */
}
}
+static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+
+ /* Write out column address, if necessary */
+ if (column != -1) {
+ /*
+ * MXC NANDFC can only perform full page+spare or
+ * spare-only read/write. When the upper layers
+ * layers perform a read/write buf operation,
+ * we will used the saved column adress to index into
+ * the full page.
+ */
+ send_addr(host, 0, page_addr == -1);
+ if (host->pagesize_2k)
+ /* another col addr cycle for 2k page */
+ send_addr(host, 0, false);
+ }
+
+ /* Write out page address, if necessary */
+ if (page_addr != -1) {
+ /* paddr_0 - p_addr_7 */
+ send_addr(host, (page_addr & 0xff), false);
+
+ if (host->pagesize_2k) {
+ if (mtd->size >= 0x10000000) {
+ /* paddr_8 - paddr_15 */
+ send_addr(host, (page_addr >> 8) & 0xff, false);
+ send_addr(host, (page_addr >> 16) & 0xff, true);
+ } else
+ /* paddr_8 - paddr_15 */
+ send_addr(host, (page_addr >> 8) & 0xff, true);
+ } else {
+ /* One more address cycle for higher density devices */
+ if (mtd->size >= 0x4000000) {
+ /* paddr_8 - paddr_15 */
+ send_addr(host, (page_addr >> 8) & 0xff, false);
+ send_addr(host, (page_addr >> 16) & 0xff, true);
+ } else
+ /* paddr_8 - paddr_15 */
+ send_addr(host, (page_addr >> 8) & 0xff, true);
+ }
+ }
+}
+
/* Used by the upper layer to write command to NAND Flash for
* different operations to be carried out on NAND Flash */
static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
break;
case NAND_CMD_PAGEPROG:
- send_prog_page(host, 0, host->spare_only);
+ send_page(host, 0, host->spare_only, NFC_INPUT);
if (host->pagesize_2k) {
/* data in 4 areas datas */
- send_prog_page(host, 1, host->spare_only);
- send_prog_page(host, 2, host->spare_only);
- send_prog_page(host, 3, host->spare_only);
+ send_page(host, 1, host->spare_only, NFC_INPUT);
+ send_page(host, 2, host->spare_only, NFC_INPUT);
+ send_page(host, 3, host->spare_only, NFC_INPUT);
}
break;
/* Write out the command to the device. */
send_cmd(host, command, useirq);
-
- /* Write out column address, if necessary */
- if (column != -1) {
- /*
- * MXC NANDFC can only perform full page+spare or
- * spare-only read/write. When the upper layers
- * layers perform a read/write buf operation,
- * we will used the saved column adress to index into
- * the full page.
- */
- send_addr(host, 0, page_addr == -1);
- if (host->pagesize_2k)
- /* another col addr cycle for 2k page */
- send_addr(host, 0, false);
- }
-
- /* Write out page address, if necessary */
- if (page_addr != -1) {
- /* paddr_0 - p_addr_7 */
- send_addr(host, (page_addr & 0xff), false);
-
- if (host->pagesize_2k) {
- if (mtd->size >= 0x10000000) {
- /* paddr_8 - paddr_15 */
- send_addr(host, (page_addr >> 8) & 0xff, false);
- send_addr(host, (page_addr >> 16) & 0xff, true);
- } else
- /* paddr_8 - paddr_15 */
- send_addr(host, (page_addr >> 8) & 0xff, true);
- } else {
- /* One more address cycle for higher density devices */
- if (mtd->size >= 0x4000000) {
- /* paddr_8 - paddr_15 */
- send_addr(host, (page_addr >> 8) & 0xff, false);
- send_addr(host, (page_addr >> 16) & 0xff, true);
- } else
- /* paddr_8 - paddr_15 */
- send_addr(host, (page_addr >> 8) & 0xff, true);
- }
- }
+ mxc_do_addr_cycle(mtd, column, page_addr);
/* Command post-processing step */
switch (command) {
/* send read confirm command */
send_cmd(host, NAND_CMD_READSTART, true);
/* read for each AREA */
- send_read_page(host, 0, host->spare_only);
- send_read_page(host, 1, host->spare_only);
- send_read_page(host, 2, host->spare_only);
- send_read_page(host, 3, host->spare_only);
+ send_page(host, 0, host->spare_only, NFC_OUTPUT);
+ send_page(host, 1, host->spare_only, NFC_OUTPUT);
+ send_page(host, 2, host->spare_only, NFC_OUTPUT);
+ send_page(host, 3, host->spare_only, NFC_OUTPUT);
} else
- send_read_page(host, 0, host->spare_only);
+ send_page(host, 0, host->spare_only, NFC_OUTPUT);
break;
case NAND_CMD_READID: