mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
nand: fix nand bugs [1/1]
PD#SWPL-120491 PD#SWPL-129754 PD#SWPL-155674 PD#SWPL-183416 Problem: 1.wrong select onfi mode 2.erase flash error during OTA upgrade 3.strncmp can't match full id 01h,DCh,00h,05h,04h(S34ML04G300BHI00) and 01h,DCh,00h,1Ah,00h(S34ML04G300TFI000) 4.mtd_device_parse_register panic when parse_mtd_partitions return -EPROBE_DEFER Solution: 1.get onfi mode from id table 2.change the check way of badblock 3.use memcmp to compare ID memory instead strncmp 4.nvmem_unregister otp_user_nvmem/otp_factory_nvmem if them existing Verify: 1-2:s4 3:AT301_T962D4-K35E(1.5G) #256 4:BR309-T950D5_SOCKET #48 Change-Id: Ie747ceb95f1045c2acaaf2afb6862c9b05d36d8b Signed-off-by: Bichao Zheng <bichao.zheng@amlogic.com> Signed-off-by: zhikui.cui <zhikui.cui@amlogic.com>
This commit is contained in:
committed by
Dongjin Kim
parent
146c08e2ed
commit
e4fe4d2af5
@@ -1008,8 +1008,15 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
|
||||
|
||||
out:
|
||||
if (ret) {
|
||||
#if (IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND) || IS_ENABLED(CONFIG_AMLOGIC_MTD_SPI_NAND))
|
||||
if (mtd->otp_user_nvmem)
|
||||
nvmem_unregister(mtd->otp_user_nvmem);
|
||||
if (mtd->otp_factory_nvmem)
|
||||
nvmem_unregister(mtd->otp_factory_nvmem);
|
||||
#else
|
||||
nvmem_unregister(mtd->otp_user_nvmem);
|
||||
nvmem_unregister(mtd->otp_factory_nvmem);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret && device_is_registered(&mtd->dev))
|
||||
|
||||
@@ -963,6 +963,10 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND)
|
||||
EXPORT_SYMBOL_GPL(nand_choose_best_sdr_timings);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* nand_choose_best_nvddr_timings - Pick up the best NVDDR timings that both the
|
||||
* NAND controller and the NAND chip support
|
||||
@@ -4891,7 +4895,12 @@ static bool find_full_id_nand(struct nand_chip *chip,
|
||||
|
||||
memorg = nanddev_get_memorg(&chip->base);
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND)
|
||||
if (!memcmp(type->id, id_data, type->id_len)) {
|
||||
#else
|
||||
if (!strncmp(type->id, id_data, type->id_len)) {
|
||||
#endif
|
||||
|
||||
memorg->pagesize = type->pagesize;
|
||||
mtd->writesize = memorg->pagesize;
|
||||
memorg->pages_per_eraseblock = type->erasesize /
|
||||
@@ -5151,7 +5160,9 @@ ident_done:
|
||||
chip->options |= NAND_ROW_ADDR_3;
|
||||
|
||||
chip->badblockbits = 8;
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND)
|
||||
chip->type = type;
|
||||
#endif
|
||||
nand_legacy_adjust_cmdfunc(chip);
|
||||
|
||||
pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
|
||||
|
||||
@@ -75,9 +75,16 @@
|
||||
|
||||
static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block)
|
||||
{
|
||||
#if !IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND)
|
||||
uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT];
|
||||
entry >>= (block & BBT_ENTRY_MASK) * 2;
|
||||
return entry & BBT_ENTRY_MASK;
|
||||
#else
|
||||
if (chip->bbt)
|
||||
return chip->bbt[block];
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void bbt_mark_entry(struct nand_chip *chip, int block,
|
||||
@@ -1454,7 +1461,7 @@ int nand_isbad_bbt(struct nand_chip *this, loff_t offs, int allowbbt)
|
||||
|
||||
pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
|
||||
(unsigned int)offs, block, res);
|
||||
|
||||
#if !IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND)
|
||||
switch (res) {
|
||||
case BBT_BLOCK_GOOD:
|
||||
return 0;
|
||||
@@ -1464,6 +1471,9 @@ int nand_isbad_bbt(struct nand_chip *this, loff_t offs, int allowbbt)
|
||||
return allowbbt ? 0 : 1;
|
||||
}
|
||||
return 1;
|
||||
#else
|
||||
return res ? 1 : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -735,3 +735,7 @@ void onfi_fill_interface_config(struct nand_chip *chip,
|
||||
else
|
||||
return onfi_fill_nvddr_interface_config(chip, iface, timing_mode);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND)
|
||||
EXPORT_SYMBOL_GPL(onfi_fill_interface_config);
|
||||
#endif
|
||||
|
||||
@@ -1304,6 +1304,9 @@ struct nand_chip {
|
||||
/* Externals */
|
||||
struct nand_controller *controller;
|
||||
struct nand_ecc_ctrl ecc;
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND)
|
||||
struct nand_flash_dev *type;
|
||||
#endif
|
||||
void *priv;
|
||||
};
|
||||
|
||||
@@ -1432,6 +1435,9 @@ struct nand_flash_dev {
|
||||
uint16_t strength_ds;
|
||||
uint16_t step_ds;
|
||||
} ecc;
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND)
|
||||
int onfi_timing_mode_default;
|
||||
#endif
|
||||
};
|
||||
|
||||
int nand_create_bbt(struct nand_chip *chip);
|
||||
@@ -1548,6 +1554,17 @@ int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf,
|
||||
int nand_scan_with_ids(struct nand_chip *chip, unsigned int max_chips,
|
||||
struct nand_flash_dev *ids);
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_MTD_NAND)
|
||||
void onfi_fill_interface_config(struct nand_chip *chip,
|
||||
struct nand_interface_config *iface,
|
||||
enum nand_interface_type type,
|
||||
unsigned int timing_mode);
|
||||
|
||||
int nand_choose_best_sdr_timings(struct nand_chip *chip,
|
||||
struct nand_interface_config *iface,
|
||||
struct nand_sdr_timings *spec_timings);
|
||||
#endif
|
||||
|
||||
static inline int nand_scan(struct nand_chip *chip, unsigned int max_chips)
|
||||
{
|
||||
return nand_scan_with_ids(chip, max_chips, NULL);
|
||||
|
||||
Reference in New Issue
Block a user