mtd: nand: add support for reading ONFI parameters from NAND device

This patch adds support for reading NAND device ONFI parameters and use
the ONFI informations to define its geometry. In case the device supports
ONFI, the onfi_version field in struct nand_chip contains the version (BCD)
and the onfi_params structure can be used by drivers to set up timings and
such. We currently only support ONFI 1.0 parameters.

Signed-off-by: Brian Norris <norris@broadcom.com>
Signed-off-by: Matthieu Castet <matthieu.castet@parrot.com>
Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
Signed-off-by: Florian Fainelli <ffainelli@freebox.fr>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 29656a3..7666c42 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -228,6 +228,69 @@
 /* Keep gcc happy */
 struct nand_chip;
 
+struct nand_onfi_params {
+	/* rev info and features block */
+	u8		sig[4]; /* 'O' 'N' 'F' 'I'  */
+	__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
@@ -360,6 +423,8 @@
  * @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
@@ -412,6 +477,9 @@
 	int		badblockpos;
 	int		badblockbits;
 
+	int		onfi_version;
+	struct nand_onfi_params	onfi_params;
+
 	flstate_t	state;
 
 	uint8_t		*oob_poi;