Re: GPMI iMX6ull timeout on DMA

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Boris,

On 9/8/19 5:32 pm, Boris Brezillon wrote:
On Fri, 9 Aug 2019 16:55:22 +1000
Greg Ungerer <gerg@xxxxxxxxxx> wrote:
On 9/8/19 4:23 pm, Boris Brezillon wrote:
On Fri, 9 Aug 2019 15:20:52 +1000
Greg Ungerer <gerg@xxxxxxxxxx> wrote:
On 9/8/19 2:36 am, Boris Brezillon wrote:
On Mon, 5 Aug 2019 15:51:05 +1000
Greg Ungerer <gerg@xxxxxxxxxx> wrote:
On 2/8/19 10:51 pm, Boris Brezillon wrote:
On Fri, 2 Aug 2019 22:34:57 +1000
Greg Ungerer <gerg@xxxxxxxxxx> wrote:
On 31/7/19 4:28 pm, Boris Brezillon wrote:
On Wed, 31 Jul 2019 12:05:44 +1000
Greg Ungerer <gerg@xxxxxxxxxx> wrote:
On 30/7/19 6:38 pm, Miquel Raynal wrote:
Greg Ungerer <gerg@xxxxxxxxxx> wrote on Tue, 30 Jul 2019 16:06:55 +1000:
On 30/7/19 10:41 am, Greg Ungerer wrote:
On 30/7/19 10:28 am, Greg Ungerer wrote:
On 29/7/19 10:47 pm, Miquel Raynal wrote:
Greg Ungerer <gerg@xxxxxxxxxx> wrote on Mon, 29 Jul 2019 22:33:56 +1000:
On 29/7/19 6:36 pm, Miquel Raynal wrote:
Greg Ungerer <gerg@xxxxxxxxxx> wrote on Mon, 29 Jul 2019 16:41:51 +1000:
[snip]
Note that this was generated on a normal boot up (not failure).

The values looks good. Can you try with the below diff applied?
--->8---
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 334fe3130285..9771f6a82abe 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -721,12 +721,10 @@ static void gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
             writel(hw->ctrl1n, gpmi_regs + HW_GPMI_CTRL1_SET);
/* Wait 64 clock cycles before using the GPMI after enabling the DLL */
-       dll_wait_time_us = USEC_PER_SEC / hw->clk_rate * 64;
-       if (!dll_wait_time_us)
-               dll_wait_time_us = 1;
+       dll_wait_time_us = DIV_ROUND_UP(USEC_PER_SEC * 64, hw->clk_rate);
/* Wait for the DLL to settle. */
-       udelay(dll_wait_time_us);
+       usleep_range(dll_wait_time_us, dll_wait_time_us * 10);
      }
