With uppcoming BCH support on OMAP devices we need to decide between differnt
algorithms when switching the ECC engine.  Currently we support 1-bit hammign
and 8-bit BCH on HW backend.

In order to switch between differnet ECC algorithms we need to change the
interface of omap_nand_switch_ecc() also.

Signed-off-by: Andreas Bießmann <andreas.de...@googlemail.com>
Cc: Tom Rini <tr...@ti.com>
---
new in v2

since v2:
 * use void omap_nand_switch_ecc(bool, uint32_t)
 * print warning if unknown HW ecc strengs choosen
 * fix alignment in help test

 arch/arm/cpu/armv7/omap3/board.c             |   31 +++++++++----
 arch/arm/include/asm/arch-am33xx/sys_proto.h |    2 +-
 arch/arm/include/asm/arch-omap3/sys_proto.h  |    2 +-
 drivers/mtd/nand/omap_gpmc.c                 |   61 ++++++++++++++------------
 4 files changed, 59 insertions(+), 37 deletions(-)

diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index c6d9a42..0150150 100644
--- a/arch/arm/cpu/armv7/omap3/board.c
+++ b/arch/arm/cpu/armv7/omap3/board.c
@@ -328,14 +328,25 @@ void abort(void)
  *****************************************************************************/
 static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const 
argv[])
 {
-       if (argc != 2)
+       if (argc < 2 || argc > 3)
                goto usage;
-       if (strncmp(argv[1], "hw", 2) == 0)
-               omap_nand_switch_ecc(1);
-       else if (strncmp(argv[1], "sw", 2) == 0)
-               omap_nand_switch_ecc(0);
-       else
+
+       if (strncmp(argv[1], "hw", 2) == 0) {
+               if (argc == 2) {
+                       omap_nand_switch_ecc(true, 1);
+               } else {
+                       if (strncmp(argv[2], "hamming", 7) == 0)
+                               omap_nand_switch_ecc(true, 1);
+                       else if (strncmp(argv[2], "bch8", 4) == 0)
+                               omap_nand_switch_ecc(true, 8);
+                       else
+                               goto usage;
+               }
+       } else if (strncmp(argv[1], "sw", 2) == 0) {
+               omap_nand_switch_ecc(false, 0);
+       } else {
                goto usage;
+       }
 
        return 0;
 
@@ -345,9 +356,13 @@ usage:
 }
 
 U_BOOT_CMD(
-       nandecc, 2, 1,  do_switch_ecc,
+       nandecc, 3, 1,  do_switch_ecc,
        "switch OMAP3 NAND ECC calculation algorithm",
-       "[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc 
algorithm"
+       "hw [hamming|bch8] - Switch between NAND hardware 1-bit hamming and"
+       " 8-bit BCH\n"
+       "                            ecc calculation (second parameter may"
+       " be omitted).\n"
+       "nandecc sw                - Switch to NAND software ecc algorithm."
 );
 
 #endif /* CONFIG_NAND_OMAP_GPMC & !CONFIG_SPL_BUILD */
diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h 
b/arch/arm/include/asm/arch-am33xx/sys_proto.h
index 0910a94..23a3049 100644
--- a/arch/arm/include/asm/arch-am33xx/sys_proto.h
+++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h
@@ -39,5 +39,5 @@ struct gpmc_cs;
 void gpmc_init(void);
 void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 
base,
                        u32 size);
-void omap_nand_switch_ecc(int);
+void omap_nand_switch_ecc(bool, uint32_t);
 #endif
diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h 
b/arch/arm/include/asm/arch-omap3/sys_proto.h
index d60f2ad..4ca4e73 100644
--- a/arch/arm/include/asm/arch-omap3/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap3/sys_proto.h
@@ -78,7 +78,7 @@ void sr32(void *, u32, u32, u32);
 u32 wait_on_value(u32, u32, void *, u32);
 void sdelay(unsigned long);
 void make_cs1_contiguous(void);
