sunxi: add support for 4.1
[openwrt/staging/chunkeey.git] / target / linux / sunxi / patches-4.1 / 119-mtd-nand-ecc-for-samsung.patch
diff --git a/target/linux/sunxi/patches-4.1/119-mtd-nand-ecc-for-samsung.patch b/target/linux/sunxi/patches-4.1/119-mtd-nand-ecc-for-samsung.patch
new file mode 100644 (file)
index 0000000..c92398e
--- /dev/null
@@ -0,0 +1,70 @@
+From 3fecbdac2fe503fb6896ec08dd2474958d198d62 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 24 May 2015 12:01:16 +0200
+Subject: [PATCH] mtd: nand: nand_decode_ext_id(): Fill in ecc strength and
+ size for Samsung
+
+On some nand controllers with hw-ecc the controller code wants to know the
+ecc strength and size and having these as 0, 0 is not accepted.
+
+Specifying these in devicetree is possible but undesirable as the nand
+may be different in different production runs of the same board, so it
+is better to get this info from the nand id where possible.
+
+This commit adds code to read the ecc strength and size from the nand for
+Samsung extended-id nands. This code is based on the info for the 5th
+id byte in the datasheets for the following Samsung nands: K9GAG08U0E,
+K9GAG08U0F, K9GAG08X0D, K9GBG08U0A, K9GBG08U0B. These all use these bits
+in the exact same way.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/mtd/nand/nand_base.c | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
+index 51642c6..e3d4d8e 100644
+--- a/drivers/mtd/nand/nand_base.c
++++ b/drivers/mtd/nand/nand_base.c
+@@ -4063,6 +4063,41 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
+               mtd->erasesize = (128 * 1024) <<
+                       (((extid >> 1) & 0x04) | (extid & 0x03));
+               *busw = 0;
++              /* Calc ecc strength and size from 5th id byte*/
++              switch ((id_data[4] >> 4) & 0x07) {
++              case 0:
++                      chip->ecc_strength_ds = 1;
++                      chip->ecc_step_ds = 512;
++                      break;
++              case 1:
++                      chip->ecc_strength_ds = 2;
++                      chip->ecc_step_ds = 512;
++                      break;
++              case 2:
++                      chip->ecc_strength_ds = 4;
++                      chip->ecc_step_ds = 512;
++                      break;
++              case 3:
++                      chip->ecc_strength_ds = 8;
++                      chip->ecc_step_ds = 512;
++                      break;
++              case 4:
++                      chip->ecc_strength_ds = 16;
++                      chip->ecc_step_ds = 512;
++                      break;
++              case 5:
++                      chip->ecc_strength_ds = 24;
++                      chip->ecc_step_ds = 1024;
++                      break;
++              case 6:
++                      chip->ecc_strength_ds = 40;
++                      chip->ecc_step_ds = 1024;
++                      break;
++              case 7:
++                      chip->ecc_strength_ds = 60;
++                      chip->ecc_step_ds = 1024;
++                      break;
++              }
+       } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
+                       !nand_is_slc(chip)) {
+               unsigned int tmp;