summaryrefslogtreecommitdiff
path: root/arch/arm/cpu
diff options
context:
space:
mode:
authorLadislav Michl <ladis@linux-mips.org>2016-07-12 20:28:15 +0200
committerTom Rini <trini@konsulko.com>2016-07-22 09:53:00 -0400
commitb1509e3a4aa55b003e814386dd83972858544e55 (patch)
treefadcc44edc93bda36df47aea7504e56188a79038 /arch/arm/cpu
parent431889d6ad9a39846636716478d504aa7ff976fc (diff)
downloadu-boot-imx-b1509e3a4aa55b003e814386dd83972858544e55.zip
u-boot-imx-b1509e3a4aa55b003e814386dd83972858544e55.tar.gz
u-boot-imx-b1509e3a4aa55b003e814386dd83972858544e55.tar.bz2
armv7: add reset timeout to identify_nand_chip
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>
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r--arch/arm/cpu/armv7/omap3/spl_id_nand.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/arch/arm/cpu/armv7/omap3/spl_id_nand.c b/arch/arm/cpu/armv7/omap3/spl_id_nand.c
index db6de09..26d3aa4 100644
--- a/arch/arm/cpu/armv7/omap3/spl_id_nand.c
+++ b/arch/arm/cpu/armv7/omap3/spl_id_nand.c
@@ -20,29 +20,16 @@
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;
}