diff mbox

[U-Boot,01/13] mxc nand: Merge mtd and spl register definitions

Message ID 903653095.2374980.1344890892208.JavaMail.root@advansee.com
State Accepted
Commit 80c8ab7b25579529809792eef51fe660308fecb6
Delegated to: Scott Wood
Headers show

Commit Message

Benoît Thébaudeau Aug. 13, 2012, 8:48 p.m. UTC
This patches fixes the TODO to use same register definitions in mtd mxc_nand and
nand_spl fsl nfc drivers.

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
Cc: Scott Wood <scottwood@freescale.com>
Cc: Stefano Babic <sbabic@denx.de>
---
 .../drivers/mtd/nand/mxc_nand.c                    |  247 ++++----------------
 .../include/fsl_nfc.h                              |   97 ++++----
 .../nand_spl/nand_boot_fsl_nfc.c                   |   58 ++---
 3 files changed, 128 insertions(+), 274 deletions(-)

Comments

Stefano Babic Aug. 14, 2012, 8:37 a.m. UTC | #1
On 13/08/2012 22:48, Benoît Thébaudeau wrote:
> This patches fixes the TODO to use same register definitions in mtd mxc_nand and
> nand_spl fsl nfc drivers.
> 
> Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
> Cc: Scott Wood <scottwood@freescale.com>
> Cc: Stefano Babic <sbabic@denx.de>
> ---

Hi Benoît,

before going deeper in the review there is a general issue.

nand_spl was used in the past and it was the first implementation to
have a first loader able to copy u-boot into RAM when the SOC boots from
NAND. It is replaced by the general SPL framework. All new
implementations must use the new SPL framework, What you see under
nand_spl is referred to already supported boards.

With general SPL, we do not have two drivers for NAND, and we are able
to boot from other devices, too. So it makes no sense to try to uniform
the driver under nand_spl with the main driver, we want to use only the
main driver.

Best regards,
Stefano Babic
Benoît Thébaudeau Aug. 14, 2012, 10:15 a.m. UTC | #2
Hi Stefano,

> On 13/08/2012 22:48, Benoît Thébaudeau wrote:
> > This patches fixes the TODO to use same register definitions in mtd
> > mxc_nand and
> > nand_spl fsl nfc drivers.
> > 
> > Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
> > Cc: Scott Wood <scottwood@freescale.com>
> > Cc: Stefano Babic <sbabic@denx.de>
> > ---
> 
> Hi Benoît,
> 
> before going deeper in the review there is a general issue.
> 
> nand_spl was used in the past and it was the first implementation to
> have a first loader able to copy u-boot into RAM when the SOC boots
> from
> NAND. It is replaced by the general SPL framework. All new
> implementations must use the new SPL framework, What you see under
> nand_spl is referred to already supported boards.
> 
> With general SPL, we do not have two drivers for NAND, and we are
> able
> to boot from other devices, too. So it makes no sense to try to
> uniform
> the driver under nand_spl with the main driver, we want to use only
> the
> main driver.

Then, I don't know what to do with these patches.

Note that this is not a new implementation, but only an enhancement of the
existing one. But I understand your point.

I don't see any i.MX board using the general SPL for NAND. So we can't say that
it's usable with the current mtd mxc_nand driver in its current state. Moreover,
with the general SPL, I'd be very concerned as to the code size of mxc_nand (the
target size of the whole SPL code is only 2 kiB for current i.MX users of
nand_spl).

IMHO, we could improve and fix the nand_spl code while it's still there and
used. This does not prevent from moving to the general SPL once ready for
mxc_nand. These are two different topics.

Best regards,
Benoît
Stefano Babic Aug. 14, 2012, 10:46 a.m. UTC | #3
On 14/08/2012 12:15, Benoît Thébaudeau wrote:
> Then, I don't know what to do with these patches.

I see two main points in your patches. You cleanup mxc-nand code and add
support for i.MX5. This is one topic, and it can go on.

> 
> Note that this is not a new implementation, but only an enhancement of the
> existing one. But I understand your point.

;-)

> 
> I don't see any i.MX board using the general SPL for NAND.

At least the MX28, and using nand_spl with MX28 was rejected for the
same reason when it was pushed. Then it was switched to SPL.

But surely it should be better to have more examples - I am working to
get a MX35 booting from external SD, and using the SPL.

> So we can't say that
> it's usable with the current mtd mxc_nand driver in its current state. Moreover,
> with the general SPL, I'd be very concerned as to the code size of mxc_nand (the
> target size of the whole SPL code is only 2 kiB for current i.MX users of
> nand_spl).

Mainly because the restriction came from the original implementation,
that was for PowerPC 4xx with only a small buffer (NFC buffer) to copy
data from NAND.

We have currently only two boards supporting this mechanismus, using
MX25 (karo tx25) and MX31. Both MX25 and MX31 have an internal RAM
(128KB) that is is suitable for installing the SPL. Note that TI SOCs
have less RAM available, and they support SPL.

IMHO the fact that only two IMX boards are using this mechanism
(nand_spl) is also due the fact that is not very flexible. And moving to
SPL we are not fixed to boot exclusively from NAND,

> 
> IMHO, we could improve and fix the nand_spl code while it's still there and
> used.

However, as you say, if the code is still available, this makes people
think that is the correct way to do and we will have two distinct
implementation (the old one and the new one), both to be supported.

Not to forget that the SPL is thought to work with different SOCs, even
if currently it is mainly used by TI, and with different media storage.
All features taht we discussed previously in the ML if we had to add
them to nand_spl, before the new implementation was pushed.

> This does not prevent from moving to the general SPL once ready for
> mxc_nand. These are two different topics.

The fact is it will be nice if also the two supported boards will move
to SPL. Of couse, we cannot break these boards, but a move will be more
difficult if we increase the number of boards using nand_spl.

Best regards,
Stefano Babic
Benoît Thébaudeau Aug. 14, 2012, 11:13 a.m. UTC | #4
Hi Stefano,

> On 14/08/2012 12:15, Benoît Thébaudeau wrote:
> > Then, I don't know what to do with these patches.
> 
> I see two main points in your patches. You cleanup mxc-nand code and
> add
> support for i.MX5. This is one topic, and it can go on.

OK, but then do you want to keep the register definitions inside mxc_nand?

> > Note that this is not a new implementation, but only an enhancement
> > of the
> > existing one. But I understand your point.
> 
> ;-)
> 
> > 
> > I don't see any i.MX board using the general SPL for NAND.
> 
> At least the MX28, and using nand_spl with MX28 was rejected for the
> same reason when it was pushed. Then it was switched to SPL.

OK. But I meant MXC. MXS does not use the same NAND driver.

> But surely it should be better to have more examples - I am working
> to
> get a MX35 booting from external SD, and using the SPL.

Great! Having mxc_nand examples would be great too.

