View Issue Details

IDProjectCategoryView StatusLast Update
0004881UBootU-Bootpublic2021-10-05 10:50
Reporterderksen Assigned To 
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionfixed 
Target Versionfsimx8mm-Y2021.04Fixed in Versionfsimx8mm-Y2021.04 
Summary0004881: mxs_nand: Reduce malloc usage in SPL
Descriptionmxs_nand: Reduce malloc usage in SPL

The mxs_nand driver allocates a buffer for doing its DMA transfers. This
buffer is already used very early for identifying the chip and reading
the ONFI data. This means when the buffer is allocated, the final size
of a NAND page is not yet known. So the buffer is allocated with a "worst
case" in mind, i.e. 16 KB page size and nearly 2 KB OOB size.
For the same reason, struct nand_buffers defines buffers of the same size.
In the end we have around 36 KB of buffers.
So the first idea is to use pointers ecccalc, ecccode and databuf in
struct nand_buffers instead of fixed size arrays. Then these arrays can
be allocated dynamically with the appropriate sizes when the page size is
The second idea is that the mxs_nand driver can also use the databuf of
struct nand_buffers instead of its own buffer for doing the DMA transfers.
So we only need a small temporary buffer at the beginning to read flash
ID and ONFI data. Here 256 bytes should be sufficient, this is the size
of one ONFI parameter page.
So in the end we only have one buffer with page+OOB size, e.g. 2048+64
bytes on a 2KB-page NAND flash instead of 36 KB.
In function nand_spl_load_image() a page sized buffer is allocated and
freed again before returning. This is normally no big deal, but in the
early SPL stage where only a very simple version of malloc is available
(the so-called MALLOC-F-Pool), buffers are only allocated but not
deallocated again. Which ends up in using for example 2 KB more of the
malloc space with each call. At this time, the malloc pool is located
in OCRAM and is rather small, so wasting 2 KB with each call is a bad
thing after all.
So the third idea is to use again the databuf of struct nand_buffers
here so that we do not need to allocate a new buffer each time. The
function only loads full pages, so it is no problem that the main read
function mxs_nand_ecc_read() uses the same buffer. In fact it means
that the final memcpy() there is actually a no-op. This even speeds up
the whole read process.
As we do not want to break existing implementations, we add a config
CONFIG_SPL_RAWNAND_BUFFERS_MALLOC and do this simplified allocation
only in SPL and when this config is set.
Forum Link


There are no notes attached to this issue.