-void omap_nand_switch_ecc(int);
+void omap_nand_switch_ecc(bool, uint32_t);
 void power_init_r(void);
 void dieid_num_r(void);
 void do_omap3_emu_romcode_call(u32 service_id, u32 parameters);
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index c7d4999..0647828 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -604,13 +604,14 @@ static int omap_read_page_bch(struct mtd_info *mtd, 
struct nand_chip *chip,
 
 #ifndef CONFIG_SPL_BUILD
 /*
- * omap_nand_switch_ecc - switch the ECC operation b/w h/w ecc and s/w ecc.
- * The default is to come up on s/w ecc
- *
- * @hardware - 1 -switch to h/w ecc, 0 - s/w ecc
+ * omap_nand_switch_ecc - switch the ECC operation between different engines
+ * (h/w and s/w) and different algorithms (hamming and BCHx)
  *
+ * @hardware           - true if one of the HW engines should be used
+ * @eccstrength                - the number of bits that could be corrected
+ *                       (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16)
  */
-void omap_nand_switch_ecc(int32_t hardware)
+void omap_nand_switch_ecc(bool hardware, uint32_t eccstrength)
 {
        struct nand_chip *nand;
        struct mtd_info *mtd;
@@ -637,35 +638,41 @@ void omap_nand_switch_ecc(int32_t hardware)
        nand->ecc.calculate = NULL;
 
        /* Setup the ecc configurations again */
-       if (hardware == 1) {
-               nand->ecc.mode = NAND_ECC_HW;
-               nand->ecc.layout = &hw_nand_oob;
-               nand->ecc.size = 512;
-               nand->ecc.bytes = 3;
-               nand->ecc.hwctl = omap_enable_hwecc;
-               nand->ecc.correct = omap_correct_data;
-               nand->ecc.calculate = omap_calculate_ecc;
-               omap_hwecc_init(nand);
-               printf("HW ECC selected\n");
+       if (hardware) {
+               if (eccstrength == 1) {
+                       nand->ecc.mode = NAND_ECC_HW;
+                       nand->ecc.layout = &hw_nand_oob;
+                       nand->ecc.size = 512;
+                       nand->ecc.bytes = 3;
+                       nand->ecc.hwctl = omap_enable_hwecc;
+                       nand->ecc.correct = omap_correct_data;
+                       nand->ecc.calculate = omap_calculate_ecc;
+                       omap_hwecc_init(nand);
+                       puts("1-bit hamming HW ECC selected\n");
+               }
 #ifdef CONFIG_AM33XX
-       } else if (hardware == 2) {
-               nand->ecc.mode = NAND_ECC_HW;
-               nand->ecc.layout = &hw_bch8_nand_oob;
-               nand->ecc.size = 512;
-               nand->ecc.bytes = 14;
-               nand->ecc.read_page = omap_read_page_bch;
-               nand->ecc.hwctl = omap_enable_ecc_bch;
-               nand->ecc.correct = omap_correct_data_bch;
-               nand->ecc.calculate = omap_calculate_ecc_bch;
-               omap_hwecc_init_bch(nand, NAND_ECC_READ);
-               printf("HW BCH8 selected\n");
+               else if (eccstrength == 8) {
+                       nand->ecc.mode = NAND_ECC_HW;
+                       nand->ecc.layout = &hw_bch8_nand_oob;
+                       nand->ecc.size = 512;
+                       nand->ecc.bytes = 14;
+                       nand->ecc.read_page = omap_read_page_bch;
+                       nand->ecc.hwctl = omap_enable_ecc_bch;
+                       nand->ecc.correct = omap_correct_data_bch;
+                       nand->ecc.calculate = omap_calculate_ecc_bch;
+                       omap_hwecc_init_bch(nand, NAND_ECC_READ);
+                       puts("8-bit BCH HW ECC selected\n");
+               }
 #endif
+               else {
+                       puts("Unsupported HW ECC algorithm\n");
+               }
        } else {
                nand->ecc.mode = NAND_ECC_SOFT;
                /* Use mtd default settings */
                nand->ecc.layout = NULL;
                nand->ecc.size = 0;
-               printf("SW ECC selected\n");
+               puts("SW ECC selected\n");
        }
 
        /* Update NAND handling after ECC mode switch */
-- 
1.7.10.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to