static int gpmi_setup_data_interface(struct nand_chip *chip, int chipnr,

Eventually it failed, in the same way with with same errors.
Took quite a while, over 600 boot cycles.

Note also that I had to hand merge the changes, since in 5.1.14 that
gpmi_nfc_apply_timings() is in gpmi-lib.c. But it was trivial to do.

Oh well. I guess the next thing to do would be to dump the timing regs
and clk rate that are set by the bootloader (before the driver override
them) or those applied by an older kernel (one that didn't have that
issue).

Is this useful?

Hm, looks like it's configured in mode 0, so no, it's not super useful.
Can you try booting an older kernel (one that didn't have the
->setup_data_interface() hook implemented).

Ok. I went back from 5.1 and the first kernel I could find that
returned no grep hits for "setup_data_interface" was 4.16.

So I built for my target with that and added similar trace to dump
the hardware register settings for that. Debug output looks like
this now for it:

...
drivers/mtd/nand/gpmi-nand/gpmi-nand.c(807): gpmi_get_clks()
     clk_get_rate(r->clock[0])=22000000
drivers/mtd/nand/gpmi-nand/gpmi-lib.c(1054): gpmi_begin()
     HW_GPMI_TIMING0=0x00010203
     HW_GPMI_TIMING1=0x05000000
nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xda
nand: Micron MT29F2G08ABAEAWP
nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
drivers/mtd/nand/gpmi-nand/gpmi-lib.c(966): enable_edo_mode()
     clk_get_rate(r->clock[0])=99000000
gpmi-nand 1806000.gpmi-nand: enable the asynchronous EDO mode 5
drivers/mtd/nand/gpmi-nand/gpmi-lib.c(1054): gpmi_begin()
     HW_GPMI_TIMING0=0x00010101

TIMING0 match the one you have with 5.1 kernels.
     HW_GPMI_TIMING1=0x90000000

And we even have a bigger timeout value in 5.1 (0xe0000000), so we
should be all safe WRT to timings in TIMING{0,1}.

Can you dump CTRL1?

drivers/mtd/nand/gpmi-nand/gpmi-lib.c(1054): gpmi_begin()
    HW_GPMI_TIMING0=0x00010101
    HW_GPMI_TIMING1=0x90000000
    HW_GPMI_CTRL1_SET=0x01c4800c

The read/write delay fields seem to match, but there are a few more
fields set in this version:
- DECOUPLE_CS
- BCH_MODE
- DEV_RESET
- CTRL1_ATA_IRQRDY_POLARITY__ACTIVEHIGH

Looks like those fields are not explicitly set in the gpmi_begin()
patch, but maybe you dumped CTRL1. Would you mind sharing your patch?

Attached.


If I'm right and you indeed dumped CTRL1, it might be worth doing the
same in your 5.1 kernel so we can more easily compare those dumps.
While at it, can you dump CTRL1 before and after applying the changes?

Will do. I am out of my lab for the weekend, but I'll get
those numbers first thing Monday morning.

Regards
Greg

--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -963,6 +963,7 @@ static int enable_edo_mode(struct gpmi_n
 	unsigned long rate;
 	int ret;
 
+printk("%s(%d): enable_edo_mode()\n", __FILE__, __LINE__);
 	feature = kzalloc(ONFI_SUBFEATURE_PARAM_LEN, GFP_KERNEL);
 	if (!feature)
 		return -ENOMEM;
@@ -988,6 +989,7 @@ static int enable_edo_mode(struct gpmi_n
 	/* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
 	rate = (mode == 5) ? 100000000 : 80000000;
 	clk_set_rate(r->clock[0], rate);
+printk("  clk_get_rate(r->clock[0])=%ld\n", clk_get_rate(r->clock[0]));
 
 	/* Let the gpmi_begin() re-compute the timing again. */
 	this->flags &= ~GPMI_TIMING_INIT_OK;
@@ -1049,6 +1051,7 @@ void gpmi_begin(struct gpmi_nand_data *t
 		return;
 	this->flags |= GPMI_TIMING_INIT_OK;
 
+printk("%s(%d): gpmi_begin()\n", __FILE__, __LINE__);
 	if (this->flags & GPMI_ASYNC_EDO_ENABLED)
 		gpmi_compute_edo_timing(this, &hw);
 	else
@@ -1060,10 +1063,12 @@ void gpmi_begin(struct gpmi_nand_data *t
 		BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles);
 
 	writel(reg, gpmi_regs + HW_GPMI_TIMING0);
+printk("  HW_GPMI_TIMING0=0x%08x\n", readl(gpmi_regs + HW_GPMI_TIMING0));
 
 	/* [2] Set HW_GPMI_TIMING1 */
 	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw.device_busy_timeout),
 		gpmi_regs + HW_GPMI_TIMING1);
+printk("  HW_GPMI_TIMING1=0x%08x\n", readl(gpmi_regs + HW_GPMI_TIMING1));
 
 	/* [3] The following code is to set the HW_GPMI_CTRL1. */
 
@@ -1088,6 +1093,7 @@ void gpmi_begin(struct gpmi_nand_data *t
 		| BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor);
 
 	writel(reg, gpmi_regs + HW_GPMI_CTRL1_SET);
+printk("  HW_GPMI_CTRL1_SET=0x%08x\n", readl(gpmi_regs + HW_GPMI_CTRL1_SET));
 
 	/* At last, we enable the DLL. */
 	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_SET);
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -804,6 +804,7 @@ static int gpmi_get_clks(struct gpmi_nan
 	struct clk *clk;
 	int err, i;
 
+printk("%s(%d): gpmi_get_clks()\n", __FILE__, __LINE__);
 	for (i = 0; i < this->devdata->clks_count; i++) {
 		clk = devm_clk_get(this->dev, this->devdata->clks[i]);
 		if (IS_ERR(clk)) {
@@ -822,6 +823,7 @@ static int gpmi_get_clks(struct gpmi_nan
 		 * Synchronous Mode, you should change the clock as you need.
 		 */
 		clk_set_rate(r->clock[0], 22000000);
+printk("  clk_get_rate(r->clock[0])=%ld\n", clk_get_rate(r->clock[0]));
 
 	return 0;
 
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux