Commit faca8ff55f4a2cf45fb906cc37f44601149fc00e

Authored by Tom Rini

Merge branch 'master' of git://git.denx.de/u-boot-nand-flash

Showing 41 changed files Side-by-side Diff

arch/arm/cpu/armv7/am33xx/Makefile
... ... @@ -19,5 +19,4 @@
19 19 obj-y += emif4.o
20 20 obj-y += board.o
21 21 obj-y += mux.o
22   -obj-$(CONFIG_NAND_OMAP_GPMC) += elm.o
arch/arm/cpu/armv7/am33xx/elm.c
1   -/*
2   - * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
3   - * Mansoor Ahamed <mansoor.ahamed@ti.com>
4   - *
5   - * BCH Error Location Module (ELM) support.
6   - *
7   - * NOTE:
8   - * 1. Supports only continuous mode. Dont see need for page mode in uboot
9   - * 2. Supports only syndrome polynomial 0. i.e. poly local variable is
10   - * always set to ELM_DEFAULT_POLY. Dont see need for other polynomial
11   - * sets in uboot
12   - *
13   - * SPDX-License-Identifier: GPL-2.0+
14   - */
15   -
16   -#include <common.h>
17   -#include <asm/io.h>
18   -#include <asm/errno.h>
19   -#include <asm/arch/cpu.h>
20   -#include <asm/omap_gpmc.h>
21   -#include <asm/arch/elm.h>
22   -
23   -#define ELM_DEFAULT_POLY (0)
24   -
25   -struct elm *elm_cfg;
26   -
27   -/**
28   - * elm_load_syndromes - Load BCH syndromes based on nibble selection
29   - * @syndrome: BCH syndrome
30   - * @nibbles:
31   - * @poly: Syndrome Polynomial set to use
32   - *
33   - * Load BCH syndromes based on nibble selection
34   - */
35   -static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
36   -{
37   - u32 *ptr;
38   - u32 val;
39   -
40   - /* reg 0 */
41   - ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[0];
42   - val = syndrome[0] | (syndrome[1] << 8) | (syndrome[2] << 16) |
43   - (syndrome[3] << 24);
44   - writel(val, ptr);
45   - /* reg 1 */
46   - ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[1];
47   - val = syndrome[4] | (syndrome[5] << 8) | (syndrome[6] << 16) |
48   - (syndrome[7] << 24);
49   - writel(val, ptr);
50   -
51   - /* BCH 8-bit with 26 nibbles (4*8=32) */
52   - if (nibbles > 13) {
53   - /* reg 2 */
54   - ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2];
55   - val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) |
56   - (syndrome[11] << 24);
57   - writel(val, ptr);
58   - /* reg 3 */
59   - ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[3];
60   - val = syndrome[12] | (syndrome[13] << 8) |
61   - (syndrome[14] << 16) | (syndrome[15] << 24);
62   - writel(val, ptr);
63   - }
64   -
65   - /* BCH 16-bit with 52 nibbles (7*8=56) */
66   - if (nibbles > 26) {
67   - /* reg 4 */
68   - ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4];
69   - val = syndrome[16] | (syndrome[17] << 8) |
70   - (syndrome[18] << 16) | (syndrome[19] << 24);
71   - writel(val, ptr);
72   -
73   - /* reg 5 */
74   - ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[5];
75   - val = syndrome[20] | (syndrome[21] << 8) |
76   - (syndrome[22] << 16) | (syndrome[23] << 24);
77   - writel(val, ptr);
78   -
79   - /* reg 6 */
80   - ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6];
81   - val = syndrome[24] | (syndrome[25] << 8) |
82   - (syndrome[26] << 16) | (syndrome[27] << 24);
83   - writel(val, ptr);
84   - }
85   -}
86   -
87   -/**
88   - * elm_check_errors - Check for BCH errors and return error locations
89   - * @syndrome: BCH syndrome
90   - * @nibbles:
91   - * @error_count: Returns number of errrors in the syndrome
92   - * @error_locations: Returns error locations (in decimal) in this array
93   - *
94   - * Check the provided syndrome for BCH errors and return error count
95   - * and locations in the array passed. Returns -1 if error is not correctable,
96   - * else returns 0
97   - */
98   -int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
99   - u32 *error_locations)
100   -{
101   - u8 poly = ELM_DEFAULT_POLY;
102   - s8 i;
103   - u32 location_status;
104   -
105   - elm_load_syndromes(syndrome, nibbles, poly);
106   -
107   - /* start processing */
108   - writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6])
109   - | ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID),
110   - &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]);
111   -
112   - /* wait for processing to complete */
113   - while ((readl(&elm_cfg->irqstatus) & (0x1 << poly)) != 0x1)
114   - ;
115   - /* clear status */
116   - writel((readl(&elm_cfg->irqstatus) | (0x1 << poly)),
117   - &elm_cfg->irqstatus);
118   -
119   - /* check if correctable */
120   - location_status = readl(&elm_cfg->error_location[poly].location_status);
121   - if (!(location_status & ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK))
122   - return -1;
123   -
124   - /* get error count */
125   - *error_count = readl(&elm_cfg->error_location[poly].location_status) &
126   - ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK;
127   -
128   - for (i = 0; i < *error_count; i++) {
129   - error_locations[i] =
130   - readl(&elm_cfg->error_location[poly].error_location_x[i]);
131   - }
132   -
133   - return 0;
134   -}
135   -
136   -
137   -/**
138   - * elm_config - Configure ELM module
139   - * @level: 4 / 8 / 16 bit BCH
140   - *
141   - * Configure ELM module based on BCH level.
142   - * Set mode as continuous mode.
143   - * Currently we are using only syndrome 0 and syndromes 1 to 6 are not used.
144   - * Also, the mode is set only for syndrome 0
145   - */
146   -int elm_config(enum bch_level level)
147   -{
148   - u32 val;
149   - u8 poly = ELM_DEFAULT_POLY;
150   - u32 buffer_size = 0x7FF;
151   -
152   - /* config size and level */
153   - val = (u32)(level) & ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK;
154   - val |= ((buffer_size << ELM_LOCATION_CONFIG_ECC_SIZE_POS) &
155   - ELM_LOCATION_CONFIG_ECC_SIZE_MASK);
156   - writel(val, &elm_cfg->location_config);
157   -
158   - /* config continous mode */
159   - /* enable interrupt generation for syndrome polynomial set */
160   - writel((readl(&elm_cfg->irqenable) | (0x1 << poly)),
161   - &elm_cfg->irqenable);
162   - /* set continuous mode for the syndrome polynomial set */
163   - writel((readl(&elm_cfg->page_ctrl) & ~(0x1 << poly)),
164   - &elm_cfg->page_ctrl);
165   -
166   - return 0;
167   -}
168   -
169   -/**
170   - * elm_reset - Do a soft reset of ELM
171   - *
172   - * Perform a soft reset of ELM and return after reset is done.
173   - */
174   -void elm_reset(void)
175   -{
176   - /* initiate reset */
177   - writel((readl(&elm_cfg->sysconfig) | ELM_SYSCONFIG_SOFTRESET),
178   - &elm_cfg->sysconfig);
179   -
180   - /* wait for reset complete and normal operation */
181   - while ((readl(&elm_cfg->sysstatus) & ELM_SYSSTATUS_RESETDONE) !=
182   - ELM_SYSSTATUS_RESETDONE)
183   - ;
184   -}
185   -
186   -/**
187   - * elm_init - Initialize ELM module
188   - *
189   - * Initialize ELM support. Currently it does only base address init
190   - * and ELM reset.
191   - */
192   -void elm_init(void)
193   -{
194   - elm_cfg = (struct elm *)ELM_BASE;
195   - elm_reset();
196   -}
arch/arm/cpu/armv7/am33xx/mem.c
... ... @@ -22,18 +22,7 @@
22 22  
23 23 struct gpmc *gpmc_cfg;
24 24  
25   -#if defined(CONFIG_CMD_NAND)
26   -static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
27   - M_NAND_GPMC_CONFIG1,
28   - M_NAND_GPMC_CONFIG2,
29   - M_NAND_GPMC_CONFIG3,
30   - M_NAND_GPMC_CONFIG4,
31   - M_NAND_GPMC_CONFIG5,
32   - M_NAND_GPMC_CONFIG6, 0
33   -};
34   -#endif
35 25  
36   -
37 26 void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
38 27 u32 size)
39 28 {
40 29  
... ... @@ -61,11 +50,34 @@
61 50 {
62 51 /* putting a blanket check on GPMC based on ZeBu for now */
63 52 gpmc_cfg = (struct gpmc *)GPMC_BASE;
64   -
65   -#ifdef CONFIG_CMD_NAND
66   - const u32 *gpmc_config = NULL;
67   - u32 base = 0;
  53 +#if defined(CONFIG_NOR)
  54 +/* configure GPMC for NOR */
  55 + const u32 gpmc_regs[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1,
  56 + STNOR_GPMC_CONFIG2,
  57 + STNOR_GPMC_CONFIG3,
  58 + STNOR_GPMC_CONFIG4,
  59 + STNOR_GPMC_CONFIG5,
  60 + STNOR_GPMC_CONFIG6,
  61 + STNOR_GPMC_CONFIG7
  62 + };
  63 + u32 size = GPMC_SIZE_16M;
  64 + u32 base = CONFIG_SYS_FLASH_BASE;
  65 +#elif defined(CONFIG_NAND)
  66 +/* configure GPMC for NAND */
  67 + const u32 gpmc_regs[GPMC_MAX_REG] = { M_NAND_GPMC_CONFIG1,
  68 + M_NAND_GPMC_CONFIG2,
  69 + M_NAND_GPMC_CONFIG3,
  70 + M_NAND_GPMC_CONFIG4,
  71 + M_NAND_GPMC_CONFIG5,
  72 + M_NAND_GPMC_CONFIG6,
  73 + 0
  74 + };
  75 + u32 size = GPMC_SIZE_256M;
  76 + u32 base = CONFIG_SYS_NAND_BASE;
  77 +#else
  78 + const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 };
68 79 u32 size = 0;
  80 + u32 base = 0;
69 81 #endif
70 82 /* global settings */
71 83 writel(0x00000008, &gpmc_cfg->sysconfig);
... ... @@ -81,13 +93,7 @@
81 93 */
82 94 writel(0, &gpmc_cfg->cs[0].config7);
83 95 sdelay(1000);
84   -
85   -#ifdef CONFIG_CMD_NAND
86   - gpmc_config = gpmc_m_nand;
87   -
88   - base = PISMO1_NAND_BASE;
89   - size = PISMO1_NAND_SIZE;
90   - enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
91   -#endif
  96 + /* enable chip-select specific configurations */
  97 + enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
92 98 }
arch/arm/include/asm/arch-am33xx/elm.h
1   -/*
2   - * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
3   - * Mansoor Ahamed <mansoor.ahamed@ti.com>
4   - *
5   - * Derived from work done by Rohit Choraria <rohitkc@ti.com> for omap3
6   - *
7   - * SPDX-License-Identifier: GPL-2.0+
8   - */
9   -#ifndef __ASM_ARCH_ELM_H
10   -#define __ASM_ARCH_ELM_H
11   -/*
12   - * ELM Module Registers
13   - */
14   -
15   -/* ELM registers bit fields */
16   -#define ELM_SYSCONFIG_SOFTRESET_MASK (0x2)
17   -#define ELM_SYSCONFIG_SOFTRESET (0x2)
18   -#define ELM_SYSSTATUS_RESETDONE_MASK (0x1)
19   -#define ELM_SYSSTATUS_RESETDONE (0x1)
20   -#define ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK (0x3)
21   -#define ELM_LOCATION_CONFIG_ECC_SIZE_MASK (0x7FF0000)
22   -#define ELM_LOCATION_CONFIG_ECC_SIZE_POS (16)
23   -#define ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID (0x00010000)
24   -#define ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK (0x100)
25   -#define ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK (0x1F)
26   -
27   -#ifndef __ASSEMBLY__
28   -
29   -enum bch_level {
30   - BCH_4_BIT = 0,
31   - BCH_8_BIT,
32   - BCH_16_BIT
33   -};
34   -
35   -
36   -/* BCH syndrome registers */
37   -struct syndrome {
38   - u32 syndrome_fragment_x[7]; /* 0x400, 0x404.... 0x418 */
39   - u8 res1[36]; /* 0x41c */
40   -};
41   -
42   -/* BCH error status & location register */
43   -struct location {
44   - u32 location_status; /* 0x800 */
45   - u8 res1[124]; /* 0x804 */
46   - u32 error_location_x[16]; /* 0x880.... */
47   - u8 res2[64]; /* 0x8c0 */
48   -};
49   -
50   -/* BCH ELM register map - do not try to allocate memmory for this structure.
51   - * We have used plenty of reserved variables to fill the slots in the ELM
52   - * register memory map.
53   - * Directly initialize the struct pointer to ELM base address.
54   - */
55   -struct elm {
56   - u32 rev; /* 0x000 */
57   - u8 res1[12]; /* 0x004 */
58   - u32 sysconfig; /* 0x010 */
59   - u32 sysstatus; /* 0x014 */
60   - u32 irqstatus; /* 0x018 */
61   - u32 irqenable; /* 0x01c */
62   - u32 location_config; /* 0x020 */
63   - u8 res2[92]; /* 0x024 */
64   - u32 page_ctrl; /* 0x080 */
65   - u8 res3[892]; /* 0x084 */
66   - struct syndrome syndrome_fragments[8]; /* 0x400 */
67   - u8 res4[512]; /* 0x600 */
68   - struct location error_location[8]; /* 0x800 */
69   -};
70   -
71   -int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
72   - u32 *error_locations);
73   -int elm_config(enum bch_level level);
74   -void elm_reset(void);
75   -void elm_init(void);
76   -#endif /* __ASSEMBLY__ */
77   -#endif /* __ASM_ARCH_ELM_H */
arch/arm/include/asm/arch-am33xx/mem.h
... ... @@ -68,10 +68,5 @@
68 68 #define PISMO2_NAND_CS0 7
69 69 #define PISMO2_NAND_CS1 8
70 70  
71   -/* make it readable for the gpmc_init */
72   -#define PISMO1_NOR_BASE FLASH_BASE
73   -#define PISMO1_NAND_BASE CONFIG_SYS_NAND_BASE
74   -#define PISMO1_NAND_SIZE GPMC_SIZE_256M
75   -
76 71 #endif /* endif _MEM_H_ */
arch/arm/include/asm/omap_elm.h
  1 +/*
  2 + * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
  3 + * Mansoor Ahamed <mansoor.ahamed@ti.com>
  4 + *
  5 + * Derived from work done by Rohit Choraria <rohitkc@ti.com> for omap3
  6 + *
  7 + * SPDX-License-Identifier: GPL-2.0+
  8 + */
  9 +#ifndef __ASM_ARCH_ELM_H
  10 +#define __ASM_ARCH_ELM_H
  11 +/*
  12 + * ELM Module Registers
  13 + */
  14 +
  15 +/* ELM registers bit fields */
  16 +#define ELM_SYSCONFIG_SOFTRESET_MASK (0x2)
  17 +#define ELM_SYSCONFIG_SOFTRESET (0x2)
  18 +#define ELM_SYSSTATUS_RESETDONE_MASK (0x1)
  19 +#define ELM_SYSSTATUS_RESETDONE (0x1)
  20 +#define ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK (0x3)
  21 +#define ELM_LOCATION_CONFIG_ECC_SIZE_MASK (0x7FF0000)
  22 +#define ELM_LOCATION_CONFIG_ECC_SIZE_POS (16)
  23 +#define ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID (0x00010000)
  24 +#define ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK (0x100)
  25 +#define ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK (0x1F)
  26 +
  27 +#ifndef __ASSEMBLY__
  28 +
  29 +enum bch_level {
  30 + BCH_4_BIT = 0,
  31 + BCH_8_BIT,
  32 + BCH_16_BIT
  33 +};
  34 +
  35 +
  36 +/* BCH syndrome registers */
  37 +struct syndrome {
  38 + u32 syndrome_fragment_x[7]; /* 0x400, 0x404.... 0x418 */
  39 + u8 res1[36]; /* 0x41c */
  40 +};
  41 +
  42 +/* BCH error status & location register */
  43 +struct location {
  44 + u32 location_status; /* 0x800 */
  45 + u8 res1[124]; /* 0x804 */
  46 + u32 error_location_x[16]; /* 0x880.... */
  47 + u8 res2[64]; /* 0x8c0 */
  48 +};
  49 +
  50 +/* BCH ELM register map - do not try to allocate memmory for this structure.
  51 + * We have used plenty of reserved variables to fill the slots in the ELM
  52 + * register memory map.
  53 + * Directly initialize the struct pointer to ELM base address.
  54 + */
  55 +struct elm {
  56 + u32 rev; /* 0x000 */
  57 + u8 res1[12]; /* 0x004 */
  58 + u32 sysconfig; /* 0x010 */
  59 + u32 sysstatus; /* 0x014 */
  60 + u32 irqstatus; /* 0x018 */
  61 + u32 irqenable; /* 0x01c */
  62 + u32 location_config; /* 0x020 */
  63 + u8 res2[92]; /* 0x024 */
  64 + u32 page_ctrl; /* 0x080 */
  65 + u8 res3[892]; /* 0x084 */
  66 + struct syndrome syndrome_fragments[8]; /* 0x400 */
  67 + u8 res4[512]; /* 0x600 */
  68 + struct location error_location[8]; /* 0x800 */
  69 +};
  70 +
  71 +int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
  72 + u32 *error_locations);
  73 +int elm_config(enum bch_level level);
  74 +void elm_reset(void);
  75 +void elm_init(void);
  76 +#endif /* __ASSEMBLY__ */
  77 +#endif /* __ASM_ARCH_ELM_H */
