diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-11-27 17:47:45 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-11-27 17:47:45 -0800 |
commit | 015d812ccc46ddbb4856023af5ae6c6dd1297e61 (patch) | |
tree | 60a16ccb72ca57b1f14e326967a5ebe77e69a047 | |
parent | bf65fa1dcae4aa4a65f9cdcab45aa013b2054ab3 (diff) | |
download | ltsi-kernel-015d812ccc46ddbb4856023af5ae6c6dd1297e61.tar.gz |
another misc patch
-rw-r--r-- | patches.misc/mtd-nand-support-for-toshiba-benand-built-in-ecc-nand.patch | 338 | ||||
-rw-r--r-- | series | 2 |
2 files changed, 339 insertions, 1 deletions
diff --git a/patches.misc/mtd-nand-support-for-toshiba-benand-built-in-ecc-nand.patch b/patches.misc/mtd-nand-support-for-toshiba-benand-built-in-ecc-nand.patch new file mode 100644 index 00000000000000..3be824b924b1c8 --- /dev/null +++ b/patches.misc/mtd-nand-support-for-toshiba-benand-built-in-ecc-nand.patch @@ -0,0 +1,338 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Thu Oct 22 12:51:02 2015 +From: KOBAYASHI Yoshitake <yoshitake.kobayashi@toshiba.co.jp> +Date: Fri, 23 Oct 2015 04:50:50 +0900 +Subject: mtd: nand: support for Toshiba BENAND (Built-in ECC NAND) +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <1445543450-26077-1-git-send-email-yoshitake.kobayashi@toshiba.co.jp> + + +Please consider adding the Toshiba BENAND patch for LTSI-4.1, +This patch was posted as below, but it hasn't merged yet. + https://lkml.org/lkml/2015/7/23/859 + +This patch enables support for Toshiba BENAND. BENAND is a SLC NAND +solution that automatically generates ECC inside NAND chip. + +Signed-off-by: KOBAYASHI Yoshitake <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/mtd/nand/Kconfig | 21 +++++ + drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/nand_base.c | 30 +++++++ + drivers/mtd/nand/nand_benand.c | 154 ++++++++++++++++++++++++++++++++++++++++ + include/linux/mtd/nand.h | 1 + include/linux/mtd/nand_benand.h | 48 ++++++++++++ + 6 files changed, 253 insertions(+), 2 deletions(-) + create mode 100644 drivers/mtd/nand/nand_benand.c + create mode 100644 include/linux/mtd/nand_benand.h + +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -22,6 +22,27 @@ menuconfig MTD_NAND + + if MTD_NAND + ++config MTD_NAND_BENAND ++ tristate ++ depends on MTD_NAND_BENAND_ENABLE ++ default MTD_NAND ++ ++config MTD_NAND_BENAND_ENABLE ++ bool "Support for Toshiba BENAND (Built-in ECC NAND)" ++ default y ++ help ++ This enables support for Toshiba BENAND. ++ Toshiba BENAND is a SLC NAND solution that automatically ++ generates ECC inside NAND chip. ++ ++config MTD_NAND_BENAND_ECC_STATUS ++ bool "Enable ECC Status Read Command(0x7A)" ++ depends on MTD_NAND_BENAND_ENABLE ++ help ++ This enables support for ECC Status Read Command(0x7A) of BENAND. ++ When this enables, report the real number of bitflips. ++ In other cases, report the assumud number. ++ + config MTD_NAND_BCH + tristate + select BCH +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -3,6 +3,7 @@ + # + + obj-$(CONFIG_MTD_NAND) += nand.o ++obj-$(CONFIG_MTD_NAND_BENAND) += nand_benand.o + obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o + obj-$(CONFIG_MTD_NAND_BCH) += nand_bch.o + obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o +--- a/drivers/mtd/nand/nand_base.c ++++ b/drivers/mtd/nand/nand_base.c +@@ -43,6 +43,7 @@ + #include <linux/mtd/nand.h> + #include <linux/mtd/nand_ecc.h> + #include <linux/mtd/nand_bch.h> ++#include <linux/mtd/nand_benand.h> + #include <linux/interrupt.h> + #include <linux/bitops.h> + #include <linux/leds.h> +@@ -3526,8 +3527,13 @@ static void nand_decode_ext_id(struct mt + if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA && + nand_is_slc(chip) && + (id_data[5] & 0x7) == 0x6 /* 24nm */ && +- !(id_data[4] & 0x80) /* !BENAND */) { +- mtd->oobsize = 32 * mtd->writesize >> 9; ++ (id_data[4] & 0x80) /* BENAND */) { ++ ++ if (IS_ENABLED(CONFIG_MTD_NAND_BENAND)) ++ chip->ecc.mode = NAND_ECC_BENAND; ++ ++ } else { ++ mtd->oobsize = 32 * mtd->writesize >> 9; /* !BENAND */ + } + + } +@@ -4075,6 +4081,26 @@ int nand_scan_tail(struct mtd_info *mtd) + } + break; + ++ case NAND_ECC_BENAND: ++ if (!mtd_nand_has_benand()) { ++ pr_warn("CONFIG_MTD_NAND_BENAND not enabled\n"); ++ BUG(); ++ } ++ ecc->calculate = NULL; ++ ecc->correct = NULL; ++ ecc->read_page = nand_read_page_benand; ++ ecc->read_subpage = nand_read_subpage_benand; ++ ecc->write_page = nand_write_page_raw; ++ ecc->read_page_raw = nand_read_page_raw; ++ ecc->write_page_raw = nand_write_page_raw; ++ ecc->read_oob = nand_read_oob_std; ++ ecc->write_oob = nand_write_oob_std; ++ ecc->size = mtd->writesize; ++ ecc->strength = 8; ++ ++ nand_benand_init(mtd); ++ break; ++ + case NAND_ECC_NONE: + pr_warn("NAND_ECC_NONE selected by board driver. This is not recommended!\n"); + ecc->read_page = nand_read_page_raw; +--- /dev/null ++++ b/drivers/mtd/nand/nand_benand.c +@@ -0,0 +1,154 @@ ++/* ++ * drivers/mtd/nand_benand.c ++ * ++ * (C) Copyright Toshiba Corporation ++ * Semiconductor and Storage Products Company 2015 ++ * ++ * This program supports BENAND. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/mtd/nand.h> ++#include <linux/mtd/nand_benand.h> ++ ++/* Recommended to rewrite for BENAND */ ++#define NAND_STATUS_RECOM_REWRT 0x08 ++ ++/* ECC Status Read Command */ ++#define NAND_CMD_ECC_STATUS 0x7A ++ ++static struct nand_ecclayout benand_oob_64 = { ++ .eccbytes = 0, ++ .eccpos = {}, ++ .oobfree = { ++ {.offset = 2, .length = 62} ++ } ++}; ++ ++static struct nand_ecclayout benand_oob_128 = { ++ .eccbytes = 0, ++ .eccpos = {}, ++ .oobfree = { ++ {.offset = 2, .length = 126} ++ } ++}; ++ ++ ++static int nand_benand_status_chk(struct mtd_info *mtd, struct nand_chip *chip) ++{ ++ unsigned int max_bitflips = 0; ++ u8 status; ++ ++ /* Check Read Status */ ++ chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); ++ status = chip->read_byte(mtd); ++ ++ /* timeout */ ++ if (!(status & NAND_STATUS_READY)) { ++ pr_debug("BENAND : Time Out!\n"); ++ return -EIO; ++ } ++ ++ /* uncorrectable */ ++ else if (status & NAND_STATUS_FAIL) ++ mtd->ecc_stats.failed++; ++ ++ /* correctable */ ++ else if (status & NAND_STATUS_RECOM_REWRT) { ++ if (chip->cmd_ctrl && ++ IS_ENABLED(CONFIG_MTD_NAND_BENAND_ECC_STATUS)) { ++ ++ int i; ++ u8 ecc_status; ++ unsigned int bitflips; ++ ++ /* Check Read ECC Status */ ++ chip->cmd_ctrl(mtd, NAND_CMD_ECC_STATUS, ++ NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); ++ /* Get bitflips info per 512Byte */ ++ for (i = 0; i < mtd->writesize >> 9; i++) { ++ ecc_status = chip->read_byte(mtd); ++ bitflips = ecc_status & 0x0f; ++ max_bitflips = max_t(unsigned int, ++ max_bitflips, bitflips); ++ } ++ mtd->ecc_stats.corrected += max_bitflips; ++ } else { ++ /* ++ * If can't use chip->cmd_ctrl, ++ * we can't get real number of bitflips. ++ * So, we set max_bitflips mtd->bitflip_threshold. ++ */ ++ max_bitflips = mtd->bitflip_threshold; ++ mtd->ecc_stats.corrected += max_bitflips; ++ } ++ } ++ ++ return max_bitflips; ++} ++ ++ ++void nand_benand_init(struct mtd_info *mtd) ++{ ++ struct nand_chip *chip = mtd->priv; ++ ++ chip->options |= NAND_SUBPAGE_READ; ++ ++ switch (mtd->oobsize) { ++ case 64: ++ chip->ecc.layout = &benand_oob_64; ++ break; ++ case 128: ++ chip->ecc.layout = &benand_oob_128; ++ break; ++ default: ++ pr_warn("No oob scheme defined for oobsize %d\n", ++ mtd->oobsize); ++ BUG(); ++ } ++ ++} ++EXPORT_SYMBOL(nand_benand_init); ++ ++int nand_read_page_benand(struct mtd_info *mtd, struct nand_chip *chip, ++ uint8_t *buf, int oob_required, int page) ++{ ++ unsigned int max_bitflips = 0; ++ ++ chip->ecc.read_page_raw(mtd, chip, buf, oob_required, page); ++ max_bitflips = nand_benand_status_chk(mtd, chip); ++ ++ return max_bitflips; ++} ++EXPORT_SYMBOL(nand_read_page_benand); ++ ++ ++int nand_read_subpage_benand(struct mtd_info *mtd, struct nand_chip *chip, ++ uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi, ++ int page) ++{ ++ uint8_t *p; ++ unsigned int max_bitflips = 0; ++ ++ if (data_offs != 0) ++ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_offs, -1); ++ ++ p = bufpoi + data_offs; ++ chip->read_buf(mtd, p, readlen); ++ ++ max_bitflips = nand_benand_status_chk(mtd, chip); ++ ++ return max_bitflips; ++} ++EXPORT_SYMBOL(nand_read_subpage_benand); ++ ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Toshiba Corporation Semiconductor and Storage Products Company"); ++MODULE_DESCRIPTION("BENAND (Built-in ECC NAND) support"); +--- a/include/linux/mtd/nand.h ++++ b/include/linux/mtd/nand.h +@@ -115,6 +115,7 @@ typedef enum { + NAND_ECC_HW_SYNDROME, + NAND_ECC_HW_OOB_FIRST, + NAND_ECC_SOFT_BCH, ++ NAND_ECC_BENAND, + } nand_ecc_modes_t; + + /* +--- /dev/null ++++ b/include/linux/mtd/nand_benand.h +@@ -0,0 +1,48 @@ ++/* ++ * linux/include/linux/mtd/nand_benand.h ++ * ++ * (C) Copyright Toshiba Corporation ++ * Semiconductor and Storage Products Company 2015 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#ifndef __MTD_NAND_BENAND_H__ ++#define __MTD_NAND_BENAND_H__ ++ ++#if defined(CONFIG_MTD_NAND_BENAND_ENABLE) ++ ++static inline int mtd_nand_has_benand(void) { return 1; } ++ ++void nand_benand_init(struct mtd_info *mtd); ++ ++int nand_read_page_benand(struct mtd_info *mtd, struct nand_chip *chip, ++ uint8_t *buf, int oob_required, int page); ++ ++int nand_read_subpage_benand(struct mtd_info *mtd, struct nand_chip *chip, ++ uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi, ++ int page); ++ ++#else /* CONFIG_MTD_NAND_BENAND_ENABLE */ ++static inline int mtd_nand_has_benand(void) { return 0; } ++ ++void nand_benand_init(struct mtd_info *mtd) {} ++ ++int nand_read_page_benand(struct mtd_info *mtd, struct nand_chip *chip, ++ uint8_t *buf, int oob_required, int page) ++{ ++ return -1; ++} ++ ++int nand_read_subpage_benand(struct mtd_info *mtd, struct nand_chip *chip, ++ uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi, ++ int page) ++{ ++ return -1; ++} ++ ++#endif /* CONFIG_MTD_NAND_BENAND_ENABLE */ ++#endif @@ -417,7 +417,7 @@ patches.altera/0009-nios2-Switch-to-generic-__xchg.patch ############################################################################# # Misc patches patches.misc/input-add-support-for-rohm-bu21023-24-touchscreen.patch - +patches.misc/mtd-nand-support-for-toshiba-benand-built-in-ecc-nand.patch ############################################################################## # fixes that go after all of the above |