> > So we can't say that
> > it's usable with the current mtd mxc_nand driver in its current
> > state. Moreover,
> > with the general SPL, I'd be very concerned as to the code size of
> > mxc_nand (the
> > target size of the whole SPL code is only 2 kiB for current i.MX
> > users of
> > nand_spl).
> 
> Mainly because the restriction came from the original implementation,
> that was for PowerPC 4xx with only a small buffer (NFC buffer) to
> copy
> data from NAND.
> 
> We have currently only two boards supporting this mechanismus, using
> MX25 (karo tx25) and MX31. Both MX25 and MX31 have an internal RAM
> (128KB) that is is suitable for installing the SPL. Note that TI SOCs
> have less RAM available, and they support SPL.

The available RAM size is not the issue. i.MX boards using nand_spl can use
internal or external RAM. The issue comes from the i.MX ROM bootloader that only
uses the NFC buffer. On i.MX31, that means max 2 kiB for SPL, and 4 kiB on
i.MX25/35/51. What can be done on the latter if using internal boot (with DCD
header) is to use at most one NF block (more is not possible because the i.MX
bootloader goes back to serial mode if any bad block is found, and one of the
1st or 2nd block has to be good).

> IMHO the fact that only two IMX boards are using this mechanism
> (nand_spl) is also due the fact that is not very flexible. And moving
> to
> SPL we are not fixed to boot exclusively from NAND,

Sure.

> > IMHO, we could improve and fix the nand_spl code while it's still
> > there and
> > used.
> 
> However, as you say, if the code is still available, this makes
> people
> think that is the correct way to do and we will have two distinct
> implementation (the old one and the new one), both to be supported.

Right.

> Not to forget that the SPL is thought to work with different SOCs,
> even
> if currently it is mainly used by TI, and with different media
> storage.
> All features taht we discussed previously in the ML if we had to add
> them to nand_spl, before the new implementation was pushed.

OK.

> > This does not prevent from moving to the general SPL once ready for
> > mxc_nand. These are two different topics.
> 
> The fact is it will be nice if also the two supported boards will
> move
> to SPL.

Sure, but I don't have time to do that.

> Of couse, we cannot break these boards,

They're already broken with the current nand_spl. See my 07/13.

> but a move will be
> more
> difficult if we increase the number of boards using nand_spl.

Sure, but my series does not add new boards.

Just tell me what to do. I don't have time to port nand_spl boards to general
SPL. The only thing I may find time for is to refactor the series in an
acceptable way for you.

Best regards,
Benoît
Stefano Babic Aug. 14, 2012, 2:02 p.m. UTC | #5
On 14/08/2012 13:13, Benoît Thébaudeau wrote:
> Hi Stefano,
> 

Hi Benoît,

>> We have currently only two boards supporting this mechanismus, using
>> MX25 (karo tx25) and MX31. Both MX25 and MX31 have an internal RAM
>> (128KB) that is is suitable for installing the SPL. Note that TI SOCs
>> have less RAM available, and they support SPL.
> 
> The available RAM size is not the issue. i.MX boards using nand_spl can use
> internal or external RAM. The issue comes from the i.MX ROM bootloader that only
> uses the NFC buffer. On i.MX31, that means max 2 kiB for SPL, and 4 kiB on
> i.MX25/35/51. What can be done on the latter if using internal boot (with DCD
> header) is to use at most one NF block (more is not possible because the i.MX
> bootloader goes back to serial mode if any bad block is found, and one of the
> 1st or 2nd block has to be good).

We are both a little off-topic here, but because we are reading probably
the same part of the manuals I would like to clear this point.

What you are saying is not exactly what I read from the manual - I
checked it now in mx35, I will take a look also on the other ones.

In 7.4.1.6 NAND Flash Boot Operation, I read:

"1. On device power-on, the boot ROM copies the first 4 Kbytes of boot
code from the NAND Flash to the NFC buffer."

So this correspond to your statement - and DCD tables go into NFC
buffer. DCD table must be smaller as 4KB, but this is always the case.

"2. ROM code checks the first 4 Kbytes of boot data copied in step 1 above.
a) If no ECC error, then DCD is verified.
– If DCD verification is successful, then the rest of the boot code
image is copied to destination RAM (internal RAM or SDRAM) and secure
boot is performed."

I understand this part as the mx35 goes on to copy the whole image,
depending on the size set into the header, to the address specified in
the table itself. There is no limitation. Exactly in the same way it
works on i.MX5 (I know, this does not mean nothing, but..)

I think the limitation of 2KB or 4KB is not correct and is valid only
for the DCD data. Do you agree ?

> 
>> Of couse, we cannot break these boards,
> 
> They're already broken with the current nand_spl. See my 07/13.
> 

Mmmhh...a bug is a bug, and should be fixed, I agree with you on this point.

>> but a move will be
>> more
>> difficult if we increase the number of boards using nand_spl.
> 
> Sure, but my series does not add new boards.

Right. Maybe I was expecting a new patch series from you adding a new
board, because I thought you have a "use case" for i.MX5,  (that means,
support for NAND in i.MX5). In other words, a new board based on
nand_spl will be not accepted.

But again, fixing current issues is another thing. I will go on on to
review the rest of patches (I admit I skip the rest of nand_spl related
patches).

> Just tell me what to do. I don't have time to port nand_spl boards to general
> SPL. The only thing I may find time for is to refactor the series in an
> acceptable way for you.

You convinced me that you are fixing current issues in already supported
boards - then it is fine with me to go on with this patchset.

Best regards,
Stefano
Benoît Thébaudeau Aug. 14, 2012, 2:29 p.m. UTC | #6
Hi Stefano,

> On 14/08/2012 13:13, Benoît Thébaudeau wrote:
> > Hi Stefano,
> > 
> 
> Hi Benoît,
> 
> >> We have currently only two boards supporting this mechanismus,
> >> using
> >> MX25 (karo tx25) and MX31. Both MX25 and MX31 have an internal RAM
> >> (128KB) that is is suitable for installing the SPL. Note that TI
> >> SOCs
> >> have less RAM available, and they support SPL.
> > 
> > The available RAM size is not the issue. i.MX boards using nand_spl
> > can use
> > internal or external RAM. The issue comes from the i.MX ROM
> > bootloader that only
> > uses the NFC buffer. On i.MX31, that means max 2 kiB for SPL, and 4
> > kiB on
> > i.MX25/35/51. What can be done on the latter if using internal boot
> > (with DCD
> > header) is to use at most one NF block (more is not possible
> > because the i.MX
> > bootloader goes back to serial mode if any bad block is found, and
> > one of the
> > 1st or 2nd block has to be good).
> 
> We are both a little off-topic here, but because we are reading
> probably
> the same part of the manuals I would like to clear this point.

OK.

> What you are saying is not exactly what I read from the manual - I
> checked it now in mx35, I will take a look also on the other ones.
> 
> In 7.4.1.6 NAND Flash Boot Operation, I read:
> 
> "1. On device power-on, the boot ROM copies the first 4 Kbytes of
> boot
> code from the NAND Flash to the NFC buffer."
> 
> So this correspond to your statement - and DCD tables go into NFC
> buffer. DCD table must be smaller as 4KB, but this is always the
> case.

