From e84d781b457904ec6eba5d4bc9cdb6a8a471d42e Mon Sep 17 00:00:00 2001 From: Yonghui Yu Date: Mon, 17 Apr 2017 15:34:50 +0800 Subject: [PATCH] nand: fix mtd0 erase operation PD#138714: add erase interface for mtd0(bootloader) Change-Id: I5d6de9013d9f2c83a218d29e390df58430eeea58 Signed-off-by: Yonghui Yu --- drivers/amlogic/mtd/aml_mtd.h | 6 +++++- drivers/amlogic/mtd/aml_nand.c | 8 +++---- drivers/amlogic/mtd/m3_nand.c | 49 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/drivers/amlogic/mtd/aml_mtd.h b/drivers/amlogic/mtd/aml_mtd.h index 4808dc1..7d9a333 100644 --- a/drivers/amlogic/mtd/aml_mtd.h +++ b/drivers/amlogic/mtd/aml_mtd.h @@ -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; diff --git a/drivers/amlogic/mtd/aml_nand.c b/drivers/amlogic/mtd/aml_nand.c index 916ba47..9085554 100644 --- a/drivers/amlogic/mtd/aml_nand.c +++ b/drivers/amlogic/mtd/aml_nand.c @@ -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 diff --git a/drivers/amlogic/mtd/m3_nand.c b/drivers/amlogic/mtd/m3_nand.c index 6d6fc37..fd5fcf7 100644 --- a/drivers/amlogic/mtd/m3_nand.c +++ b/drivers/amlogic/mtd/m3_nand.c @@ -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; -- 2.7.4