arch/arm/include/asm/omap_gpmc.h
... ... @@ -68,5 +68,21 @@
68 68 }
69 69 #endif
70 70  
  71 +enum omap_ecc {
  72 + /* 1-bit ECC calculation by Software, Error detection by Software */
  73 + OMAP_ECC_HAM1_CODE_SW = 1, /* avoid un-initialized int can be 0x0 */
  74 + /* 1-bit ECC calculation by GPMC, Error detection by Software */
  75 + /* ECC layout compatible to legacy ROMCODE. */
  76 + OMAP_ECC_HAM1_CODE_HW,
  77 + /* 4-bit ECC calculation by GPMC, Error detection by Software */
  78 + OMAP_ECC_BCH4_CODE_HW_DETECTION_SW,
  79 + /* 4-bit ECC calculation by GPMC, Error detection by ELM */
  80 + OMAP_ECC_BCH4_CODE_HW,
  81 + /* 8-bit ECC calculation by GPMC, Error detection by Software */
  82 + OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
  83 + /* 8-bit ECC calculation by GPMC, Error detection by ELM */
  84 + OMAP_ECC_BCH8_CODE_HW,
  85 +};
  86 +
71 87 #endif /* __ASM_OMAP_GPMC_H */
arch/powerpc/cpu/mpc8xxx/fsl_ifc.c
... ... @@ -34,6 +34,9 @@
34 34 #ifdef CONFIG_SYS_CSPR0_EXT
35 35 set_ifc_cspr_ext(IFC_CS0, CONFIG_SYS_CSPR0_EXT);
36 36 #endif
  37 +#ifdef CONFIG_SYS_CSOR0_EXT
  38 + set_ifc_csor_ext(IFC_CS0, CONFIG_SYS_CSOR0_EXT);
  39 +#endif
37 40 set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0);
38 41 set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0);
39 42 set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0);
... ... @@ -43,6 +46,9 @@
43 46 #ifdef CONFIG_SYS_CSPR1_EXT
44 47 set_ifc_cspr_ext(IFC_CS1, CONFIG_SYS_CSPR1_EXT);
45 48 #endif
  49 +#ifdef CONFIG_SYS_CSOR1_EXT
  50 + set_ifc_csor_ext(IFC_CS1, CONFIG_SYS_CSOR1_EXT);
  51 +#endif
46 52 #if defined(CONFIG_SYS_CSPR1) && defined(CONFIG_SYS_CSOR1)
47 53 set_ifc_ftim(IFC_CS1, IFC_FTIM0, CONFIG_SYS_CS1_FTIM0);
48 54 set_ifc_ftim(IFC_CS1, IFC_FTIM1, CONFIG_SYS_CS1_FTIM1);
... ... @@ -57,6 +63,9 @@
57 63 #ifdef CONFIG_SYS_CSPR2_EXT
58 64 set_ifc_cspr_ext(IFC_CS2, CONFIG_SYS_CSPR2_EXT);
59 65 #endif
  66 +#ifdef CONFIG_SYS_CSOR2_EXT
  67 + set_ifc_csor_ext(IFC_CS2, CONFIG_SYS_CSOR2_EXT);
  68 +#endif
60 69 #if defined(CONFIG_SYS_CSPR2) && defined(CONFIG_SYS_CSOR2)
61 70 set_ifc_ftim(IFC_CS2, IFC_FTIM0, CONFIG_SYS_CS2_FTIM0);
62 71 set_ifc_ftim(IFC_CS2, IFC_FTIM1, CONFIG_SYS_CS2_FTIM1);
... ... @@ -71,6 +80,9 @@
71 80 #ifdef CONFIG_SYS_CSPR3_EXT
72 81 set_ifc_cspr_ext(IFC_CS3, CONFIG_SYS_CSPR3_EXT);
73 82 #endif
  83 +#ifdef CONFIG_SYS_CSOR3_EXT
  84 + set_ifc_csor_ext(IFC_CS3, CONFIG_SYS_CSOR3_EXT);
  85 +#endif
74 86 #if defined(CONFIG_SYS_CSPR3) && defined(CONFIG_SYS_CSOR3)
75 87 set_ifc_ftim(IFC_CS3, IFC_FTIM0, CONFIG_SYS_CS3_FTIM0);
76 88 set_ifc_ftim(IFC_CS3, IFC_FTIM1, CONFIG_SYS_CS3_FTIM1);
... ... @@ -85,6 +97,9 @@
85 97 #ifdef CONFIG_SYS_CSPR4_EXT
86 98 set_ifc_cspr_ext(IFC_CS4, CONFIG_SYS_CSPR4_EXT);
87 99 #endif
  100 +#ifdef CONFIG_SYS_CSOR4_EXT
  101 + set_ifc_csor_ext(IFC_CS4, CONFIG_SYS_CSOR4_EXT);
  102 +#endif
