]> git.sur5r.net Git - u-boot/commitdiff
tegra: nand: fix read_byte required for proper onfi detection
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>
Wed, 5 Aug 2015 22:47:05 +0000 (00:47 +0200)
committerTom Warren <twarren@nvidia.com>
Thu, 13 Aug 2015 20:06:02 +0000 (13:06 -0700)
Fix PIO read_byte() implementation not only used for the legacy READ ID
but also the PARAM command required for proper ONFI detection.

This fix is inspired by Lucas Stach's Linux Tegra NAND driver of late
(not mainline yet but getting there soon I hope).

I vaguely remember that those commands are special on 16-bit bus NAND
(e.g. always return 8-bit data regardless) and later Linux MTD fixed/
changed the way this is handled which in turn broke once U-Boot pulled
that in. Basically instead of doing PIO read regular DMA block read is
now used which this patch actually fixes.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Acked-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Tom Warren <twarren@nvidia.com>
drivers/mtd/nand/tegra_nand.c

index b660f3b20662dfbb427dd2770765d2acd1f6a089..ca196257058cecb91472d8d8bae28d36356f870c 100644 (file)
@@ -86,16 +86,6 @@ struct fdt_nand {
 
 struct nand_drv {
        struct nand_ctlr *reg;
-
-       /*
-       * When running in PIO mode to get READ ID bytes from register
-       * RESP_0, we need this variable as an index to know which byte in
-       * register RESP_0 should be read.
-       * Because common code in nand_base.c invokes read_byte function two
-       * times for NAND_CMD_READID.
-       * And our controller returns 4 bytes at once in register RESP_0.
-       */
-       int pio_byte_index;
        struct fdt_nand config;
 };
 
@@ -181,25 +171,16 @@ static int nand_waitfor_cmd_completion(struct nand_ctlr *reg)
 static uint8_t read_byte(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
-       u32 dword_read;
        struct nand_drv *info;
 
        info = (struct nand_drv *)chip->priv;
 
-       /* In PIO mode, only 4 bytes can be transferred with single CMD_GO. */
-       if (info->pio_byte_index > 3) {
-               info->pio_byte_index = 0;
-               writel(CMD_GO | CMD_PIO
-                       | CMD_RX | CMD_CE0,
-                       &info->reg->command);
-               if (!nand_waitfor_cmd_completion(info->reg))
-                       printf("Command timeout\n");
-       }
+       writel(CMD_GO | CMD_PIO | CMD_RX | CMD_CE0 | CMD_A_VALID,
+              &info->reg->command);
+       if (!nand_waitfor_cmd_completion(info->reg))
+               printf("Command timeout\n");
 
-       dword_read = readl(&info->reg->resp);
-       dword_read = dword_read >> (8 * info->pio_byte_index);
-       info->pio_byte_index++;
-       return (uint8_t)dword_read;
+       return (uint8_t)readl(&info->reg->resp);
 }
 
 /**
@@ -330,12 +311,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        case NAND_CMD_READID:
                writel(NAND_CMD_READID, &info->reg->cmd_reg1);
                writel(column & 0xFF, &info->reg->addr_reg1);
-               writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_PIO
-                       | CMD_RX |
-                       ((4 - 1) << CMD_TRANS_SIZE_SHIFT)
-                       | CMD_CE0,
-                       &info->reg->command);
-               info->pio_byte_index = 0;
+               writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0,
+                      &info->reg->command);
                break;
        case NAND_CMD_PARAM:
                writel(NAND_CMD_PARAM, &info->reg->cmd_reg1);
@@ -376,7 +353,6 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
                        | ((1 - 0) << CMD_TRANS_SIZE_SHIFT)
                        | CMD_CE0,
                        &info->reg->command);
-               info->pio_byte_index = 0;
                break;
        case NAND_CMD_RESET:
                writel(NAND_CMD_RESET, &info->reg->cmd_reg1);