]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/nand/omap_gpmc.c
mtd: nand: omap_gpmc: rename struct nand_bch_priv to struct omap_nand_info
[u-boot] / drivers / mtd / nand / omap_gpmc.c
index 452e40f04ef5301bbc547b3b5cddf8123d730e3d..391a26858cd8302d3a7d80f14f548c1f04cf1131 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/bch.h>
 #include <linux/compiler.h>
 #include <nand.h>
-#include <asm/omap_elm.h>
+#include <linux/mtd/omap_elm.h>
 
 #define BADBLOCK_MARKER_LENGTH 2
 #define SECTOR_BYTES           512
@@ -148,35 +148,20 @@ static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
 }
 
 /*
- * Generic BCH interface
+ * Driver configurations
  */
-struct nand_bch_priv {
-       uint8_t mode;
-       uint8_t type;
-       uint8_t nibbles;
+struct omap_nand_info {
        struct bch_control *control;
        enum omap_ecc ecc_scheme;
 };
 
-/* bch types */
-#define ECC_BCH4       0
-#define ECC_BCH8       1
-#define ECC_BCH16      2
-
-/* BCH nibbles for diff bch levels */
-#define ECC_BCH4_NIBBLES       13
-#define ECC_BCH8_NIBBLES       26
-#define ECC_BCH16_NIBBLES      52
-
 /*
  * This can be a single instance cause all current users have only one NAND
  * with nearly the same setup (BCH8, some with ELM and others with sw BCH
  * library).
  * When some users with other BCH strength will exists this have to change!
  */
-static __maybe_unused struct nand_bch_priv bch_priv = {
-       .type = ECC_BCH8,
-       .nibbles = ECC_BCH8_NIBBLES,
+static __maybe_unused struct omap_nand_info omap_nand_info = {
        .control = NULL
 };
 
@@ -206,7 +191,7 @@ __maybe_unused
 static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
 {
        struct nand_chip        *nand   = mtd->priv;
-       struct nand_bch_priv    *bch    = nand->priv;
+       struct omap_nand_info   *info   = nand->priv;
        unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
        unsigned int ecc_algo = 0;
        unsigned int bch_type = 0;
@@ -215,7 +200,7 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
        u32 ecc_config_val = 0;
 
        /* configure GPMC for specific ecc-scheme */
-       switch (bch->ecc_scheme) {
+       switch (info->ecc_scheme) {
        case OMAP_ECC_HAM1_CODE_SW:
                return;
        case OMAP_ECC_HAM1_CODE_HW:
@@ -277,11 +262,11 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
                                uint8_t *ecc_code)
 {
        struct nand_chip *chip = mtd->priv;
-       struct nand_bch_priv *bch = chip->priv;
+       struct omap_nand_info *info = chip->priv;
        uint32_t *ptr, val = 0;
        int8_t i = 0, j;
 
-       switch (bch->ecc_scheme) {
+       switch (info->ecc_scheme) {
        case OMAP_ECC_HAM1_CODE_HW:
                val = readl(&gpmc_cfg->ecc1_result);
                ecc_code[0] = val & 0xFF;
@@ -309,7 +294,7 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
                return -EINVAL;
        }
        /* ECC scheme specific syndrome customizations */
-       switch (bch->ecc_scheme) {
+       switch (info->ecc_scheme) {
        case OMAP_ECC_HAM1_CODE_HW:
                break;
 #ifdef CONFIG_BCH
@@ -345,10 +330,11 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
                                uint8_t *read_ecc, uint8_t *calc_ecc)
 {
        struct nand_chip *chip = mtd->priv;
-       struct nand_bch_priv *bch = chip->priv;
+       struct omap_nand_info *info = chip->priv;
        uint32_t eccbytes = chip->ecc.bytes;
        uint32_t error_count = 0, error_max;
        uint32_t error_loc[8];
+       enum bch_level bch_type;
        uint32_t i, ecc_flag = 0;
        uint8_t count, err = 0;
        uint32_t byte_pos, bit_pos;
@@ -374,23 +360,24 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
         * while reading ECC result we read it in big endian.
         * Hence while loading to ELM we have rotate to get the right endian.
         */
-       switch (bch->ecc_scheme) {
+       switch (info->ecc_scheme) {
        case OMAP_ECC_BCH8_CODE_HW:
+               bch_type = BCH_8_BIT;
                omap_reverse_list(calc_ecc, eccbytes - 1);
                break;
        default:
                return -EINVAL;
        }
        /* use elm module to check for errors */
-       elm_config((enum bch_level)(bch->type));
-       if (elm_check_error(calc_ecc, bch->nibbles, &error_count, error_loc)) {
+       elm_config(bch_type);
+       if (elm_check_error(calc_ecc, bch_type, &error_count, error_loc)) {
                printf("nand: error: uncorrectable ECC errors\n");
                return -EINVAL;
        }
        /* correct bch error */
        for (count = 0; count < error_count; count++) {
-               switch (bch->type) {
-               case ECC_BCH8:
+               switch (info->ecc_scheme) {
+               case OMAP_ECC_BCH8_CODE_HW:
                        /* 14th byte in ECC is reserved to match ROM layout */
                        error_max = SECTOR_BYTES + (eccbytes - 1);
                        break;
@@ -403,7 +390,7 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
                        dat[byte_pos] ^= 1 << bit_pos;
                        printf("nand: bit-flip corrected @data=%d\n", byte_pos);
                } else if (byte_pos < error_max) {
-                       read_ecc[byte_pos - SECTOR_BYTES] = 1 << bit_pos;
+                       read_ecc[byte_pos - SECTOR_BYTES] ^= 1 << bit_pos;
                        printf("nand: bit-flip corrected @oob=%d\n", byte_pos -
                                                                SECTOR_BYTES);
                } else {
@@ -496,10 +483,10 @@ static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
        /* cannot correct more than 8 errors */
        unsigned int errloc[8];
        struct nand_chip *chip = mtd->priv;
-       struct nand_bch_priv *chip_priv = chip->priv;
-       struct bch_control *bch = chip_priv->control;
+       struct omap_nand_info *info = chip->priv;
 
-       count = decode_bch(bch, NULL, 512, read_ecc, calc_ecc, NULL, errloc);
+       count = decode_bch(info->control, NULL, 512, read_ecc, calc_ecc,
+                                                       NULL, errloc);
        if (count > 0) {
                /* correct errors */
                for (i = 0; i < count; i++) {
@@ -535,15 +522,11 @@ static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
 static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
-       struct nand_bch_priv *chip_priv = chip->priv;
-       struct bch_control *bch = NULL;
-
-       if (chip_priv)
-               bch = chip_priv->control;
+       struct omap_nand_info *info = chip->priv;
 
-       if (bch) {
-               free_bch(bch);
-               chip_priv->control = NULL;
+       if (info->control) {
+               free_bch(info->control);
+               info->control = NULL;
        }
 }
 #endif /* CONFIG_BCH */
@@ -557,7 +540,7 @@ static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
  */
 static int omap_select_ecc_scheme(struct nand_chip *nand,
        enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
-       struct nand_bch_priv    *bch            = nand->priv;
+       struct omap_nand_info   *info           = nand->priv;
        struct nand_ecclayout   *ecclayout      = &omap_ecclayout;
        int eccsteps = pagesize / SECTOR_BYTES;
        int i;
@@ -567,12 +550,10 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
                /* For this ecc-scheme, ecc.bytes, ecc.layout, ... are
                 * initialized in nand_scan_tail(), so just set ecc.mode */
-               bch_priv.control        = NULL;
-               bch_priv.type           = 0;
+               info->control           = NULL;
                nand->ecc.mode          = NAND_ECC_SOFT;
                nand->ecc.layout        = NULL;
                nand->ecc.size          = 0;
-               bch->ecc_scheme         = OMAP_ECC_HAM1_CODE_SW;
                break;
 
        case OMAP_ECC_HAM1_CODE_HW:
@@ -583,8 +564,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                                (3 * eccsteps) + BADBLOCK_MARKER_LENGTH));
                        return -EINVAL;
                }
-               bch_priv.control        = NULL;
-               bch_priv.type           = 0;
+               info->control           = NULL;
                /* populate ecc specific fields */
                memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
                nand->ecc.mode          = NAND_ECC_HW;
@@ -605,7 +585,6 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
                ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
                                                BADBLOCK_MARKER_LENGTH;
-               bch->ecc_scheme         = OMAP_ECC_HAM1_CODE_HW;
                break;
 
        case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
@@ -618,12 +597,11 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                        return -EINVAL;
                }
                /* check if BCH S/W library can be used for error detection */
-               bch_priv.control = init_bch(13, 8, 0x201b);
-               if (!bch_priv.control) {
+               info->control = init_bch(13, 8, 0x201b);
+               if (!info->control) {
                        printf("nand: error: could not init_bch()\n");
                        return -ENODEV;
                }
-               bch_priv.type = ECC_BCH8;
                /* populate ecc specific fields */
                memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
                nand->ecc.mode          = NAND_ECC_HW;
@@ -647,7 +625,6 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
                ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
                                                BADBLOCK_MARKER_LENGTH;
-               bch->ecc_scheme         = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
                break;
 #else
                printf("nand: error: CONFIG_BCH required for ECC\n");
@@ -665,7 +642,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                }
                /* intialize ELM for ECC error detection */
                elm_init();
-               bch_priv.type           = ECC_BCH8;
+               info->control           = NULL;
                /* populate ecc specific fields */
                memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
                nand->ecc.mode          = NAND_ECC_HW;
@@ -683,7 +660,6 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
                ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
                                                BADBLOCK_MARKER_LENGTH;
-               bch->ecc_scheme         = OMAP_ECC_BCH8_CODE_HW;
                break;
 #else
                printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
@@ -699,6 +675,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
        if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
                nand->ecc.layout = ecclayout;
 
+       info->ecc_scheme = ecc_scheme;
        return 0;
 }
 
@@ -802,7 +779,7 @@ int board_nand_init(struct nand_chip *nand)
 
        nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
        nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
-       nand->priv      = &bch_priv;
+       nand->priv      = &omap_nand_info;
        nand->cmd_ctrl  = omap_nand_hwcontrol;
        nand->options   |= NAND_NO_PADDING | NAND_CACHEPRG;
        /* If we are 16 bit dev, our gpmc config tells us that */