mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user