mtd: nand: omap_elm: use bch_type instead of nibble count to differentiate between BCH4/BCH8/BCH16

ELM hardware engine support ECC error detection for multiple ECC strengths like
 +------+------------------------+
 |Type  | ECC syndrome length    |
 +------+------------------------+
 |BCH4  | 6.5 bytes = 13 nibbles |
 |BCH8  | 13 byte = 26 nibbles   |
 |BCH16 | 26 bytes = 52 nibbles  |
 +------+------------------------+

Current implementation of omap_elm driver uses ECC syndrom length (in 'nibbles')
to differentiate between BCH4/BCH8/BCH16. This patch replaces it with 'bch_type'

Signed-off-by: Pekon Gupta <pekon@ti.com>
Reviewed-by: Stefan Roese <sr@denx.de>
This commit is contained in:
pekon gupta 2014-04-11 12:55:30 +05:30 committed by Tom Rini
parent b98c5755c0
commit 41bbe4dd49
3 changed files with 11 additions and 21 deletions

View File

@ -24,14 +24,12 @@
struct elm *elm_cfg; struct elm *elm_cfg;
/** /**
* elm_load_syndromes - Load BCH syndromes based on nibble selection * elm_load_syndromes - Load BCH syndromes based on bch_type selection
* @syndrome: BCH syndrome * @syndrome: BCH syndrome
* @nibbles: * @bch_type: BCH4/BCH8/BCH16
* @poly: Syndrome Polynomial set to use * @poly: Syndrome Polynomial set to use
*
* Load BCH syndromes based on nibble selection
*/ */
static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly) static void elm_load_syndromes(u8 *syndrome, enum bch_level bch_type, u8 poly)
{ {
u32 *ptr; u32 *ptr;
u32 val; u32 val;
@ -47,8 +45,7 @@ static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
(syndrome[7] << 24); (syndrome[7] << 24);
writel(val, ptr); writel(val, ptr);
/* BCH 8-bit with 26 nibbles (4*8=32) */ if (bch_type == BCH_8_BIT || bch_type == BCH_16_BIT) {
if (nibbles > 13) {
/* reg 2 */ /* reg 2 */
ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2]; ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2];
val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) | val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) |
@ -61,8 +58,7 @@ static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
writel(val, ptr); writel(val, ptr);
} }
/* BCH 16-bit with 52 nibbles (7*8=56) */ if (bch_type == BCH_16_BIT) {
if (nibbles > 26) {
/* reg 4 */ /* reg 4 */
ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4]; ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4];
val = syndrome[16] | (syndrome[17] << 8) | val = syndrome[16] | (syndrome[17] << 8) |
@ -86,7 +82,7 @@ static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
/** /**
* elm_check_errors - Check for BCH errors and return error locations * elm_check_errors - Check for BCH errors and return error locations
* @syndrome: BCH syndrome * @syndrome: BCH syndrome
* @nibbles: * @bch_type: BCH4/BCH8/BCH16
* @error_count: Returns number of errrors in the syndrome * @error_count: Returns number of errrors in the syndrome
* @error_locations: Returns error locations (in decimal) in this array * @error_locations: Returns error locations (in decimal) in this array
* *
@ -94,14 +90,14 @@ static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
* and locations in the array passed. Returns -1 if error is not correctable, * and locations in the array passed. Returns -1 if error is not correctable,
* else returns 0 * else returns 0
*/ */
int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count, int elm_check_error(u8 *syndrome, enum bch_level bch_type, u32 *error_count,
u32 *error_locations) u32 *error_locations)
{ {
u8 poly = ELM_DEFAULT_POLY; u8 poly = ELM_DEFAULT_POLY;
s8 i; s8 i;
u32 location_status; u32 location_status;
elm_load_syndromes(syndrome, nibbles, poly); elm_load_syndromes(syndrome, bch_type, poly);
/* start processing */ /* start processing */
writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]) writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6])

View File

@ -153,7 +153,6 @@ static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
struct nand_bch_priv { struct nand_bch_priv {
uint8_t mode; uint8_t mode;
uint8_t type; uint8_t type;
uint8_t nibbles;
struct bch_control *control; struct bch_control *control;
enum omap_ecc ecc_scheme; enum omap_ecc ecc_scheme;
}; };
@ -163,11 +162,6 @@ struct nand_bch_priv {
#define ECC_BCH8 1 #define ECC_BCH8 1
#define ECC_BCH16 2 #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 * 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 * with nearly the same setup (BCH8, some with ELM and others with sw BCH
@ -176,7 +170,6 @@ struct nand_bch_priv {
*/ */
static __maybe_unused struct nand_bch_priv bch_priv = { static __maybe_unused struct nand_bch_priv bch_priv = {
.type = ECC_BCH8, .type = ECC_BCH8,
.nibbles = ECC_BCH8_NIBBLES,
.control = NULL .control = NULL
}; };
@ -383,7 +376,8 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
} }
/* use elm module to check for errors */ /* use elm module to check for errors */
elm_config((enum bch_level)(bch->type)); elm_config((enum bch_level)(bch->type));
if (elm_check_error(calc_ecc, bch->nibbles, &error_count, error_loc)) { if (elm_check_error(calc_ecc, (enum bch_level)bch->type,
&error_count, error_loc)) {
printf("nand: error: uncorrectable ECC errors\n"); printf("nand: error: uncorrectable ECC errors\n");
return -EINVAL; return -EINVAL;
} }

View File

@ -68,7 +68,7 @@ struct elm {
struct location error_location[8]; /* 0x800 */ struct location error_location[8]; /* 0x800 */
}; };
int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count, int elm_check_error(u8 *syndrome, enum bch_level bch_type, u32 *error_count,
u32 *error_locations); u32 *error_locations);
int elm_config(enum bch_level level); int elm_config(enum bch_level level);
void elm_reset(void); void elm_reset(void);