88 103 #if defined(CONFIG_SYS_CSPR4) && defined(CONFIG_SYS_CSOR4)
89 104 set_ifc_ftim(IFC_CS4, IFC_FTIM0, CONFIG_SYS_CS4_FTIM0);
90 105 set_ifc_ftim(IFC_CS4, IFC_FTIM1, CONFIG_SYS_CS4_FTIM1);
... ... @@ -99,6 +114,9 @@
99 114 #ifdef CONFIG_SYS_CSPR5_EXT
100 115 set_ifc_cspr_ext(IFC_CS5, CONFIG_SYS_CSPR5_EXT);
101 116 #endif
  117 +#ifdef CONFIG_SYS_CSOR5_EXT
  118 + set_ifc_csor_ext(IFC_CS5, CONFIG_SYS_CSOR5_EXT);
  119 +#endif
102 120 #if defined(CONFIG_SYS_CSPR5) && defined(CONFIG_SYS_CSOR5)
103 121 set_ifc_ftim(IFC_CS5, IFC_FTIM0, CONFIG_SYS_CS5_FTIM0);
104 122 set_ifc_ftim(IFC_CS5, IFC_FTIM1, CONFIG_SYS_CS5_FTIM1);
... ... @@ -113,6 +131,9 @@
113 131 #ifdef CONFIG_SYS_CSPR6_EXT
114 132 set_ifc_cspr_ext(IFC_CS6, CONFIG_SYS_CSPR6_EXT);
115 133 #endif
  134 +#ifdef CONFIG_SYS_CSOR6_EXT
  135 + set_ifc_csor_ext(IFC_CS6, CONFIG_SYS_CSOR6_EXT);
  136 +#endif
116 137 #if defined(CONFIG_SYS_CSPR6) && defined(CONFIG_SYS_CSOR6)
117 138 set_ifc_ftim(IFC_CS6, IFC_FTIM0, CONFIG_SYS_CS6_FTIM0);
118 139 set_ifc_ftim(IFC_CS6, IFC_FTIM1, CONFIG_SYS_CS6_FTIM1);
... ... @@ -126,6 +147,9 @@
126 147  
127 148 #ifdef CONFIG_SYS_CSPR7_EXT
128 149 set_ifc_cspr_ext(IFC_CS7, CONFIG_SYS_CSPR7_EXT);
  150 +#endif
  151 +#ifdef CONFIG_SYS_CSOR7_EXT
  152 + set_ifc_csor_ext(IFC_CS7, CONFIG_SYS_CSOR7_EXT);
129 153 #endif
130 154 #if defined(CONFIG_SYS_CSPR7) && defined(CONFIG_SYS_CSOR7)
131 155 set_ifc_ftim(IFC_CS7, IFC_FTIM0, CONFIG_SYS_CS7_FTIM0);
arch/powerpc/include/asm/fsl_ifc.h
... ... @@ -77,6 +77,7 @@
77 77 #define CSOR_NAND_PGS_512 0x00000000
78 78 #define CSOR_NAND_PGS_2K 0x00080000
79 79 #define CSOR_NAND_PGS_4K 0x00100000
  80 +#define CSOR_NAND_PGS_8K 0x00180000
80 81 /* Spare region Size */
81 82 #define CSOR_NAND_SPRZ_MASK 0x0000E000
82 83 #define CSOR_NAND_SPRZ_SHIFT 13
... ... @@ -86,6 +87,7 @@
86 87 #define CSOR_NAND_SPRZ_210 0x00006000
87 88 #define CSOR_NAND_SPRZ_218 0x00008000
88 89 #define CSOR_NAND_SPRZ_224 0x0000A000
  90 +#define CSOR_NAND_SPRZ_CSOR_EXT 0x0000C000
89 91 /* Pages Per Block */
90 92 #define CSOR_NAND_PB_MASK 0x00000700
91 93 #define CSOR_NAND_PB_SHIFT 8
board/atmel/sama5d3xek/sama5d3xek.c
... ... @@ -131,7 +131,8 @@
131 131  
132 132 void lcd_show_board_info(void)
133 133 {
134   - ulong dram_size, nand_size;
  134 + ulong dram_size;
  135 + uint64_t nand_size;
135 136 int i;
136 137 char temp[32];
137 138  
... ... @@ -150,7 +151,7 @@
150 151 for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
151 152 nand_size += nand_info[i].size;
152 153 #endif
153   - lcd_printf("%ld MB SDRAM, %ld MB NAND\n",
  154 + lcd_printf("%ld MB SDRAM, %lld MB NAND\n",
154 155 dram_size >> 20, nand_size >> 20);
155 156 }
156 157 #endif /* CONFIG_LCD_INFO */
board/ti/am335x/board.c
... ... @@ -481,26 +481,14 @@
481 481 */
482 482 int board_init(void)
483 483 {
484   -#ifdef CONFIG_NOR
485   - const u32 gpmc_nor[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1,
486   - STNOR_GPMC_CONFIG2, STNOR_GPMC_CONFIG3, STNOR_GPMC_CONFIG4,
487   - STNOR_GPMC_CONFIG5, STNOR_GPMC_CONFIG6, STNOR_GPMC_CONFIG7 };
488   -#endif
489   -
490 484 #if defined(CONFIG_HW_WATCHDOG)
491 485 hw_watchdog_init();
492 486 #endif
493 487  
494 488 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
495   -
  489 +#if defined(CONFIG_NOR) || defined(CONFIG_NAND)
496 490 gpmc_init();
497   -
498   -#ifdef CONFIG_NOR
499   - /* Reconfigure CS0 for NOR instead of NAND. */
500   - enable_gpmc_cs_config(gpmc_nor, &gpmc_cfg->cs[0],
501   - CONFIG_SYS_FLASH_BASE, GPMC_SIZE_16M);
502 491 #endif
503   -
504 492 return 0;
505 493 }
506 494  
... ... @@ -104,6 +104,16 @@
104 104 CONFIG_SYS_MAX_NAND_DEVICE
105 105 The maximum number of NAND devices you want to support.
106 106  
  107 + CONFIG_SYS_NAND_MAX_ECCPOS
  108 + If specified, overrides the maximum number of ECC bytes
  109 + supported. Useful for reducing image size, especially with SPL.
  110 + This must be at least 48 if nand_base.c is used.
  111 +
  112 + CONFIG_SYS_NAND_MAX_OOBFREE
  113 + If specified, overrides the maximum number of free OOB regions
  114 + supported. Useful for reducing image size, especially with SPL.
  115 + This must be at least 2 if nand_base.c is used.
  116 +
107 117 CONFIG_SYS_NAND_MAX_CHIPS
108 118 The maximum number of NAND chips per device to be supported.
109 119  
... ... @@ -168,6 +178,59 @@
168 178  
169 179 Please convert your driver even if you don't need the extra
170 180 flexibility, so that one day we can eliminate the old mechanism.
  181 +
  182 +
  183 + CONFIG_SYS_NAND_ONFI_DETECTION
  184 + Enables detection of ONFI compliant devices during probe.
  185 + And fetching device parameters flashed on device, by parsing
  186 + ONFI parameter page.
  187 +
  188 + CONFIG_BCH
  189 + Enables software based BCH ECC algorithm present in lib/bch.c
  190 + This is used by SoC platforms which do not have built-in ELM
  191 + hardware engine required for BCH ECC correction.
  192 +
  193 +
  194 +Platform specific options
  195 +=========================
  196 + CONFIG_NAND_OMAP_GPMC
  197 + Enables omap_gpmc.c driver for OMAPx and AMxxxx platforms.
  198 + GPMC controller is used for parallel NAND flash devices, and can
  199 + do ECC calculation (not ECC error detection) for HAM1, BCH4, BCH8
  200 + and BCH16 ECC algorithms.
  201 +
  202 + CONFIG_NAND_OMAP_ELM
  203 + Enables omap_elm.c driver for OMAPx and AMxxxx platforms.
  204 + ELM controller is used for ECC error detection (not ECC calculation)
  205 + of BCH4, BCH8 and BCH16 ECC algorithms.
  206 + Some legacy platforms like OMAP3xx do not have in-built ELM h/w engine,
  207 + thus such SoC platforms need to depend on software library for ECC error
  208 + detection. However ECC calculation on such plaforms would still be
  209 + done by GPMC controller.
  210 +
  211 + CONFIG_NAND_OMAP_ECCSCHEME
  212 + On OMAP platforms, this CONFIG specifies NAND ECC scheme.
  213 + It can take following values:
  214 + OMAP_ECC_HAM1_CODE_SW
  215 + 1-bit Hamming code using software lib.
  216 + (for legacy devices only)
  217 + OMAP_ECC_HAM1_CODE_HW
  218 + 1-bit Hamming code using GPMC hardware.
  219 + (for legacy devices only)
  220 + OMAP_ECC_BCH4_CODE_HW_DETECTION_SW
  221 + 4-bit BCH code (unsupported)
  222 + OMAP_ECC_BCH4_CODE_HW
  223 + 4-bit BCH code (unsupported)
  224 + OMAP_ECC_BCH8_CODE_HW_DETECTION_SW
  225 + 8-bit BCH code with
  226 + - ecc calculation using GPMC hardware engine,
  227 + - error detection using software library.
  228 + - requires CONFIG_BCH to enable software BCH library
  229 + (For legacy device which do not have ELM h/w engine)
  230 + OMAP_ECC_BCH8_CODE_HW
  231 + 8-bit BCH code with
  232 + - ecc calculation using GPMC hardware engine,
  233 + - error detection using ELM hardware engine.
171 234  
172 235 NOTE:
173 236 =====
... ... @@ -161,8 +161,7 @@
161 161  
162 162 To enable hardware assisted BCH8 (8-bit BCH [Bose, Chaudhuri, Hocquenghem]) on
163 163 OMAP3 devices we can use the BCH library in lib/bch.c. To do so add CONFIG_BCH
164   -to enable the library and CONFIG_NAND_OMAP_BCH8 to to enable hardware assisted
165   -syndrom generation to your board config.
  164 +and set CONFIG_NAND_OMAP_ECCSCHEME=5 (refer README.nand) for selecting BCH8_SW.
166 165 The NAND OOB layout is the same as in linux kernel, if the linux kernel BCH8
167 166 implementation for OMAP3 works for you so the u-boot version should also.
168 167 When you require the SPL to read with BCH8 there are two more configs to
drivers/mtd/nand/Makefile
... ... @@ -58,6 +58,7 @@
58 58 obj-$(CONFIG_NAND_SPEAR) += spr_nand.o
59 59 obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
60 60 obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
  61 +obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
61 62 obj-$(CONFIG_NAND_PLAT) += nand_plat.o
62 63 obj-$(CONFIG_NAND_DOCG4) += docg4.o
63 64  
drivers/mtd/nand/atmel_nand.c
... ... @@ -412,7 +412,7 @@
412 412 }
413 413  
414 414 if (!timeout) {
415   - printk(KERN_ERR "atmel_nand : Timeout to calculate PMECC error location\n");
  415 + dev_err(host->dev, "atmel_nand : Timeout to calculate PMECC error location\n");
416 416 return -1;
417 417 }
418 418  
... ... @@ -452,7 +452,7 @@
452 452 *(buf + byte_pos) ^= (1 << bit_pos);
453 453  
454 454 pos = sector_num * host->pmecc_sector_size + byte_pos;
455   - printk(KERN_INFO "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
  455 + dev_dbg(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
456 456 pos, bit_pos, err_byte, *(buf + byte_pos));
457 457 } else {
458 458 /* Bit flip in OOB area */
... ... @@ -462,7 +462,7 @@
462 462 ecc[tmp] ^= (1 << bit_pos);
463 463  
464 464 pos = tmp + nand_chip->ecc.layout->eccpos[0];
465   - printk(KERN_INFO "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
  465 + dev_dbg(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
466 466 pos, bit_pos, err_byte, ecc[tmp]);
467 467 }
468 468  
... ... @@ -500,7 +500,7 @@
500 500  
501 501 err_nbr = pmecc_err_location(mtd);
502 502 if (err_nbr == -1) {
503   - printk(KERN_ERR "PMECC: Too many errors\n");
  503 + dev_err(host->dev, "PMECC: Too many errors\n");
504 504 mtd->ecc_stats.failed++;
505 505 return -EIO;
506 506 } else {
... ... @@ -544,7 +544,7 @@
544 544 }
545 545  
546 546 if (!timeout) {
547   - printk(KERN_ERR "atmel_nand : Timeout to read PMECC page\n");
  547 + dev_err(host->dev, "atmel_nand : Timeout to read PMECC page\n");
548 548 return -1;
549 549 }
550 550  
... ... @@ -584,7 +584,7 @@
584 584 }
585 585  
586 586 if (!timeout) {
587   - printk(KERN_ERR "atmel_nand : Timeout to read PMECC status, fail to write PMECC in oob\n");
  587 + dev_err(host->dev, "atmel_nand : Timeout to read PMECC status, fail to write PMECC in oob\n");
588 588 goto out;
589 589 }
590 590  
... ... @@ -827,6 +827,7 @@
827 827 switch (mtd->writesize) {
828 828 case 2048:
829 829 case 4096:
  830 + case 8192:
830 831 host->pmecc_degree = (sector_size == 512) ?
831 832 PMECC_GF_DIMENSION_13 : PMECC_GF_DIMENSION_14;
832 833 host->pmecc_cw_len = (1 << host->pmecc_degree) - 1;
833 834  
... ... @@ -840,8 +841,15 @@
840 841 nand->ecc.steps = 1;
841 842 nand->ecc.bytes = host->pmecc_bytes_per_sector *
842 843 host->pmecc_sector_number;
  844 +
  845 + if (nand->ecc.bytes > MTD_MAX_ECCPOS_ENTRIES_LARGE) {
  846 + dev_err(host->dev, "too large eccpos entries. max support ecc.bytes is %d\n",
  847 + MTD_MAX_ECCPOS_ENTRIES_LARGE);
  848 + return -EINVAL;
  849 + }
  850 +
843 851 if (nand->ecc.bytes > mtd->oobsize - 2) {
844   - printk(KERN_ERR "No room for ECC bytes\n");
  852 + dev_err(host->dev, "No room for ECC bytes\n");
845 853 return -EINVAL;
846 854 }
847 855 pmecc_config_ecc_layout(&atmel_pmecc_oobinfo,
... ... @@ -852,7 +860,7 @@
852 860 case 512:
853 861 case 1024:
854 862 /* TODO */
855   - printk(KERN_ERR "Unsupported page size for PMECC, use Software ECC\n");
  863 + dev_err(host->dev, "Unsupported page size for PMECC, use Software ECC\n");
856 864 default:
857 865 /* page size not handled by HW ECC */
858 866 /* switching back to soft ECC */
... ... @@ -1035,7 +1043,7 @@
1035 1043 /* it doesn't seems to be a freshly
1036 1044 * erased block.
1037 1045 * We can't correct so many errors */
1038   - printk(KERN_WARNING "atmel_nand : multiple errors detected."
  1046 + dev_warn(host->dev, "atmel_nand : multiple errors detected."
1039 1047 " Unable to correct.\n");
1040 1048 return -EIO;
1041 1049 }
1042 1050  
... ... @@ -1045,12 +1053,12 @@
1045 1053 /* there's nothing much to do here.
1046 1054 * the bit error is on the ECC itself.
1047 1055 */
1048   - printk(KERN_WARNING "atmel_nand : one bit error on ECC code."
  1056 + dev_warn(host->dev, "atmel_nand : one bit error on ECC code."
1049 1057 " Nothing to correct\n");
1050 1058 return 0;
1051 1059 }
1052 1060  
1053   - printk(KERN_WARNING "atmel_nand : one bit error on data."
  1061 + dev_warn(host->dev, "atmel_nand : one bit error on data."
1054 1062 " (word offset in the page :"
1055 1063 " 0x%x bit offset : 0x%x)\n",
1056 1064 ecc_word, ecc_bit);
... ... @@ -1062,7 +1070,7 @@
1062 1070 /* 8 bits words */
1063 1071 dat[ecc_word] ^= (1 << ecc_bit);
1064 1072 }
1065   - printk(KERN_WARNING "atmel_nand : error corrected\n");
  1073 + dev_warn(host->dev, "atmel_nand : error corrected\n");
1066 1074 return 1;
1067 1075 }
1068 1076  
1069 1077  
... ... @@ -1178,7 +1186,11 @@
1178 1186 mtd->priv = nand;
1179 1187 nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr;
1180 1188  
  1189 +#ifdef CONFIG_NAND_ECC_BCH
  1190 + nand->ecc.mode = NAND_ECC_SOFT_BCH;
  1191 +#else
1181 1192 nand->ecc.mode = NAND_ECC_SOFT;
  1193 +#endif
1182 1194 #ifdef CONFIG_SYS_NAND_DBW_16
1183 1195 nand->options = NAND_BUSWIDTH_16;
1184 1196 #endif
... ... @@ -1186,7 +1198,7 @@
1186 1198 #ifdef CONFIG_SYS_NAND_READY_PIN
1187 1199 nand->dev_ready = at91_nand_ready;
1188 1200 #endif
1189   - nand->chip_delay = 20;
  1201 + nand->chip_delay = 75;
1190 1202  
1191 1203 ret = nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL);
1192 1204 if (ret)
... ... @@ -1214,7 +1226,7 @@
1214 1226 int i;
1215 1227 for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
1216 1228 if (atmel_nand_chip_init(i, base_addr[i]))
1217   - printk(KERN_ERR "atmel_nand: Fail to initialize #%d chip",
  1229 + dev_err(host->dev, "atmel_nand: Fail to initialize #%d chip",
1218 1230 i);
1219 1231 }
drivers/mtd/nand/fsl_ifc_nand.c
... ... @@ -125,7 +125,70 @@
125 125 .oobfree = { {2, 6}, {136, 82} },
126 126 };
127 127  
  128 +/* 8192-byte page size with 4-bit ECC */
  129 +static struct nand_ecclayout oob_8192_ecc4 = {
  130 + .eccbytes = 128,
  131 + .eccpos = {
  132 + 8, 9, 10, 11, 12, 13, 14, 15,
  133 + 16, 17, 18, 19, 20, 21, 22, 23,
  134 + 24, 25, 26, 27, 28, 29, 30, 31,
  135 + 32, 33, 34, 35, 36, 37, 38, 39,
  136 + 40, 41, 42, 43, 44, 45, 46, 47,
  137 + 48, 49, 50, 51, 52, 53, 54, 55,
  138 + 56, 57, 58, 59, 60, 61, 62, 63,
  139 + 64, 65, 66, 67, 68, 69, 70, 71,
  140 + 72, 73, 74, 75, 76, 77, 78, 79,
  141 + 80, 81, 82, 83, 84, 85, 86, 87,
  142 + 88, 89, 90, 91, 92, 93, 94, 95,
  143 + 96, 97, 98, 99, 100, 101, 102, 103,
  144 + 104, 105, 106, 107, 108, 109, 110, 111,
  145 + 112, 113, 114, 115, 116, 117, 118, 119,
  146 + 120, 121, 122, 123, 124, 125, 126, 127,
  147 + 128, 129, 130, 131, 132, 133, 134, 135,
  148 + },
  149 + .oobfree = { {2, 6}, {136, 208} },
  150 +};
