]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - include/linux/mtd/nand.h
mtd: nand: Pass the CS line to ->setup_data_interface()
[karo-tx-linux.git] / include / linux / mtd / nand.h
index 9591e0fbe5bd76a1c47e2deb4292469e0a2cf8e6..9de3686e738c107db2d094f58b6e2775aa792042 100644 (file)
@@ -107,6 +107,8 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 #define NAND_STATUS_READY      0x40
 #define NAND_STATUS_WP         0x80
 
+#define NAND_DATA_IFACE_CHECK_ONLY     -1
+
 /*
  * Constants for ECC_MODES
  */
@@ -116,6 +118,7 @@ typedef enum {
        NAND_ECC_HW,
        NAND_ECC_HW_SYNDROME,
        NAND_ECC_HW_OOB_FIRST,
+       NAND_ECC_ON_DIE,
 } nand_ecc_modes_t;
 
 enum nand_ecc_algo {
@@ -257,6 +260,8 @@ struct nand_chip;
 
 /* Vendor-specific feature address (Micron) */
 #define ONFI_FEATURE_ADDR_READ_RETRY   0x89
+#define ONFI_FEATURE_ON_DIE_ECC                0x90
+#define   ONFI_FEATURE_ON_DIE_ECC_EN   BIT(3)
 
 /* ONFI subfeature parameters length */
 #define ONFI_SUBFEATURE_PARAM_LEN      4
@@ -366,26 +371,6 @@ struct onfi_ext_param_page {
         */
 } __packed;
 
-struct nand_onfi_vendor_micron {
-       u8 two_plane_read;
-       u8 read_cache;
-       u8 read_unique_id;
-       u8 dq_imped;
-       u8 dq_imped_num_settings;
-       u8 dq_imped_feat_addr;
-       u8 rb_pulldown_strength;
-       u8 rb_pulldown_strength_feat_addr;
-       u8 rb_pulldown_strength_num_settings;
-       u8 otp_mode;
-       u8 otp_page_start;
-       u8 otp_data_prot_addr;
-       u8 otp_num_pages;
-       u8 otp_feat_addr;
-       u8 read_retry_options;
-       u8 reserved[72];
-       u8 param_revision;
-} __packed;
-
 struct jedec_ecc_info {
        u8 ecc_bits;
        u8 codeword_size;
@@ -464,6 +449,17 @@ struct nand_jedec_params {
        __le16 crc;
 } __packed;
 
+/**
+ * struct nand_id - NAND id structure
+ * @data: buffer containing the id bytes. Currently 8 bytes large, but can
+ *       be extended if required.
+ * @len: ID length.
+ */
+struct nand_id {
+       u8 data[8];
+       int len;
+};
+
 /**
  * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
  * @lock:               protection lock
@@ -525,7 +521,7 @@ static inline void nand_hw_control_init(struct nand_hw_control *nfc)
  *                     out-of-band data).
  * @read_page: function to read a page according to the ECC generator
  *             requirements; returns maximum number of bitflips corrected in
- *             any single ECC step, 0 if bitflips uncorrectable, -EIO hw error
+ *             any single ECC step, -EIO hw error
  * @read_subpage:      function to read parts of the page covered by ECC;
  *                     returns same as read_page()
  * @write_subpage:     function to write parts of the page covered by ECC.
@@ -720,6 +716,20 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
        return &conf->timings.sdr;
 }
 
+/**
+ * struct nand_manufacturer_ops - NAND Manufacturer operations
+ * @detect: detect the NAND memory organization and capabilities
+ * @init: initialize all vendor specific fields (like the ->read_retry()
+ *       implementation) if any.
+ * @cleanup: the ->init() function may have allocated resources, ->cleanup()
+ *          is here to let vendor specific code release those resources.
+ */
+struct nand_manufacturer_ops {
+       void (*detect)(struct nand_chip *chip);
+       int (*init)(struct nand_chip *chip);
+       void (*cleanup)(struct nand_chip *chip);
+};
+
 /**
  * struct nand_chip - NAND Private Flash Chip Data
  * @mtd:               MTD device registered to the MTD framework
@@ -750,6 +760,7 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  *                     setting the read-retry mode. Mostly needed for MLC NAND.
  * @ecc:               [BOARDSPECIFIC] ECC control structure
  * @buffers:           buffer structure for read/write
+ * @buf_align:         minimum buffer alignment required by a platform
  * @hwcontrol:         platform-specific hardware control structure
  * @erase:             [REPLACEABLE] erase function
  * @scan_bbt:          [REPLACEABLE] function to scan bad block table
@@ -793,6 +804,7 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * @pagebuf_bitflips:  [INTERN] holds the bitflip count for the page which is
  *                     currently in data_buf.
  * @subpagesize:       [INTERN] holds the subpagesize
+ * @id:                        [INTERN] holds NAND ID
  * @onfi_version:      [INTERN] holds the chip ONFI version (BCD encoded),
  *                     non 0 if ONFI supported.
  * @jedec_version:     [INTERN] holds the chip JEDEC version (BCD encoded),
@@ -808,7 +820,10 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * @read_retries:      [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
- * @setup_data_interface: [OPTIONAL] setup the data interface and timing
+ * @setup_data_interface: [OPTIONAL] setup the data interface and timing. If
+ *                       chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this
+ *                       means the configuration should not be applied but
+ *                       only checked.
  * @bbt:               [INTERN] bad block table pointer
  * @bbt_td:            [REPLACEABLE] bad block table descriptor for flash
  *                     lookup.
@@ -822,7 +837,7 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * @errstat:           [OPTIONAL] hardware specific function to perform
  *                     additional error status checks (determine if errors are
  *                     correctable).
- * @write_page:                [REPLACEABLE] High-level page write function
+ * @manufacturer:      [INTERN] Contains manufacturer information
  */
 
 struct nand_chip {
@@ -847,17 +862,13 @@ struct nand_chip {
        int (*scan_bbt)(struct mtd_info *mtd);
        int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
                        int status, int page);
-       int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
-                       uint32_t offset, int data_len, const uint8_t *buf,
-                       int oob_required, int page, int cached, int raw);
        int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
                        int feature_addr, uint8_t *subfeature_para);
        int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
                        int feature_addr, uint8_t *subfeature_para);
        int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode);
