From: "Joakim Tjernlund" <Joakim.Tjernlund@transmode.se>
To: "'Anders Grafström'" <grfstrm@users.sourceforge.net>,
"'Jared Hulbert'" <jaredeh@gmail.com>,
"'Alexey Korolev'" <akorolev@infradead.org>,
"'Linux-MTD Mailing List'" <linux-mtd@lists.infradead.org>
Subject: RE: cfi_cmdset_0001.c: Excessive erase suspends
Date: Sat, 19 Apr 2008 19:01:20 +0200 [thread overview]
Message-ID: <017701c8a23e$fdd70b60$f9852220$@Tjernlund@transmode.se> (raw)
In-Reply-To: <4809F7EC.9010808@users.sourceforge.net>
> -----Original Message-----
> From: Anders Grafström [mailto:grfstrm@users.sourceforge.net]
> Sent: den 19 april 2008 15:47
> To: Joakim Tjernlund; 'Jared Hulbert'; 'Alexey Korolev'; 'Linux-MTD Mailing List'
> Subject: Re: cfi_cmdset_0001.c: Excessive erase suspends
>
> Joakim Tjernlund wrote:
> > Don't you need to check that the chip is suspended before you do any
> > new operation?
>
> You're right.
>
> Here's the improved version;
>
> static void erase_suspend(unsigned int loops)
> {
> volatile unsigned int *flash = (unsigned int *)0x41040000;
> unsigned int i;
> unsigned int suspends = 0;
> unsigned int words = 2;
> unsigned int timeout;
>
> /* Make sure there's something to erase */
> for (i = 0; i < 0x10000; i++) {
> if (flash[i] == 0xffffffff) {
> flash[i] = 0x00400040;
> flash[i] = 0;
> while ((flash[i] & 0x00800080) != 0x00800080);
> }
> }
>
> /* Clear status */
> flash[0] = 0x00500050;
>
> /* Erase */
> flash[0] = 0x00200020;
> flash[0] = 0x00d000d0;
>
> while (1) {
> /* Suspend */
> flash[0] = 0x00b000b0;
> flash[0] = 0x00700070;
> timeout = 100000;
> while ((flash[0] & 0x00800080) != 0x00800080 && --timeout);
> if (!timeout)
> printf("suspend timeout\n");
> suspends++;
>
> /* Short delay */
> for (i = 0; i < 1000; i++);
>
> /* Resume */
> flash[0] = 0x00d000d0;
> flash[0] = 0x00700070;
>
> /* Erase done ? */
> if ((flash[0] & 0x00800080) == 0x00800080) {
> printf("\nstatus %08x\n", flash[0]);
> break;
> }
>
> /* Short delay */
> for (i = 0; i < loops; i++);
> }
>
> /* Read array */
> flash[0] = 0x00ff00ff;
>
> /* Show the first 2 failed words */
> for (i = 0; i < 0x10000; i++) {
> if (flash[i] != 0xffffffff) {
> printf("%08x\n", flash[i]);
> if (--words == 0)
> break;
> }
> }
>
> printf("%d suspends\n", suspends);
> }
>
> void test_flash_erase_suspend(void)
> {
> unsigned int loops;
>
> for (loops = 6000; loops > 2000; loops -= 500) {
> printf("\n%d loops", loops);
> erase_suspend(loops);
> }
> }
>
>
> It produced this output at one occasion:
>
> 6000 loops
> status 00800080
> ffff0000
> ffff0000
> 4783 suspends
>
> 5500 loops
> status 00800080
> 5508 suspends
>
> 5000 loops
> status 008000a0
> 6394 suspends
>
> 4500 loops
> status 00a000a0
> fffffeff
> fffffffe
> 5169 suspends
>
> 4000 loops
> status 00a000a0
> fffffeff
> fffffeff
> 5378 suspends
>
> 3500 loops
> status 00a000a0
> aaaaaaaa
> aaaaaaaa
> 5715 suspends
>
> 3000 loops
> status 00a000a0
> 55555555
> 55555555
> 6142 suspends
>
> 2500 loops
> status 00a000a0
> 00000000
> 00000000
> 6929 suspends
>
> It locks up when I drop it down to 2000 or less iterations in the loop between resume and suspend.
> I think I need to do more testing with properly timed delays.
>
> Is there anything else that I have missed?
Perhaps, you should make "i" a volatile. That said I know that Intel
had erase suspend bugs in their early strata flash, thats why there is
a define in cmdset_0001 that disables them.
Maybe you got buggy chips?
oh, just remembered, strata chips needs to have a stable address bus before
CS is pulled. We had add a small delay on CS in the memory controller, otherwise
they would fail, especially when cold.
>
> /Anders
>
next prev parent reply other threads:[~2008-04-19 17:01 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-17 20:38 cfi_cmdset_0001.c: Excessive erase suspends Anders Grafström
2008-04-18 15:02 ` Alexey Korolev
2008-04-18 16:35 ` Jamie Lokier
2008-04-18 17:54 ` Jared Hulbert
2008-04-18 22:11 ` Anders Grafström
2008-04-19 2:47 ` Jared Hulbert
2008-04-19 9:18 ` Joakim Tjernlund
2008-04-19 13:47 ` Anders Grafström
2008-04-19 17:01 ` Joakim Tjernlund [this message]
2008-04-24 14:34 ` Alexey Korolev
2008-04-24 21:02 ` Anders Grafström
2008-04-25 9:59 ` Alexey Korolev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='017701c8a23e$fdd70b60$f9852220$@Tjernlund@transmode.se' \
--to=joakim.tjernlund@transmode.se \
--cc=akorolev@infradead.org \
--cc=grfstrm@users.sourceforge.net \
--cc=jaredeh@gmail.com \
--cc=linux-mtd@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.