128 151  
  152 +/* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */
  153 +static struct nand_ecclayout oob_8192_ecc8 = {
  154 + .eccbytes = 256,
  155 + .eccpos = {
  156 + 8, 9, 10, 11, 12, 13, 14, 15,
  157 + 16, 17, 18, 19, 20, 21, 22, 23,
  158 + 24, 25, 26, 27, 28, 29, 30, 31,
  159 + 32, 33, 34, 35, 36, 37, 38, 39,
  160 + 40, 41, 42, 43, 44, 45, 46, 47,
  161 + 48, 49, 50, 51, 52, 53, 54, 55,
  162 + 56, 57, 58, 59, 60, 61, 62, 63,
  163 + 64, 65, 66, 67, 68, 69, 70, 71,
  164 + 72, 73, 74, 75, 76, 77, 78, 79,
  165 + 80, 81, 82, 83, 84, 85, 86, 87,
  166 + 88, 89, 90, 91, 92, 93, 94, 95,
  167 + 96, 97, 98, 99, 100, 101, 102, 103,
  168 + 104, 105, 106, 107, 108, 109, 110, 111,
  169 + 112, 113, 114, 115, 116, 117, 118, 119,
  170 + 120, 121, 122, 123, 124, 125, 126, 127,
  171 + 128, 129, 130, 131, 132, 133, 134, 135,
  172 + 136, 137, 138, 139, 140, 141, 142, 143,
  173 + 144, 145, 146, 147, 148, 149, 150, 151,
  174 + 152, 153, 154, 155, 156, 157, 158, 159,
  175 + 160, 161, 162, 163, 164, 165, 166, 167,
  176 + 168, 169, 170, 171, 172, 173, 174, 175,
  177 + 176, 177, 178, 179, 180, 181, 182, 183,
  178 + 184, 185, 186, 187, 188, 189, 190, 191,
  179 + 192, 193, 194, 195, 196, 197, 198, 199,
  180 + 200, 201, 202, 203, 204, 205, 206, 207,
  181 + 208, 209, 210, 211, 212, 213, 214, 215,
  182 + 216, 217, 218, 219, 220, 221, 222, 223,
  183 + 224, 225, 226, 227, 228, 229, 230, 231,
  184 + 232, 233, 234, 235, 236, 237, 238, 239,
  185 + 240, 241, 242, 243, 244, 245, 246, 247,
  186 + 248, 249, 250, 251, 252, 253, 254, 255,
  187 + 256, 257, 258, 259, 260, 261, 262, 263,
  188 + },
  189 + .oobfree = { {2, 6}, {264, 80} },
  190 +};
  191 +
129 192 /*
130 193 * Generic flash bbt descriptors
131 194 */
132 195  
133 196  
... ... @@ -428,20 +491,27 @@
428 491 if (mtd->writesize > 512) {
429 492 nand_fcr0 =
430 493 (NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) |
431   - (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD1_SHIFT);
  494 + (NAND_CMD_STATUS << IFC_NAND_FCR0_CMD1_SHIFT) |
  495 + (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD2_SHIFT);
432 496  
433 497 out_be32(&ifc->ifc_nand.nand_fir0,
434 498 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
435 499 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
436 500 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
437 501 (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP3_SHIFT) |
438   - (IFC_FIR_OP_CW1 << IFC_NAND_FIR0_OP4_SHIFT));
439   - out_be32(&ifc->ifc_nand.nand_fir1, 0);
  502 + (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP4_SHIFT));
  503 + out_be32(&ifc->ifc_nand.nand_fir1,
  504 + (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT) |
  505 + (IFC_FIR_OP_RDSTAT <<
  506 + IFC_NAND_FIR1_OP6_SHIFT) |
  507 + (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP7_SHIFT));
