nand: fix mtd0 erase operation
authorYonghui Yu <yonghui.yu@amlogic.com>
Mon, 17 Apr 2017 07:34:50 +0000 (15:34 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Wed, 19 Apr 2017 11:37:01 +0000 (04:37 -0700)
PD#138714: add erase interface for mtd0(bootloader)

Change-Id: I5d6de9013d9f2c83a218d29e390df58430eeea58
Signed-off-by: Yonghui Yu <yonghui.yu@amlogic.com>
drivers/amlogic/mtd/aml_mtd.h
drivers/amlogic/mtd/aml_nand.c
drivers/amlogic/mtd/m3_nand.c

index 4808dc1..7d9a333 100644 (file)
@@ -258,6 +258,7 @@ struct aml_nand_flash_dev {
        unsigned int T_REA;
        unsigned int T_RHOH;
        u8 onfi_mode;
+       /* store new type directly */
        unsigned char new_type;
        unsigned int options;
 };
@@ -514,7 +515,10 @@ struct aml_nand_chip {
        struct new_tech_nand_t  new_nand_info;
        /* platform info */
        struct aml_nand_platform *platform;
-
+#ifndef AML_NAND_UBOOT
+       dma_addr_t data_dma_addr;
+       dma_addr_t info_dma_addr;
+#endif
        /* device info */
        struct device *device;
 
index 916ba47..9085554 100644 (file)
@@ -2482,7 +2482,7 @@ int aml_nand_init(struct aml_nand_chip *aml_chip)
 #ifndef AML_NAND_UBOOT
        aml_chip->aml_nand_data_buf = dma_alloc_coherent(aml_chip->device,
                (mtd->writesize + mtd->oobsize),
-               &controller->data_dma_addr, GFP_KERNEL);
+               &aml_chip->data_dma_addr, GFP_KERNEL);
        if (aml_chip->aml_nand_data_buf == NULL) {
                pr_info("no memory for flash data buf\n");
                err = -ENOMEM;
@@ -2490,7 +2490,7 @@ int aml_nand_init(struct aml_nand_chip *aml_chip)
        }
        aml_chip->user_info_buf = dma_alloc_coherent(aml_chip->device,
                (mtd->writesize / chip->ecc.size) * PER_INFO_BYTE,
-               &controller->info_dma_addr, GFP_KERNEL);
+               &aml_chip->info_dma_addr, GFP_KERNEL);
        if (aml_chip->user_info_buf == NULL) {
                pr_info("no memory for flash info buf\n");
                err = -ENOMEM;
@@ -2585,7 +2585,7 @@ exit_error:
                dma_free_coherent(NULL,
                        (mtd->writesize / chip->ecc.size) * PER_INFO_BYTE,
                        aml_chip->user_info_buf,
-                       controller->info_dma_addr);
+                       aml_chip->info_dma_addr);
 #else
                kfree(aml_chip->user_info_buf);
 #endif
@@ -2604,7 +2604,7 @@ exit_error:
 #ifndef AML_NAND_UBOOT
                dma_free_coherent(NULL, (mtd->writesize + mtd->oobsize),
                        aml_chip->aml_nand_data_buf,
-                       controller->data_dma_addr);
+                       aml_chip->data_dma_addr);
 #else
                kfree(aml_chip->aml_nand_data_buf);
 #endif
index 6d6fc37..fd5fcf7 100644 (file)
@@ -633,10 +633,10 @@ static int m3_nand_dma_write(struct aml_nand_chip *aml_chip,
                count = len/chip->ecc.size;
 
 #ifndef AML_NAND_UBOOT
-       NFC_SEND_CMD_ADL(controller, controller->data_dma_addr);
-       NFC_SEND_CMD_ADH(controller, controller->data_dma_addr);
-       NFC_SEND_CMD_AIL(controller, controller->info_dma_addr);
-       NFC_SEND_CMD_AIH(controller, controller->info_dma_addr);
+       NFC_SEND_CMD_ADL(controller, aml_chip->data_dma_addr);
+       NFC_SEND_CMD_ADH(controller, aml_chip->data_dma_addr);
+       NFC_SEND_CMD_AIL(controller, aml_chip->info_dma_addr);
+       NFC_SEND_CMD_AIH(controller, aml_chip->info_dma_addr);
 #else
        flush_dcache_range((unsigned long)buf, (unsigned long)buf + len);
        flush_dcache_range((unsigned long)aml_chip->user_info_buf,
@@ -707,10 +707,10 @@ static int m3_nand_dma_read(struct aml_nand_chip *aml_chip,
        smp_wmb();
        /*wmb*/
        wmb();
-       NFC_SEND_CMD_ADL(controller, controller->data_dma_addr);
-       NFC_SEND_CMD_ADH(controller, controller->data_dma_addr);
-       NFC_SEND_CMD_AIL(controller, controller->info_dma_addr);
-       NFC_SEND_CMD_AIH(controller, controller->info_dma_addr);
+       NFC_SEND_CMD_ADL(controller, aml_chip->data_dma_addr);
+       NFC_SEND_CMD_ADH(controller, aml_chip->data_dma_addr);
+       NFC_SEND_CMD_AIL(controller, aml_chip->info_dma_addr);
+       NFC_SEND_CMD_AIH(controller, aml_chip->info_dma_addr);
 #else
        flush_dcache_range((unsigned long)aml_chip->user_info_buf,
                (unsigned long)aml_chip->user_info_buf + count*PER_INFO_BYTE);
@@ -799,6 +799,36 @@ static int m3_nand_hwecc_correct(struct aml_nand_chip *aml_chip,
        return 0;
 }
 
+static int m3_nand_boot_erase_cmd(struct mtd_info *mtd, int page)
+{
+       struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
+       struct nand_chip *chip = mtd->priv;
+       loff_t ofs;
+       int i, page_addr;
+
+       if (page >= BOOT_PAGES_PER_COPY)
+               return -EPERM;
+
+       if (aml_chip->valid_chip[0]) {
+               for (i = 0; i < BOOT_COPY_NUM; i++) {
+                       page_addr = page + i*BOOT_PAGES_PER_COPY;
+                       ofs = (page_addr << chip->page_shift);
+
+                       if (chip->block_bad(mtd, ofs))
+                               continue;
+
+                       aml_chip->aml_nand_select_chip(aml_chip, 0);
+                       aml_chip->aml_nand_command(aml_chip,
+                               NAND_CMD_ERASE1, -1, page_addr, 0);
+                       aml_chip->aml_nand_command(aml_chip,
+                               NAND_CMD_ERASE2, -1, -1, 0);
+                       chip->waitfunc(mtd, chip);
+               }
+       }
+
+       return 0;
+}
+
 static int m3_nand_boot_read_page_hwecc(struct mtd_info *mtd,
        struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
 {
@@ -1371,7 +1401,8 @@ static int m3_nand_probe(struct aml_nand_platform *plat, unsigned int dev_num)
        }
        if (!strncmp((char *)plat->name,
                NAND_BOOT_NAME, strlen((const char *)NAND_BOOT_NAME))) {
-               /*chip->erase_cmd = m3_nand_boot_erase_cmd;*/
+               /* interface is chip->erase_cmd on 3.14*/
+               chip->erase = m3_nand_boot_erase_cmd;
                chip->ecc.read_page = m3_nand_boot_read_page_hwecc;
                chip->ecc.write_page = m3_nand_boot_write_page_hwecc;
                chip->write_page = m3_nand_boot_write_page;