summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/Kconfig25
-rw-r--r--drivers/mtd/nand/sunxi_nand_spl.c43
2 files changed, 39 insertions, 29 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8fac5e8..09c9668 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -99,8 +99,6 @@ config SPL_NAND_SUNXI
---help---
Enable support for NAND. This option allows SPL to read from
sunxi NAND using DMA transfers.
- Depending on the NAND chip, values like ECC strength and page sizes
- have to be configured.
config NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END
hex "Size of syndrome partitions in sunxi NAND"
@@ -110,29 +108,6 @@ config NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END
End address for boot partitions on NAND. Those partitions have a
different random seed that has to match the sunxi BROM setting.
-config NAND_SUNXI_SPL_ECC_STRENGTH
- int "ECC Strength for sunxi NAND"
- default 40
- depends on SPL_NAND_SUNXI
- ---help---
- ECC strength used by the sunxi NAND SPL driver. This is specific to the
- chosen NAND chip and has to match the value used by the sunxi BROM.
-
-config NAND_SUNXI_SPL_ECC_PAGE_SIZE
- hex "ECC page size for sunxi NAND"
- default 0x400
- depends on SPL_NAND_SUNXI
- ---help---
- ECC page size used by the sunxi NAND SPL driver for syndrome partitions.
- This setting has to match the value used by the sunxi BROM.
-
-config NAND_SUNXI_SPL_PAGE_SIZE
- hex "Page size for sunxi NAND"
- default 0x2000
- depends on SPL_NAND_SUNXI
- ---help---
- Page size of the NAND flash used by the sunxi NAND SPL driver. This is
- specific to the chosen NAND chip.
endif
endmenu
diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c
index 3206a50..eee6c7b 100644
--- a/drivers/mtd/nand/sunxi_nand_spl.c
+++ b/drivers/mtd/nand/sunxi_nand_spl.c
@@ -307,10 +307,45 @@ static int nand_read_ecc(int page_size, int ecc_strength, int ecc_page_size,
static int nand_read_buffer(uint32_t offs, unsigned int size, void *dest,
int syndrome)
{
- return nand_read_ecc(CONFIG_NAND_SUNXI_SPL_PAGE_SIZE,
- CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH,
- CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE,
- 5, offs, size, dest, syndrome);
+ const struct {
+ int page_size;
+ int ecc_strength;
+ int ecc_page_size;
+ int addr_cycles;
+ } nand_configs[] = {
+ { 8192, 40, 1024, 5 },
+ { 16384, 56, 1024, 5 },
+ { 8192, 24, 1024, 5 },
+ };
+ static int nand_config = -1;
+ int i;
+
+ if (nand_config == -1) {
+ for (i = 0; i < ARRAY_SIZE(nand_configs); i++) {
+ debug("nand: trying page %d ecc %d / %d addr %d: ",
+ nand_configs[i].page_size,
+ nand_configs[i].ecc_strength,
+ nand_configs[i].ecc_page_size,
+ nand_configs[i].addr_cycles);
+ if (nand_read_ecc(nand_configs[i].page_size,
+ nand_configs[i].ecc_strength,
+ nand_configs[i].ecc_page_size,
+ nand_configs[i].addr_cycles,
+ offs, size, dest, syndrome) == 0) {
+ debug("success\n");
+ nand_config = i;
+ return 0;
+ }
+ debug("failed\n");
+ }
+ return -1;
+ }
+
+ return nand_read_ecc(nand_configs[nand_config].page_size,
+ nand_configs[nand_config].ecc_strength,
+ nand_configs[nand_config].ecc_page_size,
+ nand_configs[nand_config].addr_cycles,
+ offs, size, dest, syndrome);
}
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)