440 508 } else {
441 509 nand_fcr0 = ((NAND_CMD_PAGEPROG <<
442 510 IFC_NAND_FCR0_CMD1_SHIFT) |
443 511 (NAND_CMD_SEQIN <<
444   - IFC_NAND_FCR0_CMD2_SHIFT));
  512 + IFC_NAND_FCR0_CMD2_SHIFT) |
  513 + (NAND_CMD_STATUS <<
  514 + IFC_NAND_FCR0_CMD3_SHIFT));
445 515  
446 516 out_be32(&ifc->ifc_nand.nand_fir0,
447 517 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
... ... @@ -450,7 +520,11 @@
450 520 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) |
451 521 (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT));
452 522 out_be32(&ifc->ifc_nand.nand_fir1,
453   - (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT));
  523 + (IFC_FIR_OP_CMD1 << IFC_NAND_FIR1_OP5_SHIFT) |
  524 + (IFC_FIR_OP_CW3 << IFC_NAND_FIR1_OP6_SHIFT) |
  525 + (IFC_FIR_OP_RDSTAT <<
  526 + IFC_NAND_FIR1_OP7_SHIFT) |
  527 + (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP8_SHIFT));
454 528  
455 529 if (column >= mtd->writesize)
456 530 nand_fcr0 |=
... ... @@ -901,6 +975,21 @@
901 975  
902 976 priv->bufnum_mask = 1;
903 977 break;
  978 +
  979 + case CSOR_NAND_PGS_8K:
  980 + if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
  981 + CSOR_NAND_ECC_MODE_4) {
  982 + layout = &oob_8192_ecc4;
  983 + nand->ecc.strength = 4;
  984 + } else {
  985 + layout = &oob_8192_ecc8;
  986 + nand->ecc.strength = 8;
  987 + nand->ecc.bytes = 16;
  988 + }
  989 +
  990 + priv->bufnum_mask = 0;
  991 + break;
  992 +
904 993  
905 994 default:
906 995 printf("ifc nand: bad csor %#x: bad page size\n", csor);
drivers/mtd/nand/fsl_ifc_spl.c
... ... @@ -112,10 +112,13 @@
112 112  
113 113 port_size = (cspr & CSPR_PORT_SIZE_16) ? 16 : 8;
114 114  
115   - if (csor & CSOR_NAND_PGS_4K) {
  115 + if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_8K) {
  116 + page_size = 8192;
  117 + bufnum_mask = 0x0;
  118 + } else if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_4K) {
116 119 page_size = 4096;
117 120 bufnum_mask = 0x1;
118   - } else if (csor & CSOR_NAND_PGS_2K) {
  121 + } else if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_2K) {
119 122 page_size = 2048;
120 123 bufnum_mask = 0x3;
121 124 } else {
drivers/mtd/nand/omap_elm.c
  1 +/*
  2 + * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
  3 + * Mansoor Ahamed <mansoor.ahamed@ti.com>
  4 + *
  5 + * BCH Error Location Module (ELM) support.
  6 + *
  7 + * NOTE:
  8 + * 1. Supports only continuous mode. Dont see need for page mode in uboot
  9 + * 2. Supports only syndrome polynomial 0. i.e. poly local variable is
  10 + * always set to ELM_DEFAULT_POLY. Dont see need for other polynomial
  11 + * sets in uboot
  12 + *
  13 + * SPDX-License-Identifier: GPL-2.0+
  14 + */
  15 +
  16 +#include <common.h>
  17 +#include <asm/io.h>
  18 +#include <asm/errno.h>
  19 +#include <asm/arch/cpu.h>
  20 +#include <asm/omap_gpmc.h>
  21 +#include <asm/omap_elm.h>
  22 +
  23 +#define ELM_DEFAULT_POLY (0)
  24 +
  25 +struct elm *elm_cfg;
  26 +
  27 +/**
  28 + * elm_load_syndromes - Load BCH syndromes based on nibble selection
  29 + * @syndrome: BCH syndrome
  30 + * @nibbles:
  31 + * @poly: Syndrome Polynomial set to use
  32 + *
  33 + * Load BCH syndromes based on nibble selection
  34 + */
  35 +static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
  36 +{
  37 + u32 *ptr;
  38 + u32 val;
  39 +
  40 + /* reg 0 */
  41 + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[0];
  42 + val = syndrome[0] | (syndrome[1] << 8) | (syndrome[2] << 16) |
  43 + (syndrome[3] << 24);
  44 + writel(val, ptr);
  45 + /* reg 1 */
  46 + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[1];
  47 + val = syndrome[4] | (syndrome[5] << 8) | (syndrome[6] << 16) |
  48 + (syndrome[7] << 24);
  49 + writel(val, ptr);
  50 +
  51 + /* BCH 8-bit with 26 nibbles (4*8=32) */
  52 + if (nibbles > 13) {
  53 + /* reg 2 */
  54 + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2];
  55 + val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) |
  56 + (syndrome[11] << 24);
  57 + writel(val, ptr);
  58 + /* reg 3 */
  59 + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[3];
  60 + val = syndrome[12] | (syndrome[13] << 8) |
  61 + (syndrome[14] << 16) | (syndrome[15] << 24);
  62 + writel(val, ptr);
  63 + }
  64 +
  65 + /* BCH 16-bit with 52 nibbles (7*8=56) */
  66 + if (nibbles > 26) {
  67 + /* reg 4 */
  68 + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4];
  69 + val = syndrome[16] | (syndrome[17] << 8) |
  70 + (syndrome[18] << 16) | (syndrome[19] << 24);
  71 + writel(val, ptr);
  72 +
  73 + /* reg 5 */
  74 + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[5];
  75 + val = syndrome[20] | (syndrome[21] << 8) |
  76 + (syndrome[22] << 16) | (syndrome[23] << 24);
  77 + writel(val, ptr);
  78 +
  79 + /* reg 6 */
  80 + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6];
  81 + val = syndrome[24] | (syndrome[25] << 8) |
  82 + (syndrome[26] << 16) | (syndrome[27] << 24);
  83 + writel(val, ptr);
  84 + }
  85 +}
  86 +
  87 +/**
  88 + * elm_check_errors - Check for BCH errors and return error locations
  89 + * @syndrome: BCH syndrome
  90 + * @nibbles:
  91 + * @error_count: Returns number of errrors in the syndrome
  92 + * @error_locations: Returns error locations (in decimal) in this array
  93 + *
  94 + * Check the provided syndrome for BCH errors and return error count
  95 + * and locations in the array passed. Returns -1 if error is not correctable,
  96 + * else returns 0
  97 + */
  98 +int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
  99 + u32 *error_locations)
  100 +{
  101 + u8 poly = ELM_DEFAULT_POLY;
  102 + s8 i;
  103 + u32 location_status;
  104 +
  105 + elm_load_syndromes(syndrome, nibbles, poly);
  106 +
  107 + /* start processing */
  108 + writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6])
  109 + | ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID),
  110 + &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]);
  111 +
  112 + /* wait for processing to complete */
  113 + while ((readl(&elm_cfg->irqstatus) & (0x1 << poly)) != 0x1)
  114 + ;
  115 + /* clear status */
  116 + writel((readl(&elm_cfg->irqstatus) | (0x1 << poly)),
  117 + &elm_cfg->irqstatus);
  118 +
  119 + /* check if correctable */
  120 + location_status = readl(&elm_cfg->error_location[poly].location_status);
  121 + if (!(location_status & ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK))
  122 + return -1;
  123 +
  124 + /* get error count */
  125 + *error_count = readl(&elm_cfg->error_location[poly].location_status) &
  126 + ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK;
  127 +
  128 + for (i = 0; i < *error_count; i++) {
  129 + error_locations[i] =
  130 + readl(&elm_cfg->error_location[poly].error_location_x[i]);
  131 + }
  132 +
  133 + return 0;
  134 +}
  135 +
  136 +
  137 +/**
  138 + * elm_config - Configure ELM module
  139 + * @level: 4 / 8 / 16 bit BCH
  140 + *
  141 + * Configure ELM module based on BCH level.
  142 + * Set mode as continuous mode.
  143 + * Currently we are using only syndrome 0 and syndromes 1 to 6 are not used.
  144 + * Also, the mode is set only for syndrome 0
  145 + */
  146 +int elm_config(enum bch_level level)
  147 +{
  148 + u32 val;
  149 + u8 poly = ELM_DEFAULT_POLY;
  150 + u32 buffer_size = 0x7FF;
  151 +
  152 + /* config size and level */
  153 + val = (u32)(level) & ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK;
  154 + val |= ((buffer_size << ELM_LOCATION_CONFIG_ECC_SIZE_POS) &
  155 + ELM_LOCATION_CONFIG_ECC_SIZE_MASK);
  156 + writel(val, &elm_cfg->location_config);
  157 +
  158 + /* config continous mode */
  159 + /* enable interrupt generation for syndrome polynomial set */
  160 + writel((readl(&elm_cfg->irqenable) | (0x1 << poly)),
  161 + &elm_cfg->irqenable);
  162 + /* set continuous mode for the syndrome polynomial set */
  163 + writel((readl(&elm_cfg->page_ctrl) & ~(0x1 << poly)),
  164 + &elm_cfg->page_ctrl);
  165 +
  166 + return 0;
  167 +}
  168 +
  169 +/**
  170 + * elm_reset - Do a soft reset of ELM
  171 + *
  172 + * Perform a soft reset of ELM and return after reset is done.
  173 + */
  174 +void elm_reset(void)
  175 +{
  176 + /* initiate reset */
  177 + writel((readl(&elm_cfg->sysconfig) | ELM_SYSCONFIG_SOFTRESET),
  178 + &elm_cfg->sysconfig);
  179 +
  180 + /* wait for reset complete and normal operation */
  181 + while ((readl(&elm_cfg->sysstatus) & ELM_SYSSTATUS_RESETDONE) !=
  182 + ELM_SYSSTATUS_RESETDONE)
  183 + ;
  184 +}
  185 +
  186 +/**
  187 + * elm_init - Initialize ELM module
  188 + *
  189 + * Initialize ELM support. Currently it does only base address init
  190 + * and ELM reset.
  191 + */
  192 +void elm_init(void)
  193 +{
  194 + elm_cfg = (struct elm *)ELM_BASE;
  195 + elm_reset();
  196 +}
drivers/mtd/nand/omap_gpmc.c
... ... @@ -15,15 +15,13 @@
15 15 #include <linux/bch.h>
16 16 #include <linux/compiler.h>
17 17 #include <nand.h>
18   -#ifdef CONFIG_AM33XX
19   -#include <asm/arch/elm.h>
20   -#endif
  18 +#include <asm/omap_elm.h>
21 19  
  20 +#define BADBLOCK_MARKER_LENGTH 2
  21 +#define SECTOR_BYTES 512
  22 +
22 23 static uint8_t cs;
23   -static __maybe_unused struct nand_ecclayout hw_nand_oob =
24   - GPMC_NAND_HW_ECC_LAYOUT;
25   -static __maybe_unused struct nand_ecclayout hw_bch8_nand_oob =
26   - GPMC_NAND_HW_BCH8_ECC_LAYOUT;
  24 +static __maybe_unused struct nand_ecclayout omap_ecclayout;