Indeed.

> "2. ROM code checks the first 4 Kbytes of boot data copied in step 1
> above.
> a) If no ECC error, then DCD is verified.
> – If DCD verification is successful, then the rest of the boot code
> image is copied to destination RAM (internal RAM or SDRAM) and secure
> boot is performed."
> 
> I understand this part as the mx35 goes on to copy the whole image,
> depending on the size set into the header, to the address specified
> in
> the table itself. There is no limitation. Exactly in the same way it
> works on i.MX5 (I know, this does not mean nothing, but..)
> 
> I think the limitation of 2KB or 4KB is not correct and is valid only
> for the DCD data. Do you agree ?

No, it's way more complicated than that.

First, there various boot modes available depending on the device for NAND:
i.MX31: external only
i.MX25 and i.MX35: internal or external
i.MX51: internal only

External means that the NFC buffer is filled from NAND and executed without any
DCD or flash header. The limit is 2 kiB on i.MX31. On i.MX25 and i.MX35, it is
not clear from the RMs if only a single NF page is read, or if the NFC buffer is
fully filled (4 kiB). This is the use case for mx31pdk and tx25.

Internal means that 4 kiB are read from NF. If this fails from the 1st block, it
is retried with the 2nd block. If it fails again, boot is aborted. If it
succeeds, DCD and Flash headers are checked and executed. The behavior of the
ROM bootloader while loading the image indicated by the headers is not clear
from the RMs in case of bad blocks, so I asked FSL support which told me that
as soon as a bad block is found, the boot is aborted. This means that an SPL is
required for NAND boot to be reliable, even with internal boot. This also means
that this SPL can not be larger than a single block.

> >> Of couse, we cannot break these boards,
> > 
> > They're already broken with the current nand_spl. See my 07/13.
> > 
> 
> Mmmhh...a bug is a bug, and should be fixed, I agree with you on this
> point.

OK.

> >> but a move will be
> >> more
> >> difficult if we increase the number of boards using nand_spl.
> > 
> > Sure, but my series does not add new boards.
> 
> Right. Maybe I was expecting a new patch series from you adding a new
> board, because I thought you have a "use case" for i.MX5,  (that
> means,
> support for NAND in i.MX5). In other words, a new board based on
> nand_spl will be not accepted.

I indeed have such boards supported locally, but they are not yet ready for
upstream, and I did not intend to post patches for them before the other i.MX
nand_spl boards have moved to generic SPL.

> But again, fixing current issues is another thing. I will go on on to
> review the rest of patches (I admit I skip the rest of nand_spl
> related
> patches).

OK.

> > Just tell me what to do. I don't have time to port nand_spl boards
> > to general
> > SPL. The only thing I may find time for is to refactor the series
> > in an
> > acceptable way for you.
> 
> You convinced me that you are fixing current issues in already
> supported
> boards - then it is fine with me to go on with this patchset.

Great.

Best regards,
Benoît
Scott Wood Aug. 14, 2012, 4:01 p.m. UTC | #7
On 08/14/2012 03:37 AM, Stefano Babic wrote:
> On 13/08/2012 22:48, Benoît Thébaudeau wrote:
>> This patches fixes the TODO to use same register definitions in mtd mxc_nand and
>> nand_spl fsl nfc drivers.
>>
>> Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
>> Cc: Scott Wood <scottwood@freescale.com>
>> Cc: Stefano Babic <sbabic@denx.de>
>> ---
> 
> Hi Benoît,
> 
> before going deeper in the review there is a general issue.
> 
> nand_spl was used in the past and it was the first implementation to
> have a first loader able to copy u-boot into RAM when the SOC boots from
> NAND. It is replaced by the general SPL framework. All new
> implementations must use the new SPL framework, What you see under
> nand_spl is referred to already supported boards.
> 
> With general SPL, we do not have two drivers for NAND, and we are able
> to boot from other devices, too. So it makes no sense to try to uniform
> the driver under nand_spl with the main driver, we want to use only the
> main driver.

It is not true that new-SPL will always have one uniform NAND driver,
nor is it true that nand_spl always has separate NAND drivers (it always
has a separate NAND subsystem, but the basic nand_spl/nand_boot.c does
use the standard device-specific driver).

It depends on space constraints of the target, and how big the standard
device-specific driver is.  With Wolfgang's mandate that no new boards
be added to nand_spl, we're going to have to support boards with a small
buffer for NAND booting in new SPL (even if it turns out this isn't one
of them).  It's not just 4xx; Freescale PPC chips are like this too,
including some that have not yet had NAND boot support added to mainline
U-Boot and thus can't use nand_spl.

-Scott
Benoît Thébaudeau Aug. 15, 2012, 6:11 p.m. UTC | #8
Hi Stefano,

On 08/14/2012 04:29:04 PM, Benoît Thébaudeau wrote:
> Hi Stefano,
> 
> > On 14/08/2012 13:13, Benoît Thébaudeau wrote:
> > > Hi Stefano,
> > > 
> > 
> > Hi Benoît,
> > 
> > >> We have currently only two boards supporting this mechanismus,
> > >> using
> > >> MX25 (karo tx25) and MX31. Both MX25 and MX31 have an internal
> > >> RAM
> > >> (128KB) that is is suitable for installing the SPL. Note that TI
> > >> SOCs
> > >> have less RAM available, and they support SPL.
> > > 
> > > The available RAM size is not the issue. i.MX boards using
> > > nand_spl
> > > can use
> > > internal or external RAM. The issue comes from the i.MX ROM
> > > bootloader that only
> > > uses the NFC buffer. On i.MX31, that means max 2 kiB for SPL, and
> > > 4
> > > kiB on
> > > i.MX25/35/51. What can be done on the latter if using internal
> > > boot
> > > (with DCD
> > > header) is to use at most one NF block (more is not possible
> > > because the i.MX
> > > bootloader goes back to serial mode if any bad block is found,
> > > and
> > > one of the
> > > 1st or 2nd block has to be good).
> > 
> > We are both a little off-topic here, but because we are reading
> > probably
> > the same part of the manuals I would like to clear this point.
> 
> OK.
> 
> > What you are saying is not exactly what I read from the manual - I
> > checked it now in mx35, I will take a look also on the other ones.
> > 
> > In 7.4.1.6 NAND Flash Boot Operation, I read:
> > 
> > "1. On device power-on, the boot ROM copies the first 4 Kbytes of
> > boot
> > code from the NAND Flash to the NFC buffer."
> > 
> > So this correspond to your statement - and DCD tables go into NFC
> > buffer. DCD table must be smaller as 4KB, but this is always the
> > case.
> 
> Indeed.
> 
> > "2. ROM code checks the first 4 Kbytes of boot data copied in step
> > 1
> > above.
> > a) If no ECC error, then DCD is verified.
> > – If DCD verification is successful, then the rest of the boot code
> > image is copied to destination RAM (internal RAM or SDRAM) and
> > secure
> > boot is performed."
> > 
> > I understand this part as the mx35 goes on to copy the whole image,
> > depending on the size set into the header, to the address specified
> > in
> > the table itself. There is no limitation. Exactly in the same way
> > it
> > works on i.MX5 (I know, this does not mean nothing, but..)
> > 
> > I think the limitation of 2KB or 4KB is not correct and is valid
> > only
> > for the DCD data. Do you agree ?
> 
> No, it's way more complicated than that.
> 
> First, there various boot modes available depending on the device for
> NAND:
> i.MX31: external only

