nand: fix mtd0 erase operation

PD#138714: add erase interface for mtd0(bootloader)

Change-Id: I5d6de9013d9f2c83a218d29e390df58430eeea58
Signed-off-by: Yonghui Yu <yonghui.yu@amlogic.com>
This commit is contained in:
Yonghui Yu
2017-04-17 15:34:50 +08:00
committed by Jianxin Pan
parent 9a2e9f09c0
commit e84d781b45
3 changed files with 49 additions and 14 deletions

View 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;

View 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

View 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;