27 25  
28 26 /*
29 27 * omap_nand_hwcontrol - Set the address pointers corretly for the
... ... @@ -233,6 +231,7 @@
233 231 uint8_t type;
234 232 uint8_t nibbles;
235 233 struct bch_control *control;
  234 + enum omap_ecc ecc_scheme;
236 235 };
237 236  
238 237 /* bch types */
239 238  
240 239  
... ... @@ -274,17 +273,15 @@
274 273 {
275 274 uint32_t val;
276 275 uint32_t dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
277   -#ifdef CONFIG_AM33XX
278 276 uint32_t unused_length = 0;
279   -#endif
280 277 uint32_t wr_mode = BCH_WRAPMODE_6;
281 278 struct nand_bch_priv *bch = chip->priv;
282 279  
283 280 /* Clear the ecc result registers, select ecc reg as 1 */
284 281 writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
285 282  
286   -#ifdef CONFIG_AM33XX
287   - wr_mode = BCH_WRAPMODE_1;
  283 + if (bch->ecc_scheme == OMAP_ECC_BCH8_CODE_HW) {
  284 + wr_mode = BCH_WRAPMODE_1;
288 285  
289 286 switch (bch->nibbles) {
290 287 case ECC_BCH4_NIBBLES:
... ... @@ -320,7 +317,7 @@
320 317 val |= (unused_length << 22);
321 318 break;
322 319 }
323   -#else
  320 + } else {
324 321 /*
325 322 * This ecc_size_config setting is for BCH sw library.
326 323 *
... ... @@ -333,7 +330,7 @@
333 330 * size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
334 331 */
335 332 val = (32 << 22) | (0 << 12);
336   -#endif
  333 + }
337 334 /* ecc size configuration */
338 335 writel(val, &gpmc_cfg->ecc_size_config);
339 336  
340 337  
... ... @@ -376,9 +373,9 @@
376 373 }
377 374  
378 375 /*
379   - * BCH8 support (needs ELM and thus AM33xx-only)
  376 + * BCH support using ELM module
380 377 */
381   -#ifdef CONFIG_AM33XX
  378 +#ifdef CONFIG_NAND_OMAP_ELM
382 379 /*
383 380 * omap_read_bch8_result - Read BCH result for BCH8 level
384 381 *
385 382  
386 383  
387 384  
... ... @@ -631,20 +628,20 @@
631 628 }
632 629 return 0;
633 630 }
634   -#endif /* CONFIG_AM33XX */
  631 +#endif /* CONFIG_NAND_OMAP_ELM */
635 632  
636 633 /*
637 634 * OMAP3 BCH8 support (with BCH library)
638 635 */
639   -#ifdef CONFIG_NAND_OMAP_BCH8
  636 +#ifdef CONFIG_BCH
640 637 /*
641   - * omap_calculate_ecc_bch - Read BCH ECC result
  638 + * omap_calculate_ecc_bch_sw - Read BCH ECC result
642 639 *
643 640 * @mtd: MTD device structure
644 641 * @dat: The pointer to data on which ecc is computed (unused here)
645 642 * @ecc: The ECC output buffer
646 643 */
647   -static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
  644 +static int omap_calculate_ecc_bch_sw(struct mtd_info *mtd, const uint8_t *dat,
648 645 uint8_t *ecc)
649 646 {
650 647 int ret = 0;
651 648  
... ... @@ -689,13 +686,13 @@
689 686 }
690 687  
691 688 /**
692   - * omap_correct_data_bch - Decode received data and correct errors
  689 + * omap_correct_data_bch_sw - Decode received data and correct errors
693 690 * @mtd: MTD device structure
694 691 * @data: page data
695 692 * @read_ecc: ecc read from nand flash
696 693 * @calc_ecc: ecc read from HW ECC registers
697 694 */
698   -static int omap_correct_data_bch(struct mtd_info *mtd, u_char *data,
  695 +static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
699 696 u_char *read_ecc, u_char *calc_ecc)
700 697 {
701 698 int i, count;
702 699  
... ... @@ -752,8 +749,151 @@
752 749 chip_priv->control = NULL;
753 750 }
754 751 }
755   -#endif /* CONFIG_NAND_OMAP_BCH8 */
  752 +#endif /* CONFIG_BCH */