Note that internal NAND Flash boot is also mentioned in the RM, but without
further details. FSL should be contacted to know more. But the RM refers to
secure boot and HAB, so it's probably something close to the internal boot modes
of i.MX25 and i.MX35. Anyway, it does not seem to be used by U-Boot i.MX31
boards.

> i.MX25 and i.MX35: internal or external
> i.MX51: internal only
> 
> External means that the NFC buffer is filled from NAND and executed
> without any
> DCD or flash header. The limit is 2 kiB on i.MX31. On i.MX25 and
> i.MX35, it is
> not clear from the RMs if only a single NF page is read, or if the
> NFC buffer is
> fully filled (4 kiB). This is the use case for mx31pdk and tx25.

The details about external NF boot are in the NFC chapter of the RMs. For
i.MX31, it's perfectly clear: The whole 2-kiB NFC buffer is filled whether the
NF pages are 512-B or 2-kiB. For i.MX25 and i.MX35, it's more difficult to find
the details, but I interpret the RMs as meaning that the whole 4-kiB NFC buffer
is filled whatever the NF page sizes. In both cases, the code is run from the
NFC buffer, so that the SPL size cannot exceed 2 kiB for mx31pdk, and 4 kiB for
tx25.

> Internal means that 4 kiB are read from NF. If this fails from the
> 1st block, it
> is retried with the 2nd block. If it fails again, boot is aborted. If
> it
> succeeds, DCD and Flash headers are checked and executed. The
> behavior of the
> ROM bootloader while loading the image indicated by the headers is
> not clear
> from the RMs in case of bad blocks, so I asked FSL support which told
> me that
> as soon as a bad block is found, the boot is aborted. This means that
> an SPL is
> required for NAND boot to be reliable, even with internal boot. This
> also means
> that this SPL can not be larger than a single block.

Best regards,
Benoît
Stefano Babic Aug. 16, 2012, 7:27 a.m. UTC | #9
On 15/08/2012 20:11, Benoît Thébaudeau wrote:
> Hi Stefano,

Hi Benoît,


>>> I understand this part as the mx35 goes on to copy the whole image,
>>> depending on the size set into the header, to the address specified
>>> in
>>> the table itself. There is no limitation. Exactly in the same way
>>> it
>>> works on i.MX5 (I know, this does not mean nothing, but..)
>>>
>>> I think the limitation of 2KB or 4KB is not correct and is valid
>>> only
>>> for the DCD data. Do you agree ?
>>
>> No, it's way more complicated than that.
>>
>> First, there various boot modes available depending on the device for
>> NAND:
>> i.MX31: external only
> 
> Note that internal NAND Flash boot is also mentioned in the RM, but without
> further details.

I know - thanks for sharing your information.

> FSL should be contacted to know more. But the RM refers to
> secure boot and HAB, so it's probably something close to the internal boot modes
> of i.MX25 and i.MX35.
> Anyway, it does not seem to be used by U-Boot i.MX31
> boards.

I have the same feeling.

> The details about external NF boot are in the NFC chapter of the RMs. For
> i.MX31, it's perfectly clear: The whole 2-kiB NFC buffer is filled whether the
> NF pages are 512-B or 2-kiB. For i.MX25 and i.MX35, it's more difficult to find
> the details, but I interpret the RMs as meaning that the whole 4-kiB NFC buffer
> is filled whatever the NF page sizes. In both cases, the code is run from the
> NFC buffer, so that the SPL size cannot exceed 2 kiB for mx31pdk, and 4 kiB for
> tx25.

I have the same interpretation - for this reason it was interesting for
me to understand the behavior with internal boot, where I can set the
size of the whole image in the imx header.

However, if the boot stops after a bad block is found instead of
skipping it and reading the next one, it seems to me that this feature
cannot be really used. It will be also interesting to know if the
behavior is the same also for the newer i.MX, I mean MX5 and MX6.

> 
>> Internal means that 4 kiB are read from NF. If this fails from the
>> 1st block, it
>> is retried with the 2nd block. If it fails again, boot is aborted. If
>> it
>> succeeds, DCD and Flash headers are checked and executed.
> The
>> behavior of the
>> ROM bootloader while loading the image indicated by the headers is
>> not clear
>> from the RMs in case of bad blocks, so I asked FSL support which told
>> me that
>> as soon as a bad block is found, the boot is aborted. This means that
>> an SPL is
>> required for NAND boot to be reliable, even with internal boot. This
>> also means
>> that this SPL can not be larger than a single block.

The other way that a project can take is to use SLC NAND (or in any
case, NAND where is guaranted that the first sector cannot be bad). A
hard limitation, anyway.

Best regards,
Stefano
diff mbox

Patch

diff --git u-boot-4d3c95f.orig/drivers/mtd/nand/mxc_nand.c u-boot-4d3c95f/drivers/mtd/nand/mxc_nand.c
index 936186f..9a9260c 100644
--- u-boot-4d3c95f.orig/drivers/mtd/nand/mxc_nand.c
+++ u-boot-4d3c95f/drivers/mtd/nand/mxc_nand.c
@@ -25,168 +25,23 @@ 
 #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35)
 #include <asm/arch/imx-regs.h>
 #endif
+#include <fsl_nfc.h>
 
 #define DRIVER_NAME "mxc_nand"
 
