@@ -1415,8 +1415,9 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
sector number * sector size + offset in
sector
*/
- int offset = err_sector * ECC_SECTOR_SIZE +
- err_byte;
+ int offset = (err_sector * ECC_SECTOR_SIZE +
+ err_byte) * denali->devnum +
+ err_device;
if (offset < denali->mtd.writesize) {
/* correct the ECC error */
buf[offset] ^= err_correction_value;
@@ -2032,6 +2033,27 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto failed_nand;
}
+ /* support for multi nand
+ * MTD known nothing about multi nand,
+ * so we should tell it the real pagesize
+ * and anything necessery,
+ * Some NAND chip has a spectial OOB size, so here do
+ * a recheck */
+ denali->mtd.oobsize = ioread32(denali->flash_reg +
+ DEVICE_SPARE_AREA_SIZE);
+ denali->devnum = ioread32(denali->flash_reg + DEVICES_CONNECTED);
+ denali->nand.chipsize <<= (denali->devnum - 1);
+ denali->nand.page_shift += (denali->devnum - 1);
+ denali->nand.pagemask = (denali->nand.chipsize >>
+ denali->nand.page_shift) - 1;
+ denali->nand.bbt_erase_shift += (denali->devnum - 1);
+ denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift;
+ denali->nand.chip_shift += (denali->devnum - 1);
+ denali->mtd.writesize <<= (denali->devnum - 1);
+ denali->mtd.oobsize <<= (denali->devnum - 1);
+ denali->mtd.erasesize <<= (denali->devnum - 1);
+ denali->mtd.size = denali->nand.numchips * denali->nand.chipsize;
+
/* second stage of the NAND scan
* this stage requires information regarding ECC and
* bad block management. */
@@ -2060,7 +2082,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
denali->nand.ecc.hwctl = denali_ecc_hwctl;
/* override the default read operations */
- denali->nand.ecc.size = denali->mtd.writesize;
+ denali->nand.ecc.size = denali->mtd.writesize * denali->devnum;
denali->nand.ecc.read_page = denali_read_page;
denali->nand.ecc.read_page_raw = denali_read_page_raw;
denali->nand.ecc.write_page = denali_write_page;
@@ -802,6 +802,8 @@ struct denali_nand_info {
uint32_t irq_status;
int irq_debug_array[32];
int idx;
+
+ uint32_t devnum; /* represent how many nands connected */
};
#endif /*_LLD_NAND_*/