diff mbox

Issue in oamp nand driver with 32-bit reads in prefetch mode

Message ID ce9ab5790912310420h20beb04csba060b3f5cfeee92@mail.gmail.com
State New, archived
Headers show

Commit Message

vimal singh Dec. 31, 2009, 12:20 p.m. UTC
On Wed, Dec 30, 2009 at 3:17 AM, Steve Sakoman <sakoman@gmail.com> wrote:
> On Tue, Dec 29, 2009 at 12:38 PM, Steve Sakoman <sakoman@gmail.com> wrote:
>
>> I can confirm that this issue exists on Overo too.  Sadly, switching
>> to 16 bit reads does not fix the issue for me.  I'll start digging to
>> see if I can find what's broken.
>
> I can also confirm that there are days when I am not even capable of
> applying a patch properly :-(
>
> Switching to 16 bit read accesses does indeed fix the ECC issue on Overo too.
>
> Which still leaves us needing to find the root cause of the breakage . . .

There is a bug in nand prefetch read routine, which comes into effect
only if nand device is a 16-bit device (as we have in zoom boards).
This bug is effective only with below combination of conditions:
1. nand deivce, in use, is a 16 bit device
2. nand driver supports 'subpage' read
3. SW ECC is in use

This was not seen old  kernel (ex: .23), because when, in early days,
we tested this (nand prefetch read in LDP boards) there was no
'subpage read' support.
Later when we had subpage read in (.27) kernel, we had hw ecc enabled
always in our internal tree. So, we missed this bug.

Here is a patch to fix this issue:

Comments

Steve Sakoman Jan. 2, 2010, 3:02 p.m. UTC | #1
On Thu, Dec 31, 2009 at 4:20 AM, Vimal Singh <vimal.newwork@gmail.com> wrote:
> On Wed, Dec 30, 2009 at 3:17 AM, Steve Sakoman <sakoman@gmail.com> wrote:
>> On Tue, Dec 29, 2009 at 12:38 PM, Steve Sakoman <sakoman@gmail.com> wrote:
>>
>>> I can confirm that this issue exists on Overo too.  Sadly, switching
>>> to 16 bit reads does not fix the issue for me.  I'll start digging to
>>> see if I can find what's broken.
>>
>> I can also confirm that there are days when I am not even capable of
>> applying a patch properly :-(
>>
>> Switching to 16 bit read accesses does indeed fix the ECC issue on Overo too.
>>
>> Which still leaves us needing to find the root cause of the breakage . . .
>
> There is a bug in nand prefetch read routine, which comes into effect
> only if nand device is a 16-bit device (as we have in zoom boards).
> This bug is effective only with below combination of conditions:
> 1. nand deivce, in use, is a 16 bit device
> 2. nand driver supports 'subpage' read
> 3. SW ECC is in use
>
> This was not seen old  kernel (ex: .23), because when, in early days,
> we tested this (nand prefetch read in LDP boards) there was no
> 'subpage read' support.
> Later when we had subpage read in (.27) kernel, we had hw ecc enabled
> always in our internal tree. So, we missed this bug.
>
> Here is a patch to fix this issue:
>
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 1bb799f..75004fe 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -295,11 +295,14 @@ static void omap_read_buf_pref(struct
>        u32 *p = (u32 *)buf;
>
>        /* take care of subpage reads */
> -       for (; len % 4 != 0; ) {
> -               *buf++ = __raw_readb(info->nand.IO_ADDR_R);
> -               len--;
> +       if (len % 4) {
> +               if (info->nand.options & NAND_BUSWIDTH_16)
> +                       omap_read_buf16(mtd, buf, len % 4);
> +               else
> +                       omap_read_buf8(mtd, buf, len % 4);
> +               p = (u32 *) (buf + len % 4);
> +               len -= len % 4;
>        }
> -       p = (u32 *) buf;
>
>        /* configure and start prefetch transfer */
>        ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);

I tested this on Overo and can confirm that it fixes the issue.

Steve
Artem Bityutskiy Jan. 10, 2010, 8:46 a.m. UTC | #2
On Thu, 2009-12-31 at 17:50 +0530, Vimal Singh wrote:
> There is a bug in nand prefetch read routine, which comes into effect
> only if nand device is a 16-bit device (as we have in zoom boards).
> This bug is effective only with below combination of conditions:
> 1. nand deivce, in use, is a 16 bit device
> 2. nand driver supports 'subpage' read
> 3. SW ECC is in use
> 
> This was not seen old  kernel (ex: .23), because when, in early days,
> we tested this (nand prefetch read in LDP boards) there was no
> 'subpage read' support.
> Later when we had subpage read in (.27) kernel, we had hw ecc enabled
> always in our internal tree. So, we missed this bug.
> 
> Here is a patch to fix this issue:
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 1bb799f..75004fe 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -295,11 +295,14 @@ static void omap_read_buf_pref(struct
>  	u32 *p = (u32 *)buf;
> 
>  	/* take care of subpage reads */
> -	for (; len % 4 != 0; ) {
> -		*buf++ = __raw_readb(info->nand.IO_ADDR_R);
> -		len--;
> +	if (len % 4) {
> +		if (info->nand.options & NAND_BUSWIDTH_16)
> +			omap_read_buf16(mtd, buf, len % 4);
> +		else
> +			omap_read_buf8(mtd, buf, len % 4);
> +		p = (u32 *) (buf + len % 4);
> +		len -= len % 4;
>  	}
> -	p = (u32 *) buf;
> 
>  	/* configure and start prefetch transfer */
>  	ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);

Pushed this patch to my l2-mtd-2.6.git/dunno.
vimal singh Jan. 11, 2010, 6:30 a.m. UTC | #3
On Sun, Jan 10, 2010 at 2:16 PM, Artem Bityutskiy <dedekind1@gmail.com> wrote:
> On Thu, 2009-12-31 at 17:50 +0530, Vimal Singh wrote:
>> There is a bug in nand prefetch read routine, which comes into effect
>> only if nand device is a 16-bit device (as we have in zoom boards).
>> This bug is effective only with below combination of conditions:
>> 1. nand deivce, in use, is a 16 bit device
>> 2. nand driver supports 'subpage' read
>> 3. SW ECC is in use
>>
>> This was not seen old  kernel (ex: .23), because when, in early days,
>> we tested this (nand prefetch read in LDP boards) there was no
>> 'subpage read' support.
>> Later when we had subpage read in (.27) kernel, we had hw ecc enabled
>> always in our internal tree. So, we missed this bug.
>>
>> Here is a patch to fix this issue:
>>
>> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
>> index 1bb799f..75004fe 100644
>> --- a/drivers/mtd/nand/omap2.c
>> +++ b/drivers/mtd/nand/omap2.c
>> @@ -295,11 +295,14 @@ static void omap_read_buf_pref(struct
>>       u32 *p = (u32 *)buf;
>>
>>       /* take care of subpage reads */
>> -     for (; len % 4 != 0; ) {
>> -             *buf++ = __raw_readb(info->nand.IO_ADDR_R);
>> -             len--;
>> +     if (len % 4) {
>> +             if (info->nand.options & NAND_BUSWIDTH_16)
>> +                     omap_read_buf16(mtd, buf, len % 4);
>> +             else
>> +                     omap_read_buf8(mtd, buf, len % 4);
>> +             p = (u32 *) (buf + len % 4);
>> +             len -= len % 4;
>>       }
>> -     p = (u32 *) buf;
>>
>>       /* configure and start prefetch transfer */
>>       ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);
>
> Pushed this patch to my l2-mtd-2.6.git/dunno.
>

I have posted this patch formally in patch series:
[PATCH 0/3][NAND][OMAP]: fixing omap nand driver issues

Corresponding patch is:
[PATCH 3/3][NAND][OMAP] : Fixing issue in oamp nand driver in prefetch mode read

Can you please give a look for this patch series?
Artem Bityutskiy Jan. 16, 2010, 9:35 p.m. UTC | #4
On Mon, 2010-01-11 at 12:00 +0530, Vimal Singh wrote:
> On Sun, Jan 10, 2010 at 2:16 PM, Artem Bityutskiy <dedekind1@gmail.com> wrote:
> > On Thu, 2009-12-31 at 17:50 +0530, Vimal Singh wrote:
> >> There is a bug in nand prefetch read routine, which comes into effect
> >> only if nand device is a 16-bit device (as we have in zoom boards).
> >> This bug is effective only with below combination of conditions:
> >> 1. nand deivce, in use, is a 16 bit device
> >> 2. nand driver supports 'subpage' read
> >> 3. SW ECC is in use
> >>
> >> This was not seen old  kernel (ex: .23), because when, in early days,
> >> we tested this (nand prefetch read in LDP boards) there was no
> >> 'subpage read' support.
> >> Later when we had subpage read in (.27) kernel, we had hw ecc enabled
> >> always in our internal tree. So, we missed this bug.
> >>
> >> Here is a patch to fix this issue:
> >>
> >> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> >> index 1bb799f..75004fe 100644
> >> --- a/drivers/mtd/nand/omap2.c
> >> +++ b/drivers/mtd/nand/omap2.c
> >> @@ -295,11 +295,14 @@ static void omap_read_buf_pref(struct
> >>       u32 *p = (u32 *)buf;
> >>
> >>       /* take care of subpage reads */
> >> -     for (; len % 4 != 0; ) {
> >> -             *buf++ = __raw_readb(info->nand.IO_ADDR_R);
> >> -             len--;
> >> +     if (len % 4) {
> >> +             if (info->nand.options & NAND_BUSWIDTH_16)
> >> +                     omap_read_buf16(mtd, buf, len % 4);
> >> +             else
> >> +                     omap_read_buf8(mtd, buf, len % 4);
> >> +             p = (u32 *) (buf + len % 4);
> >> +             len -= len % 4;
> >>       }
> >> -     p = (u32 *) buf;
> >>
> >>       /* configure and start prefetch transfer */
> >>       ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);
> >
> > Pushed this patch to my l2-mtd-2.6.git/dunno.
> >
> 
> I have posted this patch formally in patch series:
> [PATCH 0/3][NAND][OMAP]: fixing omap nand driver issues
> 
> Corresponding patch is:
> [PATCH 3/3][NAND][OMAP] : Fixing issue in oamp nand driver in prefetch mode read
> 
> Can you please give a look for this patch series?

Just pushed them to my l2-mtd-2.6.git/dunno
diff mbox

Patch

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 1bb799f..75004fe 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -295,11 +295,14 @@  static void omap_read_buf_pref(struct
 	u32 *p = (u32 *)buf;

 	/* take care of subpage reads */
-	for (; len % 4 != 0; ) {
-		*buf++ = __raw_readb(info->nand.IO_ADDR_R);
-		len--;
+	if (len % 4) {
+		if (info->nand.options & NAND_BUSWIDTH_16)
+			omap_read_buf16(mtd, buf, len % 4);
+		else
+			omap_read_buf8(mtd, buf, len % 4);
+		p = (u32 *) (buf + len % 4);
+		len -= len % 4;
 	}
-	p = (u32 *) buf;

 	/* configure and start prefetch transfer */
 	ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);