-/*
- * TODO: Use same register defs here as nand_spl mxc nand driver.
- */
-/*
- * Register map and bit definitions for the Freescale NAND Flash Controller
- * present in various i.MX devices.
- *
- * MX31 and MX27 have version 1 which has
- * 	4 512 byte main buffers and
- * 	4 16 byte spare buffers
- * 	to support up to 2K byte pagesize nand.
- * 	Reading or writing a 2K page requires 4 FDI/FDO cycles.
- *
- * MX25 has version 1.1 which has
- * 	8 512 byte main buffers and
- * 	8 64 byte spare buffers
- * 	to support up to 4K byte pagesize nand.
- * 	Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle.
- *      Also some of registers are moved and/or changed meaning as seen below.
- */
-#if defined(CONFIG_MX31) || defined(CONFIG_MX27)
-#define MXC_NFC_V1
-#elif defined(CONFIG_MX25) || defined(CONFIG_MX35)
-#define MXC_NFC_V1_1
-#else
-#warning "MXC NFC version not defined"
-#endif
-
-#if defined(MXC_NFC_V1)
-#define NAND_MXC_NR_BUFS		4
-#define NAND_MXC_SPARE_BUF_SIZE		16
-#define NAND_MXC_REG_OFFSET		0xe00
-#define is_mxc_nfc_11() 		0
-#elif defined(MXC_NFC_V1_1)
-#define NAND_MXC_NR_BUFS		8
-#define NAND_MXC_SPARE_BUF_SIZE		64
-#define NAND_MXC_REG_OFFSET		0x1e00
-#define is_mxc_nfc_11() 		1
-#else
-#error "define CONFIG_NAND_MXC_VXXX to use mtd mxc nand driver"
-#endif
-struct nfc_regs {
-	uint8_t main_area[NAND_MXC_NR_BUFS][0x200];
-	uint8_t spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE];
-	/*
-	 * reserved size is offset of nfc registers
-	 * minus total main and spare sizes
-	 */
-	uint8_t reserved1[NAND_MXC_REG_OFFSET
-		- NAND_MXC_NR_BUFS * (512 + NAND_MXC_SPARE_BUF_SIZE)];
-#if defined(MXC_NFC_V1)
-	uint16_t nfc_buf_size;
-	uint16_t reserved2;
-	uint16_t nfc_buf_addr;
-	uint16_t nfc_flash_addr;
-	uint16_t nfc_flash_cmd;
-	uint16_t nfc_config;
-	uint16_t nfc_ecc_status_result;
-	uint16_t nfc_rsltmain_area;
-	uint16_t nfc_rsltspare_area;
-	uint16_t nfc_wrprot;
-	uint16_t nfc_unlockstart_blkaddr;
-	uint16_t nfc_unlockend_blkaddr;
-	uint16_t nfc_nf_wrprst;
-	uint16_t nfc_config1;
-	uint16_t nfc_config2;
-#elif defined(MXC_NFC_V1_1)
-	uint16_t reserved2[2];
-	uint16_t nfc_buf_addr;
-	uint16_t nfc_flash_addr;
-	uint16_t nfc_flash_cmd;
-	uint16_t nfc_config;
-	uint16_t nfc_ecc_status_result;
-	uint16_t nfc_ecc_status_result2;
-	uint16_t nfc_spare_area_size;
-	uint16_t nfc_wrprot;
-	uint16_t reserved3[2];
-	uint16_t nfc_nf_wrprst;
-	uint16_t nfc_config1;
-	uint16_t nfc_config2;
-	uint16_t reserved4;
-	uint16_t nfc_unlockstart_blkaddr;
-	uint16_t nfc_unlockend_blkaddr;
-	uint16_t nfc_unlockstart_blkaddr1;
-	uint16_t nfc_unlockend_blkaddr1;
-	uint16_t nfc_unlockstart_blkaddr2;
-	uint16_t nfc_unlockend_blkaddr2;
-	uint16_t nfc_unlockstart_blkaddr3;
-	uint16_t nfc_unlockend_blkaddr3;
-#endif
-};
-
-/*
- * Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register
- * for Command operation
- */
-#define NFC_CMD            0x1
-
-/*
- * Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register
- * for Address operation
- */
-#define NFC_ADDR           0x2
-
-/*
- * Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register
- * for Input operation
- */
-#define NFC_INPUT          0x4
-
-/*
- * Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register
- * for Data Output operation
- */
-#define NFC_OUTPUT         0x8
-
-/*
- * Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register
- * for Read ID operation
- */
-#define NFC_ID             0x10
-
-/*
- * Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register
- * for Read Status operation
- */
-#define NFC_STATUS         0x20
-
-/*
- * Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read
- * Status operation
- */
-#define NFC_INT            0x8000
-
-#ifdef MXC_NFC_V1_1
-#define NFC_4_8N_ECC	(1 << 0)
-#else
-#define NFC_4_8N_ECC	0
-#endif
-#define NFC_SP_EN           (1 << 2)
-#define NFC_ECC_EN          (1 << 3)
-#define NFC_BIG             (1 << 5)
-#define NFC_RST             (1 << 6)
-#define NFC_CE              (1 << 7)
-#define NFC_ONE_CYCLE       (1 << 8)
-
 typedef enum {false, true} bool;
 
 struct mxc_nand_host {
-	struct mtd_info		mtd;
-	struct nand_chip	*nand;
-
-	struct nfc_regs __iomem	*regs;
-	int			spare_only;
-	int			status_request;
-	int			pagesize_2k;
-	int			clk_act;
-	uint16_t		col_addr;
-	unsigned int		page_addr;
+	struct mtd_info			mtd;
+	struct nand_chip		*nand;
+
+	struct fsl_nfc_regs __iomem	*regs;
+	int				spare_only;
+	int				status_request;
+	int				pagesize_2k;
+	int				clk_act;
+	uint16_t			col_addr;
+	unsigned int			page_addr;
 };
 
 static struct mxc_nand_host mxc_host;
@@ -304,10 +159,10 @@  static void wait_op_done(struct mxc_nand_host *host, int max_retries,
 	uint32_t tmp;
 
 	while (max_retries-- > 0) {
-		if (readw(&host->regs->nfc_config2) & NFC_INT) {
-			tmp = readw(&host->regs->nfc_config2);
+		if (readw(&host->regs->config2) & NFC_INT) {
+			tmp = readw(&host->regs->config2);
 			tmp  &= ~NFC_INT;
-			writew(tmp, &host->regs->nfc_config2);
+			writew(tmp, &host->regs->config2);
 			break;
 		}
 		udelay(1);
@@ -326,8 +181,8 @@  static void send_cmd(struct mxc_nand_host *host, uint16_t cmd)
 {
 	MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x)\n", cmd);
 
-	writew(cmd, &host->regs->nfc_flash_cmd);
-	writew(NFC_CMD, &host->regs->nfc_config2);
+	writew(cmd, &host->regs->flash_cmd);
+	writew(NFC_CMD, &host->regs->config2);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, cmd);
@@ -342,8 +197,8 @@  static void send_addr(struct mxc_nand_host *host, uint16_t addr)
 {
 	MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x)\n", addr);
 
-	writew(addr, &host->regs->nfc_flash_addr);
-	writew(NFC_ADDR, &host->regs->nfc_config2);
+	writew(addr, &host->regs->flash_addr);
+	writew(NFC_ADDR, &host->regs->config2);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, addr);
@@ -375,19 +230,19 @@  static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id,
 		}
 	}
 
-	writew(buf_id, &host->regs->nfc_buf_addr);
+	writew(buf_id, &host->regs->buf_addr);
 
 	/* Configure spare or page+spare access */
 	if (!host->pagesize_2k) {
-		uint16_t config1 = readw(&host->regs->nfc_config1);
+		uint16_t config1 = readw(&host->regs->config1);
 		if (spare_only)
 			config1 |= NFC_SP_EN;
 		else
 			config1 &= ~(NFC_SP_EN);
-		writew(config1, &host->regs->nfc_config1);
+		writew(config1, &host->regs->config1);
 	}
 