-       int (*setup_data_interface)(struct mtd_info *mtd,
-                                   const struct nand_data_interface *conf,
-                                   bool check_only);
+       int (*setup_data_interface)(struct mtd_info *mtd, int chipnr,
+                                   const struct nand_data_interface *conf);
 
 
        int chip_delay;
@@ -881,6 +892,7 @@ struct nand_chip {
        int badblockpos;
        int badblockbits;
 
+       struct nand_id id;
        int onfi_version;
        int jedec_version;
        union {
@@ -901,6 +913,7 @@ struct nand_chip {
 
        struct nand_ecc_ctrl ecc;
        struct nand_buffers *buffers;
+       unsigned long buf_align;
        struct nand_hw_control hwcontrol;
 
        uint8_t *bbt;
@@ -910,6 +923,11 @@ struct nand_chip {
        struct nand_bbt_descr *badblock_pattern;
 
        void *priv;
+
+       struct {
+               const struct nand_manufacturer *desc;
+               void *priv;
+       } manufacturer;
 };
 
 extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops;
@@ -946,6 +964,17 @@ static inline void nand_set_controller_data(struct nand_chip *chip, void *priv)
        chip->priv = priv;
 }
 
+static inline void nand_set_manufacturer_data(struct nand_chip *chip,
+                                             void *priv)
+{
+       chip->manufacturer.priv = priv;
+}
+
+static inline void *nand_get_manufacturer_data(struct nand_chip *chip)
+{
+       return chip->manufacturer.priv;
+}
+
 /*
  * NAND Flash Manufacturer ID Codes
  */
@@ -1049,17 +1078,33 @@ struct nand_flash_dev {
 };
 
 /**
- * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
+ * struct nand_manufacturer - NAND Flash Manufacturer structure
  * @name:      Manufacturer name
  * @id:                manufacturer ID code of device.
+ * @ops:       manufacturer operations
 */
-struct nand_manufacturers {
+struct nand_manufacturer {
        int id;
        char *name;
+       const struct nand_manufacturer_ops *ops;
 };
 
+const struct nand_manufacturer *nand_get_manufacturer(u8 id);
+
+static inline const char *
+nand_manufacturer_name(const struct nand_manufacturer *manufacturer)
+{
+       return manufacturer ? manufacturer->name : "Unknown";
+}
+
 extern struct nand_flash_dev nand_flash_ids[];
-extern struct nand_manufacturers nand_manuf_ids[];
+
+extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops;
+extern const struct nand_manufacturer_ops samsung_nand_manuf_ops;
+extern const struct nand_manufacturer_ops hynix_nand_manuf_ops;
+extern const struct nand_manufacturer_ops micron_nand_manuf_ops;
+extern const struct nand_manufacturer_ops amd_nand_manuf_ops;
+extern const struct nand_manufacturer_ops macronix_nand_manuf_ops;
 
 int nand_default_bbt(struct mtd_info *mtd);
 int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
@@ -1220,10 +1265,25 @@ int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page);
 int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
                           int page);
 
+/* Stub used by drivers that do not support GET/SET FEATURES operations */
+int nand_onfi_get_set_features_notsupp(struct mtd_info *mtd,
+                                      struct nand_chip *chip, int addr,
+                                      u8 *subfeature_param);
+
+/* Default read_page_raw implementation */
+int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+                      uint8_t *buf, int oob_required, int page);
+
+/* Default write_page_raw implementation */
+int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+                       const uint8_t *buf, int oob_required, int page);
+
 /* Reset and initialize a NAND device */
 int nand_reset(struct nand_chip *chip, int chipnr);
 
 /* Free resources held by the NAND device */
 void nand_cleanup(struct nand_chip *chip);
 
+/* Default extended ID decoding function */
+void nand_decode_ext_id(struct nand_chip *chip);
 #endif /* __LINUX_MTD_NAND_H */