X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=drivers%2Fmtd%2Fnand%2Fnand_base.c;h=d98e146d6f7111c3c150a364d0731ba2a6957480;hp=de2c713bf15406aa50dc0fa892d0f078c87cb2fb;hb=1e362dc3e799fd86722a60f5639e52a67dfc0658;hpb=c6c2a8263fc92e049a7fa90796baad34d4f273d3 diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index de2c713bf1..d98e146d6f 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1245,7 +1245,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, if (unlikely(ops->mode == MTD_OOB_RAW)) ret = chip->ecc.read_page_raw(mtd, chip, bufpoi, page); - else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob) + else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) && + !oob) ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi); else @@ -1256,7 +1257,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, /* Transfer not aligned data */ if (!aligned) { - if (!NAND_SUBPAGE_READ(chip) && !oob && + if (!NAND_HAS_SUBPAGE_READ(chip) && !oob && !(mtd->ecc_stats.failed - stats.failed)) chip->pagebuf = realpage; memcpy(buf, chip->buffers->databuf + col, bytes); @@ -2528,13 +2529,14 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') return 0; - printk(KERN_INFO "ONFI flash detected\n"); + MTDDEBUG(MTD_DEBUG_LEVEL0, "ONFI flash detected\n"); chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); for (i = 0; i < 3; i++) { chip->read_buf(mtd, (uint8_t *)p, sizeof(*p)); if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) == le16_to_cpu(p->crc)) { - printk(KERN_INFO "ONFI param page %d valid\n", i); + MTDDEBUG(MTD_DEBUG_LEVEL0, + "ONFI param page %d valid\n", i); break; } } @@ -2570,14 +2572,13 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, mtd->writesize = le32_to_cpu(p->byte_per_page); mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); - chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; + chip->chipsize = le32_to_cpu(p->blocks_per_lun); + chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; *busw = 0; if (le16_to_cpu(p->features) & 1) *busw = NAND_BUSWIDTH_16; - chip->options &= ~NAND_CHIPOPTIONS_MSK; - chip->options |= (NAND_NO_READRDY | - NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK; + chip->options |= NAND_NO_READRDY | NAND_NO_AUTOINCR; return 1; } @@ -2599,6 +2600,7 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, int *maf_id, int *dev_id, const struct nand_flash_dev *type) { + const char *name; int i, maf_idx; u8 id_data[8]; int ret; @@ -2749,8 +2751,7 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, } } /* Get chip options, preserve non chip based options */ - chip->options &= ~NAND_CHIPOPTIONS_MSK; - chip->options |= type->options & NAND_CHIPOPTIONS_MSK; + chip->options |= type->options; /* Check if chip is a not a samsung device. Do not clear the * options for chips which are not having an extended id. @@ -2847,14 +2848,14 @@ ident_done: chip->cmdfunc = nand_command_lp; /* TODO onfi flash name */ - MTDDEBUG (MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:" - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id, - nand_manuf_ids[maf_idx].name, + name = type->name; #ifdef CONFIG_SYS_NAND_ONFI_DETECTION - chip->onfi_version ? chip->onfi_params.model : type->name); -#else - type->name); + if (chip->onfi_version) + name = chip->onfi_params.model; #endif + MTDDEBUG(MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:" + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id, + nand_manuf_ids[maf_idx].name, name); return type; } @@ -2929,20 +2930,18 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, */ int nand_scan_tail(struct mtd_info *mtd) { - uint32_t dev_width; int i; struct nand_chip *chip = mtd->priv; if (!(chip->options & NAND_OWN_BUFFERS)) - chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL); + chip->buffers = memalign(ARCH_DMA_MINALIGN, + sizeof(*chip->buffers)); if (!chip->buffers) return -ENOMEM; /* Set the internal oob buffer location, just after the page data */ chip->oob_poi = chip->buffers->databuf + mtd->writesize; - dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1; - /* * If no default placement scheme is given, select an appropriate one */ @@ -3118,6 +3117,8 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.steps = mtd->writesize / chip->ecc.size; if (chip->ecc.steps * chip->ecc.size != mtd->writesize) { printk(KERN_WARNING "Invalid ecc parameters\n"); + printk(KERN_WARNING "steps=%d size=%d writesize=%d\n", + chip->ecc.steps, chip->ecc.size, mtd->writesize); BUG(); } chip->ecc.total = chip->ecc.steps * chip->ecc.bytes; @@ -3150,6 +3151,10 @@ int nand_scan_tail(struct mtd_info *mtd) /* Invalidate the pagebuffer reference */ chip->pagebuf = -1; + /* Large page NAND with SOFT_ECC should support subpage reads */ + if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9)) + chip->options |= NAND_SUBPAGE_READ; + /* Fill in remaining MTD driver data */ mtd->type = MTD_NANDFLASH; mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :