From: John Jacques <john.jacq...@lsi.com> Signed-off-by: John Jacques <john.jacq...@lsi.com> --- drivers/mtd/nand/lsi_acp_nand.c | 171 +++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 78 deletions(-)
diff --git a/drivers/mtd/nand/lsi_acp_nand.c b/drivers/mtd/nand/lsi_acp_nand.c index 1cac342..07c521e 100644 --- a/drivers/mtd/nand/lsi_acp_nand.c +++ b/drivers/mtd/nand/lsi_acp_nand.c @@ -342,16 +342,11 @@ _WRITEL(const char *file, int line, unsigned long value, unsigned long address) */ static void *gpreg_base; - -#define LSI_NAND_PECC_BUSY_REGISTER (gpreg_base + 0x00c) - -#ifdef CONFIG_ACP_X1V1 -#define LSI_NAND_PECC_BUSY_MASK (1 << 25) -#else -#define LSI_NAND_PECC_BUSY_MASK (1 << 28) -#endif +static void *pecc_busy_register; +static unsigned long pecc_busy_mask; #define MAX_READ_BUF 16 + /* ---------------------------------------------------------------------- MTD structures @@ -706,8 +701,8 @@ lsi_nand_command(struct mtd_info *mtd, unsigned int command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); do { udelay(chip->chip_delay); - status = READL((void *)LSI_NAND_PECC_BUSY_REGISTER); - } while (0 != (status & LSI_NAND_PECC_BUSY_MASK)); + status = READL(pecc_busy_register); + } while (0 != (status & pecc_busy_mask)); /* wait until CHIP_BUSY goes low */ do { @@ -835,9 +830,9 @@ static int lsi_nand_wait(struct mtd_info *mtd, struct nand_chip *chip) #ifdef NOT_USED if (FL_READING == chip->state || FL_WRITING == chip->state) { for (;;) { - status = READL((void *)LSI_NAND_PECC_BUSY_REGISTER); + status = READL((void *)pecc_busy_register); - if (0 == (status & LSI_NAND_PECC_BUSY_MASK)) + if (0 == (status & pecc_busy_mask)) break; udelay(chip->chip_delay); @@ -845,9 +840,9 @@ static int lsi_nand_wait(struct mtd_info *mtd, struct nand_chip *chip) } #else for (;;) { - status = READL((void *)LSI_NAND_PECC_BUSY_REGISTER); + status = READL((void *)pecc_busy_register); - if (0 == (status & LSI_NAND_PECC_BUSY_MASK)) + if (0 == (status & pecc_busy_mask)) break; udelay(chip->chip_delay); @@ -3468,15 +3463,17 @@ lsi_nand_init(void) void *nand_base; struct device_node *np = NULL; struct mtd_part_parser_data ppdata; - static const char *part_probe_types[] - = { "cmdlinepart", "ofpart", NULL }; - - np = of_find_compatible_node(NULL, NULL, "lsi,acp3500"); - - if (NULL != np) { - printk(KERN_ERR "NAND Support is Not Yet Available on 3500\n"); - return -1; - } + static const char *part_probe_types[] = + { "cmdlinepart", "ofpart", NULL }; + const u32 *reg; + int reglen; + u64 nand_address; + unsigned long nand_length; + u64 gpreg_address; + unsigned long gpreg_length; + const u32 *enabled; + unsigned long cr; + unsigned long cr_save; memset(&ppdata, 0, sizeof(ppdata)); @@ -3485,74 +3482,92 @@ lsi_nand_init(void) while (np && !of_device_is_compatible(np, "acp-nand")) np = of_find_node_by_type(np, "nand"); - if (np) { - const u32 *reg; - int reglen; - u64 nand_address; - unsigned long nand_length; - u64 gpreg_address; - unsigned long gpreg_length; - const u32 *enabled; + if (NULL == np) { + printk(KERN_ERR "No NAND Nodes in Device Tree\n"); - enabled = of_get_property(np, "enabled", NULL); + return -1; + } - if (!enabled || (enabled && (0 == *enabled))) { - printk(KERN_INFO "ACP NAND Controller Isn't Enabled.\n"); - return -ENODEV; - } + enabled = of_get_property(np, "enabled", NULL); - reg = of_get_property(np, "reg", ®len); - - if (reg && (16 == reglen)) { - nand_address = of_translate_address(np, reg); - nand_length = reg[1]; - reg += 2; - gpreg_address = of_translate_address(np, reg); - gpreg_length = reg[1]; - printk(KERN_INFO "nand_address=0x%08llx nand_length=0x%lx\n" - "gpreg_address=0x%08llx gpreg_length=0x%lx\n", - nand_address, nand_length, - gpreg_address, gpreg_length); - nand_base = ioremap(nand_address, nand_length); - gpreg_base = ioremap(gpreg_address, gpreg_length); - } else { - return -1; - } + if (!enabled || (enabled && (0 == *enabled))) { + printk(KERN_INFO "ACP NAND Controller Isn't Enabled.\n"); + return -ENODEV; + } + + reg = of_get_property(np, "reg", ®len); + + if (reg && (16 == reglen)) { + nand_address = of_translate_address(np, reg); + nand_length = reg[1]; + reg += 2; + gpreg_address = of_translate_address(np, reg); + gpreg_length = reg[1]; + printk(KERN_INFO "nand_address=0x%08llx nand_length=0x%lx\n" + "gpreg_address=0x%08llx gpreg_length=0x%lx\n", + nand_address, nand_length, + gpreg_address, gpreg_length); + nand_base = ioremap(nand_address, nand_length); + gpreg_base = ioremap(gpreg_address, gpreg_length); + } else { + return -1; + } + + ppdata.of_node = np; + + /* + Determine the Axxia system type. + + The ECC status register and mask are different on 344x, 342x, 35xx... + */ - ppdata.of_node = np; + np = of_find_compatible_node(NULL, NULL, "lsi,acp3500"); + + if (NULL != np) { + pecc_busy_register = (gpreg_base + 0x8c); + pecc_busy_mask = (1 << 20); } else { - printk(KERN_INFO "ACP NAND: Using Static Addresses.\n"); - nand_base = ioremap(0x002000440000ULL, 0x20000); - gpreg_base = ioremap(0x00200040c000ULL, 0x1000); + np = of_find_compatible_node(NULL, NULL, "lsi,acp3420"); + + if (NULL != np) { + pecc_busy_register = (gpreg_base + 0xc); + pecc_busy_mask = (1 << 28); + } else { + np = of_find_compatible_node(NULL, NULL, "lsi,acp3440"); + + if (NULL != np) { + pecc_busy_register = (gpreg_base + 0xc); + pecc_busy_mask = (1 << 25); + } else { + printk(KERN_ERR "Unsupported NAND Target\n"); + + return -1; + } + } } /* Determine the version of the controller. - As there is not version register, see if bits 5:3 of the - configuration register are writable. There are in the EP501 + As there is no version register, see if bits 5:3 of the + configuration register are writable. They are in the EP501 case and aren't in the EP501G1 case. */ - { - unsigned long cr; - unsigned long cr_save; - - cr = cr_save = READL((void *)(nand_base + NAND_CONFIG_REG)); - cr = 0x2038; - WRITEL(cr, (void *)(nand_base + EP501_NAND_CONFIG_REG)); - cr = READL((void *)nand_base + EP501_NAND_CONFIG_REG); - WRITEL(cr_save, (void *)(nand_base + EP501_NAND_CONFIG_REG)); - - if (0 == (cr & 0x2038)) - lsi_nand_type = LSI_NAND_EP501G1; - else if (0x38 == (cr & 0x2038)) - lsi_nand_type = LSI_NAND_EP501; - else if (0x2000 == (cr & 0x2038)) - lsi_nand_type = LSI_NAND_EP501G3; - else - lsi_nand_type = LSI_NAND_NONE; - } + cr = cr_save = READL((void *)(nand_base + NAND_CONFIG_REG)); + cr = 0x2038; + WRITEL(cr, (void *)(nand_base + EP501_NAND_CONFIG_REG)); + cr = READL((void *)nand_base + EP501_NAND_CONFIG_REG); + WRITEL(cr_save, (void *)(nand_base + EP501_NAND_CONFIG_REG)); + + if (0 == (cr & 0x2038)) + lsi_nand_type = LSI_NAND_EP501G1; + else if (0x38 == (cr & 0x2038)) + lsi_nand_type = LSI_NAND_EP501; + else if (0x2000 == (cr & 0x2038)) + lsi_nand_type = LSI_NAND_EP501G3; + else + lsi_nand_type = LSI_NAND_NONE; switch (lsi_nand_type) { case LSI_NAND_EP501: -- 1.7.9.5 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto