Message ID | 000001c91e42$1aa86c50$3dd66c6b@sisodomain.com |
---|---|
State | Superseded |
Headers | show |
Hi, A few comments > > Signed-off-by: Vishak G <vishak.g@samsung.com> > Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com> Acked-by: Kyungmin Park <kyungmin.park@samsung.com> > --- > diff -uprN a/drivers/mtd/onenand/onenand_base.c > b/drivers/mtd/onenand/onenand_base.c > --- a/drivers/mtd/onenand/onenand_base.c 2008-09-16 > 20:48:12.000000000 +0530 > +++ b/drivers/mtd/onenand/onenand_base.c 2008-09-24 > 17:51:34.000000000 +0530 > @@ -9,6 +9,10 @@ > * auto-placement support, read-while load support, various fixes > * Copyright (C) Nokia Corporation, 2007 > * > + * Vishak G <vishak.g@samsung.com>, Rohit Hagargundgi > <h.rohit@samsung.com> > + * Flex-OneNAND support > + * Copyright (C) Samsung Electronics, 2008 > + * > * This program is free software; you can redistribute it and/or modify > * it under the terms of the GNU General Public License version 2 as > * published by the Free Software Foundation. > @@ -27,6 +31,37 @@ > > #include <asm/io.h> > > +const static int boundary[] = { > + FLEXONENAND_DIE0_BOUNDARY, > + FLEXONENAND_DIE1_BOUNDARY, > +}; > + > +const static int lock[] = { > + FLEXONENAND_DIE0_ISLOCKED, > + FLEXONENAND_DIE1_ISLOCKED, > +}; > + static const as others. > diff -uprN a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h > --- a/include/mtd/mtd-abi.h 2008-09-16 20:48:12.000000000 +0530 > +++ b/include/mtd/mtd-abi.h 2008-09-24 14:09:06.000000000 +0530 > @@ -102,7 +102,11 @@ struct nand_oobinfo { > uint32_t useecc; > uint32_t eccbytes; > uint32_t oobfree[8][2]; > +#ifdef CONFIG_MTD_ONENAND > + uint32_t eccpos[128]; > +#else > uint32_t eccpos[32]; > +#endif > }; > > struct nand_oobfree { > @@ -117,7 +121,11 @@ struct nand_oobfree { > */ > struct nand_ecclayout { > uint32_t eccbytes; > +#ifdef CONFIG_MTD_ONENAND > + uint32_t eccpos[128]; > +#else > uint32_t eccpos[64]; > +#endif > uint32_t oobavail; > struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; > }; > > This patch is already included others. Please remove it at this patch. Thank you, Kyungmin Park -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
On Fri, 2008-09-26 at 09:31 +0900, Kyungmin Park wrote: > Hi, > > A few comments > > > > > Signed-off-by: Vishak G <vishak.g@samsung.com> > > Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com> > > Acked-by: Kyungmin Park <kyungmin.park@samsung.com> > > > --- > > diff -uprN a/drivers/mtd/onenand/onenand_base.c > > b/drivers/mtd/onenand/onenand_base.c > > --- a/drivers/mtd/onenand/onenand_base.c 2008-09-16 > > 20:48:12.000000000 +0530 > > +++ b/drivers/mtd/onenand/onenand_base.c 2008-09-24 > > 17:51:34.000000000 +0530 > > @@ -9,6 +9,10 @@ > > * auto-placement support, read-while load support, various fixes > > * Copyright (C) Nokia Corporation, 2007 > > * > > + * Vishak G <vishak.g@samsung.com>, Rohit Hagargundgi > > <h.rohit@samsung.com> > > + * Flex-OneNAND support > > + * Copyright (C) Samsung Electronics, 2008 > > + * > > * This program is free software; you can redistribute it and/or modify > > * it under the terms of the GNU General Public License version 2 as > > * published by the Free Software Foundation. > > @@ -27,6 +31,37 @@ > > > > #include <asm/io.h> > > > > +const static int boundary[] = { > > + FLEXONENAND_DIE0_BOUNDARY, > > + FLEXONENAND_DIE1_BOUNDARY, > > +}; > > + > > +const static int lock[] = { > > + FLEXONENAND_DIE0_ISLOCKED, > > + FLEXONENAND_DIE1_ISLOCKED, > > +}; > > + > > static const as others. > > > > diff -uprN a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h > > --- a/include/mtd/mtd-abi.h 2008-09-16 20:48:12.000000000 +0530 > > +++ b/include/mtd/mtd-abi.h 2008-09-24 14:09:06.000000000 +0530 > > @@ -102,7 +102,11 @@ struct nand_oobinfo { > > uint32_t useecc; > > uint32_t eccbytes; > > uint32_t oobfree[8][2]; > > +#ifdef CONFIG_MTD_ONENAND > > + uint32_t eccpos[128]; > > +#else > > uint32_t eccpos[32]; > > +#endif > > }; > > > > struct nand_oobfree { > > @@ -117,7 +121,11 @@ struct nand_oobfree { > > */ > > struct nand_ecclayout { > > uint32_t eccbytes; > > +#ifdef CONFIG_MTD_ONENAND > > + uint32_t eccpos[128]; > > +#else > > uint32_t eccpos[64]; > > +#endif > > uint32_t oobavail; > > struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; > > }; I do not think stuff like this is going to be accepted because you change ABI. You should instead introduce new ioctls or add sysfs support and expose this information via sysfs. This is much bigger work, but it is needed.
Hi >> >> >> > diff -uprN a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h >> > --- a/include/mtd/mtd-abi.h 2008-09-16 20:48:12.000000000 +0530 >> > +++ b/include/mtd/mtd-abi.h 2008-09-24 14:09:06.000000000 +0530 >> > @@ -102,7 +102,11 @@ struct nand_oobinfo { >> > uint32_t useecc; >> > uint32_t eccbytes; >> > uint32_t oobfree[8][2]; >> > +#ifdef CONFIG_MTD_ONENAND >> > + uint32_t eccpos[128]; >> > +#else >> > uint32_t eccpos[32]; >> > +#endif >> > }; >> > >> > struct nand_oobfree { >> > @@ -117,7 +121,11 @@ struct nand_oobfree { >> > */ >> > struct nand_ecclayout { >> > uint32_t eccbytes; >> > +#ifdef CONFIG_MTD_ONENAND >> > + uint32_t eccpos[128]; >> > +#else >> > uint32_t eccpos[64]; >> > +#endif >> > uint32_t oobavail; >> > struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; >> > }; > > I do not think stuff like this is going to be accepted because you > change ABI. You should instead introduce new ioctls or add sysfs > support and expose this information via sysfs. This is much bigger > work, but it is needed. > Thank you for your kind comments. Yes that's I concerned it breaks the other NAND ABI. Actually In OneNAND it doesn't use eccpos since OneNAND controller handle all ECC functions. we don't need to concern it. As pages are bigger, it requires more eccpos and other fields are similar. we need more flexible filed definitions. Well how do you think that at this time it only describes the 64 bytes only for temporarily and next time it adds remaining parts if it is really needed. Thank you, Kyungmin Park
On Fri, 2008-09-26 at 14:30 +0900, Kyungmin Park wrote: > Thank you for your kind comments. > > Yes that's I concerned it breaks the other NAND ABI. Actually In > OneNAND it doesn't use eccpos since OneNAND controller handle all ECC > functions. we don't need to concern it. Right. > As pages are bigger, it requires more eccpos and other fields are > similar. we need more flexible filed definitions. Right. > Well how do you think that at this time it only describes the 64 bytes > only for temporarily and next time it adds remaining parts if it is > really needed. Well, it is not very nice, but I guess it should be OK for this case, because people are not supposed to look at OOB of MLC OneNAND anyway. So I would go this way, although I'm not sure dwmw2 would agree on this.
Hi Artem we have following erro message if we maintain 64 bytes eccpos. /flash_eraseall -j /dev/mtd4 ./flash_eraseall: /dev/mtd4: unable to get NAND oobinfo ./nandwrite -j /dev/mtd2 /jffs2.img MEMSETOOBSEL: Inappropriate ioctl for device but i think as OneNAND has hw ecc controller so Jffs2 will not face any problem still i think mtd should consider for 128 bytes eccpos for 4K page size. Rgs Amit ----- Original Message ----- From: "Artem Bityutskiy" <dedekind@infradead.org> To: "Kyungmin Park" <kmpark@infradead.org> Cc: "apgmoorthy" <moorthy.apg@samsung.com>; <linux-mtd@lists.infradead.org>; "Kyungmin Park" <kyungmin.park@samsung.com>; "lkml" <linux-kernel@vger.kernel.org> Sent: Friday, September 26, 2008 10:21 AM Subject: Re: [ANNOUNCE] [PATCH] [MTD] Flex-OneNAND MTD Driver available. > > On Fri, 2008-09-26 at 09:31 +0900, Kyungmin Park wrote: >> Hi, >> >> A few comments >> >> > >> > Signed-off-by: Vishak G <vishak.g@samsung.com> >> > Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com> >> >> Acked-by: Kyungmin Park <kyungmin.park@samsung.com> >> >> > --- >> > diff -uprN a/drivers/mtd/onenand/onenand_base.c >> > b/drivers/mtd/onenand/onenand_base.c >> > --- a/drivers/mtd/onenand/onenand_base.c >> > 2008-09-16 >> > 20:48:12.000000000 +0530 >> > +++ b/drivers/mtd/onenand/onenand_base.c >> > 2008-09-24 >> > 17:51:34.000000000 +0530 >> > @@ -9,6 +9,10 @@ >> > * auto-placement support, read-while load support, >> > various fixes >> > * Copyright (C) Nokia Corporation, 2007 >> > * >> > + * Vishak G <vishak.g@samsung.com>, Rohit >> > Hagargundgi >> > <h.rohit@samsung.com> >> > + * Flex-OneNAND support >> > + * Copyright (C) Samsung Electronics, 2008 >> > + * >> > * This program is free software; you can redistribute >> > it and/or modify >> > * it under the terms of the GNU General Public License >> > version 2 as >> > * published by the Free Software Foundation. >> > @@ -27,6 +31,37 @@ >> > >> > #include <asm/io.h> >> > >> > +const static int boundary[] = { >> > + FLEXONENAND_DIE0_BOUNDARY, >> > + FLEXONENAND_DIE1_BOUNDARY, >> > +}; >> > + >> > +const static int lock[] = { >> > + FLEXONENAND_DIE0_ISLOCKED, >> > + FLEXONENAND_DIE1_ISLOCKED, >> > +}; >> > + >> >> static const as others. >> >> >> > diff -uprN a/include/mtd/mtd-abi.h >> > b/include/mtd/mtd-abi.h >> > --- a/include/mtd/mtd-abi.h 2008-09-16 >> > 20:48:12.000000000 +0530 >> > +++ b/include/mtd/mtd-abi.h 2008-09-24 >> > 14:09:06.000000000 +0530 >> > @@ -102,7 +102,11 @@ struct nand_oobinfo { >> > uint32_t useecc; >> > uint32_t eccbytes; >> > uint32_t oobfree[8][2]; >> > +#ifdef CONFIG_MTD_ONENAND >> > + uint32_t eccpos[128]; >> > +#else >> > uint32_t eccpos[32]; >> > +#endif >> > }; >> > >> > struct nand_oobfree { >> > @@ -117,7 +121,11 @@ struct nand_oobfree { >> > */ >> > struct nand_ecclayout { >> > uint32_t eccbytes; >> > +#ifdef CONFIG_MTD_ONENAND >> > + uint32_t eccpos[128]; >> > +#else >> > uint32_t eccpos[64]; >> > +#endif >> > uint32_t oobavail; >> > struct nand_oobfree >> > oobfree[MTD_MAX_OOBFREE_ENTRIES]; >> > }; > > I do not think stuff like this is going to be accepted > because you > change ABI. You should instead introduce new ioctls or add > sysfs > support and expose this information via sysfs. This is > much bigger > work, but it is needed. > > -- > Best regards, > Artem Bityutskiy (???????? ?????) > > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ >
On Fri, 2008-09-26 at 13:31 +0530, Amit Kumar Sharma wrote: > Hi Artem > > we have following erro message if we maintain 64 bytes > eccpos. > > /flash_eraseall -j /dev/mtd4 > ./flash_eraseall: /dev/mtd4: unable to get NAND oobinfo > > ./nandwrite -j /dev/mtd2 /jffs2.img > MEMSETOOBSEL: Inappropriate ioctl for device > > but i think as OneNAND has hw ecc controller so Jffs2 will > not face any problem > still i think mtd should consider for 128 bytes eccpos for > 4K page size. Well, anyway, in Linux ABI is a holy cow, you cannot change it. That is a tough rule. Old user-space binaries have to always works. Thus you may do one of: 1. Invent a new ioctl for 4KiB page NANDs 2. Add sysfs support 3. Just do not expose whole OOB as Kyungmin suggested But I think assume dwmw2 would need to comment on this and tell which approach would agree on.
Hi David, Please do comment on this patch. "Not to expose whole OOB" suggestion by Kyungmin should be fine , but looking for your suggestion. With Regards Gangheyamoorthy.A.P -----Original Message----- From: Artem Bityutskiy [mailto:dedekind@infradead.org] Sent: Friday, September 26, 2008 1:50 PM To: Amit Kumar Sharma Cc: Kyungmin Park; apgmoorthy; linux-mtd@lists.infradead.org; Kyungmin Park; lkml; David Woodhouse Subject: Re: [ANNOUNCE] [PATCH] [MTD] Flex-OneNAND MTD Driver available. On Fri, 2008-09-26 at 13:31 +0530, Amit Kumar Sharma wrote: > Hi Artem > > we have following erro message if we maintain 64 bytes > eccpos. > > /flash_eraseall -j /dev/mtd4 > ./flash_eraseall: /dev/mtd4: unable to get NAND oobinfo > > ./nandwrite -j /dev/mtd2 /jffs2.img > MEMSETOOBSEL: Inappropriate ioctl for device > > but i think as OneNAND has hw ecc controller so Jffs2 will > not face any problem > still i think mtd should consider for 128 bytes eccpos for > 4K page size. Well, anyway, in Linux ABI is a holy cow, you cannot change it. That is a tough rule. Old user-space binaries have to always works. Thus you may do one of: 1. Invent a new ioctl for 4KiB page NANDs 2. Add sysfs support 3. Just do not expose whole OOB as Kyungmin suggested But I think assume dwmw2 would need to comment on this and tell which approach would agree on.
On Mon, 2008-09-29 at 14:58 +0530, apgmoorthy wrote: > Please do comment on this patch. > > "Not to expose whole OOB" suggestion by Kyungmin should be fine , > but looking for your suggestion. I'm working on a revamp of the MTD core which would start exposing attributes by sysfs, which would mean a lot of the ioctl problems go away. I suspect it would be OK simply not to export the whole OOB, until that's done. I posted other code which can export things in sysfs already -- perhaps we don't need to wait until the core rewrite is done?
diff -uprN a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c --- a/drivers/mtd/onenand/onenand_bbt.c 2008-09-16 20:48:12.000000000 +0530 +++ b/drivers/mtd/onenand/onenand_bbt.c 2008-09-24 16:05:10.000000000 +0530 @@ -60,6 +60,7 @@ static int create_bbt(struct mtd_info *m struct bbm_info *bbm = this->bbm; int i, j, numblocks, len, scanlen; int startblock; + unsigned slc = 0; loff_t from; size_t readlen, ooblen; struct mtd_oob_ops ops; @@ -76,7 +77,7 @@ static int create_bbt(struct mtd_info *m /* Note that numblocks is 2 * (real numblocks) here; * see i += 2 below as it makses shifting and masking less painful */ - numblocks = mtd->size >> (bbm->bbt_erase_shift - 1); + numblocks = this->chipsize >> (bbm->bbt_erase_shift - 1); startblock = 0; from = 0; @@ -106,7 +107,13 @@ static int create_bbt(struct mtd_info *m } } i += 2; - from += (1 << bbm->bbt_erase_shift); + if (FLEXONENAND(this)) { + onenand_get_block(mtd, from, &slc); + from += (1 << bbm->bbt_erase_shift) >> 1; + if (!slc) + from += (1 << bbm->bbt_erase_shift) >> 1; + } else + from += (1 << bbm->bbt_erase_shift); } return 0; @@ -143,7 +150,7 @@ static int onenand_isbad_bbt(struct mtd_ uint8_t res; /* Get block number * 2 */ - block = (int) (offs >> (bbm->bbt_erase_shift - 1)); + block = (int) (onenand_get_block(mtd, offs, NULL) << 1); res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03; DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n", @@ -178,7 +185,7 @@ int onenand_scan_bbt(struct mtd_info *mt struct bbm_info *bbm = this->bbm; int len, ret = 0; - len = mtd->size >> (this->erase_shift + 2); + len = this->chipsize >> (this->erase_shift + 2); /* Allocate memory (2bit per block) and clear the memory bad block table */ bbm->bbt = kzalloc(len, GFP_KERNEL); if (!bbm->bbt) { diff -uprN a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c --- a/drivers/mtd/onenand/onenand_sim.c 2008-09-16 20:48:12.000000000 +0530 +++ b/drivers/mtd/onenand/onenand_sim.c 2008-09-24 14:09:06.000000000 +0530 @@ -6,6 +6,10 @@ * Copyright © 2005-2007 Samsung Electronics * Kyungmin Park <kyungmin.park@samsung.com> * + * Vishak G <vishak.g@samsung.com>, Rohit Hagargundgi <h.rohit@samsung.com> + * Flex-OneNAND simulator support + * Copyright (C) Samsung Electronics, 2008 + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -24,16 +28,38 @@ #ifndef CONFIG_ONENAND_SIM_MANUFACTURER #define CONFIG_ONENAND_SIM_MANUFACTURER 0xec #endif + #ifndef CONFIG_ONENAND_SIM_DEVICE_ID #define CONFIG_ONENAND_SIM_DEVICE_ID 0x04 #endif + +#define CONFIG_FLEXONENAND ((CONFIG_ONENAND_SIM_DEVICE_ID >> 9) & 1) + #ifndef CONFIG_ONENAND_SIM_VERSION_ID #define CONFIG_ONENAND_SIM_VERSION_ID 0x1e #endif +#ifndef CONFIG_ONENAND_SIM_TECHNOLOGY_ID +#define CONFIG_ONENAND_SIM_TECHNOLOGY_ID CONFIG_FLEXONENAND +#endif + +/* Initial boundary values for Flex-OneNAND Simulator */ +#ifndef CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY +#define CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY 0x01 +#endif + +#ifndef CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY +#define CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY 0x01 +#endif + static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER; static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID; static int version_id = CONFIG_ONENAND_SIM_VERSION_ID; +static int technology_id = CONFIG_ONENAND_SIM_TECHNOLOGY_ID; +static int boundary[] = { + CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY, + CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY, +}; struct onenand_flash { void __iomem *base; @@ -57,12 +83,18 @@ struct onenand_flash { (writew(v, this->base + ONENAND_REG_WP_STATUS)) /* It has all 0xff chars */ -#define MAX_ONENAND_PAGESIZE (2048 + 64) +#define MAX_ONENAND_PAGESIZE (4096 + 128) static unsigned char *ffchars; +#if CONFIG_FLEXONENAND +#define PARTITION_NAME "Flex-OneNAND simulator partition" +#else +#define PARTITION_NAME "OneNAND simulator partition" +#endif + static struct mtd_partition os_partitions[] = { { - .name = "OneNAND simulator partition", + .name = PARTITION_NAME, .offset = 0, .size = MTDPART_SIZ_FULL, }, @@ -104,6 +136,7 @@ static void onenand_lock_handle(struct o switch (cmd) { case ONENAND_CMD_UNLOCK: + case ONENAND_CMD_UNLOCK_ALL: if (block_lock_scheme) ONENAND_SET_WP_STATUS(ONENAND_WP_US, this); else @@ -228,10 +261,11 @@ static void onenand_data_handle(struct o { struct mtd_info *mtd = &info->mtd; struct onenand_flash *flash = this->priv; - int main_offset, spare_offset; + int main_offset, spare_offset, die = 0; void __iomem *src; void __iomem *dest; - unsigned int i; + unsigned int i, slc = 0; + static int pi_operation; if (dataram) { main_offset = mtd->writesize; @@ -241,10 +275,27 @@ static void onenand_data_handle(struct o spare_offset = 0; } + if (pi_operation) { + die = readw(this->base + ONENAND_REG_START_ADDRESS2); + die >>= ONENAND_DDP_SHIFT; + } + switch (cmd) { + case FLEXONENAND_CMD_PI_ACCESS: + pi_operation = 1; + break; + + case ONENAND_CMD_RESET: + pi_operation = 0; + break; + case ONENAND_CMD_READ: src = ONENAND_CORE(flash) + offset; dest = ONENAND_MAIN_AREA(this, main_offset); + if (pi_operation) { + writew(boundary[die], this->base + ONENAND_DATARAM); + break; + } memcpy(dest, src, mtd->writesize); /* Fall through */ @@ -257,6 +308,10 @@ static void onenand_data_handle(struct o case ONENAND_CMD_PROG: src = ONENAND_MAIN_AREA(this, main_offset); dest = ONENAND_CORE(flash) + offset; + if (pi_operation) { + boundary[die] = readw(this->base + ONENAND_DATARAM); + break; + } /* To handle partial write */ for (i = 0; i < (1 << mtd->subpage_sft); i++) { int off = i * this->subpagesize; @@ -284,9 +339,16 @@ static void onenand_data_handle(struct o break; case ONENAND_CMD_ERASE: + if (pi_operation) + break; + onenand_get_block(mtd, offset, &slc); + if (slc && (mtd->numeraseregions > 1)) + mtd->erasesize >>= 1; memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize); memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff, (mtd->erasesize >> 5)); + if (slc && (mtd->numeraseregions > 1)) + mtd->erasesize <<= 1; break; default: @@ -295,6 +357,29 @@ static void onenand_data_handle(struct o } /** + * flexonenand_get_addr - Return address of the block + * @block: Block number on Flex-OneNAND + * + */ +loff_t flexonenand_get_addr(struct onenand_chip *this, int block) +{ + loff_t ofs; + int die = 0, boundary; + + ofs = 0; + if (ONENAND_IS_DDP(this) && block >= this->density_mask) { + block -= this->density_mask; + die = 1; + ofs = this->diesize[0]; + } + boundary = this->boundary[die]; + ofs += block << (this->erase_shift - 1); + if (block > (boundary + 1)) + ofs += (block - boundary - 1) << (this->erase_shift - 1); + return ofs; +} + +/** * onenand_command_handle - Handle command * @this: OneNAND device structure * @cmd: The command to be sent @@ -338,8 +423,12 @@ static void onenand_command_handle(struc break; } - if (block != -1) - offset += block << this->erase_shift; + if (block != -1) { + if (FLEXONENAND(this)) + offset = flexonenand_get_addr(this, block); + else + offset += block << this->erase_shift; + } if (page != -1) offset += page << this->page_shift; @@ -390,6 +479,7 @@ static int __init flash_init(struct onen } density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT; + density &= ONENAND_DEVICE_DENSITY_MASK; size = ((16 << 20) << density); ONENAND_CORE(flash) = vmalloc(size + (size >> 5)); @@ -405,8 +495,9 @@ static int __init flash_init(struct onen writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID); writew(device_id, flash->base + ONENAND_REG_DEVICE_ID); writew(version_id, flash->base + ONENAND_REG_VERSION_ID); + writew(technology_id, flash->base + ONENAND_REG_TECHNOLOGY); - if (density < 2) + if (density < 2 && (!CONFIG_FLEXONENAND)) buffer_size = 0x0400; /* 1KiB page */ else buffer_size = 0x0800; /* 2KiB page */ diff -uprN a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h --- a/include/linux/mtd/onenand.h 2008-09-16 20:48:12.000000000 +0530 +++ b/include/linux/mtd/onenand.h 2008-09-24 14:09:06.000000000 +0530 @@ -17,8 +17,24 @@ #include <linux/mtd/onenand_regs.h> #include <linux/mtd/bbm.h> +#define MAX_DIES 2 #define MAX_BUFFERRAM 2 +/** + * FlexOneNAND device boundary setting + * Setting -1 will not change the boundary + */ +#define FLEXONENAND_DIE0_BOUNDARY -1 +#define FLEXONENAND_DIE1_BOUNDARY -1 + +/** + * Setting value 1 locks the boundary + * WARNING : Once locked, the boundary cannot be changed. + * Use with care. + */ +#define FLEXONENAND_DIE0_ISLOCKED 0 +#define FLEXONENAND_DIE1_ISLOCKED 0 + /* Scan and identify a OneNAND device */ extern int onenand_scan(struct mtd_info *mtd, int max_chips); /* Free resources held by the OneNAND device */ @@ -51,6 +67,11 @@ struct onenand_bufferram { /** * struct onenand_chip - OneNAND Private Flash Chip Data * @base: [BOARDSPECIFIC] address to access OneNAND + * @dies: [INTERN][FLEX-ONENAND] number of dies on chip + * @boundary: [INTERN][FLEX-ONENAND] Boundary of the dies + * @boundary_locked: [INTERN][FLEX-ONENAND] TRUE indicates die boundary + * is locked and cannot be changed + * @diesize: [INTERN][FLEX-ONENAND] Size of the dies * @chipsize: [INTERN] the size of one chip for multichip arrays * @device_id: [INTERN] device ID * @density_mask: chip density, used for DDP devices @@ -92,9 +113,14 @@ struct onenand_bufferram { */ struct onenand_chip { void __iomem *base; + unsigned dies; + unsigned boundary[MAX_DIES]; + unsigned int boundary_locked[MAX_DIES]; + unsigned int diesize[MAX_DIES]; unsigned int chipsize; unsigned int device_id; unsigned int version_id; + unsigned int technology; unsigned int density_mask; unsigned int options; @@ -145,6 +171,8 @@ struct onenand_chip { #define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0) #define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1) +#define FLEXONENAND(this) \ + (this->device_id & DEVICE_IS_FLEXONENAND) #define ONENAND_GET_SYS_CFG1(this) \ (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) #define ONENAND_SET_SYS_CFG1(v, this) \ @@ -153,6 +181,9 @@ struct onenand_chip { #define ONENAND_IS_DDP(this) \ (this->device_id & ONENAND_DEVICE_IS_DDP) +#define ONENAND_IS_MLC(this) \ + (this->technology & ONENAND_TECHNOLOGY_IS_MLC) + #ifdef CONFIG_MTD_ONENAND_2X_PROGRAM #define ONENAND_IS_2PLANE(this) \ (this->options & ONENAND_HAS_2PLANE) @@ -189,5 +220,7 @@ struct onenand_manufacturers { int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops); +unsigned onenand_get_block(struct mtd_info *mtd, loff_t addr, + unsigned *isblkslc); #endif /* __LINUX_MTD_ONENAND_H */ diff -uprN a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h --- a/include/linux/mtd/onenand_regs.h 2008-09-16 20:48:12.000000000 +0530 +++ b/include/linux/mtd/onenand_regs.h 2008-09-24 14:09:06.000000000 +0530 @@ -67,6 +67,9 @@ /* * Device ID Register F001h (R) */ +#define DEVICE_IS_FLEXONENAND (1 << 9) +#define FLEXONENAND_PI_MASK (0x3ff) +#define FLEXONENAND_PI_UNLOCK_SHIFT (14) #define ONENAND_DEVICE_DENSITY_MASK (0xf) #define ONENAND_DEVICE_DENSITY_SHIFT (4) #define ONENAND_DEVICE_IS_DDP (1 << 3) @@ -84,6 +87,11 @@ #define ONENAND_VERSION_PROCESS_SHIFT (8) /* + * Technology Register F006h (R) + */ +#define ONENAND_TECHNOLOGY_IS_MLC (1 << 0) + +/* * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W) */ #define ONENAND_DDP_SHIFT (15) @@ -93,7 +101,8 @@ /* * Start Address 8 F107h (R/W) */ -#define ONENAND_FPA_MASK (0x3f) +/* Note: It's actually 0x3f in case of SLC */ +#define ONENAND_FPA_MASK (0x7f) #define ONENAND_FPA_SHIFT (2) #define ONENAND_FSA_MASK (0x03) @@ -105,7 +114,8 @@ #define ONENAND_BSA_BOOTRAM (0 << 2) #define ONENAND_BSA_DATARAM0 (2 << 2) #define ONENAND_BSA_DATARAM1 (3 << 2) -#define ONENAND_BSC_MASK (0x03) +/* Note: It's actually 0x03 in case of SLC */ +#define ONENAND_BSC_MASK (0x07) /* * Command Register F220h (R/W) @@ -124,6 +134,9 @@ #define ONENAND_CMD_RESET (0xF0) #define ONENAND_CMD_OTP_ACCESS (0x65) #define ONENAND_CMD_READID (0x90) +#define FLEXONENAND_CMD_PI_UPDATE (0x05) +#define FLEXONENAND_CMD_PI_ACCESS (0x66) +#define FLEXONENAND_CMD_RECOVER_LSB (0x05) /* NOTE: Those are not *REAL* commands */ #define ONENAND_CMD_BUFFERRAM (0x1978) @@ -192,10 +205,12 @@ #define ONENAND_ECC_1BIT_ALL (0x5555) #define ONENAND_ECC_2BIT (1 << 1) #define ONENAND_ECC_2BIT_ALL (0xAAAA) +#define FLEXONENAND_UNCORRECTABLE_ERROR (0x1010) /* * One-Time Programmable (OTP) */ +#define FLEXONENAND_OTP_LOCK_OFFSET (2048) #define ONENAND_OTP_LOCK_OFFSET (14) #endif /* __ONENAND_REG_H */ diff -uprN a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h --- a/include/mtd/mtd-abi.h 2008-09-16 20:48:12.000000000 +0530 +++ b/include/mtd/mtd-abi.h 2008-09-24 14:09:06.000000000 +0530 @@ -102,7 +102,11 @@ struct nand_oobinfo { uint32_t useecc; uint32_t eccbytes; uint32_t oobfree[8][2]; +#ifdef CONFIG_MTD_ONENAND + uint32_t eccpos[128]; +#else uint32_t eccpos[32]; +#endif }; struct nand_oobfree { @@ -117,7 +121,11 @@ struct nand_oobfree { */ struct nand_ecclayout { uint32_t eccbytes; +#ifdef CONFIG_MTD_ONENAND + uint32_t eccpos[128]; +#else uint32_t eccpos[64]; +#endif uint32_t oobavail; struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; };