* [PATCH 1/3] string: add strim for ONFI code
@ 2012-07-05 10:22 Eric Bénard
2012-07-05 10:22 ` [PATCH 2/3] nand_base: add ONFI flash detection Eric Bénard
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Eric Bénard @ 2012-07-05 10:22 UTC (permalink / raw)
To: barebox
Signed-off-by: Eric Bénard <eric@eukrea.com>
---
include/linux/string.h | 3 +++
lib/string.c | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index 62d743e..afd0aa6 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -93,6 +93,9 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
#ifndef __HAVE_ARCH_MEMCHR
extern void * memchr(const void *,int,__kernel_size_t);
#endif
+extern char * skip_spaces(const char *);
+
+extern char *strim(char *);
#ifdef __cplusplus
}
diff --git a/lib/string.c b/lib/string.c
index 2865088..db4f2ae 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -567,3 +567,42 @@ void *memchr(const void *s, int c, size_t n)
#endif
EXPORT_SYMBOL(memchr);
+/**
+ * skip_spaces - Removes leading whitespace from @str.
+ * @str: The string to be stripped.
+ *
+ * Returns a pointer to the first non-whitespace character in @str.
+ */
+char *skip_spaces(const char *str)
+{
+ while (isspace(*str))
+ ++str;
+ return (char *)str;
+}
+
+/**
+ * strim - Removes leading and trailing whitespace from @s.
+ * @s: The string to be stripped.
+ *
+ * Note that the first trailing whitespace is replaced with a %NUL-terminator
+ * in the given string @s. Returns a pointer to the first non-whitespace
+ * character in @s.
+ */
+char *strim(char *s)
+{
+ size_t size;
+ char *end;
+
+ s = skip_spaces(s);
+ size = strlen(s);
+ if (!size)
+ return s;
+
+ end = s + size - 1;
+ while (end >= s && isspace(*end))
+ end--;
+ *(end + 1) = '\0';
+
+ return s;
+}
+EXPORT_SYMBOL(strim);
--
1.7.7.6
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] nand_base: add ONFI flash detection
2012-07-05 10:22 [PATCH 1/3] string: add strim for ONFI code Eric Bénard
@ 2012-07-05 10:22 ` Eric Bénard
2012-07-05 19:02 ` Sascha Hauer
2012-07-05 10:22 ` [PATCH 3/3] nand_imx: update to support onfi & 4k flashs Eric Bénard
2012-07-09 7:30 ` [PATCH 1/3] string: add strim for ONFI code Sascha Hauer
2 siblings, 1 reply; 6+ messages in thread
From: Eric Bénard @ 2012-07-05 10:22 UTC (permalink / raw)
To: barebox
the code is taken from linux & u-boot implementations
Validated on an i.MX53 which gives the following log :
ONFI flash detected ... ONFI param page 0 valid
NAND device: Manufacturer ID: 0x2c, Chip ID: 0x38 (Micron MT29F8G08ABABAWP), page size: 4096, OOB size: 224
Signed-off-by: Eric Bénard <eric@eukrea.com>
---
drivers/mtd/nand/nand_base.c | 174 ++++++++++++++++++++++++++++++++++++------
include/linux/mtd/mtd-abi.h | 7 +-
include/linux/mtd/nand.h | 74 ++++++++++++++++++-
3 files changed, 226 insertions(+), 29 deletions(-)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index c4eca0d..a5bf757 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1027,6 +1027,108 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
}
/*
+ * sanitize ONFI strings so we can safely print them
+ */
+static void sanitize_string(char *s, size_t len)
+{
+ ssize_t i;
+
+ /* null terminate */
+ s[len - 1] = 0;
+
+ /* remove non printable chars */
+ for (i = 0; i < len - 1; i++) {
+ if (s[i] < ' ' || s[i] > 127)
+ s[i] = '?';
+ }
+
+ /* remove trailing spaces */
+ strim(s);
+}
+
+static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
+{
+ int i;
+ while (len--) {
+ crc ^= *p++ << 8;
+ for (i = 0; i < 8; i++)
+ crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
+ }
+
+ return crc;
+}
+
+/*
+ * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise
+ */
+static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
+ int *busw)
+{
+ struct nand_onfi_params *p = &chip->onfi_params;
+ int i;
+ int val;
+
+ /* try ONFI for unknow chip or LP */
+ chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
+ if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
+ chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
+ return 0;
+
+ printk(KERN_INFO "ONFI flash detected ... ");
+ chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
+ for (i = 0; i < 3; i++) {
+ chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
+ if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
+ le16_to_cpu(p->crc)) {
+ printk(KERN_INFO "ONFI param page %d valid\n", i);
+ break;
+ }
+ }
+
+ if (i == 3) {
+ printk(KERN_INFO "no valid ONFI param page found\n");
+ return 0;
+ }
+
+ /* check version */
+ val = le16_to_cpu(p->revision);
+ if (val & (1 << 5))
+ chip->onfi_version = 23;
+ else if (val & (1 << 4))
+ chip->onfi_version = 22;
+ else if (val & (1 << 3))
+ chip->onfi_version = 21;
+ else if (val & (1 << 2))
+ chip->onfi_version = 20;
+ else if (val & (1 << 1))
+ chip->onfi_version = 10;
+ else
+ chip->onfi_version = 0;
+
+ if (!chip->onfi_version) {
+ printk(KERN_INFO "unsupported ONFI version: %d\n", val);
+ return 0;
+ }
+
+ sanitize_string(p->manufacturer, sizeof(p->manufacturer));
+ sanitize_string(p->model, sizeof(p->model));
+ if (!mtd->name)
+ mtd->name = p->model;
+ mtd->writesize = le32_to_cpu(p->byte_per_page);
+ mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
+ mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
+ chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize;
+ *busw = 0;
+ if (le16_to_cpu(p->features) & 1)
+ *busw = NAND_BUSWIDTH_16;
+
+ chip->options &= ~NAND_CHIPOPTIONS_MSK;
+ chip->options |= NAND_NO_READRDY & NAND_CHIPOPTIONS_MSK;
+
+ return 1;
+}
+
+/*
* Get the flash and manufacturer id and lookup if the type is supported
*/
static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
@@ -1036,6 +1138,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
struct nand_flash_dev *type = NULL;
int i, dev_id, maf_idx;
int tmp_id, tmp_manf;
+ int ret;
/* Select the device */
chip->select_chip(mtd, 0);
@@ -1081,9 +1184,16 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
}
}
+ chip->onfi_version = 0;
if (!type) {
- printk(KERN_ERR "NAND type unknown: %02x,%02x\n", *maf_id, dev_id);
- return ERR_PTR(-ENODEV);
+ /* Check is chip is ONFI compliant */
+ ret = nand_flash_detect_onfi(mtd, chip, &busw);
+ if (ret)
+ goto ident_done;
+ else {
+ printk(KERN_ERR "NAND type unknown: %02x,%02x\n", *maf_id, dev_id);
+ return ERR_PTR(-ENODEV);
+ }
}
if (!mtd->name)
@@ -1126,17 +1236,39 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
break;
}
+ /* Get chip options, preserve non chip based options */
+ chip->options &= ~NAND_CHIPOPTIONS_MSK;
+ chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
+
+ /* Check if chip is a not a samsung device. Do not clear the
+ * options for chips which are not having an extended id.
+ */
+ if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
+ chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
+
+ident_done:
+ /*
+ * Set chip as a default. Board drivers can override it, if necessary
+ */
+ chip->options |= NAND_NO_AUTOINCR;
+
+ /* Try to identify manufacturer */
+ for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
+ if (nand_manuf_ids[maf_idx].id == *maf_id)
+ break;
+ }
+
/*
* Check, if buswidth is correct. Hardware drivers should set
* chip correct !
*/
if (busw != (chip->options & NAND_BUSWIDTH_16)) {
printk(KERN_INFO "NAND device: Manufacturer ID:"
- " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
- dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
+ " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
+ dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
printk(KERN_WARNING "NAND bus width %d instead %d bit\n",
- (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
- busw ? 16 : 8);
+ (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
+ busw ? 16 : 8);
return ERR_PTR(-EINVAL);
}
@@ -1147,27 +1279,17 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
chip->bbt_erase_shift = chip->phys_erase_shift =
ffs(mtd->erasesize) - 1;
- chip->chip_shift = ffs(chip->chipsize) - 1;
+ if (chip->chipsize & 0xffffffff)
+ chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
+ else {
+ chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32));
+ chip->chip_shift += 32 - 1;
+ }
/* Set the bad block position */
chip->badblockpos = mtd->writesize > 512 ?
NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
- /* Get chip options, preserve non chip based options */
- chip->options &= ~NAND_CHIPOPTIONS_MSK;
- chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
-
- /*
- * Set chip as a default. Board drivers can override it, if necessary
- */
- chip->options |= NAND_NO_AUTOINCR;
-
- /* Check if chip is a not a samsung device. Do not clear the
- * options for chips which are not having an extended id.
- */
- if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
- chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
-
#ifdef CONFIG_MTD_WRITE
/* Check for AND chips with 4 page planes */
if (chip->options & NAND_4PAGE_ARRAY)
@@ -1179,9 +1301,11 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
chip->cmdfunc = nand_command_lp;
- printk(KERN_INFO "NAND device: Manufacturer ID:"
- " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id,
- nand_manuf_ids[maf_idx].name, type->name);
+ printk("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
+ " page size: %d, OOB size: %d\n",
+ *maf_id, dev_id, nand_manuf_ids[maf_idx].name,
+ chip->onfi_version ? chip->onfi_params.model : type->name,
+ mtd->writesize, mtd->oobsize);
return type;
}
diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h
index 33e1fe2..90dee7e 100644
--- a/include/linux/mtd/mtd-abi.h
+++ b/include/linux/mtd/mtd-abi.h
@@ -115,16 +115,17 @@ struct nand_oobfree {
uint32_t length;
};
-#define MTD_MAX_OOBFREE_ENTRIES 8
+#define MTD_MAX_OOBFREE_ENTRIES_LARGE 32
+#define MTD_MAX_ECCPOS_ENTRIES_LARGE 128 /* FIXME : understand why 448 is not working */
/*
* ECC layout control structure. Exported to userspace for
* diagnosis and to allow creation of raw images
*/
struct nand_ecclayout {
uint32_t eccbytes;
- uint32_t eccpos[64];
+ uint32_t eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
uint32_t oobavail;
- struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
+ struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
};
/**
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 2a1c4ff..4a492b5 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -80,6 +80,7 @@ extern void nand_wait_ready(struct mtd_info *mtd);
#define NAND_CMD_RNDIN 0x85
#define NAND_CMD_READID 0x90
#define NAND_CMD_ERASE2 0xd0
+#define NAND_CMD_PARAM 0xec
#define NAND_CMD_RESET 0xff
/* Extended commands for large page devices */
@@ -217,6 +218,70 @@ typedef enum {
/* Keep gcc happy */
struct nand_chip;
+struct nand_onfi_params {
+ /* rev info and features block */
+ /* 'O' 'N' 'F' 'I' */
+ u8 sig[4];
+ __le16 revision;
+ __le16 features;
+ __le16 opt_cmd;
+ u8 reserved[22];
+
+ /* manufacturer information block */
+ char manufacturer[12];
+ char model[20];
+ u8 jedec_id;
+ __le16 date_code;
+ u8 reserved2[13];
+
+ /* memory organization block */
+ __le32 byte_per_page;
+ __le16 spare_bytes_per_page;
+ __le32 data_bytes_per_ppage;
+ __le16 spare_bytes_per_ppage;
+ __le32 pages_per_block;
+ __le32 blocks_per_lun;
+ u8 lun_count;
+ u8 addr_cycles;
+ u8 bits_per_cell;
+ __le16 bb_per_lun;
+ __le16 block_endurance;
+ u8 guaranteed_good_blocks;
+ __le16 guaranteed_block_endurance;
+ u8 programs_per_page;
+ u8 ppage_attr;
+ u8 ecc_bits;
+ u8 interleaved_bits;
+ u8 interleaved_ops;
+ u8 reserved3[13];
+
+ /* electrical parameter block */
+ u8 io_pin_capacitance_max;
+ __le16 async_timing_mode;
+ __le16 program_cache_timing_mode;
+ __le16 t_prog;
+ __le16 t_bers;
+ __le16 t_r;
+ __le16 t_ccs;
+ __le16 src_sync_timing_mode;
+ __le16 src_ssync_features;
+ __le16 clk_pin_capacitance_typ;
+ __le16 io_pin_capacitance_typ;
+ __le16 input_pin_capacitance_typ;
+ u8 input_pin_capacitance_max;
+ u8 driver_strenght_support;
+ __le16 t_int_r;
+ __le16 t_ald;
+ u8 reserved4[7];
+
+ /* vendor */
+ u8 reserved5[90];
+
+ __le16 crc;
+} __attribute__((packed));
+
+#define ONFI_CRC_BASE 0x4F4E
+
/**
* struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
* @lock: protection lock
@@ -347,6 +412,10 @@ struct nand_buffers {
* @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
* @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf
* @subpagesize: [INTERN] holds the subpagesize
+ * @onfi_version: [INTERN] holds the chip ONFI version (BCD encoded),
+ * non 0 if ONFI supported.
+ * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is
+ * supported, 0 otherwise.
* @ecclayout: [REPLACEABLE] the default ecc placement scheme
* @bbt: [INTERN] bad block table pointer
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup
@@ -391,13 +460,16 @@ struct nand_chip {
int bbt_erase_shift;
int chip_shift;
int numchips;
- unsigned long chipsize;
+ uint64_t chipsize;
int pagemask;
int pagebuf;
int subpagesize;
uint8_t cellinfo;
int badblockpos;
+ int onfi_version;
+ struct nand_onfi_params onfi_params;
+
nand_state_t state;
uint8_t *oob_poi;
--
1.7.7.6
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] nand_imx: update to support onfi & 4k flashs
2012-07-05 10:22 [PATCH 1/3] string: add strim for ONFI code Eric Bénard
2012-07-05 10:22 ` [PATCH 2/3] nand_base: add ONFI flash detection Eric Bénard
@ 2012-07-05 10:22 ` Eric Bénard
2012-07-09 7:30 ` [PATCH 1/3] string: add strim for ONFI code Sascha Hauer
2 siblings, 0 replies; 6+ messages in thread
From: Eric Bénard @ 2012-07-05 10:22 UTC (permalink / raw)
To: barebox
- add CMD_PARAM and read_param to get the ONFI structure
- fix OOB size for flash with 224 OOB on i.MX51/3
- add the same ecc layout as the one in the kernel for
4k page flashs
Tested on an i.MX53.
Signed-off-by: Eric Bénard <eric@eukrea.com>
---
drivers/mtd/nand/nand_imx.c | 98 ++++++++++++++++++++++++++++++++++++++++--
1 files changed, 93 insertions(+), 5 deletions(-)
diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c
index e75ffbc..83b49e3 100644
--- a/drivers/mtd/nand/nand_imx.c
+++ b/drivers/mtd/nand/nand_imx.c
@@ -106,6 +106,7 @@ struct imx_nand_host {
void (*send_addr)(struct imx_nand_host *, uint16_t);
void (*send_page)(struct imx_nand_host *, unsigned int);
void (*send_read_id)(struct imx_nand_host *);
+ void (*send_read_param)(struct imx_nand_host *);
uint16_t (*get_dev_status)(struct imx_nand_host *);
int (*check_int)(struct imx_nand_host *);
};
@@ -154,6 +155,31 @@ static struct nand_ecclayout nandv2_hw_eccoob_largepage = {
}
};
+/* OOB description for 4096 byte pages with 128 byte OOB */
+static struct nand_ecclayout nandv2_hw_eccoob_4k = {
+ .eccbytes = 8 * 9,
+ .eccpos = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ },
+ .oobfree = {
+ {.offset = 2, .length = 4},
+ {.offset = 16, .length = 7},
+ {.offset = 32, .length = 7},
+ {.offset = 48, .length = 7},
+ {.offset = 64, .length = 7},
+ {.offset = 80, .length = 7},
+ {.offset = 96, .length = 7},
+ {.offset = 112, .length = 7},
+ }
+};
+
static void memcpy32(void *trg, const void *src, int size)
{
int i;
@@ -335,6 +361,16 @@ static void send_read_id_v3(struct imx_nand_host *host)
memcpy(host->data_buf, host->main_area0, 16);
}
+static void send_read_param_v3(struct imx_nand_host *host)
+{
+ /* Read ID into main buffer */
+ writel(NFC_OUTPUT, NFC_V3_LAUNCH);
+
+ wait_op_done(host);
+
+ memcpy(host->data_buf, host->main_area0, 1024);
+}
+
static void send_read_id_v1_v2(struct imx_nand_host *host)
{
struct nand_chip *this = &host->nand;
@@ -363,6 +399,34 @@ static void send_read_id_v1_v2(struct imx_nand_host *host)
memcpy32(host->data_buf, host->main_area0, 16);
}
+/* FIXME : to check on real HW */
+static void send_read_param_v1_v2(struct imx_nand_host *host)
+{
+ struct nand_chip *this = &host->nand;
+
+ /* NANDFC buffer 0 is used for device ID output */
+ writew(0x0, host->regs + NFC_V1_V2_BUF_ADDR);
+
+ writew(NFC_OUTPUT, host->regs + NFC_V1_V2_CONFIG2);
+
+ /* Wait for operation to complete */
+ wait_op_done(host);
+
+ if (this->options & NAND_BUSWIDTH_16) {
+ volatile u16 *mainbuf = host->main_area0;
+
+ /*
+ * Pack the every-other-byte result for 16-bit ID reads
+ * into every-byte as the generic code expects and various
+ * chips implement.
+ */
+
+ mainbuf[0] = (mainbuf[0] & 0xff) | ((mainbuf[1] & 0xff) << 8);
+ mainbuf[1] = (mainbuf[2] & 0xff) | ((mainbuf[3] & 0xff) << 8);
+ mainbuf[2] = (mainbuf[4] & 0xff) | ((mainbuf[5] & 0xff) << 8);
+ }
+ memcpy32(host->data_buf, host->main_area0, 1024);
+}
/*
* This function requests the NANDFC to perform a read of the
* NAND device status and returns the current status.
@@ -579,6 +643,10 @@ static void imx_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len)
n = min(n, len);
+ /* handle the read param special case */
+ if ((mtd->writesize == 0) && (len != 0))
+ n = len;
+
memcpy(buf, host->data_buf + col, n);
host->buf_start += n;
@@ -677,8 +745,11 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
* layers perform a read/write buf operation,
* we will used the saved column adress to index into
* the full page.
+ *
+ * The colum address must be sent to the flash in
+ * order to get the ONFI header (0x20)
*/
- host->send_addr(host, 0);
+ host->send_addr(host, column);
if (host->pagesize_2k)
/* another col addr cycle for 2k page */
host->send_addr(host, 0);
@@ -790,9 +861,11 @@ static void preset_v3(struct mtd_info *mtd)
writel(0, NFC_V3_IPC);
+ /* if the flash has a 224 oob, the NFC must be configured to 218 */
config2 = NFC_V3_CONFIG2_ONE_CYCLE |
NFC_V3_CONFIG2_2CMD_PHASES |
- NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) |
+ NFC_V3_CONFIG2_SPAS(((mtd->oobsize > 218) ?
+ 218 : mtd->oobsize) >> 1) |
NFC_V3_CONFIG2_ST_CMD(0x70) |
NFC_V3_CONFIG2_NUM_ADDR_PHASE0;
@@ -944,8 +1017,15 @@ static void imx_nand_command(struct mtd_info *mtd, unsigned command,
case NAND_CMD_READID:
host->send_cmd(host, command);
mxc_do_addr_cycle(mtd, column, page_addr);
- host->buf_start = 0;
host->send_read_id(host);
+ host->buf_start = 0;
+ break;
+
+ case NAND_CMD_PARAM:
+ host->send_cmd(host, command);
+ mxc_do_addr_cycle(mtd, column, page_addr);
+ host->send_read_param(host);
+ host->buf_start = 0;
break;
case NAND_CMD_ERASE1:
@@ -1024,7 +1104,7 @@ static int __init imxnd_probe(struct device_d *dev)
struct mtd_info *mtd;
struct imx_nand_platform_data *pdata = dev->platform_data;
struct imx_nand_host *host;
- struct nand_ecclayout *oob_smallpage, *oob_largepage;
+ struct nand_ecclayout *oob_smallpage, *oob_largepage, *oob_4kpage;
int err = 0;
#ifdef CONFIG_ARCH_IMX27
@@ -1047,6 +1127,7 @@ static int __init imxnd_probe(struct device_d *dev)
host->send_addr = send_addr_v1_v2;
host->send_page = send_page_v1_v2;
host->send_read_id = send_read_id_v1_v2;
+ host->send_read_param = send_read_param_v1_v2; /* FIXME : to check */
host->get_dev_status = get_dev_status_v1_v2;
host->check_int = check_int_v1_v2;
}
@@ -1059,6 +1140,7 @@ static int __init imxnd_probe(struct device_d *dev)
host->spare_len = 64;
oob_smallpage = &nandv2_hw_eccoob_smallpage;
oob_largepage = &nandv2_hw_eccoob_largepage;
+ oob_4kpage = &nandv2_hw_eccoob_4k; /* FIXME : to check */
} else if (nfc_is_v1()) {
host->base = dev_request_mem_region(dev, 0);
host->main_area0 = host->base;
@@ -1067,6 +1149,7 @@ static int __init imxnd_probe(struct device_d *dev)
host->spare_len = 16;
oob_smallpage = &nandv1_hw_eccoob_smallpage;
oob_largepage = &nandv1_hw_eccoob_largepage;
+ oob_4kpage = &nandv1_hw_eccoob_smallpage; /* FIXME : to check */
} else if (nfc_is_v3_2()) {
host->regs_ip = dev_request_mem_region(dev, 0);
host->base = dev_request_mem_region(dev, 1);
@@ -1086,10 +1169,12 @@ static int __init imxnd_probe(struct device_d *dev)
host->send_addr = send_addr_v3;
host->send_page = send_page_v3;
host->send_read_id = send_read_id_v3;
+ host->send_read_param = send_read_param_v3;
host->get_dev_status = get_dev_status_v3;
host->check_int = check_int_v3;
oob_smallpage = &nandv2_hw_eccoob_smallpage;
oob_largepage = &nandv2_hw_eccoob_largepage;
+ oob_4kpage = &nandv2_hw_eccoob_4k;
}
host->dev = dev;
@@ -1161,7 +1246,10 @@ static int __init imxnd_probe(struct device_d *dev)
imx_nand_set_layout(mtd->writesize, pdata->width == 2 ? 16 : 8);
if (mtd->writesize >= 2048) {
- this->ecc.layout = oob_largepage;
+ if (mtd->writesize == 2048)
+ this->ecc.layout = oob_largepage;
+ else
+ this->ecc.layout = oob_4kpage;
host->pagesize_2k = 1;
if (nfc_is_v21())
writew(NFC_V2_SPAS_SPARESIZE(64), host->regs + NFC_V2_SPAS);
--
1.7.7.6
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] nand_base: add ONFI flash detection
2012-07-05 10:22 ` [PATCH 2/3] nand_base: add ONFI flash detection Eric Bénard
@ 2012-07-05 19:02 ` Sascha Hauer
2012-07-05 20:32 ` Eric Bénard
0 siblings, 1 reply; 6+ messages in thread
From: Sascha Hauer @ 2012-07-05 19:02 UTC (permalink / raw)
To: Eric Bénard; +Cc: barebox
On Thu, Jul 05, 2012 at 12:22:46PM +0200, Eric Bénard wrote:
> the code is taken from linux & u-boot implementations
> Validated on an i.MX53 which gives the following log :
> ONFI flash detected ... ONFI param page 0 valid
> NAND device: Manufacturer ID: 0x2c, Chip ID: 0x38 (Micron MT29F8G08ABABAWP), page size: 4096, OOB size: 224
>
> Signed-off-by: Eric Bénard <eric@eukrea.com>
> ---
> drivers/mtd/nand/nand_base.c | 174 ++++++++++++++++++++++++++++++++++++------
> include/linux/mtd/mtd-abi.h | 7 +-
> include/linux/mtd/nand.h | 74 ++++++++++++++++++-
> 3 files changed, 226 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> #ifdef CONFIG_MTD_WRITE
> /* Check for AND chips with 4 page planes */
> if (chip->options & NAND_4PAGE_ARRAY)
> @@ -1179,9 +1301,11 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
> if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
> chip->cmdfunc = nand_command_lp;
>
> - printk(KERN_INFO "NAND device: Manufacturer ID:"
> - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id,
> - nand_manuf_ids[maf_idx].name, type->name);
> + printk("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
> + " page size: %d, OOB size: %d\n",
> + *maf_id, dev_id, nand_manuf_ids[maf_idx].name,
> + chip->onfi_version ? chip->onfi_params.model : type->name,
> + mtd->writesize, mtd->oobsize);
Do we need to output writesize and oobsize here? 'devinfo nand0' will
give the same information.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] nand_base: add ONFI flash detection
2012-07-05 19:02 ` Sascha Hauer
@ 2012-07-05 20:32 ` Eric Bénard
0 siblings, 0 replies; 6+ messages in thread
From: Eric Bénard @ 2012-07-05 20:32 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
Hi Sascha,
Le Thu, 5 Jul 2012 21:02:40 +0200,
Sascha Hauer <s.hauer@pengutronix.de> a écrit :
> > - printk(KERN_INFO "NAND device: Manufacturer ID:"
> > - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id,
> > - nand_manuf_ids[maf_idx].name, type->name);
> > + printk("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
> > + " page size: %d, OOB size: %d\n",
> > + *maf_id, dev_id, nand_manuf_ids[maf_idx].name,
> > + chip->onfi_version ? chip->onfi_params.model : type->name,
> > + mtd->writesize, mtd->oobsize);
>
> Do we need to output writesize and oobsize here? 'devinfo nand0' will
> give the same information.
>
that's the way it's done in the kernel so I imported the log update.
Eric
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] string: add strim for ONFI code
2012-07-05 10:22 [PATCH 1/3] string: add strim for ONFI code Eric Bénard
2012-07-05 10:22 ` [PATCH 2/3] nand_base: add ONFI flash detection Eric Bénard
2012-07-05 10:22 ` [PATCH 3/3] nand_imx: update to support onfi & 4k flashs Eric Bénard
@ 2012-07-09 7:30 ` Sascha Hauer
2 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2012-07-09 7:30 UTC (permalink / raw)
To: Eric Bénard; +Cc: barebox
On Thu, Jul 05, 2012 at 12:22:45PM +0200, Eric Bénard wrote:
> Signed-off-by: Eric Bénard <eric@eukrea.com>
> ---
> include/linux/string.h | 3 +++
> lib/string.c | 39 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 42 insertions(+), 0 deletions(-)
Applied all three
Sascha
>
> diff --git a/include/linux/string.h b/include/linux/string.h
> index 62d743e..afd0aa6 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -93,6 +93,9 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
> #ifndef __HAVE_ARCH_MEMCHR
> extern void * memchr(const void *,int,__kernel_size_t);
> #endif
> +extern char * skip_spaces(const char *);
> +
> +extern char *strim(char *);
>
> #ifdef __cplusplus
> }
> diff --git a/lib/string.c b/lib/string.c
> index 2865088..db4f2ae 100644
> --- a/lib/string.c
> +++ b/lib/string.c
> @@ -567,3 +567,42 @@ void *memchr(const void *s, int c, size_t n)
> #endif
> EXPORT_SYMBOL(memchr);
>
> +/**
> + * skip_spaces - Removes leading whitespace from @str.
> + * @str: The string to be stripped.
> + *
> + * Returns a pointer to the first non-whitespace character in @str.
> + */
> +char *skip_spaces(const char *str)
> +{
> + while (isspace(*str))
> + ++str;
> + return (char *)str;
> +}
> +
> +/**
> + * strim - Removes leading and trailing whitespace from @s.
> + * @s: The string to be stripped.
> + *
> + * Note that the first trailing whitespace is replaced with a %NUL-terminator
> + * in the given string @s. Returns a pointer to the first non-whitespace
> + * character in @s.
> + */
> +char *strim(char *s)
> +{
> + size_t size;
> + char *end;
> +
> + s = skip_spaces(s);
> + size = strlen(s);
> + if (!size)
> + return s;
> +
> + end = s + size - 1;
> + while (end >= s && isspace(*end))
> + end--;
> + *(end + 1) = '\0';
> +
> + return s;
> +}
> +EXPORT_SYMBOL(strim);
> --
> 1.7.7.6
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-07-09 7:30 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-05 10:22 [PATCH 1/3] string: add strim for ONFI code Eric Bénard
2012-07-05 10:22 ` [PATCH 2/3] nand_base: add ONFI flash detection Eric Bénard
2012-07-05 19:02 ` Sascha Hauer
2012-07-05 20:32 ` Eric Bénard
2012-07-05 10:22 ` [PATCH 3/3] nand_imx: update to support onfi & 4k flashs Eric Bénard
2012-07-09 7:30 ` [PATCH 1/3] string: add strim for ONFI code Sascha Hauer
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.