756 753  
  754 +/**
  755 + * omap_select_ecc_scheme - configures driver for particular ecc-scheme
  756 + * @nand: NAND chip device structure
  757 + * @ecc_scheme: ecc scheme to configure
  758 + * @pagesize: number of main-area bytes per page of NAND device
  759 + * @oobsize: number of OOB/spare bytes per page of NAND device
  760 + */
  761 +static int omap_select_ecc_scheme(struct nand_chip *nand,
  762 + enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
  763 + struct nand_bch_priv *bch = nand->priv;
  764 + struct nand_ecclayout *ecclayout = nand->ecc.layout;
  765 + int eccsteps = pagesize / SECTOR_BYTES;
  766 + int i;
  767 +
  768 + switch (ecc_scheme) {
  769 + case OMAP_ECC_HAM1_CODE_SW:
  770 + debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
  771 + /* For this ecc-scheme, ecc.bytes, ecc.layout, ... are
  772 + * initialized in nand_scan_tail(), so just set ecc.mode */
  773 + bch_priv.control = NULL;
  774 + bch_priv.type = 0;
  775 + nand->ecc.mode = NAND_ECC_SOFT;
  776 + nand->ecc.layout = NULL;
  777 + nand->ecc.size = pagesize;
  778 + bch->ecc_scheme = OMAP_ECC_HAM1_CODE_SW;
  779 + break;
  780 +
  781 + case OMAP_ECC_HAM1_CODE_HW:
  782 + debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n");
  783 + /* check ecc-scheme requirements before updating ecc info */
  784 + if ((3 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  785 + printf("nand: error: insufficient OOB: require=%d\n", (
  786 + (3 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  787 + return -EINVAL;
  788 + }
  789 + bch_priv.control = NULL;
  790 + bch_priv.type = 0;
  791 + /* populate ecc specific fields */
  792 + nand->ecc.mode = NAND_ECC_HW;
  793 + nand->ecc.strength = 1;
  794 + nand->ecc.size = SECTOR_BYTES;
  795 + nand->ecc.bytes = 3;
  796 + nand->ecc.hwctl = omap_enable_hwecc;
  797 + nand->ecc.correct = omap_correct_data;
  798 + nand->ecc.calculate = omap_calculate_ecc;
  799 + /* define ecc-layout */
  800 + ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  801 + for (i = 0; i < ecclayout->eccbytes; i++)
  802 + ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
  803 + ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  804 + ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
  805 + BADBLOCK_MARKER_LENGTH;
  806 + bch->ecc_scheme = OMAP_ECC_HAM1_CODE_HW;
  807 + break;
  808 +
  809 + case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  810 +#ifdef CONFIG_BCH
  811 + debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
  812 + /* check ecc-scheme requirements before updating ecc info */
  813 + if ((13 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  814 + printf("nand: error: insufficient OOB: require=%d\n", (
  815 + (13 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  816 + return -EINVAL;
  817 + }
  818 + /* check if BCH S/W library can be used for error detection */
  819 + bch_priv.control = init_bch(13, 8, 0x201b);
  820 + if (!bch_priv.control) {
  821 + printf("nand: error: could not init_bch()\n");
  822 + return -ENODEV;
  823 + }
  824 + bch_priv.type = ECC_BCH8;
  825 + /* populate ecc specific fields */
  826 + nand->ecc.mode = NAND_ECC_HW;
  827 + nand->ecc.strength = 8;
  828 + nand->ecc.size = SECTOR_BYTES;
  829 + nand->ecc.bytes = 13;
  830 + nand->ecc.hwctl = omap_enable_ecc_bch;
  831 + nand->ecc.correct = omap_correct_data_bch_sw;
  832 + nand->ecc.calculate = omap_calculate_ecc_bch_sw;
  833 + /* define ecc-layout */
  834 + ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  835 + ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH;
  836 + for (i = 1; i < ecclayout->eccbytes; i++) {
  837 + if (i % nand->ecc.bytes)
  838 + ecclayout->eccpos[i] =
  839 + ecclayout->eccpos[i - 1] + 1;
  840 + else
  841 + ecclayout->eccpos[i] =
  842 + ecclayout->eccpos[i - 1] + 2;
  843 + }
  844 + ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  845 + ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
  846 + BADBLOCK_MARKER_LENGTH;
  847 + omap_hwecc_init_bch(nand, NAND_ECC_READ);
  848 + bch->ecc_scheme = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
  849 + break;
  850 +#else
  851 + printf("nand: error: CONFIG_BCH required for ECC\n");
  852 + return -EINVAL;
  853 +#endif
  854 +
  855 + case OMAP_ECC_BCH8_CODE_HW:
  856 +#ifdef CONFIG_NAND_OMAP_ELM
  857 + debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n");
  858 + /* check ecc-scheme requirements before updating ecc info */
  859 + if ((14 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  860 + printf("nand: error: insufficient OOB: require=%d\n", (
  861 + (14 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  862 + return -EINVAL;
  863 + }
  864 + /* intialize ELM for ECC error detection */
  865 + elm_init();
  866 + bch_priv.type = ECC_BCH8;
  867 + /* populate ecc specific fields */
  868 + nand->ecc.mode = NAND_ECC_HW;
  869 + nand->ecc.strength = 8;
  870 + nand->ecc.size = SECTOR_BYTES;
  871 + nand->ecc.bytes = 14;
  872 + nand->ecc.hwctl = omap_enable_ecc_bch;
  873 + nand->ecc.correct = omap_correct_data_bch;
  874 + nand->ecc.calculate = omap_calculate_ecc_bch;
  875 + nand->ecc.read_page = omap_read_page_bch;
  876 + /* define ecc-layout */
  877 + ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  878 + for (i = 0; i < ecclayout->eccbytes; i++)
  879 + ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
  880 + ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  881 + ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
  882 + BADBLOCK_MARKER_LENGTH;
  883 + bch->ecc_scheme = OMAP_ECC_BCH8_CODE_HW;
  884 + break;
  885 +#else
  886 + printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
  887 + return -EINVAL;
  888 +#endif
  889 +
  890 + default:
  891 + debug("nand: error: ecc scheme not enabled or supported\n");
  892 + return -EINVAL;
  893 + }
  894 + return 0;
  895 +}
  896 +
757 897 #ifndef CONFIG_SPL_BUILD
758 898 /*
759 899 * omap_nand_switch_ecc - switch the ECC operation between different engines
760 900  
761 901  
762 902  
763 903  
764 904  
765 905  
766 906  
767 907  
... ... @@ -763,77 +903,45 @@
763 903 * @eccstrength - the number of bits that could be corrected
764 904 * (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16)
765 905 */
766   -void omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
  906 +int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
767 907 {
768 908 struct nand_chip *nand;
769 909 struct mtd_info *mtd;
  910 + int err = 0;
770 911  
771 912 if (nand_curr_device < 0 ||
772 913 nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
773 914 !nand_info[nand_curr_device].name) {
774   - printf("Error: Can't switch ecc, no devices available\n");
775   - return;
  915 + printf("nand: error: no NAND devices found\n");
  916 + return -ENODEV;
776 917 }
777 918  
778 919 mtd = &nand_info[nand_curr_device];
779 920 nand = mtd->priv;
780   -
781 921 nand->options |= NAND_OWN_BUFFERS;
782   -
783   - /* Reset ecc interface */
784   - nand->ecc.mode = NAND_ECC_NONE;
785   - nand->ecc.read_page = NULL;
786   - nand->ecc.write_page = NULL;
787   - nand->ecc.read_oob = NULL;
788   - nand->ecc.write_oob = NULL;
789   - nand->ecc.hwctl = NULL;
790   - nand->ecc.correct = NULL;
791   - nand->ecc.calculate = NULL;
792   - nand->ecc.strength = eccstrength;
793   -
794 922 /* Setup the ecc configurations again */
795 923 if (hardware) {
796 924 if (eccstrength == 1) {
797   - nand->ecc.mode = NAND_ECC_HW;
798   - nand->ecc.layout = &hw_nand_oob;
799   - nand->ecc.size = 512;
800   - nand->ecc.bytes = 3;
801   - nand->ecc.hwctl = omap_enable_hwecc;
802   - nand->ecc.correct = omap_correct_data;
803   - nand->ecc.calculate = omap_calculate_ecc;
804   - omap_hwecc_init(nand);
805   - printf("1-bit hamming HW ECC selected\n");
  925 + err = omap_select_ecc_scheme(nand,
  926 + OMAP_ECC_HAM1_CODE_HW,
  927 + mtd->writesize, mtd->oobsize);
  928 + } else if (eccstrength == 8) {
  929 + err = omap_select_ecc_scheme(nand,
  930 + OMAP_ECC_BCH8_CODE_HW,
  931 + mtd->writesize, mtd->oobsize);
  932 + } else {
  933 + printf("nand: error: unsupported ECC scheme\n");
  934 + return -EINVAL;
806 935 }
807   -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8)
808   - else if (eccstrength == 8) {
809   - nand->ecc.mode = NAND_ECC_HW;
810   - nand->ecc.layout = &hw_bch8_nand_oob;
811   - nand->ecc.size = 512;
812   -#ifdef CONFIG_AM33XX
813   - nand->ecc.bytes = 14;
814   - nand->ecc.read_page = omap_read_page_bch;
815   -#else
816   - nand->ecc.bytes = 13;
817   -#endif
818   - nand->ecc.hwctl = omap_enable_ecc_bch;
819   - nand->ecc.correct = omap_correct_data_bch;
820   - nand->ecc.calculate = omap_calculate_ecc_bch;
821   - omap_hwecc_init_bch(nand, NAND_ECC_READ);
822   - printf("8-bit BCH HW ECC selected\n");
823   - }
824   -#endif
825 936 } else {
826   - nand->ecc.mode = NAND_ECC_SOFT;
827   - /* Use mtd default settings */
828   - nand->ecc.layout = NULL;
829   - nand->ecc.size = 0;
830   - printf("SW ECC selected\n");
  937 + err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
  938 + mtd->writesize, mtd->oobsize);
831 939 }
832 940  
833 941 /* Update NAND handling after ECC mode switch */
834   - nand_scan_tail(mtd);
835   -
836   - nand->options &= ~NAND_OWN_BUFFERS;
  942 + if (!err)
  943 + err = nand_scan_tail(mtd);
  944 + return err;
837 945 }
838 946 #endif /* CONFIG_SPL_BUILD */
839 947  
... ... @@ -856,7 +964,7 @@
856 964 {
857 965 int32_t gpmc_config = 0;
858 966 cs = 0;
859   -
  967 + int err = 0;
860 968 /*
861 969 * xloader/Uboot's gpmc configuration would have configured GPMC for
862 970 * nand type of memory. The following logic scans and latches on to the
... ... @@ -873,7 +981,7 @@
873 981 cs++;
874 982 }
875 983 if (cs >= GPMC_MAX_CS) {
876   - printf("NAND: Unable to find NAND settings in "
  984 + printf("nand: error: Unable to find NAND settings in "
877 985 "GPMC Configuration - quitting\n");
878 986 return -ENODEV;
879 987 }
880 988  
881 989  
882 990  
883 991  
... ... @@ -885,64 +993,27 @@
885 993  
886 994 nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
887 995 nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
888   -
889   - nand->cmd_ctrl = omap_nand_hwcontrol;
890   - nand->options = NAND_NO_PADDING | NAND_CACHEPRG;
  996 + nand->priv = &bch_priv;
  997 + nand->cmd_ctrl = omap_nand_hwcontrol;
  998 + nand->options |= NAND_NO_PADDING | NAND_CACHEPRG;
891 999 /* If we are 16 bit dev, our gpmc config tells us that */
892 1000 if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000)
893 1001 nand->options |= NAND_BUSWIDTH_16;
894 1002  
895 1003 nand->chip_delay = 100;
  1004 + nand->ecc.layout = &omap_ecclayout;
896 1005  
897   -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8)
898   -#ifdef CONFIG_AM33XX
899   - /* AM33xx uses the ELM */
900   - /* required in case of BCH */
901   - elm_init();
  1006 + /* select ECC scheme */
  1007 +#if defined(CONFIG_NAND_OMAP_ECCSCHEME)
  1008 + err = omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME,
  1009 + CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE);
902 1010 #else
903   - /*
904   - * Whereas other OMAP based SoC do not have the ELM, they use the BCH
905   - * SW library.
906   - */
907   - bch_priv.control = init_bch(13, 8, 0x201b /* hw polynominal */);
908   - if (!bch_priv.control) {
909   - puts("Could not init_bch()\n");
910   - return -ENODEV;
911   - }
  1011 + /* pagesize and oobsize are not required to configure sw ecc-scheme */
  1012 + err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
  1013 + 0, 0);
912 1014 #endif
913   - /* BCH info that will be correct for SPL or overridden otherwise. */
914   - nand->priv = &bch_priv;
915   -#endif
916   -
917   - /* Default ECC mode */
918   -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8)
919   - nand->ecc.mode = NAND_ECC_HW;
920   - nand->ecc.layout = &hw_bch8_nand_oob;
921   - nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
922   - nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
923   - nand->ecc.strength = 8;
924   - nand->ecc.hwctl = omap_enable_ecc_bch;
925   - nand->ecc.correct = omap_correct_data_bch;
926   - nand->ecc.calculate = omap_calculate_ecc_bch;
927   -#ifdef CONFIG_AM33XX
928   - nand->ecc.read_page = omap_read_page_bch;
929   -#endif
930   - omap_hwecc_init_bch(nand, NAND_ECC_READ);
931   -#else
932   -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC)
933   - nand->ecc.mode = NAND_ECC_SOFT;
934   -#else
935   - nand->ecc.mode = NAND_ECC_HW;
936   - nand->ecc.layout = &hw_nand_oob;
937   - nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
938   - nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
939   - nand->ecc.hwctl = omap_enable_hwecc;
940   - nand->ecc.correct = omap_correct_data;
941   - nand->ecc.calculate = omap_calculate_ecc;
942   - nand->ecc.strength = 1;
943   - omap_hwecc_init(nand);
944   -#endif
945   -#endif
  1015 + if (err)
  1016 + return err;
946 1017  
947 1018 #ifdef CONFIG_SPL_BUILD
948 1019 if (nand->options & NAND_BUSWIDTH_16)
drivers/mtd/onenand/onenand_base.c
... ... @@ -761,7 +761,8 @@
761 761 uint8_t *oob_buf = this->oob_buf;
762 762  
763 763 free = this->ecclayout->oobfree;
764   - for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
  764 + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
  765 + i++, free++) {
765 766 if (readcol >= lastgap)
766 767 readcol += free->offset - lastgap;
767 768 if (readend >= lastgap)
... ... @@ -770,7 +771,8 @@
770 771 }
771 772 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
772 773 free = this->ecclayout->oobfree;
773   - for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
  774 + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
  775 + i++, free++) {
774 776 int free_end = free->offset + free->length;
775 777 if (free->offset < readend && free_end > readcol) {
776 778 int st = max_t(int,free->offset,readcol);
... ... @@ -1356,7 +1358,8 @@
1356 1358 unsigned int i;
1357 1359  
1358 1360 free = this->ecclayout->oobfree;
1359   - for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
  1361 + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
  1362 + i++, free++) {
1360 1363 if (writecol >= lastgap)
1361 1364 writecol += free->offset - lastgap;
1362 1365 if (writeend >= lastgap)
... ... @@ -1364,7 +1367,8 @@
1364 1367 lastgap = free->offset + free->length;
1365 1368 }
1366 1369 free = this->ecclayout->oobfree;
1367   - for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
  1370 + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
  1371 + i++, free++) {
1368 1372 int free_end = free->offset + free->length;
1369 1373 if (free->offset < writeend && free_end > writecol) {
1370 1374 int st = max_t(int,free->offset,writecol);
... ... @@ -2750,7 +2754,8 @@
2750 2754 * the out of band area
2751 2755 */
2752 2756 this->ecclayout->oobavail = 0;
2753   - for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES &&
  2757 +
  2758 + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE &&
2754 2759 this->ecclayout->oobfree[i].length; i++)
2755 2760 this->ecclayout->oobavail +=
2756 2761 this->ecclayout->oobfree[i].length;
include/configs/ASH405.h
... ... @@ -143,6 +143,8 @@
143 143  
144 144 #define CONFIG_SYS_NAND_SKIP_BAD_DOT_I 1 /* ".i" read skips bad blocks */
145 145 #define CONFIG_SYS_NAND_QUIET 1
  146 +#define CONFIG_SYS_NAND_MAX_OOBFREE 2
  147 +#define CONFIG_SYS_NAND_MAX_ECCPOS 56
146 148  
147 149 /*-----------------------------------------------------------------------
148 150 * PCI stuff
include/configs/C29XPCIE.h
... ... @@ -191,13 +191,14 @@
191 191 | CSPR_MSEL_NAND \
192 192 | CSPR_V)
193 193 #define CONFIG_SYS_NAND_AMASK IFC_AMASK(64*1024)
  194 +#define CONFIG_SYS_NAND_OOBSIZE 0x00000280 /* 640b */
194 195 #define CONFIG_SYS_NAND_CSOR (CSOR_NAND_ECC_ENC_EN /* ECC on encode */ \
195 196 | CSOR_NAND_ECC_DEC_EN /* ECC on decode */ \
196 197 | CSOR_NAND_ECC_MODE_4 /* 4-bit ECC */ \
197   - | CSOR_NAND_RAL_2 /* RAL = 2 Bytes */ \
198   - | CSOR_NAND_PGS_2K /* Page Size = 2k */ \
199   - | CSOR_NAND_SPRZ_64 /* Spare size = 64 */ \
200   - | CSOR_NAND_PB(64)) /* 64 Pages Per Block */
  198 + | CSOR_NAND_RAL_3 /* RAL = 3 Bytes */ \
  199 + | CSOR_NAND_PGS_8K /* Page Size = 8K */ \
  200 + | CSOR_NAND_SPRZ_CSOR_EXT /*oob in csor_ext*/\
  201 + | CSOR_NAND_PB(128)) /*128 Pages Per Block*/
201 202 #define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x01) | \
202 203 FTIM0_NAND_TWP(0x0c) | \
203 204 FTIM0_NAND_TWCHT(0x08) | \
... ... @@ -224,6 +225,7 @@
224 225 #define CONFIG_SYS_CSPR1 CONFIG_SYS_NAND_CSPR
225 226 #define CONFIG_SYS_AMASK1 CONFIG_SYS_NAND_AMASK
226 227 #define CONFIG_SYS_CSOR1 CONFIG_SYS_NAND_CSOR
  228 +#define CONFIG_SYS_CSOR1_EXT CONFIG_SYS_NAND_OOBSIZE
227 229 #define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_NAND_FTIM0
228 230 #define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NAND_FTIM1
229 231 #define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NAND_FTIM2
include/configs/MPC8572DS.h
... ... @@ -322,6 +322,8 @@
322 322 #define CONFIG_CMD_NAND 1
323 323 #define CONFIG_NAND_FSL_ELBC 1
324 324 #define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024)
  325 +#define CONFIG_SYS_NAND_MAX_OOBFREE 5
  326 +#define CONFIG_SYS_NAND_MAX_ECCPOS 56
325 327  
326 328 /* NAND boot: 4K NAND loader config */
327 329 #define CONFIG_SYS_NAND_SPL_SIZE 0x1000
include/configs/T4240QDS.h
... ... @@ -229,6 +229,8 @@
229 229 #define CONFIG_CMD_NAND
230 230  
231 231 #define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024)
  232 +#define CONFIG_SYS_NAND_MAX_OOBFREE 2
  233 +#define CONFIG_SYS_NAND_MAX_ECCPOS 256
232 234  
233 235 #if defined(CONFIG_NAND)
234 236 #define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NAND_CSPR_EXT
include/configs/alpr.h
... ... @@ -324,6 +324,8 @@
324 324 #define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE + 0, CONFIG_SYS_NAND_BASE + 2, \
325 325 CONFIG_SYS_NAND_BASE + 4, CONFIG_SYS_NAND_BASE + 6 }
326 326 #define CONFIG_SYS_NAND_QUIET_TEST 1 /* don't warn upon unknown NAND flash */
  327 +#define CONFIG_SYS_NAND_MAX_OOBFREE 2
  328 +#define CONFIG_SYS_NAND_MAX_ECCPOS 56
327 329  
328 330 /*-----------------------------------------------------------------------
329 331 * External Bus Controller (EBC) Setup
include/configs/am335x_evm.h
... ... @@ -220,6 +220,8 @@
220 220 #define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/am33xx/u-boot-spl.lds"
221 221  
222 222 #ifdef CONFIG_NAND
  223 +#define CONFIG_NAND_OMAP_GPMC
  224 +#define CONFIG_NAND_OMAP_ELM
223 225 #define CONFIG_SYS_NAND_5_ADDR_CYCLE
224 226 #define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \
225 227 CONFIG_SYS_NAND_PAGE_SIZE)
... ... @@ -237,7 +239,8 @@
237 239  
238 240 #define CONFIG_SYS_NAND_ECCSIZE 512
239 241 #define CONFIG_SYS_NAND_ECCBYTES 14
240   -
  242 +#define CONFIG_SYS_NAND_ONFI_DETECTION
  243 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH8_CODE_HW
241 244 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
242 245 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
243 246 #endif
include/configs/am335x_igep0033.h
... ... @@ -187,6 +187,7 @@
187 187 /* NAND support */
188 188 #define CONFIG_NAND
189 189 #define CONFIG_NAND_OMAP_GPMC
  190 +#define CONFIG_NAND_OMAP_ELM
190 191 #define GPMC_NAND_ECC_LP_x16_LAYOUT 1
191 192 #define CONFIG_SYS_NAND_BASE (0x08000000) /* phys address CS0 */
192 193 #define CONFIG_SYS_MAX_NAND_DEVICE 1
... ... @@ -263,6 +264,7 @@
263 264  
264 265 #define CONFIG_SYS_NAND_ECCSIZE 512
265 266 #define CONFIG_SYS_NAND_ECCBYTES 14
  267 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH8_CODE_HW
266 268  
267 269 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
268 270  
include/configs/am3517_crane.h
... ... @@ -340,6 +340,7 @@
340 340 10, 11, 12, 13}
341 341 #define CONFIG_SYS_NAND_ECCSIZE 512
342 342 #define CONFIG_SYS_NAND_ECCBYTES 3
  343 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_HW