-	writew(NFC_INPUT, &host->regs->nfc_config2);
+	writew(NFC_INPUT, &host->regs->config2);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, spare_only);
@@ -402,19 +257,19 @@  static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id,
 {
 	MTDDEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only);
 
-	writew(buf_id, &host->regs->nfc_buf_addr);
+	writew(buf_id, &host->regs->buf_addr);
 
 	/* Configure spare or page+spare access */
 	if (!host->pagesize_2k) {
-		uint32_t config1 = readw(&host->regs->nfc_config1);
+		uint32_t config1 = readw(&host->regs->config1);
 		if (spare_only)
 			config1 |= NFC_SP_EN;
 		else
 			config1 &= ~NFC_SP_EN;
-		writew(config1, &host->regs->nfc_config1);
+		writew(config1, &host->regs->config1);
 	}
 
-	writew(NFC_OUTPUT, &host->regs->nfc_config2);
+	writew(NFC_OUTPUT, &host->regs->config2);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, spare_only);
@@ -442,14 +297,14 @@  static void send_read_id(struct mxc_nand_host *host)
 	uint16_t tmp;
 
 	/* NANDFC buffer 0 is used for device ID output */
-	writew(0x0, &host->regs->nfc_buf_addr);
+	writew(0x0, &host->regs->buf_addr);
 
 	/* Read ID into main buffer */
-	tmp = readw(&host->regs->nfc_config1);
+	tmp = readw(&host->regs->config1);
 	tmp &= ~NFC_SP_EN;
-	writew(tmp, &host->regs->nfc_config1);
+	writew(tmp, &host->regs->config1);
 
-	writew(NFC_ID, &host->regs->nfc_config2);
+	writew(NFC_ID, &host->regs->config2);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, 0);
@@ -469,14 +324,14 @@  static uint16_t get_dev_status(struct mxc_nand_host *host)
 	/* store the main area1 first word, later do recovery */
 	store = readl(main_buf);
 	/* NANDFC buffer 1 is used for device status */
-	writew(1, &host->regs->nfc_buf_addr);
+	writew(1, &host->regs->buf_addr);
 
 	/* Read status into main buffer */
-	tmp = readw(&host->regs->nfc_config1);
+	tmp = readw(&host->regs->config1);
 	tmp &= ~NFC_SP_EN;
-	writew(tmp, &host->regs->nfc_config1);
+	writew(tmp, &host->regs->config1);
 
-	writew(NFC_STATUS, &host->regs->nfc_config2);
+	writew(NFC_STATUS, &host->regs->config2);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, 0);
@@ -515,13 +370,13 @@  static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on)
 {
 	struct nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
-	uint16_t tmp = readw(&host->regs->nfc_config1);
+	uint16_t tmp = readw(&host->regs->config1);
 
 	if (on)
 		tmp |= NFC_ECC_EN;
 	else
 		tmp &= ~NFC_ECC_EN;
-	writew(tmp, &host->regs->nfc_config1);
+	writew(tmp, &host->regs->config1);
 }
 
 static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd,
@@ -799,7 +654,7 @@  static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
 {
 	struct nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
-	uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result);
+	uint16_t ecc_status = readw(&host->regs->ecc_status_result);
 	int subpages = mtd->writesize / nand_chip->subpagesize;
 	int pg2blk_shift = nand_chip->phys_erase_shift -
 			   nand_chip->page_shift;
@@ -845,7 +700,7 @@  static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
 	 * additional correction.  2-Bit errors cannot be corrected by
 	 * HW ECC, so we need to return failure
 	 */
