MLK-16329-2: mtd: fsl-flexspi: fix the start address alignment issue
authorHan Xu <han.xu@nxp.com>
Wed, 30 Aug 2017 20:12:53 +0000 (15:12 -0500)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:38:22 +0000 (15:38 -0500)
FLEXSPI AHBCR register has one bit READADDROPT, which defined if start
address must be aligned when doing wordaddress access. This bit must be
set (no alignment limitation), otherwise controller may always try
to access from even address and got wrong data when AHB read data under
Octal DDR mode. Mounting UBIFS failed in this case since it read from
odd address.

[  250.367893] fsl_fspi_read: from 620ad1, len: 11
[  250.374700] UBIFS error (ubi0:0 pid 2871): check_lpt_type: invalid
type (4) in LPT node type 2
[  250.383326] CPU: 0 PID: 2871 Comm: mount Not tainted
4.9.11-03067-gd6ce90a-dirty #251
[  250.391156] Hardware name: Freescale i.MX8QM ARM2 (DT)
[  250.396291] Call trace:
[  250.398739] [<ffff0000080882bc>] dump_backtrace+0x0/0x1e0
[  250.404139] [<ffff0000080884b0>] show_stack+0x14/0x1c
[  250.409198] [<ffff0000083b3798>] dump_stack+0x8c/0xac
[  250.414251] [<ffff00000833c434>] check_lpt_type+0x80/0x88
[  250.419654] [<ffff00000833eb74>] ubifs_lpt_init+0x448/0x8a4
[  250.425222] [<ffff000008325a38>] ubifs_mount+0xde0/0x198c
[  250.430620] [<ffff0000081db2e0>] mount_fs+0x3c/0x15c
[  250.435589] [<ffff0000081f7070>] vfs_kern_mount+0x4c/0x11c
[  250.441077] [<ffff0000081fa26c>] do_mount+0x1b8/0xb5c
[  250.446125] [<ffff0000081faf3c>] SyS_mount+0x78/0xd8
[  250.451085] [<ffff000008082f4c>] __sys_trace_return+0x0/0x4
[  250.456787] ---lpt_init_rd
[  250.459530] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" stops

Signed-off-by: Han Xu <han.xu@nxp.com>
drivers/mtd/spi-nor/fsl-flexspi.c

index 7828b6b..d4f122b 100644 (file)
@@ -97,6 +97,8 @@
 #define FLEXSPI_MCR2_ABR_CMD_MASK      (1 << FLEXSPI_MCR2_ABR_CMD_SHIFT)
 
 #define FLEXSPI_AHBCR                  0x0c
+#define FLEXSPI_AHBCR_RDADDROPT_SHIFT  6
+#define FLEXSPI_AHBCR_RDADDROPT_MASK   (1 << FLEXSPI_AHBCR_RDADDROPT_SHIFT)
 #define FLEXSPI_AHBCR_PREF_EN_SHIFT    5
 #define FLEXSPI_AHBCR_PREF_EN_MASK     (1 << FLEXSPI_AHBCR_PREF_EN_SHIFT)
 #define FLEXSPI_AHBCR_BUFF_EN_SHIFT    4
@@ -697,7 +699,6 @@ fsl_flexspi_runcmd(struct fsl_flexspi *flex, u8 cmd, unsigned int addr, int len)
                    (reg & FLEXSPI_STS0_SEQ_IDLE_MASK))
                        break;
                udelay(1);
-               dev_err(flex->dev, "The controller is busy, 0x%x\n", reg);
        } while (1);
 
        /* trigger the LUT now */
@@ -878,7 +879,9 @@ static void fsl_flexspi_init_ahb_read(struct fsl_flexspi *flex)
                FLEXSPI_AHBRXBUF0CR7_PREF_MASK),
               base + FLEXSPI_AHBRX_BUF7CR0);
 
-       writel(FLEXSPI_AHBCR_PREF_EN_MASK, base + FLEXSPI_AHBCR);
+       /* prefetch and no start address alignment limitation */
+       writel(FLEXSPI_AHBCR_PREF_EN_MASK | FLEXSPI_AHBCR_RDADDROPT_MASK,
+              base + FLEXSPI_AHBCR);
 
        /* Set the default lut sequence for AHB Read. */
        seqid = fsl_flexspi_get_seqid(flex, nor->read_opcode);