343 344 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
344 345 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
345 346  
include/configs/am3517_evm.h
... ... @@ -334,6 +334,7 @@
334 334 10, 11, 12, 13}
335 335 #define CONFIG_SYS_NAND_ECCSIZE 512
336 336 #define CONFIG_SYS_NAND_ECCBYTES 3
  337 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_HW
337 338 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
338 339 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
339 340  
include/configs/devkit8000.h
... ... @@ -327,6 +327,7 @@
327 327  
328 328 #define CONFIG_SYS_NAND_ECCSIZE 512
329 329 #define CONFIG_SYS_NAND_ECCBYTES 3
  330 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_HW
330 331  
331 332 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
332 333  
include/configs/mcx.h
... ... @@ -353,7 +353,6 @@
353 353 #define CONFIG_SPL_FRAMEWORK
354 354 #define CONFIG_SPL_BOARD_INIT
355 355 #define CONFIG_SPL_NAND_SIMPLE
356   -#define CONFIG_SPL_NAND_SOFTECC
357 356  
358 357 #define CONFIG_SPL_LIBCOMMON_SUPPORT
359 358 #define CONFIG_SPL_LIBDISK_SUPPORT
... ... @@ -395,6 +394,7 @@
395 394 56, 57, 58, 59, 60, 61, 62, 63}
396 395 #define CONFIG_SYS_NAND_ECCSIZE 256
397 396 #define CONFIG_SYS_NAND_ECCBYTES 3
  397 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_SW
398 398  
399 399 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
400 400  
include/configs/omap3_beagle.h
... ... @@ -431,6 +431,7 @@
431 431 10, 11, 12, 13}
432 432 #define CONFIG_SYS_NAND_ECCSIZE 512
433 433 #define CONFIG_SYS_NAND_ECCBYTES 3
  434 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_HW
434 435 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
435 436 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
436 437  
include/configs/omap3_evm.h
... ... @@ -107,6 +107,7 @@
107 107 10, 11, 12, 13}
108 108 #define CONFIG_SYS_NAND_ECCSIZE 512
109 109 #define CONFIG_SYS_NAND_ECCBYTES 3
  110 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_HW
110 111 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
111 112 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
112 113  
include/configs/omap3_evm_quick_nand.h
... ... @@ -86,6 +86,7 @@
86 86 10, 11, 12, 13}
87 87 #define CONFIG_SYS_NAND_ECCSIZE 512
88 88 #define CONFIG_SYS_NAND_ECCBYTES 3
  89 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_HW
89 90 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
90 91 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
91 92  
include/configs/omap3_igep00x0.h
... ... @@ -362,6 +362,7 @@
362 362 10, 11, 12, 13}
363 363 #define CONFIG_SYS_NAND_ECCSIZE 512
364 364 #define CONFIG_SYS_NAND_ECCBYTES 3
  365 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_HW
365 366 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
366 367 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
367 368 #endif
include/configs/omap3_overo.h
... ... @@ -324,6 +324,7 @@
324 324 10, 11, 12, 13}
325 325 #define CONFIG_SYS_NAND_ECCSIZE 512
326 326 #define CONFIG_SYS_NAND_ECCBYTES 3
  327 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_HW
327 328 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
328 329 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
329 330  
include/configs/siemens-am33x-common.h
... ... @@ -195,6 +195,7 @@
195 195  
196 196 #define CONFIG_SYS_NAND_ECCSIZE 512
197 197 #define CONFIG_SYS_NAND_ECCBYTES 14
  198 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH8_CODE_HW
198 199  
199 200 #define CONFIG_SYS_NAND_ECCSTEPS 4
200 201 #define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
... ... @@ -430,6 +431,7 @@
430 431 "\0"
431 432  
432 433 #define CONFIG_NAND_OMAP_GPMC
  434 +#define CONFIG_NAND_OMAP_ELM
433 435 #define GPMC_NAND_ECC_LP_x16_LAYOUT 1
434 436 #define CONFIG_SYS_NAND_BASE (0x08000000) /* physical address */
435 437 /* to access nand at */
include/configs/tam3517-common.h
... ... @@ -224,7 +224,6 @@
224 224 #define CONFIG_SPL_BOARD_INIT
225 225 #define CONFIG_SPL_CONSOLE
226 226 #define CONFIG_SPL_NAND_SIMPLE
227   -#define CONFIG_SPL_NAND_SOFTECC
228 227 #define CONFIG_SPL_NAND_WORKSPACE 0x8f07f000 /* below BSS */
229 228  
230 229 #define CONFIG_SPL_LIBCOMMON_SUPPORT
... ... @@ -261,6 +260,7 @@
261 260 56, 57, 58, 59, 60, 61, 62, 63}
262 261 #define CONFIG_SYS_NAND_ECCSIZE 256
263 262 #define CONFIG_SYS_NAND_ECCBYTES 3
  263 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_HAM1_CODE_SW
264 264  
265 265 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
266 266  
include/configs/tricorder.h
... ... @@ -138,8 +138,9 @@
138 138  
139 139 #define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */
140 140 /* devices */
141   -#define CONFIG_NAND_OMAP_BCH8
142 141 #define CONFIG_BCH
  142 +#define CONFIG_SYS_NAND_MAX_OOBFREE 2
  143 +#define CONFIG_SYS_NAND_MAX_ECCPOS 56
143 144  
144 145 /* commands to include */
145 146 #include <config_cmd_default.h>
... ... @@ -374,6 +375,7 @@
374 375  
375 376 #define CONFIG_SYS_NAND_ECCSIZE 512
376 377 #define CONFIG_SYS_NAND_ECCBYTES 13
  378 +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH8_CODE_HW_DETECTION_SW
377 379  
378 380 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
379 381  
include/linux/mtd/mtd.h
... ... @@ -96,6 +96,29 @@
96 96 uint8_t *oobbuf;
97 97 };
98 98  
  99 +#ifdef CONFIG_SYS_NAND_MAX_OOBFREE
  100 +#define MTD_MAX_OOBFREE_ENTRIES_LARGE CONFIG_SYS_NAND_MAX_OOBFREE
  101 +#else
  102 +#define MTD_MAX_OOBFREE_ENTRIES_LARGE 32
  103 +#endif
  104 +
  105 +#ifdef CONFIG_SYS_NAND_MAX_ECCPOS
  106 +#define MTD_MAX_ECCPOS_ENTRIES_LARGE CONFIG_SYS_NAND_MAX_ECCPOS
  107 +#else
  108 +#define MTD_MAX_ECCPOS_ENTRIES_LARGE 640
  109 +#endif
  110 +
  111 +/*
  112 + * ECC layout control structure. Exported to userspace for
  113 + * diagnosis and to allow creation of raw images
  114 + */
  115 +struct nand_ecclayout {
  116 + uint32_t eccbytes;
  117 + uint32_t eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
  118 + uint32_t oobavail;
  119 + struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
  120 +};
  121 +
99 122 struct mtd_info {
100 123 u_char type;
101 124 u_int32_t flags;
include/mtd/mtd-abi.h
... ... @@ -155,18 +155,6 @@
155 155 uint32_t length;
156 156 };
157 157  
158   -#define MTD_MAX_OOBFREE_ENTRIES 8
159   -/*
160   - * ECC layout control structure. Exported to userspace for
161   - * diagnosis and to allow creation of raw images
162   - */
163   -struct nand_ecclayout {
164   - uint32_t eccbytes;
165   - uint32_t eccpos[128];
166   - uint32_t oobavail;
167   - struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
168   -};
169   -
170 158 /**
171 159 * struct mtd_ecc_stats - error correction stats
172 160 *