]> git.sur5r.net Git - u-boot/commitdiff
armv7: add reset timeout to identify_nand_chip
authorLadislav Michl <ladis@linux-mips.org>
Tue, 12 Jul 2016 18:28:15 +0000 (20:28 +0200)
committerTom Rini <trini@konsulko.com>
Fri, 22 Jul 2016 13:53:00 +0000 (09:53 -0400)
identify_nand_chip hangs forever in loop when NAND is not present.
As IGEPv2 comes either with NAND or OneNAND flash, add reset timeout
to let function fail gracefully allowing caller to know NAND is
not present. On NAND equipped board, reset succeeds on first read,
so 1000 loops seems to be safe timeout.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
arch/arm/cpu/armv7/omap3/spl_id_nand.c
arch/arm/include/asm/arch-omap3/sys_proto.h

index db6de0911bfe1fc120472335628bf11fa74ab217..26d3aa42c11a399ee1f7be1fc86232fdf81f71fa 100644 (file)
 
 static struct gpmc *gpmc_config = (struct gpmc *)GPMC_BASE;
 
-/* nand_command: Send a flash command to the flash chip */
-static void nand_command(u8 command)
-{
-       writeb(command, &gpmc_config->cs[0].nand_cmd);
-
-       if (command == NAND_CMD_RESET) {
-               unsigned char ret_val;
-               writeb(NAND_CMD_STATUS, &gpmc_config->cs[0].nand_cmd);
-               do {
-                       /* Wait until ready */
-                       ret_val = readl(&gpmc_config->cs[0].nand_dat);
-               } while ((ret_val & NAND_STATUS_READY) != NAND_STATUS_READY);
-       }
-}
-
 /*
  * Many boards will want to know the results of the NAND_CMD_READID command
  * in order to decide what to do about DDR initialization.  This function
  * allows us to do that very early and to pass those results back to the
  * board so it can make whatever decisions need to be made.
  */
-void identify_nand_chip(int *mfr, int *id)
+int identify_nand_chip(int *mfr, int *id)
 {
+       int loops = 1000;
+
        /* Make sure that we have setup GPMC for NAND correctly. */
        writel(M_NAND_GPMC_CONFIG1, &gpmc_config->cs[0].config1);
        writel(M_NAND_GPMC_CONFIG2, &gpmc_config->cs[0].config2);
@@ -62,8 +49,15 @@ void identify_nand_chip(int *mfr, int *id)
        sdelay(2000);
 
        /* Issue a RESET and then READID */
-       nand_command(NAND_CMD_RESET);
-       nand_command(NAND_CMD_READID);
+       writeb(NAND_CMD_RESET, &gpmc_config->cs[0].nand_cmd);
+       writeb(NAND_CMD_STATUS, &gpmc_config->cs[0].nand_cmd);
+       while ((readl(&gpmc_config->cs[0].nand_dat) & NAND_STATUS_READY)
+                                                  != NAND_STATUS_READY) {
+               sdelay(100);
+               if (--loops == 0)
+                       return 1;
+       }
+       writeb(NAND_CMD_READID, &gpmc_config->cs[0].nand_cmd);
 
        /* Set the address to read to 0x0 */
        writeb(0x0, &gpmc_config->cs[0].nand_adr);
@@ -71,4 +65,6 @@ void identify_nand_chip(int *mfr, int *id)
        /* Read off the manufacturer and device id. */
        *mfr = readb(&gpmc_config->cs[0].nand_dat);
        *id = readb(&gpmc_config->cs[0].nand_dat);
+
+       return 0;
 }
index 24563c08e4d2097405d0576c473f475d6857afe8..1be2b157b8b4d660539e352a1691894427747382 100644 (file)
@@ -40,7 +40,7 @@ void sdrc_init(void);
 void do_sdrc_init(u32, u32);
 
 void get_board_mem_timings(struct board_sdrc_timings *timings);
-void identify_nand_chip(int *mfr, int *id);
+int identify_nand_chip(int *mfr, int *id);
 void emif4_init(void);
 void gpmc_init(void);
 void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,