-	uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result);
+	uint16_t ecc_status = readw(&host->regs->ecc_status_result);
 
 	if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
 		MTDDEBUG(MTD_DEBUG_LEVEL0,
@@ -1289,14 +1144,14 @@  static void mxc_setup_config1(void)
 {
 	uint16_t tmp;
 
-	tmp = readw(&host->regs->nfc_config1);
+	tmp = readw(&host->regs->config1);
 	tmp |= NFC_ONE_CYCLE;
 	tmp |= NFC_4_8N_ECC;
-	writew(tmp, &host->regs->nfc_config1);
+	writew(tmp, &host->regs->config1);
 	if (host->pagesize_2k)
-		writew(64/2, &host->regs->nfc_spare_area_size);
+		writew(64/2, &host->regs->spare_area_size);
 	else
-		writew(16/2, &host->regs->nfc_spare_area_size);
+		writew(16/2, &host->regs->spare_area_size);
 }
 #else
 #define mxc_setup_config1()
@@ -1359,7 +1214,7 @@  int board_nand_init(struct nand_chip *this)
 	this->read_buf = mxc_nand_read_buf;
 	this->verify_buf = mxc_nand_verify_buf;
 
-	host->regs = (struct nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE;
+	host->regs = (struct fsl_nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE;
 	host->clk_act = 1;
 
 #ifdef CONFIG_MXC_NAND_HWECC
@@ -1383,15 +1238,15 @@  int board_nand_init(struct nand_chip *this)
 	host->pagesize_2k = 0;
 
 	this->ecc.size = 512;
-	tmp = readw(&host->regs->nfc_config1);
+	tmp = readw(&host->regs->config1);
 	tmp |= NFC_ECC_EN;
-	writew(tmp, &host->regs->nfc_config1);
+	writew(tmp, &host->regs->config1);
 #else
 	this->ecc.layout = &nand_soft_eccoob;
 	this->ecc.mode = NAND_ECC_SOFT;
-	tmp = readw(&host->regs->nfc_config1);
+	tmp = readw(&host->regs->config1);
 	tmp &= ~NFC_ECC_EN;
-	writew(tmp, &host->regs->nfc_config1);
+	writew(tmp, &host->regs->config1);
 #endif
 	/* Reset NAND */
 	this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
@@ -1400,10 +1255,10 @@  int board_nand_init(struct nand_chip *this)
 	 * preset operation
 	 * Unlock the internal RAM Buffer
 	 */
-	writew(0x2, &host->regs->nfc_config);
+	writew(0x2, &host->regs->config);
 
 	/* Blocks to be unlocked */
-	writew(0x0, &host->regs->nfc_unlockstart_blkaddr);
+	writew(0x0, &host->regs->unlockstart_blkaddr);
 	/* Originally (Freescale LTIB 2.6.21) 0x4000 was written to the
 	 * unlockend_blkaddr, but the magic 0x4000 does not always work
 	 * when writing more than some 32 megabytes (on 2k page nands)
@@ -1415,10 +1270,10 @@  int board_nand_init(struct nand_chip *this)
 	 * This might be NAND chip specific and the i.MX31 datasheet is
 	 * extremely vague about the semantics of this register.
 	 */
-	writew(0xFFFF, &host->regs->nfc_unlockend_blkaddr);
+	writew(0xFFFF, &host->regs->unlockend_blkaddr);
 
 	/* Unlock Block Command for given address range */
-	writew(0x4, &host->regs->nfc_wrprot);
+	writew(0x4, &host->regs->wrprot);
 
 	/* NAND bus width determines access functions used by upper layer */
 	if (is_16bit_nand())
diff --git u-boot-4d3c95f.orig/include/fsl_nfc.h u-boot-4d3c95f/include/fsl_nfc.h
index 279aaa5..6691e41 100644
--- u-boot-4d3c95f.orig/include/fsl_nfc.h
+++ u-boot-4d3c95f/include/fsl_nfc.h
@@ -24,28 +24,25 @@ 
 #define __FSL_NFC_H
 
 /*
- * TODO: Use same register defs for nand_spl mxc nand driver
- * and mtd mxc nand driver.
+ * Register map and bit definitions for the Freescale NAND Flash Controller
+ * present in various i.MX devices.
  *
- * Register map and bit definitions for the Freescale NAND Flash
- * Controller present in various i.MX devices.
+ * MX31 and MX27 have version 1, which has:
+ *	4 512-byte main buffers and
+ *	4 16-byte spare buffers
+ *	to support up to 2K byte pagesize nand.
+ *	Reading or writing a 2K page requires 4 FDI/FDO cycles.
  *
- * MX31 and MX27 have version 1 which has
- * 	4 512 byte main buffers and
- * 	4 16 byte spare buffers
- * 	to support up to 2K byte pagesize nand.
- * 	Reading or writing a 2K page requires 4 FDI/FDO cycles.
- *
- * MX25 has version 1.1 which has
- * 	8 512 byte main buffers and
- * 	8 64 byte spare buffers
- * 	to support up to 4K byte pagesize nand.
- * 	Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle.
- *      Also some of registers are moved and/or changed meaning as seen below.
+ * MX25 and MX35 have version 1.1, which has:
+ *	8 512-byte main buffers and
+ *	8 64-byte spare buffers
+ *	to support up to 4K byte pagesize nand.
+ *	Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle.
+ *	Also some of registers are moved and/or changed meaning as seen below.
  */
-#if defined(CONFIG_MX31) || defined(CONFIG_MX27)
+#if defined(CONFIG_MX27) || defined(CONFIG_MX31)
 #define MXC_NFC_V1
-#elif defined(CONFIG_MX25)
+#elif defined(CONFIG_MX25) || defined(CONFIG_MX35)
 #define MXC_NFC_V1_1
 #else
 #warning "MXC NFC version not defined"
@@ -55,18 +52,20 @@ 
 #define NAND_MXC_NR_BUFS		4
 #define NAND_MXC_SPARE_BUF_SIZE		16
 #define NAND_MXC_REG_OFFSET		0xe00
-#define NAND_MXC_2K_MULTI_CYCLE		1
+#define NAND_MXC_2K_MULTI_CYCLE
+#define is_mxc_nfc_11()			0
 #elif defined(MXC_NFC_V1_1)
 #define NAND_MXC_NR_BUFS		8
 #define NAND_MXC_SPARE_BUF_SIZE		64
 #define NAND_MXC_REG_OFFSET		0x1e00
+#define is_mxc_nfc_11()			1
 #else
-#error "define CONFIG_NAND_MXC_VXXX to use the mxc spl_nand driver"
+#error "define CONFIG_NAND_MXC_VXXX to use the mxc nand driver"
 #endif
 
 struct fsl_nfc_regs {
-	u32 main_area[NAND_MXC_NR_BUFS][512/4];
-	u32 spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE/4];
+	u8 main_area[NAND_MXC_NR_BUFS][0x200];
+	u8 spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE];
 	/*
 	 * reserved size is offset of nfc registers
 	 * minus total main and spare sizes
@@ -74,44 +73,44 @@  struct fsl_nfc_regs {
 	u8 reserved1[NAND_MXC_REG_OFFSET
 		- NAND_MXC_NR_BUFS * (512 + NAND_MXC_SPARE_BUF_SIZE)];
 #if defined(MXC_NFC_V1)
-	u16 bufsiz;
+	u16 buf_size;
 	u16 reserved2;
-	u16 buffer_address;
-	u16 flash_add;
+	u16 buf_addr;
+	u16 flash_addr;
 	u16 flash_cmd;
-	u16 configuration;
+	u16 config;
 	u16 ecc_status_result;
-	u16 ecc_rslt_main_area;
-	u16 ecc_rslt_spare_area;
-	u16 nf_wr_prot;
-	u16 unlock_start_blk_add;
-	u16 unlock_end_blk_add;
-	u16 nand_flash_wr_pr_st;
-	u16 nand_flash_config1;
-	u16 nand_flash_config2;
+	u16 rsltmain_area;
+	u16 rsltspare_area;
+	u16 wrprot;
+	u16 unlockstart_blkaddr;
+	u16 unlockend_blkaddr;
+	u16 nf_wrprst;
+	u16 config1;
+	u16 config2;
 #elif defined(MXC_NFC_V1_1)
 	u16 reserved2[2];
-	u16 buffer_address;
-	u16 flash_add;
+	u16 buf_addr;
+	u16 flash_addr;
 	u16 flash_cmd;
-	u16 configuration;
+	u16 config;
 	u16 ecc_status_result;
 	u16 ecc_status_result2;
 	u16 spare_area_size;
-	u16 nf_wr_prot;
+	u16 wrprot;
 	u16 reserved3[2];
-	u16 nand_flash_wr_pr_st;
-	u16 nand_flash_config1;
-	u16 nand_flash_config2;
+	u16 nf_wrprst;
+	u16 config1;
+	u16 config2;
 	u16 reserved4;
-	u16 unlock_start_blk_add0;
-	u16 unlock_end_blk_add0;
-	u16 unlock_start_blk_add1;
-	u16 unlock_end_blk_add1;
-	u16 unlock_start_blk_add2;
-	u16 unlock_end_blk_add2;
-	u16 unlock_start_blk_add3;
-	u16 unlock_end_blk_add3;
+	u16 unlockstart_blkaddr;
+	u16 unlockend_blkaddr;
+	u16 unlockstart_blkaddr1;
+	u16 unlockend_blkaddr1;
+	u16 unlockstart_blkaddr2;
+	u16 unlockend_blkaddr2;
+	u16 unlockstart_blkaddr3;
+	u16 unlockend_blkaddr3;
 #endif
 };
 
diff --git u-boot-4d3c95f.orig/nand_spl/nand_boot_fsl_nfc.c u-boot-4d3c95f/nand_spl/nand_boot_fsl_nfc.c
index d6b0d9b..f437deb 100644
--- u-boot-4d3c95f.orig/nand_spl/nand_boot_fsl_nfc.c
+++ u-boot-4d3c95f/nand_spl/nand_boot_fsl_nfc.c
@@ -36,13 +36,13 @@  static void nfc_wait_ready(void)
 {
 	uint32_t tmp;
 
-	while (!(readw(&nfc->nand_flash_config2) & NFC_INT))
+	while (!(readw(&nfc->config2) & NFC_INT))
 		;
 
 	/* Reset interrupt flag */
-	tmp = readw(&nfc->nand_flash_config2);
+	tmp = readw(&nfc->config2);
 	tmp &= ~NFC_INT;
-	writew(tmp, &nfc->nand_flash_config2);
+	writew(tmp, &nfc->config2);
 }
 
 void nfc_nand_init(void)
@@ -54,10 +54,10 @@  void nfc_nand_init(void)
 	writew(CONFIG_SYS_NAND_SPARE_SIZE / 2, &nfc->spare_area_size);
 
 	/* unlocking RAM Buff */
-	writew(0x2, &nfc->configuration);
+	writew(0x2, &nfc->config);
 
 	/* hardware ECC checking and correct */
-	config1 = readw(&nfc->nand_flash_config1) | NFC_ECC_EN | 0x800;
+	config1 = readw(&nfc->config1) | NFC_ECC_EN | 0x800;
 	/*
 	 * if spare size is larger that 16 bytes per 512 byte hunk
 	 * then use 8 symbol correction instead of 4
@@ -66,20 +66,20 @@  void nfc_nand_init(void)
 		config1 &= ~NFC_4_8N_ECC;
 	else
 		config1 |= NFC_4_8N_ECC;
-	writew(config1, &nfc->nand_flash_config1);
+	writew(config1, &nfc->config1);
 #elif defined(MXC_NFC_V1)
 	/* unlocking RAM Buff */
-	writew(0x2, &nfc->configuration);
+	writew(0x2, &nfc->config);
 
 	/* hardware ECC checking and correct */
-	writew(NFC_ECC_EN, &nfc->nand_flash_config1);
+	writew(NFC_ECC_EN, &nfc->config1);
 #endif
 }
 
 static void nfc_nand_command(unsigned short command)
 {
 	writew(command, &nfc->flash_cmd);
-	writew(NFC_CMD, &nfc->nand_flash_config2);
+	writew(NFC_CMD, &nfc->config2);
 	nfc_wait_ready();
 }
 
