[U-Boot] [PATCH 1/2] mtd: vf610_nfc: mark page as dirty on block erase

Bill Pringlemeir bpringlemeir at nbsps.com
Tue Mar 31 17:02:43 CEST 2015


On 31 Mar 2015, scottwood at freescale.com wrote:

> On Tue, 2015-03-31 at 00:24 +0200, Stefan Agner wrote:
>> Actually, I just realized that the driver is not caching writes.
>>
>> switch (command) {
>> case NAND_CMD_PAGEPROG:
>> nfc->page = -1;
>> +        vf610_nfc_transfer_size(nfc->regs, nfc->page_sz);
>> vf610_nfc_send_commands(nfc->regs, NAND_CMD_SEQIN,
>> command, PROGRAM_PAGE_CMD_CODE);
>> vf610_nfc_addr_cycle(mtd, column, page);
>> break;
>>
>> The nfc->page = -1 resets the page cache, so the next read triggers a
>> full page read.

Yes, this is correct.  I should have looked at the code again.  It would
be interesting to see what it would do if we did cache.  I know I was
concerned about the upper layers and this caching; Ie, they may
explicitly want to check a physical re-read of a page just after
programming.

>> I will check the performance consequences when disabling cache
>> entirely, and whether it would be possible to implement a OOB only
>> read.

> OK.  In the meantime I'll apply this.

The patches are surely an improvement; maybe not perfect.  I think this
is a good decision.

On 2015-03-31 00:15, Scott Wood wrote:

> Especially since you'd be doing one write rather than four full-page
> "partial" writes.  Surely the bottleneck here is the NAND chip itself,
> not copying data to the buffer?

The AHB bus that the NFC controller is on is relatively slow.  Here are
some numbers from 'AN4947-vybrid-bus-architechure',

Vybrid Cortex A5 to DDR (in CPU clocks 400/500MHz),

   First read     Subsequent
   285            8              all caches on
   345            269            no cache, mmu
   437            371            no cache, no mmu

The NFC is on an AHB bus 32bit, 66MHz (not AXI 64bit, 133-166MHz like
DDR).  The AHB will be about four times slower.  Also the reads and
writes to the physical NAND must take place serially.  Here are the
program page steps.

  1. Issue controller Read full page to NFC buffer.
  2. Copy update partial page from DDR to NFC buffer.
  3. Issue write NAND page.

The alternate,

  1. Issue Read full page to NFC buffer.
  2. Copy full page to DDR.
  3. Update DDR with new data.
  4. Copy updated DDR page to NFC buffer.
  5. Issue write NAND page.

This involves a lot more bus transactions with the NFC AHB as either the
source and/or destination.  To disable the 'cache' (code in vf610_nfc),
we would actually need page program to only be called with full page
data (maybe that is the case?).  This is then much better,

  1. Copy full page to NFC buffer.
  2. Write NAND page.

Probably it would be beneficial to test this in the 'NAND_CMD_SEQIN' and
not issue the 'read'.  Unfortunately, I don't think there is a way to
know if a full page is being written from the driver with the current
NAND API?  Maybe the upper layer has already read the whole page, so the
NAND_CMD_SEQIN is always called with the page as current.  Maybe,

        case NAND_CMD_SEQIN: /* Pre-read for partial writes. */
+               /* Already read? */
+               if (nfc->page == page)   /* If this is always true, the */
+                       return;          /* NFC caching does nothing. */
        case NAND_CMD_READ0:
                column = 0;
-               /* Already read? */
-               if (nfc->page == page)
-                       return;
                nfc->page = page;

The AHB bus speed is a similar order to the NFC (33 MHz NFC clock versus
66MHz AHB clock) with both single beat after setup; you can actually
clock the NAND faster with out hw ECC with some NAND chips supporting
~50MHz.  Initially the NFC clock was under 10MHz; at this frequency NAND
chip timing is quite dominate.  After improving the NFC clock, the
actual transfer from/to the main DDR to the NFC buffers actually becomes
significant.

Well, that is my hypothesis.  I guess some measurements are always
beneficial.  I had measured with/without 'cache' and the results were not
insignificant.  I also put 'printk()' to see what pages were being
read/written and it seemed that both 'read followed by write' and 'write
followed by read' were issued quite frequently to the same page.  I am
also pretty sure that most systems will be structured like this.

     CPU -> L1 -> L2? - High speed bus -> DDR
     CPU              - Low speed bus  -> NFC

So, I don't think that this is Vybrid specific.  The PPC, ColdFire, etc
will probably have similar issues.  DMA has the same limitations as the
CPU, with setup overhead.  Of course, you can parallel the main CPU with
DMA but many systems want the NAND to complete synchronously; especially
u-boot.

Fwiw,
Bill Pringlemeir.


More information about the U-Boot mailing list