mtdparts fails with NAND >= 4GB
Hi all,
It looks like the mtd partitioning code fails if the flash size exceeds a u32. I am working with an 8GB flash chip on our board and was wondering if anyone else has any experience with MTD with a chip this large?
-Aaron
Quoted 5 lines · On Thu, 27 Jan 2011 16:24:31 -0800 Aaron Williams…
Hi all,
It looks like the mtd partitioning code fails if the flash size exceeds a u32. I am working with an 8GB flash chip on our board and was wondering if anyone else has any experience with MTD with a chip this large?
There's been some effort to make the U-Boot NAND code work with large devices, but it's not complete. Patches to take care of the rest of the problem spots are welcome, especially if you have hardware to test.
-Scott
I'll probably have something later today. I got it working with an earlier version of u-boot though it hasn't been thoroughly tested.
-Aaron
Quoted 15 lines · Scott Wood
On Thu, 27 Jan 2011 16:24:31 -0800
Quoted 5 lines · Aaron Williams
Hi all,
It looks like the mtd partitioning code fails if the flash size exceeds a u32. I am working with an 8GB flash chip on our board and was wondering if anyone else has any experience with MTD with a chip this large?
There's been some effort to make the U-Boot NAND code work with large devices, but it's not complete. Patches to take care of the rest of the problem spots are welcome, especially if you have hardware to test.
-Scott
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB
I have included my preliminary patch which seems to be working. It has not been extensively tested yet. All of the changes were basically making the sizes and offsets u64 instead of u32. When looking at the Linux kernel code it looks like they also use u64. I was mistaken and our NAND flash chip is 4GiB in size so I can't test with any larger chips.
-Aaron
common/cmd_mtdparts.c +31 -25
@@ -21,6 +21,11 @@* $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $ * Copyright 2002 SYSGO Real-Time Solutions GmbH * +* (C) Copyright 2011 +* Aaron Williams, Cavium Networks, Inc. <[email protected]> +* +* Added support for partitions and flash greater than or equal to 4GiB. +* * See file CREDITS for list of people who contributed to this * project. *
@@ -174,7 +179,7 @@ static int device_del(struct mtd_device *dev);* @param retptr output pointer to next char after parse completes (output) * @return resulting unsigned int */ -static unsigned long memsize_parse (const char *const ptr,const char **retptr) +static u64 memsize_parse (const char *const ptr,const char **retptr) {unsigned long ret =simple_strtoul (ptr, (char **)retptr,0 );
@@ -207,20 +212,20 @@ static unsigned long memsize_parse (const char *const ptr, const char **retptr)* @param buf output buffer * @param size size to be converted to string */ -static void memsize_format (char *buf,u32 size) +static void memsize_format (char *buf,u64 size) {#define SIZE_GB ((u32)1024*1024*1024)#define SIZE_MB ((u32)1024*1024)#define SIZE_KB ((u32)1024)if ((size %SIZE_GB ) ==0 ) -sprintf (buf,"%ug" , size/SIZE_GB ); +sprintf (buf,"%llug" , size/SIZE_GB );else if ((size %SIZE_MB ) ==0 ) -sprintf (buf,"%um" , size/SIZE_MB ); +sprintf (buf,"%llum" , size/SIZE_MB );else if (size %SIZE_KB ==0 ) -sprintf (buf,"%uk" , size/SIZE_KB ); +sprintf (buf,"%lluk" , size/SIZE_KB );else -sprintf (buf,"%u" , size); +sprintf (buf,"%llu" , size); }/**
@@ -325,7 +330,7 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part) {struct mtd_info *mtd =NULL ;int i, j; -ulong start; +u64 start;if (get_mtd_info (id->type, id->num, &mtd))return 1 ;
@@ -337,7 +342,7 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)* Only one eraseregion (NAND, OneNAND or uniform NOR), * checking for alignment is easy here */ -if ((unsigned long )part->offset % mtd->erasesize) { +if ((u64 )part->offset % mtd->erasesize) {printf ("%s%d: partition (%s) start offset" "alignment incorrect\n" ,MTD_DEV_TYPE (id->type), id->num, part->name);
@@ -412,7 +417,7 @@ static int part_validate(struct mtdids *id, struct part_info *part) part->size = id->size - part->offset;if (part->offset > id->size) { -printf ("%s: offset %08x beyond flash size %08x\n" , +printf ("%s: offset %08llx beyond flash size %08llx\n" , id->mtd_id, part->offset, id->size);return 1 ; }
@@ -595,8 +600,8 @@ static int part_add(struct mtd_device *dev, struct part_info *part)static int part_parse (const char *const partdef,const char **ret,struct part_info **retpart) {struct part_info *part; -unsigned long size; -unsigned long offset; +u64 size; +u64 offset;const char *name;int name_len;unsigned int mask_flags;
@@ -615,7 +620,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i }else { size =memsize_parse (p, &p);if (size <MIN_PART_SIZE ) { -printf ("partition size too small (%lx)\n" , size); +printf ("partition size too small (%llx)\n" , size);return 1 ; } }
@@ -687,14 +692,14 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i part->auto_name =0 ; }else {/* auto generated name in form of size at offset */ -sprintf (part->name,"0x%08lx at 0x%08lx" , size, offset); +sprintf (part->name,"0x%08llx at 0x%08llx" , size, offset); part->auto_name =1 ; } part->name[name_len -1 ] ='\0' ;INIT_LIST_HEAD (&part->link); -debug ("+ partition: name %-22s size 0x%08x offset 0x%08x mask flags %d\n" , +debug ("+ partition: name %-22s size 0x%08llx offset 0x%08llx mask flags %d\n" , part->name, part->size, part->offset, part->mask_flags);
@@ -710,7 +715,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i* @param size a pointer to the size of the mtd device (output) * @return 0 if device is valid, 1 otherwise */ -int mtd_device_validate (u8 type,u8 num,u32 *size) +int mtd_device_validate (u8 type,u8 num,u64 *size) {struct mtd_info *mtd =NULL ;
@@ -842,7 +847,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_LIST_HEAD (tmp_list);struct list_head *entry, *n;u16 num_parts; -u32 offset; +u64 offset;int err =1 ;debug ("===device_parse===\n" );
@@ -1077,15 +1082,16 @@ int mtd_id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num)* @param buflen buffer size * @return 0 on success, 1 otherwise */ -static int generate_mtdparts (char *buf,u32 buflen) +static int generate_mtdparts (char *buf,size_t buflen) {struct list_head *pentry, *dentry;struct mtd_device *dev;struct part_info *part, *prev_part;char *p = buf;char tmpbuf[32 ]; -u32 size, offset, len, part_cnt; -u32 maxlen = buflen -1 ; +u64 size, offset, len; +u32 part_cnt; +size_t maxlen = buflen -1 ;debug ("--- generate_mtdparts ---\n" );
@@ -1204,7 +1210,7 @@ cleanup:* @param buflen buffer size * @return 0 on success, 1 otherwise */ -static int generate_mtdparts_save (char *buf,u32 buflen) +static int generate_mtdparts_save (char *buf,size_t buflen) {int ret;
@@ -1265,13 +1271,13 @@ static void print_partition_table(void)printf (" #: name\t\tsize\t\tnet size\toffset\t\tmask_flags\n" );list_for_each (pentry, &dev->parts) { -u32 net_size; +u64 net_size;char *size_note; part = list_entry(pentry, struct part_info, link); net_size =net_part_size (mtd, part); size_note = part->size == net_size ?" " :" (!)" ; -printf ("%2d: %-20s0x%08x\t0x%08x%s\t0x%08x\t%d\n" , +printf ("%2d: %-20s0x%08llx\t0x%08llx%s\t0x%08llx\t%d\n" , part_num, part->name, part->size, net_size, size_note, part->offset, part->mask_flags);
@@ -1283,7 +1289,7 @@ static void print_partition_table(void)list_for_each (pentry, &dev->parts) { part = list_entry(pentry, struct part_info, link); -printf ("%2d: %-20s0x%08x\t0x%08x\t%d\n" , +printf ("%2d: %-20s0x%08llx\t0x%08llx\t%d\n" , part_num, part->name, part->size, part->offset, part->mask_flags);#endif /* defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) */
@@ -1310,7 +1316,7 @@ static void list_partitions(void)if (current_mtd_dev) { part =mtd_part_info (current_mtd_dev, current_mtd_partnum);if (part) { -printf ("\nactive partition: %s%d,%d - (%s) 0x%08x @ 0x%08x\n" , +printf ("\nactive partition: %s%d,%d - (%s) 0x%08llx @ 0x%08llx\n" ,MTD_DEV_TYPE (current_mtd_dev->id->type), current_mtd_dev->id->num, current_mtd_partnum, part->name, part->size, part->offset);
@@ -1410,7 +1416,7 @@ static int delete_partition(const char *id)if (find_dev_and_part (id, &dev, &pnum, &part) ==0 ) { -debug ("delete_partition: device = %s%d, partition %d = (%s) 0x%08x at 0x%08x\n" , +debug ("delete_partition: device = %s%d, partition %d = (%s) 0x%08llx at 0x%08llx\n" ,MTD_DEV_TYPE (dev->id->type), dev->id->num, pnum, part->name, part->size, part->offset);
@@ -1499,7 +1505,7 @@ static int spread_partitions(void)
part = list_entry(pentry, struct part_info, link);
debug("spread_partitions: device = %s%d, partition %d ="
- " (%s) 0x%08x at 0x%08x\n",
+ " (%s) 0x%08llx at 0x%08llx\n",
MTD_DEV_TYPE(dev->id->type), dev->id->num,
part_num, part->name, part->size,
part->offset);
@@ -1596,7 +1602,7 @@ static int parse_mtdids(const char *const ids)
struct list_head *entry, *n;
struct mtdids *id_tmp;
u8 type, num;
- u32 size;
+ u64 size;
int ret = 1;
debug("\n---parse_mtdids---\nmtdids = %s\n\n", ids);
@@ -1670,7 +1676,7 @@ static int parse_mtdids(const char *const ids)
id->mtd_id[mtd_id_len - 1] = '\0';
INIT_LIST_HEAD(&id->link);- debug("+ id %s%d\t%16d bytes\t%s\n",
+ debug("+ id %s%d\t%16llu bytes\t%s\n",
MTD_DEV_TYPE(id->type), id->num,
id->size, id->mtd_id);@@ -1999,7 +2005,7 @@ int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (!strcmp(&argv[1][3], ".spread")) {
spread_partition(mtd, p, &next_offset);
- debug("increased %s to %d bytes\n", p->name, p->size);
+ debug("increased %s to %llu bytes\n", p->name, p->size);
}#endif
include/jffs2/load_kernel.h +3 -3
@@ -46,8 +46,8 @@ struct part_info {struct list_head link;char *name;/* partition name */ u8 auto_name;/* set to 1 for generated name */ -u32 size;/* total size of the partition */ -u32 offset;/* offset within device */ +u64 size;/* total size of the partition */ +u64 offset;/* offset within device */ void *jffs2_priv;/* used internaly by jffs2 */ u32 mask_flags;/* kernel MTD mask flags */ u32 sector_size;/* size of sector */
@@ -58,7 +58,7 @@ struct mtdids {struct list_head link;u8 type;/* device type */ u8 num;/* device number */ -u32 size;/* device size */ +u64 size;/* device size */ char *mtd_id;/* linux kernel device id */ };
Quoted 27 lines · Aaron Williams
I'll probably have something later today. I got it working with an earlier version of u-boot though it hasn't been thoroughly tested.
-Aaron
Quoted 10 lines · Scott Wood
On Thu, 27 Jan 2011 16:24:31 -0800
Quoted 6 lines · Aaron Williams
Hi all,
It looks like the mtd partitioning code fails if the flash size exceeds a u32. I am working with an 8GB flash chip on our board and was wondering if anyone else has any experience with MTD with a chip this large?
Quoted 6 lines
There's been some effort to make the U-Boot NAND code work with large devices, but it's not complete. Patches to take care of the rest of the problem spots are welcome, especially if you have hardware to test.
-Scott
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB
This patch seems to be working fine in my setup. Any comments?
-Aaron
Quoted 309 lines · Aaron Williams
I have included my preliminary patch which seems to be working. It has not been extensively tested yet. All of the changes were basically making the sizes and offsets u64 instead of u32. When looking at the Linux kernel code it looks like they also use u64. I was mistaken and our NAND flash chip is 4GiB in size so I can't test with any larger chips.
(quoted diff) +0
-1-Aaroncommon/cmd_mtdparts.c +2
-0@@ -21,6 +21,11 @@* $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $ * Copyright 2002 SYSGO Real-Time Solutions GmbH * +* (C) Copyright 2011 +* Aaron Williams, Cavium Networks, Inc. <[email protected]> + *
+ * Added support for partitions and flash greater than or equal to 4GiB.
+ *
* See file CREDITS for list of people who contributed to this
* project.
*common/cmd_mtdparts.c +0
-0@@ -174,7 +179,7 @@ static int device_del(struct mtd_device *dev);* @param retptr output pointer to next char after parse completes (output) * @return resulting unsigned int
*/
-static unsigned longmemsize_parse(const char *const ptr, const char **retptr) +static u64memsize_parse(const char *const ptr, const char**retptr) { unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);common/cmd_mtdparts.c +0
-0@@ -207,20 +212,20 @@ static unsigned long memsize_parse (const char *constptr, const char **retptr) * @param buf output buffer
* @param size size to be converted to string */common/cmd_mtdparts.c +6
-6-static void memsize_format (char *buf,u32 size) +static void memsize_format (char *buf,u64 size) {#define SIZE_GB ((u32)1024*1024*1024)#define SIZE_MB ((u32)1024*1024)#define SIZE_KB ((u32)1024)if ((size %SIZE_GB ) ==0 ) -sprintf (buf,"%ug" , size/SIZE_GB ); +sprintf (buf,"%llug" , size/SIZE_GB );else if ((size %SIZE_MB ) ==0 ) -sprintf (buf,"%um" , size/SIZE_MB ); +sprintf (buf,"%llum" , size/SIZE_MB );else if (size %SIZE_KB ==0 ) -sprintf (buf,"%uk" , size/SIZE_KB ); +sprintf (buf,"%lluk" , size/SIZE_KB );else -sprintf (buf,"%u" , size); +sprintf (buf,"%llu" , size); }/** @@ -325,7 +330,7 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part) {struct mtd_info *mtd =NULL ;int i, j; -ulong start; +u64 start;if (get_mtd_info (id->type, id->num, &mtd))return 1 ;@@ -337,7 +342,7 @@ static int part_validate_eraseblock(struct mtdids *id,struct
part_info*part) * Only one eraseregion (NAND, OneNAND or uniform NOR), * checking for alignment is easy here*/common/cmd_mtdparts.c +1
-1-if ((unsigned long )part->offset % mtd->erasesize) { +if ((u64 )part->offset % mtd->erasesize) { printf("%s%d: partition (%s) start offset" "alignment incorrect\n", MTD_DEV_TYPE(id->type), id->num,
part->name); @@ -412,7 +417,7 @@ static intpart_validate(struct mtdids *id, struct part_info *part)part->size=id->size-part->offset;if (part->offset > id->size) {common/cmd_mtdparts.c +1
-1-printf ("%s: offset %08x beyond flash size %08x\n" , +printf ("%s: offset %08llx beyond flash size %08llx\n" , id->mtd_id, part->offset, id->size);return 1 ; }@@ -595,8 +600,8 @@ static int part_add(struct mtd_device *dev, struct
part_info*part) static int part_parse(const char *const partdef, constchar **ret, struct part_info **retpart) { struct part_info *part;common/cmd_mtdparts.c +4
-5-unsigned long size; -unsigned long offset; +u64 size; +u64 offset;const char *name;int name_len;unsigned int mask_flags;@@ -615,7 +620,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i } else { size =memsize_parse (p, &p);if (size <MIN_PART_SIZE ) { -printf ("partition size too small (%lx)\n" , size); +printf ("partition size too small (%llx)\n" , size);return 1 ; } }@@ -687,14 +692,14 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i part->auto_name = 0; }else {/* auto generated name in form of size at offset */ -sprintf (part->name,"0x%08lx at 0x%08lx" , size, offset); +sprintf (part->name,"0x%08llx at 0x%08llx" , size, offset); part->auto_name =1 ; } part->name[name_len -1 ] ='\0' ;INIT_LIST_HEAD (&part->link); - debug("+ partition: name %-22s size 0x%08x offset 0x%08x mask flags%d\n", + debug("+ partition: name %-22s size 0x%08llx offset
0x%08llx mask flags %d\n",part->name,part->size,part->offset, part->mask_flags);common/cmd_mtdparts.c +0
-0@@ -710,7 +715,7 @@ static int part_parse(const char *const partdef, constchar **ret, struct
part_i* @param size a pointer to the size of the mtd device (output)
* @return 0 if device is valid, 1 otherwise
*/common/cmd_mtdparts.c +10
-10-int mtd_device_validate (u8 type,u8 num,u32 *size) +int mtd_device_validate (u8 type,u8 num,u64 *size) {struct mtd_info *mtd =NULL ;@@ -842,7 +847,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ LIST_HEAD(tmp_list);struct list_head *entry, *n;u16 num_parts; -u32 offset; +u64 offset;int err =1 ;debug ("===device_parse===\n" );@@ -1077,15 +1082,16 @@ int mtd_id_parse(const char *id, const char**ret_id, u8 *dev_type, u8 *dev_num) * @param buflen buffer size * @return 0 on success, 1 otherwise */ -static int generate_mtdparts (char *buf,u32 buflen) +static int generate_mtdparts (char *buf,size_t buflen) {struct list_head *pentry, *dentry;struct mtd_device *dev;struct part_info *part, *prev_part;char *p = buf;char tmpbuf[32 ]; -u32 size, offset, len, part_cnt; -u32 maxlen = buflen -1 ; +u64 size, offset, len; +u32 part_cnt; +size_t maxlen = buflen -1 ;debug ("--- generate_mtdparts ---\n" );@@ -1204,7 +1210,7 @@ cleanup:* @param buflen buffer size * @return 0 on success, 1 otherwise */ -static int generate_mtdparts_save (char *buf,u32 buflen) +static int generate_mtdparts_save (char *buf,size_t buflen) {int ret;@@ -1265,13 +1271,13 @@ static void print_partition_table(void)printf (" #: name\t\tsize\t\tnet size\toffset\t\tmask_flags\n");list_for_each (pentry, &dev->parts) { -u32 net_size; +u64 net_size;char *size_note; part = list_entry(pentry, struct part_info, link); net_size =net_part_size (mtd, part); size_note = part->size == net_size ?" " :" (!)" ; - printf("%2d: %-20s0x%08x\t0x%08x%s\t0x%08x\t%d\n", + printf("%2d: %-20s0x%08llx\t0x%08llx%s\t0x%08llx\t%d\n", part_num, part->name, part->size, net_size, size_note, part->offset, part->mask_flags);@@ -1283,7 +1289,7 @@ static void print_partition_table(void)list_for_each (pentry, &dev->parts) { part = list_entry(pentry, struct part_info, link); -printf ("%2d: %-20s0x%08x\t0x%08x\t%d\n" , +printf ("%2d: %-20s0x%08llx\t0x%08llx\t%d\n" , part_num, part->name, part->size, part->offset, part->mask_flags);#endif /* defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) */ @@ -1310,7 +1316,7 @@ static void list_partitions(void)if (current_mtd_dev) { part =mtd_part_info (current_mtd_dev, current_mtd_partnum);if (part) { - printf("\nactive partition: %s%d,%d - (%s) 0x%08x @0x%08x\n", + printf("\nactive partition: %s%d,%d -
(%s) 0x%08llx @ 0x%08llx\n",MTD_DEV_TYPE(current_mtd_dev->id->type),current_mtd_dev->id->num,current_mtd_partnum,part->name,part->size,part->offset); @@ -1410,7 +1416,7 @@ static intdelete_partition(const char *id)if (find_dev_and_part(id, &dev, &pnum, &part) == 0) {- debug("delete_partition: device = %s%d, partition %d = (%s)
0x%08x at 0x%08x\n", + debug("delete_partition: device = %s%d,
partition %d = (%s) 0x%08llx at 0x%08llx\n",MTD_DEV_TYPE(dev->id->type),dev->id->num, pnum,part->name,part->size,part->offset);common/cmd_mtdparts.c +3
-3@@ -1499,7 +1505,7 @@ static int spread_partitions(void) part = list_entry(pentry, struct part_info, link); debug("spread_partitions: device = %s%d, partition %d =" - " (%s) 0x%08x at 0x%08x\n", + " (%s) 0x%08llx at 0x%08llx\n",MTD_DEV_TYPE (dev->id->type), dev->id->num, part_num, part->name, part->size, part->offset);@@ -1596,7 +1602,7 @@ static int parse_mtdids(const char *const ids)struct list_head *entry, *n;struct mtdids *id_tmp;u8 type, num; -u32 size; +u64 size;int ret =1 ;debug ("\n---parse_mtdids---\nmtdids = %s\n\n" , ids);@@ -1670,7 +1676,7 @@ static int parse_mtdids(const char *const ids) id->mtd_id[mtd_id_len -1 ] ='\0' ;INIT_LIST_HEAD (&id->link); -debug ("+ id %s%d\t%16d bytes\t%s\n" , +debug ("+ id %s%d\t%16llu bytes\t%s\n" ,MTD_DEV_TYPE (id->type), id->num, id->size, id->mtd_id);@@ -1999,7 +2005,7 @@ int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])if (!strcmp (&argv[1 ][3 ],".spread" )) {spread_partition (mtd, p, &next_offset); -debug ("increased %s to %d bytes\n" , p->name, p->size); + debug("increased %s to %llu bytes\n", p->name, p->size); }#endif include/jffs2/load_kernel.h +3
-3@@ -46,8 +46,8 @@ struct part_info {struct list_head link;char *name;/* partition name */ u8 auto_name;/* set to 1 for generated name */ -u32 size;/* total size of the partition */ -u32 offset;/* offset within device */ +u64 size;/* total size of the partition */ +u64 offset;/* offset within device */ void *jffs2_priv;/* used internaly by jffs2 */ u32 mask_flags;/* kernel MTD mask flags */ u32 sector_size;/* size of sector */ @@ -58,7 +58,7 @@ struct mtdids {struct list_head link;u8 type;/* device type */ u8 num;/* device number */ -u32 size;/* device size */ +u64 size;/* device size */ char *mtd_id;/* linux kernel device id */ };Quoted 21 lines · Aaron Williams
I'll probably have something later today. I got it working with an earlier version of u-boot though it hasn't been thoroughly tested.
-Aaron
Quoted 15 lines · Scott Wood
On Thu, 27 Jan 2011 16:24:31 -0800
Quoted 6 lines · Aaron Williams
Hi all,
It looks like the mtd partitioning code fails if the flash size exceeds a u32. I am working with an 8GB flash chip on our board and was wondering if anyone else has any experience with MTD with a chip this large?
There's been some effort to make the U-Boot NAND code work with large devices, but it's not complete. Patches to take care of the rest of the problem spots are welcome, especially if you have hardware to test.
Quoted 6 lines
Quoted 1 line
-Scott
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB
In reply to Aaron WilliamsQuoted 7 lines · On Thu, 27 Jan 2011 17:43:10 -0800 Aaron Williams…
I have included my preliminary patch which seems to be working. It has not been extensively tested yet. All of the changes were basically making the sizes and offsets u64 instead of u32. When looking at the Linux kernel code it looks like they also use u64. I was mistaken and our NAND flash chip is 4GiB in size so I can't test with any larger chips.
-Aaron
Patch is whitespace-mangled and does not apply.
Also needs sign-off and propper commit message. See
http://www.denx.de/wiki/U-Boot/Patches
and also the Developer's Certificate of Origin in
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/SubmittingPatches;h=689e2371095cc5dfea9927120009341f369159aa;hb=HEAD
Quoted 15 lines
common/cmd_mtdparts.c +2
-2@@ -207,20 +212,20 @@ static unsigned long memsize_parse (const char *const ptr, const char **retptr)* @param buf output buffer * @param size size to be converted to string */ -static void memsize_format (char *buf,u32 size) +static void memsize_format (char *buf,u64 size) {#define SIZE_GB ((u32)1024*1024*1024)#define SIZE_MB ((u32)1024*1024)#define SIZE_KB ((u32)1024)if ((size %SIZE_GB ) ==0 ) -sprintf (buf,"%ug" , size/SIZE_GB ); +sprintf (buf,"%llug" , size/SIZE_GB );else if ((size %SIZE_MB ) ==0 )
common/cmd_mtdparts.c static unsigned long memsize_parse (const char *const ptr, const char **retptr) · line 230
Quoted 10 lines
common/cmd_mtdparts.c +3
-3-sprintf (buf,"%um" , size/SIZE_MB ); +sprintf (buf,"%llum" , size/SIZE_MB ); else if (size % SIZE_KB == 0) - sprintf(buf, "%uk", size/SIZE_KB); + sprintf(buf, "%lluk", size/SIZE_KB); else - sprintf(buf, "%u", size); + sprintf(buf, "%llu", size); }
Need to make sure there are no boards with MTD enabled but not CONFIG_SYS_64BIT_VSPRINTF.
-Scot
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Trying again submitting the patch.
Adds support for NAND flash chips that are 4GiB and larger.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nand64.patch
Type: text/x-patch
Size: 10270 bytes
Desc: not available
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110131/62db4f2e/attachment.bin
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 12 lines · Aaron Williams
Trying again submitting the patch.
Adds support for NAND flash chips that are 4GiB and larger.
Signed-off-by Aaron Williams <[email protected]>common/cmd_mtdparts.c +0
-0@@ -21,6 +21,11 @@* $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $
common/cmd_mtdparts.c line 31
Quoted 10 lines
common/cmd_mtdparts.c +5
-0* Copyright 2002 SYSGO Real-Time Solutions GmbH * +* (C) Copyright 2011 +* Aaron Williams, Cavium Networks, Inc. <[email protected]> +* +* Added support for partitions and flash greater than or equal to 4GiB. +* * See file CREDITS for list of people who contributed to this * project. *
Changelogs go in git, not at the top of the file.
Quoted 18 lines
drivers/mtd/cfi_flash.c +2
-2@@ -1162,10 +1162,10 @@ void flash_print_info (flash_info_t * info) info->name, (info->portwidth << 3), (info->chipwidth << 3));if (info->size <1024 *1024 ) -printf (" Size: %ld kB in %d Sectors\n" , +printf (" Size: %ld KiB in %d Sectors\n" , info->size >>10 , info->sector_count);else -printf (" Size: %ld MB in %d Sectors\n" , +printf (" Size: %ld MiB in %d Sectors\n" , info->size >>20 , info->sector_count);printf (" " );switch (info->vendor) {
drivers/mtd/cfi_flash.c ulong flash_get_size (phys_addr_t base, int banknum) · line 1930
Quoted 7 lines
drivers/mtd/cfi_flash.c +1
-0@@ -1924,6 +1924,7 @@ ulong flash_get_size (phys_addr_t base, int banknum)/* Do manufacturer-specific fixups */ switch (info->manufacturer_id) { +case 0x0000 :case 0x0001 :flash_fixup_amd (info, &qry);break ;
This seems unrelated.
Otherwise, the patch looks good. Whose tree should it go through? It's not really a NAND patch, though NAND is the reason for it.
-Scott
Andrew Dyer
NAKPATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 10 lines · Scott Wood
Quoted 8 lines · Aaron Williams
Trying again submitting the patch.
? ? ? ? ? ? ? /* Do manufacturer-specific fixups */ ? ? ? ? ? ? ? switch (
info->manufacturer_id) {
+ ? ? ? ? ? ? case0x0000:
? ? ? ? ? ? ? case0x0001:
? ? ? ? ? ? ? ? ? ? ?flash_fixup_amd(info, &qry); ? ? ? ? ? ? ? ? ? ? ? break;
Quoted 4 lines
This seems unrelated.
Otherwise, the patch looks good. ?Whose tree should it go through? It's not really a NAND patch, though NAND is the reason for it.
NAK
This is not only unrelated (which the OP was told to fix on the previous post of this patch), but wrong. The S29GL series chips don't return 0x0000 for the manufacturer ID. AMD (later Spansion) have always had mfg. ID 0x0001.
I have various boards with S29GL064, S29GL128N, and S29GL256P, and they all return the correct value (0x0001) for the mfg. ID. I looked up the latest datasheet and they have not changed that section.
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 18 lines · Andrew Dyer
Quoted 10 lines · Scott Wood
Quoted 8 lines · Aaron Williams
Trying again submitting the patch.
/* Do manufacturer-specific fixups */ switch (info->manufacturer_id) { + case 0x0000: case 0x0001: flash_fixup_amd(info, &qry); break;Quoted 4 lines
This seems unrelated.
Otherwise, the patch looks good. Whose tree should it go through? It's not really a NAND patch, though NAND is the reason for it.
NAK
Quoted 8 lines
This is not only unrelated (which the OP was told to fix on the previous post of this patch), but wrong. The S29GL series chips don't return
0x0000for the manufacturer ID. AMD (later Spansion) have always had mfg. ID0x0001.I have various boards with S29GL064, S29GL128N, and S29GL256P, and they all return the correct value (
0x0001) for the mfg. ID. I looked up the latest datasheet and they have not changed that section.
I always get 0x0000 for the mfg ID and cannot explain it. The full part number is S29GL064N90TF103 010FF058. That is why it was added. Without it, the proper fixup doesn't happen with this chip.
-Aaron
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 29 lines · Aaron Williams
Quoted 19 lines · Andrew Dyer
Quoted 11 lines · Scott Wood
Quoted 9 lines · Aaron Williams
Trying again submitting the patch.
/* Do manufacturer-specific fixups */ switch (info->manufacturer_id) {+ case
0x0000:case 0x0001: flash_fixup_amd(info, &qry); break;Quoted 4 lines
This seems unrelated.
Otherwise, the patch looks good. Whose tree should it go through? It's not really a NAND patch, though NAND is the reason for it.
NAK
Quoted 8 lines
This is not only unrelated (which the OP was told to fix on the previous post of this patch), but wrong. The S29GL series chips don't return
0x0000for the manufacturer ID. AMD (later Spansion) have always had mfg. ID0x0001.I have various boards with S29GL064, S29GL128N, and S29GL256P, and they all return the correct value (
0x0001) for the mfg. ID. I looked up the latest datasheet and they have not changed that section.
Quoted 5 lines
I always get
0x0000for the mfg ID and cannot explain it. The full part number is S29GL064N90TF103 010FF058. That is why it was added. Without it, the proper fixup doesn't happen with this chip.-Aaron
Note that in our case the port width is 16-bits and the chip width is 8 bits.
I added some printf statements for all read accesses to help.
Here's the output when I enable debugging:
flash detect cfi
fwc addr 1f400000 cmd f0 f0f0 16bit x 8 bit
fwc addr 1f400000 cmd ff ffff 16bit x 8 bit
fwc addr 1f4000aa cmd 98 9898 16bit x 8 bit
is= cmd 51(Q) addr 1f400020 flash_read16: address 1f400020, value 0x5151 is= 5151 5151flash_read16: address 1f400020, value 0x5151
is= cmd 52(R) addr 1f400022 flash_read16: address 1f400022, value 0x5252 is= 5252 5252flash_read16: address 1f400022, value 0x5252
is= cmd 59(Y) addr 1f400024 flash_read16: address 1f400024, value 0x5959 is= 5959 5959flash_read16: address 1f400024, value 0x5959flash_read8: address 1f400021, value 0x51flash_read8: address 1f400023, value 0x52flash_read8: address 1f400025, value 0x59flash_read8: address 1f400027, value 0x2flash_read8: address 1f400029, value 0x0flash_read8: address 1f40002b, value 0x40flash_read8: address 1f40002d, value 0x0flash_read8: address 1f40002f, value 0x0flash_read8: address 1f400031, value 0x0flash_read8: address 1f400033, value 0x0flash_read8: address 1f400035, value 0x0flash_read8: address 1f400037, value 0x27flash_read8: address 1f400039, value 0x36flash_read8: address 1f40003b, value 0x0flash_read8: address 1f40003d, value 0x0flash_read8: address 1f40003f, value 0x7flash_read8: address 1f400041, value 0x7flash_read8: address 1f400043, value 0xaflash_read8: address 1f400045, value 0x0flash_read8: address 1f400047, value 0x3flash_read8: address 1f400049, value 0x5flash_read8: address 1f40004b, value 0x4flash_read8: address 1f40004d, value 0x0flash_read8: address 1f40004f, value 0x17flash_read8: address 1f400051, value 0x2flash_read8: address 1f400053, value 0x0flash_read8: address 1f400055, value 0x5flash_read8: address 1f400057, value 0x0flash_read8: address 1f400059, value 0x2flash_read8: address 1f40005b, value 0x7flash_read8: address 1f40005d, value 0x0flash_read8: address 1f40005f, value 0x20flash_read8: address 1f400061, value 0x0flash_read8: address 1f400063, value 0x7eflash_read8: address 1f400065, value 0x0flash_read8: address 1f400067, value 0x0flash_read8: address 1f400069, value 0x1flash_read8: address 1f40006b, value 0x0flash_read8: address 1f40006d, value 0x0flash_read8: address 1f40006f, value 0x0flash_read8: address 1f400071, value 0x0flash_read8: address 1f400073, value 0x0flash_read8: address 1f400075, value 0x0flash_read8: address 1f400077, value 0x0flash_read8: address 1f400079, value 0x0
device interface is 2
found port 2 chip 1 port 16 bits chip 8 bitsflash_read8: address 1f400087, value 0x31flash_read8: address 1f400089, value 0x33
00 : 51 52 59 02 00 40 00 00 00 00 00 27 36 00 00 07 QRY.. at .....'6... 10 : 07 0a 00 03 05 04 00 17 02 00 05 00 02 07 00 20 ............... 20 : 00 7e 00 00 01 00 00 00 00 00 00 00 00 00 00 10 .~..............
fwc addr 1f400000 cmd f0 f0f0 16bit x 8 bit fwc addr 1f401554 cmd aa aaaa 16bit x 8 bit fwc addr 1f400aaa cmd 55 5555 16bit x 8 bit fwc addr 1f401554 cmd 90 9090 16bit x 8 bitflash_read8: address 1f400001, value 0x0flash_read8: address 1f400003, value 0x3f fwc addr 1f400000 cmd f0 f0f0 16bit x 8 bit fwc addr 1f4000aa cmd 98 9898 16bit x 8 bitflash_read8: address 1f40009f, value 0x3 manufacturer is 2
manufacturer id is 0x0
device id is 0x3f
device id2 is 0x0
cfi version is 0x3133size_ratio 1 port 16 bits chip 8 bits found 2 erase regions
erase region 0: 0x0100007e erase_region_count = 127 erase_region_size = 65536 erase region 1: 0x00200007 erase_region_count = 8 erase_region_size = 8192 fwc addr 1f400000 cmd f0 f0 8bit x 8 bit fwc addr 1fbfe000 cmd 70 70 8bit x 8 bitflash_read8: address 1fbfe000, value 0xe5flash_read8: address 1fbfe000, value 0xe5flash_is_busy: 0
Flash: 8 MiB
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 34 lines · Andrew Dyer
On Thu, Feb 10, 2011 at 00:28, Aaron Williams
Quoted 17 lines · <[email protected]> wrote:
Quoted 9 lines
I would suggest to make sure any caching/prefetching stuff is off, hardware is doing one flash bus access per CPU read/write.
In
cmdset_amd_read_jedec_ids()after this line:manuId =
flash_read_uchar(info,FLASH_OFFSET_MANUFACTURER_ID);add something like
Quoted 7 lines
printf("test manf id word = %04x\n", *(volatile uint16_t *)0x1f400000);printf("test device id word = %04x\n", *(volatile uint16_t *)0x1f400002);printf("test device id word = %04x\n", *(volatile uint16_t *)0x1f40001c);printf("test device id word = %04x\n", *(volatile uint16_t *)0x1f40001e);and see what you get.
Quoted 13 lines
fwc addr
1f400000cmd f0 f0f0 16bit x 8 bitflash_write16: address:1f400000, value:0xf0f0fwc addr1f401554cmd aa aaaa 16bit x 8 bitflash_write16: address:1f401554, value:0xaaaafwc addr1f400aaacmd 55 5555 16bit x 8 bitflash_write16: address:1f400aaa, value:0x5555fwc addr1f401554cmd 90 9090 16bit x 8 bitflash_write16: address:1f401554, value:0x9090flash_read8: address:1f400001, value:0x0test manf id word = 1000
test device id word = 013f
test device id word = da6c
test device id word = 2926
Quoted 7 lines
looks like garbage :-( What's in the flash at those addresses? Maybe something is happening to mess up the unlock sequence and you're reading the memory data instead of the device codes.
It's odd that earlier in the sequence when the CFI query data is read the byte data is mirrored across both bytes of the response, here the two bytes are different.
I received an email back from Spansion about this problem. They suggested that instead of the following:
fwc addr 1f401554 cmd aa aaaa 16bit x 8 bitflash_write16: Wrote 0xaaaa to address 1f401554
funlock writing 0xaa to address 0x555
fwc addr 1f400aaa cmd 55 5555 16bit x 8 bitflash_write16: Wrote 0x5555 to address 1f400aaa
fwc addr 1f401554 cmd 90 9090 16bit x 8 bitflash_write16: Wrote 0x9090 to address 1f401554
to instead do the following:
write 0xAA to 0x1F400AAA
write 0x55 to 0x1F400555
write 0x90 to 0x1F400AAA
read 0x1F400001 returns 0x01
read 0x1F400003 returns 0x7e
This looks correct.
I found two things I need to do to work around the problem. First, in flash_write_cmd I use info->chipwidth instead of info->portwidth for the write commands, and second, in __flash_detect_cfi I don't modify the address in compatibility mode. This works. If either of those steps are left out then reading the manufacturer ID fails.
-Aaron
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 65 lines · Aaron Williams
Quoted 35 lines · Andrew Dyer
On Thu, Feb 10, 2011 at 00:28, Aaron Williams
Quoted 18 lines · <[email protected]> wrote:
Quoted 9 lines
I would suggest to make sure any caching/prefetching stuff is off, hardware is doing one flash bus access per CPU read/write.
In
cmdset_amd_read_jedec_ids()after this line:manuId =
flash_read_uchar(info,FLASH_OFFSET_MANUFACTURER_ID);add something like
Quoted 8 lines
printf("test manf id word = %04x\n", *(volatile uint16_t *)0x1f400000); printf("test device id word = %04x\n", *(volatileuint16_t
*)0x1f400002);printf("test device id word = %04x\n", *(volatile uint16_t *)0x1f40001c);printf("test device id word = %04x\n", *(volatile uint16_t *)0x1f40001e);and see what you get.
Quoted 13 lines
fwc addr
1f400000cmd f0 f0f0 16bit x 8 bitflash_write16: address:1f400000, value:0xf0f0fwc addr1f401554cmd aa aaaa 16bit x 8 bitflash_write16: address:1f401554, value:0xaaaafwc addr1f400aaacmd 55 5555 16bit x 8 bitflash_write16: address:1f400aaa, value:0x5555fwc addr1f401554cmd 90 9090 16bit x 8 bitflash_write16: address:1f401554, value:0x9090flash_read8: address:1f400001, value:0x0test manf id word = 1000
test device id word = 013f
test device id word = da6c
test device id word = 2926Quoted 7 lines
looks like garbage :-( What's in the flash at those addresses? Maybe something is happening to mess up the unlock sequence and you're reading the memory data instead of the device codes.
It's odd that earlier in the sequence when the CFI query data is read the byte data is mirrored across both bytes of the response, here the two bytes are different.
I received an email back from Spansion about this problem. They suggested that instead of the following:
fwc addr
1f401554cmd aa aaaa 16bit x 8 bitflash_write16: Wrote0xaaaato address1f401554
funlock writing0xaato address0x555
fwc addr1f400aaacmd 55 5555 16bit x 8 bitflash_write16: Wrote0x5555to address1f400aaa
fwc addr1f401554cmd 90 9090 16bit x 8 bitflash_write16: Wrote0x9090to address1f401554to instead do the following:
write0xAAto0x1F400AAA
write0x55to0x1F400555
write0x90to0x1F400AAAread
0x1F400001returns0x01
read0x1F400003returns0x7eThis looks correct.
Quoted 7 lines
I found two things I need to do to work around the problem. First, in
flash_write_cmdI useinfo->chipwidthinstead ofinfo->portwidthfor the write commands, and second, in__flash_detect_cfiI don't modify the address in compatibility mode. This works. If either of those steps are left out then reading the manufacturer ID fails.-Aaron
It looks like I spoke too soon. It fixes the manufacturer problem but everything else is now broken.
-Aaron
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 72 lines · Aaron Williams
Quoted 71 lines · Aaron Williams
Quoted 35 lines · Andrew Dyer
On Thu, Feb 10, 2011 at 00:28, Aaron Williams
Quoted 18 lines · <[email protected]> wrote:
Quoted 9 lines
I would suggest to make sure any caching/prefetching stuff is off, hardware is doing one flash bus access per CPU read/write.
In
cmdset_amd_read_jedec_ids()after this line:manuId =
flash_read_uchar(info,FLASH_OFFSET_MANUFACTURER_ID);add something like
Quoted 8 lines
printf("test manf id word = %04x\n", *(volatile uint16_t *)0x1f400000); printf("test device id word = %04x\n", *(volatileuint16_t
*)0x1f400002);printf("test device id word = %04x\n", *(volatile uint16_t *)0x1f40001c);printf("test device id word = %04x\n", *(volatile uint16_t *)0x1f40001e);and see what you get.
Quoted 13 lines
fwc addr
1f400000cmd f0 f0f0 16bit x 8 bitflash_write16: address:1f400000, value:0xf0f0fwc addr1f401554cmd aa aaaa 16bit x 8 bitflash_write16: address:1f401554, value:0xaaaafwc addr1f400aaacmd 55 5555 16bit x 8 bitflash_write16: address:1f400aaa, value:0x5555fwc addr1f401554cmd 90 9090 16bit x 8 bitflash_write16: address:1f401554, value:0x9090flash_read8: address:1f400001, value:0x0test manf id word = 1000
test device id word = 013f
test device id word = da6c
test device id word = 2926Quoted 7 lines
looks like garbage :-( What's in the flash at those addresses? Maybe something is happening to mess up the unlock sequence and you're reading the memory data instead of the device codes.
It's odd that earlier in the sequence when the CFI query data is read the byte data is mirrored across both bytes of the response, here the two bytes are different.
I received an email back from Spansion about this problem. They suggested that instead of the following:
fwc addr
1f401554cmd aa aaaa 16bit x 8 bitflash_write16: Wrote0xaaaato address1f401554
funlock writing0xaato address0x555
fwc addr1f400aaacmd 55 5555 16bit x 8 bitflash_write16: Wrote0x5555to address1f400aaa
fwc addr1f401554cmd 90 9090 16bit x 8 bitflash_write16: Wrote0x9090to address1f401554to instead do the following:
write0xAAto0x1F400AAA
write0x55to0x1F400555
write0x90to0x1F400AAAread
0x1F400001returns0x01
read0x1F400003returns0x7eThis looks correct.
I found two things I need to do to work around the problem. First, in
flash_write_cmdI useinfo->chipwidthinstead ofinfo->portwidthfor the write commands, and second, in__flash_detect_cfiI don't modify the address in compatibility mode. This works. If either of those steps are left out then reading the manufacturer ID fails.
Quoted 6 lines
Quoted 1 line
-Aaron
It looks like I spoke too soon. It fixes the manufacturer problem but everything else is now broken.
-Aaron
It works now, but I had to hard-code cmdset_amd_read_jedec_ids for some reason.
static void cmdset_amd_read_jedec_ids(flash_info_t *info)
{
ushort bankId = 0;
uchar manuId;
debug("In %s\n", __func__);
flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
flash_write_cmd(info, 0, 0x555, AMD_CMD_UNLOCK_START);
flash_write_cmd(info, 0, 0x2AA, AMD_CMD_UNLOCK_ACK);
flash_write_cmd(info, 0, 0x555, FLASH_CMD_READ_ID);
/*flash_unlock_seq(info, 0); */
/*flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);*/With this, everything works with my mod to flash_write_cmd to use chipwidth instead of portwidth.
-Aaron
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
I think I found the problem. The cfi code does not work properly in x8 mode.
In x8 mode, according to the datasheet, the addresses should be doubled for all of the commands. Additionally, according to my correspondence with Spansion, there needs to be at least a 500ns delay after a reset command.
The cfi code is incorrectly detecting the port width as FLASH_CFI_16BIT when it is actually 8-bits. Currently things just happen to work because the bus is being incorrectly detected as 16-bits,
The 16-bit bus detection, however, breaks in x8 mode when it issues the commands for the manufacturer ID.
In this case, the following takes place:
In cmdset_amd_read_jedec_ids
fwc addr 1f400000 cmd f0 f0f0 16bit x 8 bitflash_write16: Wrote 0xf0f0 to address 1f400000
funlock writing 0xaa to address 0xaaa
fwc addr 1f401554 cmd aa aaaa 16bit x 8 bitflash_write16: Wrote 0xaaaa to address 1f401554
funlock writing 0xaa to address 0x555
fwc addr 1f400aaa cmd 55 5555 16bit x 8 bitflash_write16: Wrote 0x5555 to address 1f400aaa
fwc addr 1f401554 cmd 90 9090 16bit x 8 bitflash_write16: Wrote 0x9090 to address 1f401554flash_read8: Read 0x0 from address 1f400001flash_read8: Read 0x3f from address 1f400003
This does not work.
If the proper sequence is written, then it works fine.
The proper sequence, according to the datasheet, is to do the following:
write 0xf0 to address 0x0000
write 0xaa to address 0xaaa
write 0x55 to address 0x555
write 0x90 to address 0xaaa
read address 0 (returns 1 as expected)
read address 2 (returns 0x7e as expected)
...
So the cfi code is broken in the x8 case.
-Aaron Williams
Quoted 104 lines · Aaron Williams
Quoted 72 lines · Aaron Williams
Quoted 71 lines · Aaron Williams
Quoted 35 lines · Andrew Dyer
On Thu, Feb 10, 2011 at 00:28, Aaron Williams
Quoted 18 lines · <[email protected]> wrote:
Quoted 9 lines
I would suggest to make sure any caching/prefetching stuff is off, hardware is doing one flash bus access per CPU read/write.
In
cmdset_amd_read_jedec_ids()after this line:manuId =
flash_read_uchar(info,FLASH_OFFSET_MANUFACTURER_ID);add something like
Quoted 8 lines
printf("test manf id word = %04x\n", *(volatile uint16_t *)0x1f400000); printf("test device id word = %04x\n", *(volatileuint16_t
*)0x1f400002);printf("test device id word = %04x\n", *(volatile uint16_t *)0x1f40001c);printf("test device id word = %04x\n", *(volatile uint16_t *)0x1f40001e);and see what you get.
Quoted 13 lines
fwc addr
1f400000cmd f0 f0f0 16bit x 8 bitflash_write16: address:1f400000, value:0xf0f0fwc addr1f401554cmd aa aaaa 16bit x 8 bitflash_write16: address:1f401554, value:0xaaaafwc addr1f400aaacmd 55 5555 16bit x 8 bitflash_write16: address:1f400aaa, value:0x5555fwc addr1f401554cmd 90 9090 16bit x 8 bitflash_write16: address:1f401554, value:0x9090flash_read8: address:1f400001, value:0x0test manf id word = 1000
test device id word = 013f
test device id word = da6c
test device id word = 2926Quoted 7 lines
looks like garbage :-( What's in the flash at those addresses? Maybe something is happening to mess up the unlock sequence and you're reading the memory data instead of the device codes.
It's odd that earlier in the sequence when the CFI query data is read the byte data is mirrored across both bytes of the response, here the two bytes are different.
I received an email back from Spansion about this problem. They suggested that instead of the following:
fwc addr
1f401554cmd aa aaaa 16bit x 8 bitflash_write16: Wrote0xaaaato address1f401554
funlock writing0xaato address0x555
fwc addr1f400aaacmd 55 5555 16bit x 8 bitflash_write16: Wrote0x5555to address1f400aaa
fwc addr1f401554cmd 90 9090 16bit x 8 bitflash_write16: Wrote0x9090to address1f401554to instead do the following:
write0xAAto0x1F400AAA
write0x55to0x1F400555
write0x90to0x1F400AAAread
0x1F400001returns0x01
read0x1F400003returns0x7eThis looks correct.
I found two things I need to do to work around the problem. First, in
flash_write_cmdI useinfo->chipwidthinstead ofinfo->portwidthfor the write commands, and second, in__flash_detect_cfiI don't modify the address in compatibility mode. This works. If either of those steps are left out then reading the manufacturer ID fails.Quoted 6 lines
Quoted 1 line
-Aaron
It looks like I spoke too soon. It fixes the manufacturer problem but everything else is now broken.
-Aaron
It works now, but I had to hard-code
cmdset_amd_read_jedec_idsfor some reason.static void
cmdset_amd_read_jedec_ids(flash_info_t *info){ ushort bankId = 0; uchar manuId; debug("In %s\n", __func__); flash_write_cmd(info, 0, 0, AMD_CMD_RESET); flash_write_cmd(info, 0, 0x555, AMD_CMD_UNLOCK_START); flash_write_cmd(info, 0, 0x2AA, AMD_CMD_UNLOCK_ACK); flash_write_cmd(info, 0, 0x555, FLASH_CMD_READ_ID); /*flash_unlock_seq(info, 0); */ /*flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);*/With this, everything works with my mod to
flash_write_cmdto use chipwidth instead of portwidth.-Aaron
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Le 12/02/2011 01:15, Aaron Williams a ?crit :
Quoted 43 lines
I think I found the problem. The cfi code does not work properly in x8 mode.
In x8 mode, according to the datasheet, the addresses should be doubled for all of the commands. Additionally, according to my correspondence with Spansion, there needs to be at least a 500ns delay after a reset command.
The cfi code is incorrectly detecting the port width as
FLASH_CFI_16BITwhen it is actually 8-bits. Currently things just happen to work because the bus is being incorrectly detected as 16-bits,The 16-bit bus detection, however, breaks in x8 mode when it issues the commands for the manufacturer ID.
In this case, the following takes place:
In
cmdset_amd_read_jedec_ids
fwc addr1f400000cmd f0 f0f0 16bit x 8 bitflash_write16: Wrote0xf0f0to address1f400000
funlock writing0xaato address0xaaa
fwc addr1f401554cmd aa aaaa 16bit x 8 bitflash_write16: Wrote0xaaaato address1f401554
funlock writing0xaato address0x555
fwc addr1f400aaacmd 55 5555 16bit x 8 bitflash_write16: Wrote0x5555to address1f400aaa
fwc addr1f401554cmd 90 9090 16bit x 8 bitflash_write16: Wrote0x9090to address1f401554flash_read8: Read0x0from address1f400001flash_read8: Read0x3ffrom address1f400003This does not work.
If the proper sequence is written, then it works fine.
The proper sequence, according to the datasheet, is to do the following:
write
0xf0to address0x0000
write0xaato address0xaaa
write0x55to address0x555
write0x90to address0xaaa
read address 0 (returns 1 as expected)
read address 2 (returns0x7eas expected)
...
Quoted 1 line
So the cfi code is broken in the x8 case.
Hmm... It would be surprising that the x8 CFI code be broken -- not impossible, mind you -- because it was intensively used with a variety of chips, and thus extensively checked for brokenness.
What *might* be at stake is the result of the width detection, because many reputedly CFI compliant Flash devices are actually not compliant, especially among the dual-width, x8/x16, ones. On my ED Mini V2, there is a Macronix x8/x16 part which presents its CFI QRY response as a pure x16 even though it is a x8/x16, thus tricking the width detection mechanism into taking the wrong decision; I had to resort to using the LEGACY feature of manually defining the widths.
Did you check the Flash part against the CFI specs, including the QRY location and layout?
Can you boot into a RAM-baed u-boot and use its memory write and read commands (m[wd].[lwb]) to test the main CFI sequences of your Flash device?
Amicalement,
Signature · 1 line
Albert.
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 60 lines · Albert ARIBAUD
Le 12/02/2011 01:15, Aaron Williams a ?crit :
Quoted 45 lines
I think I found the problem. The cfi code does not work properly in x8 mode.
In x8 mode, according to the datasheet, the addresses should be doubled for all of the commands. Additionally, according to my correspondence with Spansion, there needs to be at least a 500ns delay after a reset command.
The cfi code is incorrectly detecting the port width as
FLASH_CFI_16BITwhen it is actually 8-bits. Currently things just happen to work because the bus is being incorrectly detected as 16-bits,The 16-bit bus detection, however, breaks in x8 mode when it issues the commands for the manufacturer ID.
In this case, the following takes place:
In
cmdset_amd_read_jedec_ids
fwc addr1f400000cmd f0 f0f0 16bit x 8 bitflash_write16: Wrote0xf0f0to address1f400000
funlock writing0xaato address0xaaa
fwc addr1f401554cmd aa aaaa 16bit x 8 bitflash_write16: Wrote0xaaaato address1f401554
funlock writing0xaato address0x555
fwc addr1f400aaacmd 55 5555 16bit x 8 bitflash_write16: Wrote0x5555to address1f400aaa
fwc addr1f401554cmd 90 9090 16bit x 8 bitflash_write16: Wrote0x9090to address1f401554flash_read8: Read0x0from address1f400001flash_read8: Read0x3ffrom address1f400003This does not work.
If the proper sequence is written, then it works fine.
The proper sequence, according to the datasheet, is to do the following:
write
0xf0to address0x0000
write0xaato address0xaaa
write0x55to address0x555
write0x90to address0xaaa
read address 0 (returns 1 as expected)
read address 2 (returns0x7eas expected)
...Quoted 1 line
So the cfi code is broken in the x8 case.
Hmm... It would be surprising that the x8 CFI code be broken -- not impossible, mind you -- because it was intensively used with a variety of chips, and thus extensively checked for brokenness.
What *might* be at stake is the result of the width detection, because many reputedly CFI compliant Flash devices are actually not compliant, especially among the dual-width, x8/x16, ones. On my ED Mini V2, there is a Macronix x8/x16 part which presents its CFI QRY response as a pure x16 even though it is a x8/x16, thus tricking the width detection mechanism into taking the wrong decision; I had to resort to using the LEGACY feature of manually defining the widths.
Quoted 7 lines
Did you check the Flash part against the CFI specs, including the QRY location and layout?
Can you boot into a RAM-baed u-boot and use its memory write and read commands (m[wd].[lwb]) to test the main CFI sequences of your Flash device?
Amicalement,
I've placed the results of the scan below.
The problem is that in 8-bit mode the code that scans the CFI does not follow the specification.
In the specification to read the CFI data you write 0x98 to address 0xAA, not address 0x55 as you do in 16-bit mode. flash_offset_cfi is set to 0x55 which in this case is wrong and won't work. When it tries 16-bit mode then it writes to address 0xAA which causes it to work.
-Aaron
Here's the results of the scan:
flash detect cfi
fwc addr 1f400000 cmd f0 f0 8bit x 8 bitflash_write8: Wrote 0xf0 to address 1f400000
fwc addr 1f400055 cmd 98 98 8bit x 8 bitflash_write8: Wrote 0x98 to address 1f400055
is= cmd 51(Q) addr 1f400010 flash_read8: Read 0x0 from address 1f400010 is= 0 51flash_read8: Read 0x0 from address 1f400010
fwc addr 1f400000 cmd f0 f0 8bit x 8 bitflash_write8: Wrote 0xf0 to address 1f400000
fwc addr 1f400555 cmd 98 98 8bit x 8 bitflash_write8: Wrote 0x98 to address 1f400555
is= cmd 51(Q) addr 1f400010 flash_read8: Read 0x0 from address 1f400010 is= 0 51flash_read8: Read 0x0 from address 1f400010
fwc addr 1f400000 cmd f0 f0 8bit x 8 bitflash_write8: Wrote 0xf0 to address 1f400000
fwc addr 1f400000 cmd 98 98 8bit x 8 bitflash_write8: Wrote 0x98 to address 1f400000
is= cmd 51(Q) addr 1f400010 flash_read8: Read 0x0 from address 1f400010 is= 0 51flash_read8: Read 0x0 from address 1f400010
fwc addr 1f400000 cmd f0 f0f0 16bit x 8 bitflash_write16: Wrote 0xf0f0 to address 1f400000
fwc addr 1f4000aa cmd 98 9898 16bit x 8 bitflash_write16: Wrote 0x9898 to address 1f4000aa
is= cmd 51(Q) addr 1f400020 flash_read16: Read 0x5151 from address 1f400020 is= 5151 5151flash_read16: Read 0x5151 from address 1f400020
is= cmd 52(R) addr 1f400022 flash_read16: Read 0x5252 from address 1f400022 is= 5252 5252flash_read16: Read 0x5252 from address 1f400022
is= cmd 59(Y) addr 1f400024 flash_read16: Read 0x5959 from address 1f400024 is= 5959 5959flash_read16: Read 0x5959 from address 1f400024flash_read8: Read 0x51 from address 1f400021flash_read8: Read 0x52 from address 1f400023flash_read8: Read 0x59 from address 1f400025flash_read8: Read 0x2 from address 1f400027flash_read8: Read 0x0 from address 1f400029flash_read8: Read 0x40 from address 1f40002bflash_read8: Read 0x0 from address 1f40002dflash_read8: Read 0x0 from address 1f40002fflash_read8: Read 0x0 from address 1f400031flash_read8: Read 0x0 from address 1f400033flash_read8: Read 0x0 from address 1f400035flash_read8: Read 0x27 from address 1f400037flash_read8: Read 0x36 from address 1f400039flash_read8: Read 0x0 from address 1f40003bflash_read8: Read 0x0 from address 1f40003dflash_read8: Read 0x7 from address 1f40003fflash_read8: Read 0x7 from address 1f400041flash_read8: Read 0xa from address 1f400043flash_read8: Read 0x0 from address 1f400045flash_read8: Read 0x3 from address 1f400047flash_read8: Read 0x5 from address 1f400049flash_read8: Read 0x4 from address 1f40004bflash_read8: Read 0x0 from address 1f40004dflash_read8: Read 0x17 from address 1f40004fflash_read8: Read 0x2 from address 1f400051flash_read8: Read 0x0 from address 1f400053flash_read8: Read 0x5 from address 1f400055flash_read8: Read 0x0 from address 1f400057flash_read8: Read 0x2 from address 1f400059flash_read8: Read 0x7 from address 1f40005bflash_read8: Read 0x0 from address 1f40005dflash_read8: Read 0x20 from address 1f40005fflash_read8: Read 0x0 from address 1f400061flash_read8: Read 0x7e from address 1f400063flash_read8: Read 0x0 from address 1f400065flash_read8: Read 0x0 from address 1f400067flash_read8: Read 0x1 from address 1f400069flash_read8: Read 0x0 from address 1f40006bflash_read8: Read 0x0 from address 1f40006dflash_read8: Read 0x0 from address 1f40006fflash_read8: Read 0x0 from address 1f400071flash_read8: Read 0x0 from address 1f400073flash_read8: Read 0x0 from address 1f400075flash_read8: Read 0x0 from address 1f400077flash_read8: Read 0x0 from address 1f400079
device interface is 2
found port 2 chip 1 port 16 bits chip 8 bits __flash_detect_cfi: unlock addresses 0xaaa, 0x555, interface 2flash_read8: Read 0x31 from address 1f400087flash_read8: Read 0x33 from address 1f400089
00 : 51 52 59 02 00 40 00 00 00 00 00 27 36 00 00 07 QRY.. at .....'6... 10 : 07 0a 00 03 05 04 00 17 02 00 05 00 02 07 00 20 ............... 20 : 00 7e 00 00 01 00 00 00 00 00 00 00 00 06 d6 98 .~..............
In cmdset_amd_read_jedec_ids
fwc addr 1f400000 cmd f0 f0f0 16bit x 8 bitflash_write16: Wrote 0xf0f0 to address 1f400000 funlock writing 0xaa to address 0xaaa
fwc addr 1f401554 cmd aa aaaa 16bit x 8 bitflash_write16: Wrote 0xaaaa to address 1f401554 funlock writing 0xaa to address 0x555
fwc addr 1f400aaa cmd 55 5555 16bit x 8 bitflash_write16: Wrote 0x5555 to address 1f400aaa fwc addr 1f401554 cmd 90 9090 16bit x 8 bitflash_write16: Wrote 0x9090 to address 1f401554flash_read8: Read 0x0 from address 1f400001flash_read8: Read 0x3f from address 1f400003 fwc addr 1f400000 cmd f0 f0f0 16bit x 8 bitflash_write16: Wrote 0xf0f0 to address 1f400000 fwc addr 1f4000aa cmd 98 9898 16bit x 8 bitflash_write16: Wrote 0x9898 to address 1f4000aaflash_read8: Read 0x3 from address 1f40009f manufacturer is 2
manufacturer id is 0x0
device id is 0x3f
device id2 is 0x0
cfi version is 0x3133size_ratio 1 port 16 bits chip 8 bits found 2 erase regions
erase region 0: 0x0100007e erase_region_count = 127 erase_region_size = 65536 erase region 1: 0x00200007 erase_region_count = 8 erase_region_size = 8192 fwc addr 1f400000 cmd f0 f0 8bit x 8 bitflash_write8: Wrote 0xf0 to address 1f400000 fwc addr 1fbfe000 cmd 70 70 8bit x 8 bitflash_write8: Wrote 0x70 to address 1fbfe000flash_read8: Read 0x6f from address 1fbfe000flash_read8: Read 0x6f from address 1fbfe000flash_is_busy: 0
Flash: 8 MiB
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Le 12/02/2011 07:42, Aaron Williams a ?crit :
Quoted 9 lines
I've placed the results of the scan below.
The problem is that in 8-bit mode the code that scans the CFI does not follow the specification.
In the specification to read the CFI data you write
0x98to address0xAA, not address0x55as you do in 16-bit mode.flash_offset_cfiis set to0x55which in this case is wrong and won't work. When it tries 16-bit mode then it writes to address0xAAwhich causes it to work.
Let us see the specs, then. The specs I have (admittedly not necessarily the latest: I use JESD 68.01, september 1999) state the following:
"Nonvolatile memory devices are assumed to power up in a read-only state. Independent of that assumption, the Query structure contents must be able to be read at the specific address locations following a single system write cycle where: 1) a 98h Query command code is written to 55h address location within the device?s address space (in maximum device buswidth), and 2) the device is in any valid read state, such as ?Read Array? or ?Read ID Data?.
I read "55h address location within the device?s address space (in maximum device buswidth" as implying that 0x55 is the only address to use but is in device bus terms, and that may mean different CPU addresses for different devices types: for x8 devices, one should access the byte address 0x55 because the device bus is in bytes, whereas for x8/x16 and x16 devices, one should access byte address 0xAA because it translates to x16 device bus address 0x55 -- regardless of actual x8 or x16 mode.
Are we in sync here?
Now it's been a long time since I last looked at my ED Mini V2 Flash, but I should be able to dig it up and do a test within one or two hours.
Quoted 3 lines
-Aaron
Here's the results of the scan:
Yes, that's what U-boot *CFI code* does, but I'd like to see what very basic writes and reads give without any detection logic involved.
Amicalement,
Signature · 1 line
Albert.
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 36 lines · Albert ARIBAUD
Le 12/02/2011 07:42, Aaron Williams a ?crit :
Quoted 9 lines
I've placed the results of the scan below.
The problem is that in 8-bit mode the code that scans the CFI does not follow the specification.
In the specification to read the CFI data you write
0x98to address0xAA, not address0x55as you do in 16-bit mode.flash_offset_cfiis set to0x55which in this case is wrong and won't work. When it tries 16-bit mode then it writes to address0xAAwhich causes it to work.Let us see the specs, then. The specs I have (admittedly not necessarily the latest: I use JESD 68.01, september 1999) state the following:
"Nonvolatile memory devices are assumed to power up in a read-only state. Independent of that assumption, the Query structure contents must be able to be read at the specific address locations following a single system write cycle where: 1) a 98h Query command code is written to 55h address location within the device?s address space (in maximum device buswidth), and 2) the device is in any valid read state, such as ?Read Array? or ?Read ID Data?.
I read "55h address location within the device?s address space (in maximum device buswidth" as implying that
0x55is the only address to use but is in device bus terms, and that may mean different CPU addresses for different devices types: for x8 devices, one should access the byte address0x55because the device bus is in bytes, whereas for x8/x16 and x16 devices, one should access byte address0xAAbecause it translates to x16 device bus address0x55-- regardless of actual x8 or x16 mode.Are we in sync here?
Now it's been a long time since I last looked at my ED Mini V2 Flash, but I should be able to dig it up and do a test within one or two hours.
Quoted 7 lines
Quoted 3 lines
-Aaron
Here's the results of the scan:
Yes, that's what U-boot *CFI code* does, but I'd like to see what very basic writes and reads give without any detection logic involved.
Amicalement,
I'm looking at the Spansion S29GL-N datasheet from 2008. Look at table 10.3 on page 53.
http://www.spansion.com/Support/Datasheets/S29GL-N_01_12_e.pdf
-Aaron
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
In reply to Albert ARIBAUDQuoted 31 lines · Albert ARIBAUD
Le 12/02/2011 07:42, Aaron Williams a ?crit :
Quoted 9 lines
I've placed the results of the scan below.
The problem is that in 8-bit mode the code that scans the CFI does not follow the specification.
In the specification to read the CFI data you write
0x98to address0xAA, not address0x55as you do in 16-bit mode.flash_offset_cfiis set to0x55which in this case is wrong and won't work. When it tries 16-bit mode then it writes to address0xAAwhich causes it to work.Let us see the specs, then. The specs I have (admittedly not necessarily the latest: I use JESD 68.01, september 1999) state the following:
"Nonvolatile memory devices are assumed to power up in a read-only state. Independent of that assumption, the Query structure contents must be able to be read at the specific address locations following a single system write cycle where: 1) a 98h Query command code is written to 55h address location within the device?s address space (in maximum device buswidth), and 2) the device is in any valid read state, such as ?Read Array? or ?Read ID Data?.
I read "55h address location within the device?s address space (in maximum device buswidth" as implying that
0x55is the only address to use but is in device bus terms, and that may mean different CPU addresses for different devices types: for x8 devices, one should access the byte address0x55because the device bus is in bytes, whereas for x8/x16 and x16 devices, one should access byte address0xAAbecause it translates to x16 device bus address0x55-- regardless of actual x8 or x16 mode.
Quoted 1 line
Are we in sync here?
This is wrong. The address is actually 0xAA in x8 mode and 0x55 in x16 mode according to the data sheet.
Quoted 11 lines
Now it's been a long time since I last looked at my ED Mini V2 Flash, but I should be able to dig it up and do a test within one or two hours.
Quoted 3 lines
-Aaron
Here's the results of the scan:
Yes, that's what U-boot *CFI code* does, but I'd like to see what very basic writes and reads give without any detection logic involved.
Amicalement,
When I use the addresses and data shown in the datasheet, everything responds as it should using mw.b and md.b.
Octeon ebb6300(ram)# mw.b 0x1f400000 0xf0
Octeon ebb6300(ram)# mw.b 0x1f400aaa 0xaa
Octeon ebb6300(ram)# mw.b 0x1f400555 0x55
Octeon ebb6300(ram)# mw.b 0x1f400aaa 0x90
Octeon ebb6300(ram)# md.b 0x1f400000 11f400000: 01 .
Octeon ebb6300(ram)# md.b 0x1f400002 11f400002: 7e ~
Octeon ebb6300(ram)# md.b 0x1f400004 11f400004: 00 .
Octeon ebb6300(ram)# mw.b 0x1f400000 0xf0
Octeon ebb6300(ram)# mw.b 0x1f4000AA 0x98
Octeon ebb6300(ram)# md.b 0x1f4000201f400020: 51 Q
Octeon ebb6300(ram)# md.b 0x1f4000221f400022: 52 R
Octeon ebb6300(ram)# md.b 0x1f4000241f400024: 59 Y
Octeon ebb6300(ram)# md.b 0x1f4000261f400026: 02 .
Octeon ebb6300(ram)# md.b 0x1f4000281f400028: 00 .
-Aaron
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Le 12/02/2011 08:14, Aaron Williams a ?crit :
Quoted 32 lines · Albert ARIBAUD
Quoted 31 lines
Le 12/02/2011 07:42, Aaron Williams a ?crit :
Quoted 9 lines
I've placed the results of the scan below.
The problem is that in 8-bit mode the code that scans the CFI does not follow the specification.
In the specification to read the CFI data you write
0x98to address0xAA, not address0x55as you do in 16-bit mode.flash_offset_cfiis set to0x55which in this case is wrong and won't work. When it tries 16-bit mode then it writes to address0xAAwhich causes it to work.Let us see the specs, then. The specs I have (admittedly not necessarily the latest: I use JESD 68.01, september 1999) state the following:
"Nonvolatile memory devices are assumed to power up in a read-only state. Independent of that assumption, the Query structure contents must be able to be read at the specific address locations following a single system write cycle where: 1) a 98h Query command code is written to 55h address location within the device?s address space (in maximum device buswidth), and 2) the device is in any valid read state, such as ?Read Array? or ?Read ID Data?.
I read "55h address location within the device?s address space (in maximum device buswidth" as implying that
0x55is the only address to use but is in device bus terms, and that may mean different CPU addresses for different devices types: for x8 devices, one should access the byte address0x55because the device bus is in bytes, whereas for x8/x16 and x16 devices, one should access byte address0xAAbecause it translates to x16 device bus address0x55-- regardless of actual x8 or x16 mode.
Quoted 4 lines
Quoted 1 line
Are we in sync here?
This is wrong. The address is actually
0xAAin x8 mode and0x55in x16 mode according to the data sheet.
Yes, but the 0xAA address is a byte address and the 0x55 address is a word address, translating to byte address 0xAA as well.
On the JESD 68.01 spec, page number 3 (that's PDF page 9), the byte location for a pure x8 device is 0x55, and 0xAA for a x16 device, both in x16 or x8 mode (the difference is that byte mode will expect a byte write of 0x98 where x16 mode will expect a word write of 0x0098).
This is in sync with my Macronix MX29LV400CB/CT spec.
Quoted 38 lines
Quoted 10 lines
Now it's been a long time since I last looked at my ED Mini V2 Flash, but I should be able to dig it up and do a test within one or two hours.
Quoted 3 lines
-Aaron
Here's the results of the scan:
Yes, that's what U-boot *CFI code* does, but I'd like to see what very basic writes and reads give without any detection logic involved.
Amicalement,
When I use the addresses and data shown in the datasheet, everything responds as it should using mw.b and md.b.
Octeon ebb6300(ram)# mw.b
0x1f4000000xf0
Octeon ebb6300(ram)# mw.b0x1f400aaa0xaa
Octeon ebb6300(ram)# mw.b0x1f4005550x55
Octeon ebb6300(ram)# mw.b0x1f400aaa0x90
Octeon ebb6300(ram)# md.b0x1f40000011f400000: 01 .
Octeon ebb6300(ram)# md.b0x1f40000211f400002: 7e ~
Octeon ebb6300(ram)# md.b0x1f40000411f400004: 00 .Octeon ebb6300(ram)# mw.b
0x1f4000000xf0
Octeon ebb6300(ram)# mw.b0x1f4000AA0x98
Octeon ebb6300(ram)# md.b0x1f4000201f400020: 51 Q
Octeon ebb6300(ram)# md.b0x1f4000221f400022: 52 R
Octeon ebb6300(ram)# md.b0x1f4000241f400024: 59 Y
Octeon ebb6300(ram)# md.b0x1f4000261f400026: 02 .
Octeon ebb6300(ram)# md.b0x1f4000281f400028: 00 .
Quoted 1 line
-Aaron
The CFI query is normal for a x16 device: byte address 0xAA is word address 0x55, which is what is expected from a x16 device in x8 mode as in x16 mode.
Can you try a 'md.b 0x1f400020 20' once in CFI QRY mode?
Amicalement,
Signature · 1 line
Albert.
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 88 lines · Albert ARIBAUD
Le 12/02/2011 08:14, Aaron Williams a ?crit :
Quoted 32 lines · Albert ARIBAUD
Quoted 31 lines
Le 12/02/2011 07:42, Aaron Williams a ?crit :
Quoted 9 lines
I've placed the results of the scan below.
The problem is that in 8-bit mode the code that scans the CFI does not follow the specification.
In the specification to read the CFI data you write
0x98to address0xAA, not address0x55as you do in 16-bit mode.flash_offset_cfiis set to0x55which in this case is wrong and won't work. When it tries 16-bit mode then it writes to address0xAAwhich causes it to work.Let us see the specs, then. The specs I have (admittedly not necessarily the latest: I use JESD 68.01, september 1999) state the following:
"Nonvolatile memory devices are assumed to power up in a read-only state. Independent of that assumption, the Query structure contents must be able to be read at the specific address locations following a single system write cycle where: 1) a 98h Query command code is written to 55h address location within the device?s address space (in maximum device buswidth), and 2) the device is in any valid read state, such as ?Read Array? or ?Read ID Data?.
I read "55h address location within the device?s address space (in maximum device buswidth" as implying that
0x55is the only address to use but is in device bus terms, and that may mean different CPU addresses for different devices types: for x8 devices, one should access the byte address0x55because the device bus is in bytes, whereas for x8/x16 and x16 devices, one should access byte address0xAAbecause it translates to x16 device bus address0x55-- regardless of actual x8 or x16 mode.Quoted 4 lines
Quoted 1 line
Are we in sync here?
This is wrong. The address is actually
0xAAin x8 mode and0x55in x16 mode according to the data sheet.Yes, but the
0xAAaddress is a byte address and the0x55address is a word address, translating to byte address0xAAas well.On the JESD 68.01 spec, page number 3 (that's PDF page 9), the byte location for a pure x8 device is
0x55, and0xAAfor a x16 device, both in x16 or x8 mode (the difference is that byte mode will expect a byte write of0x98where x16 mode will expect a word write of0x0098).This is in sync with my Macronix MX29LV400CB/CT spec.
Quoted 38 lines
Quoted 10 lines
Now it's been a long time since I last looked at my ED Mini V2 Flash, but I should be able to dig it up and do a test within one or two hours.
Quoted 3 lines
-Aaron
Here's the results of the scan:
Yes, that's what U-boot *CFI code* does, but I'd like to see what very basic writes and reads give without any detection logic involved.
Amicalement,
When I use the addresses and data shown in the datasheet, everything responds as it should using mw.b and md.b.
Octeon ebb6300(ram)# mw.b
0x1f4000000xf0
Octeon ebb6300(ram)# mw.b0x1f400aaa0xaa
Octeon ebb6300(ram)# mw.b0x1f4005550x55
Octeon ebb6300(ram)# mw.b0x1f400aaa0x90
Octeon ebb6300(ram)# md.b0x1f40000011f400000: 01 .
Octeon ebb6300(ram)# md.b0x1f40000211f400002: 7e ~
Octeon ebb6300(ram)# md.b0x1f40000411f400004: 00 .Octeon ebb6300(ram)# mw.b
0x1f4000000xf0
Octeon ebb6300(ram)# mw.b0x1f4000AA0x98
Octeon ebb6300(ram)# md.b0x1f4000201f400020: 51 Q
Octeon ebb6300(ram)# md.b0x1f4000221f400022: 52 R
Octeon ebb6300(ram)# md.b0x1f4000241f400024: 59 Y
Octeon ebb6300(ram)# md.b0x1f4000261f400026: 02 .
Octeon ebb6300(ram)# md.b0x1f4000281f400028: 00 .Quoted 1 line
-Aaron
Quoted 7 lines
The CFI query is normal for a x16 device: byte address
0xAAis word address0x55, which is what is expected from a x16 device in x8 mode as in x16 mode.Can you try a 'md.b
0x1f40002020' once in CFI QRY mode?Amicalement,
You mean like this?
Octeon ebb6300(ram)# mw.b 0x1f400000 0xf0 Octeon ebb6300(ram)# mw.b 0x1f400aaa 0xaa Octeon ebb6300(ram)# mw.b 0x1f400555 0x55 Octeon ebb6300(ram)# mw.b 0x1f400aaa 0x90 Octeon ebb6300(ram)# md.b 0x1f400000 0 Octeon ebb6300(ram)# md.b 0x1f400000 11f400000: 01 .
Octeon ebb6300(ram)# md.b 0x1f400002 11f400002: 7e ~
Octeon ebb6300(ram)# md.b 0x1f400004 11f400004: 00 .
Octeon ebb6300(ram)# md.b 0x1f400005 11f400005: 00 .
Octeon ebb6300(ram)# md.b 0x1f400006 11f400006: 1a .
Octeon ebb6300(ram)# md.b 0x1f400008 11f400008: 00 .
Octeon ebb6300(ram)# md.b 0x1f40000a 11f40000a: 00 .
Octeon ebb6300(ram)# mw.b 0x1f400000 0xf0 Octeon ebb6300(ram)# mw.b 0x1f4000AA 0x98 Octeon ebb6300(ram)# md.b 0x1f4000201f400020: 51 Q
Octeon ebb6300(ram)# md.b 0x1f4000221f400022: 52 R
Octeon ebb6300(ram)# md.b 0x1f4000241f400024: 59 Y
Octeon ebb6300(ram)# md.b 0x1f4000261f400026: 02 .
Octeon ebb6300(ram)# md.b 0x1f4000281f400028: 00 .
-Aaron
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Le 12/02/2011 08:57, Aaron Williams a ?crit :
Quoted 41 lines
Quoted 7 lines
The CFI query is normal for a x16 device: byte address
0xAAis word address0x55, which is what is expected from a x16 device in x8 mode as in x16 mode.Can you try a 'md.b
0x1f40002020' once in CFI QRY mode?Amicalement,
You mean like this?
Octeon ebb6300(ram)# mw.b
0x1f4000000xf0Octeon ebb6300(ram)# mw.b0x1f400aaa0xaaOcteon ebb6300(ram)# mw.b0x1f4005550x55Octeon ebb6300(ram)# mw.b0x1f400aaa0x90Octeon ebb6300(ram)# md.b0x1f4000000 Octeon ebb6300(ram)# md.b0x1f40000011f400000: 01 .
Octeon ebb6300(ram)# md.b0x1f40000211f400002: 7e ~
Octeon ebb6300(ram)# md.b0x1f40000411f400004: 00 .
Octeon ebb6300(ram)# md.b0x1f40000511f400005: 00 .
Octeon ebb6300(ram)# md.b0x1f40000611f400006: 1a .
Octeon ebb6300(ram)# md.b0x1f40000811f400008: 00 .
Octeon ebb6300(ram)# md.b0x1f40000a11f40000a: 00 .
Octeon ebb6300(ram)# mw.b0x1f4000000xf0Octeon ebb6300(ram)# mw.b0x1f4000AA0x98Octeon ebb6300(ram)# md.b0x1f4000201f400020: 51 Q
Octeon ebb6300(ram)# md.b0x1f4000221f400022: 52 R
Octeon ebb6300(ram)# md.b0x1f4000241f400024: 59 Y
Octeon ebb6300(ram)# md.b0x1f4000261f400026: 02 .
Octeon ebb6300(ram)# md.b0x1f4000281f400028: 00 .
Quoted 1 line
-Aaron
No, I meant the instruction exactly as I quoted it: 'md.b 0x1f400020 20' once in CFI QRY mode, that is:
mw.b 0x1f400000 0xf0 mw.b 0x1f4000AA 0x98 md.b 0x1f400020 20
Amicalement,
Signature · 1 line
Albert.
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 45 lines · Albert ARIBAUD
Le 12/02/2011 08:57, Aaron Williams a ?crit :
Quoted 42 lines
Quoted 7 lines
The CFI query is normal for a x16 device: byte address
0xAAis word address0x55, which is what is expected from a x16 device in x8 mode as in x16 mode.Can you try a 'md.b
0x1f40002020' once in CFI QRY mode?Amicalement,
You mean like this?
Octeon ebb6300(ram)# mw.b
0x1f4000000xf0Octeon ebb6300(ram)# mw.b0x1f400aaa0xaaOcteon ebb6300(ram)# mw.b0x1f4005550x55Octeon ebb6300(ram)# mw.b0x1f400aaa0x90Octeon ebb6300(ram)# md.b0x1f4000000 Octeon ebb6300(ram)# md.b0x1f40000011f400000: 01 .
Octeon ebb6300(ram)# md.b0x1f40000211f400002: 7e ~
Octeon ebb6300(ram)# md.b0x1f40000411f400004: 00 .
Octeon ebb6300(ram)# md.b0x1f40000511f400005: 00 .
Octeon ebb6300(ram)# md.b0x1f40000611f400006: 1a .
Octeon ebb6300(ram)# md.b0x1f40000811f400008: 00 .
Octeon ebb6300(ram)# md.b0x1f40000a11f40000a: 00 .
Octeon ebb6300(ram)# mw.b0x1f4000000xf0Octeon ebb6300(ram)# mw.b0x1f4000AA0x98Octeon ebb6300(ram)# md.b0x1f4000201f400020: 51 Q
Octeon ebb6300(ram)# md.b0x1f4000221f400022: 52 R
Octeon ebb6300(ram)# md.b0x1f4000241f400024: 59 Y
Octeon ebb6300(ram)# md.b0x1f4000261f400026: 02 .
Octeon ebb6300(ram)# md.b0x1f4000281f400028: 00 .Quoted 1 line
-Aaron
Quoted 8 lines
No, I meant the instruction exactly as I quoted it: 'md.b
0x1f40002020' once in CFI QRY mode, that is:mw.b 0x1f400000 0xf0 mw.b 0x1f4000AA 0x98 md.b 0x1f400020 20Amicalement,
Octeon ebb6300(ram)# mw.b 0x1f400000 0xf0 Octeon ebb6300(ram)# mw.b 0x1f400000 0xf0 Octeon ebb6300(ram)# mw.b 0x1f4000AA 0x98 Octeon ebb6300(ram)# md.b 0x1f400020 201f400020: 51 51 52 52 59 59 02 02 00 00 40 40 00 00 00 00 QQRRYY....@@....1f400030: 00 00 00 00 00 00 27 27 36 36 00 00 00 00 07 07 ......''66......
-Aaron
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Le 12/02/2011 09:54, Aaron Williams a ?crit :
Quoted 6 lines
Octeon ebb6300(ram)# mw.b
0x1f4000000xf0Octeon ebb6300(ram)# mw.b0x1f4000000xf0Octeon ebb6300(ram)# mw.b0x1f4000AA0x98Octeon ebb6300(ram)# md.b0x1f400020201f400020: 51 51 52 52 59 59 02 02 00 00 40 40 00 00 00 00 QQRRYY....@@....1f400030: 00 00 00 00 00 00 27 27 36 36 00 00 00 00 07 07 ......''66......
This, according to the CFI spec, gives us the proof that the Spansion chip is a x16 device in x8 mode.
Can you now please, based on the knowledge that the device is x16 in x8 mode, go through the CFI detection sequence agin and determine which line exactly fails to work as expected?
Quoted 1 line
-Aaron
Amicalement,
Signature · 1 line
Albert.
PATCH 1/1 NAND Re: mtdparts fails with NAND >= 4GB - Second try
Quoted 12 lines · Albert ARIBAUD
Le 12/02/2011 09:54, Aaron Williams a ?crit :
Quoted 7 lines
Octeon ebb6300(ram)# mw.b
0x1f4000000xf0
Octeon ebb6300(ram)# mw.b0x1f4000000xf0
Octeon ebb6300(ram)# mw.b0x1f4000AA0x98
Octeon ebb6300(ram)# md.b0x1f400020201f400020: 51 51 52 52 59 59 02 02 00 00 40 40 00 00 00 00 QQRRYY....@@....1f400030: 00 00 00 00 00 00 27 27 36 36 00 00 00 00 07
07 ......''66......This, according to the CFI spec, gives us the proof that the Spansion chip is a x16 device in x8 mode.
Quoted 7 lines
Can you now please, based on the knowledge that the device is x16 in x8 mode, go through the CFI detection sequence agin and determine which line exactly fails to work as expected?
Quoted 1 line
-Aaron
Amicalement,
I'll take a look at this next week. The problem with the current code is that it detects the chip width of 8 but a port width of 16 which results in 16-bit writes. This fails for obtaining the manufacturer ID.
-Aaron