@@ -87,14 +87,14 @@  static void nfc_nand_page_address(unsigned int page_address)
 {
 	unsigned int page_count;
 
-	writew(0x00, &nfc->flash_add);
-	writew(NFC_ADDR, &nfc->nand_flash_config2);
+	writew(0x00, &nfc->flash_addr);
+	writew(NFC_ADDR, &nfc->config2);
 	nfc_wait_ready();
 
 	/* code only for large page flash */
 	if (CONFIG_SYS_NAND_PAGE_SIZE > 512) {
-		writew(0x00, &nfc->flash_add);
-		writew(NFC_ADDR, &nfc->nand_flash_config2);
+		writew(0x00, &nfc->flash_addr);
+		writew(NFC_ADDR, &nfc->config2);
 		nfc_wait_ready();
 	}
 
@@ -103,30 +103,30 @@  static void nfc_nand_page_address(unsigned int page_address)
 	if (page_address <= page_count) {
 		page_count--; /* transform 0x01000000 to 0x00ffffff */
 		do {
-			writew(page_address & 0xff, &nfc->flash_add);
-			writew(NFC_ADDR, &nfc->nand_flash_config2);
+			writew(page_address & 0xff, &nfc->flash_addr);
+			writew(NFC_ADDR, &nfc->config2);
 			nfc_wait_ready();
 			page_address = page_address >> 8;
 			page_count = page_count >> 8;
 		} while (page_count);
 	}
 
-	writew(0x00, &nfc->flash_add);
-	writew(NFC_ADDR, &nfc->nand_flash_config2);
+	writew(0x00, &nfc->flash_addr);
+	writew(NFC_ADDR, &nfc->config2);
 	nfc_wait_ready();
 }
 
 static void nfc_nand_data_output(void)
 {
-	int config1 = readw(&nfc->nand_flash_config1);
+	int config1 = readw(&nfc->config1);
 #ifdef NAND_MXC_2K_MULTI_CYCLE
 	int i;
 #endif
 
 	config1 |= NFC_ECC_EN | NFC_INT_MSK;
-	writew(config1, &nfc->nand_flash_config1);
-	writew(0, &nfc->buffer_address);
-	writew(NFC_OUTPUT, &nfc->nand_flash_config2);
+	writew(config1, &nfc->config1);
+	writew(0, &nfc->buf_addr);
+	writew(NFC_OUTPUT, &nfc->config2);
 	nfc_wait_ready();
 #ifdef NAND_MXC_2K_MULTI_CYCLE
 	/*
@@ -134,11 +134,11 @@  static void nfc_nand_data_output(void)
 	 * for pages larger than 512 bytes.
 	 */
 	for (i = 1; i < (CONFIG_SYS_NAND_PAGE_SIZE / 512); i++) {
-		config1 = readw(&nfc->nand_flash_config1);
+		config1 = readw(&nfc->config1);
 		config1 |= NFC_ECC_EN | NFC_INT_MSK;
-		writew(config1, &nfc->nand_flash_config1);
-		writew(i, &nfc->buffer_address);
-		writew(NFC_OUTPUT, &nfc->nand_flash_config2);
+		writew(config1, &nfc->config1);
+		writew(i, &nfc->buf_addr);
+		writew(NFC_OUTPUT, &nfc->config2);
 		nfc_wait_ready();
 	}
 #endif
@@ -155,7 +155,7 @@  static int nfc_read_page(unsigned int page_address, unsigned char *buf)
 	u32 *src;
 	u32 *dst;
 
-	writew(0, &nfc->buffer_address); /* read in first 0 buffer */
+	writew(0, &nfc->buf_addr); /* read in first 0 buffer */
 	nfc_nand_command(NAND_CMD_READ0);
 	nfc_nand_page_address(page_address);
 
@@ -167,7 +167,7 @@  static int nfc_read_page(unsigned int page_address, unsigned char *buf)
 	if (nfc_nand_check_ecc())
 		return -1;
 
-	src = &nfc->main_area[0][0];
+	src = (u32 *)&nfc->main_area[0][0];
 	dst = (u32 *)buf;
 
 	/* main copy loop from NAND-buffer to SDRAM memory */
@@ -188,7 +188,7 @@  static int is_badblock(int pagenumber)
 
 	/* Check the first two pages for bad block markers */
 	for (page = pagenumber; page < pagenumber + 2; page++) {
-		writew(0, &nfc->buffer_address); /* read in first 0 buffer */
+		writew(0, &nfc->buf_addr); /* read in first 0 buffer */
 		nfc_nand_command(NAND_CMD_READ0);
 		nfc_nand_page_address(page);
 
@@ -197,7 +197,7 @@  static int is_badblock(int pagenumber)
 
 		nfc_nand_data_output(); /* fill the main buffer 0 */
 
-		src = &nfc->spare_area[0][0];
+		src = (u32 *)&nfc->spare_area[0][0];
 
 		/*
 		 * IMPORTANT NOTE: The nand flash controller uses a non-