Skip to contentSkip to conversation

Sunxi NAND support for U-Boot

RFC In review Roy Spliet 7 participants 49 messages Jun 5, 2015 – Jun 15, 2015

Subsystems (5)
lore
Share & tools
lore

Roy Spliet

author
#0 lore raw

Following up on earlier SPL patches, here a series based on Yassin Jaffer's work to bring NAND support to U-boot. RFC because I know that the sunxi nand configuration options are dependent on a work-in-progress by Daniel - trying to deliver a single SPL for both MMC and NAND boot.
Given I have spent the past few weeks learning how Boris' original driver works, I have probably grown a bit blind for potentially existing issues. Please provide plenty of feedback so I can bring this in good shape.

Patches tested on an Olimex Lime with 4GB Hynix nand. Has a partition as defined in sunxi-common.h with two UBIFS partitions (boot, rootfs) set up in Linux. To me it feels self-explanatory how to set this up, but I've spent the last few weeks full-time on this, implying my view of the world and how it revolves around MTD is rather distorted. Feel free to ask directed questions if you desire assistance in setting up and/or testing.
Thanks!

Roy

Signature · 6 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
author
#1 lore raw

RFC 1/11 mtd/nand: define struct nand_timings

From: yassin <[email protected]>

---
 include/linux/mtd/nand.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
include/linux/mtd/nand.h +49 -0
index bc927ec..b026110 100644
@@ -1008,6 +1008,55 @@ static inline int jedec_feature(struct nand_chip *chip)
 		: 0;
 }
 
+/**
+ * struct nand_sdr_timings - SDR NAND chip timings
+ *
+ * This struct defines the timing requirements of a SDR NAND chip.
+ * These informations can be found in every NAND datasheets and the timings
+ * meaning are described in the ONFI specifications:
+ * www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing
+ * Parameters)
+ *
+ * All these timings are expressed in picoseconds.
+ */
+
+struct nand_sdr_timings {
+	u32 tALH_min;
+	u32 tADL_min;
+	u32 tALS_min;
+	u32 tAR_min;
+	u32 tCEA_max;
+	u32 tCEH_min;
+	u32 tCH_min;
+	u32 tCHZ_max;
+	u32 tCLH_min;
+	u32 tCLR_min;
+	u32 tCLS_min;
+	u32 tCOH_min;
+	u32 tCS_min;
+	u32 tDH_min;
+	u32 tDS_min;
+	u32 tFEAT_max;
+	u32 tIR_min;
+	u32 tITC_max;
+	u32 tRC_min;
+	u32 tREA_max;
+	u32 tREH_min;
+	u32 tRHOH_min;
+	u32 tRHW_min;
+	u32 tRHZ_max;
+	u32 tRLOH_min;
+	u32 tRP_min;
+	u32 tRR_min;
+	u64 tRST_max;
+	u32 tWB_max;
+	u32 tWC_min;
+	u32 tWH_min;
+	u32 tWHR_min;
+	u32 tWP_min;
+	u32 tWW_min;
+};
+
 #ifdef __UBOOT__
 /* Standard NAND functions from nand_base.c */
 void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
author
#2 lore raw

RFC 2/11 mtd/nand: add ONFI timing mode to nand_timings converter

In reply to Roy Spliet

From: yassin <[email protected]>

---
 drivers/mtd/nand/Makefile       |   2 +-
 drivers/mtd/nand/nand_timings.c | 252 ++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h        |   3 +
 3 files changed, 256 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/nand/nand_timings.c
drivers/mtd/nand/Makefile +1 -1
index a0cf4d5..f194493 100644
@@ -32,7 +32,7 @@ obj-y += nand_bbt.o
 obj-y += nand_ids.o
 obj-y += nand_util.o
 obj-y += nand_ecc.o
-obj-y += nand_base.o
+obj-y += nand_base.o nand_timings.o
 
 endif # not spl
 
drivers/mtd/nand/nand_timings.c new file +252 -0

252 lines not on this page · raw message

include/linux/mtd/nand.h +3 -0
index b026110..abda5c3 100644
@@ -1057,6 +1057,9 @@ struct nand_sdr_timings {
 	u32 tWW_min;
 };
 
+/* get timing characteristics from ONFI timing mode. */
+const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
+
 #ifdef __UBOOT__
 /* Standard NAND functions from nand_base.c */
 void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#3 lore raw

RFC 2/11 mtd/nand: add ONFI timing mode to nand_timings converter

Quoted 10 lines · Roy Spliet

From: yassin <[email protected]>

---
 drivers/mtd/nand/Makefile       |   2 +-
 drivers/mtd/nand/nand_timings.c | 252 
++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h        |   3 +
 3 files changed, 256 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/nand/nand_timings.c

This code comes from Linux and yet I see no acknowledgement of that, much less a statement of which version of Linux this was pulled from.

It would probably be better to handle this as part of a general sync with the Linux mtd code.

-Scott

author
#4 lore raw

RFC 2/11 mtd/nand: add ONFI timing mode to nand_timings converter

Hello Scott et al.,

Op 06-06-15 om 00:02 schreef Scott Wood:

Quoted 11 lines · Roy Spliet
Quoted 10 lines

From: yassin <[email protected]>

---
  drivers/mtd/nand/Makefile       |   2 +-
  drivers/mtd/nand/nand_timings.c | 252
++++++++++++++++++++++++++++++++++++++++
  include/linux/mtd/nand.h        |   3 +
  3 files changed, 256 insertions(+), 1 deletion(-)

create mode 100644 drivers/mtd/nand/nand_timings.c

Quoted 2 lines

This code comes from Linux and yet I see no acknowledgement of that, much less a statement of which version of Linux this was pulled from.

Correct, my apologies as I should have clarified that "work by Boris Brezillon" does not
mean "upsteam work". The code comes from Boris' github tree[1] and contains work
that was not yet brought upstream, yet is required for NAND on sunxi to work.

Quoted 2 lines

It would probably be better to handle this as part of a general sync with the Linux mtd code.

Ideally yes, but. In upstream Linux MTD we have a few issues to address as shown
by Boris' patch-set, most importantly:
- NAND chip timings (patch 1 to 3)
- Randomisation support (patch 6)
- Per-partition settings for ECC and randomisation (left out of my RFC, highly desirable
but not strictly required for U-boot booting)
- OF definition of all the above

U-Boot has the additional challenge
- Partitioning is not done the upstream way, but rather in/around cmd_mtdparts

We started discussion on these topics in the #mtd IRC channel (OFTC), and several ideas
have come up. The way I see it these issues can currently either be addressed by
bolting/duct-taping/tie-wrapping more layers of indirection on top of upstream MTD
framework, but really I feel that it might require a bit more of a structural approach
that may or may not break existing drivers.
The code I posted as RFC is functional. If you wish to steer towards an MTD sync-up, I
highly suggest first getting these issues tackled, and then making sure that we extend
the U-boot side of MTD with OF support for everything. This trajectory should include
deprecating the current implementation of cmd_mtdparts and hook that command up
to the "new" upstream way. In other words: now is probably not the right moment.

I'm afraid that as much as I'd like to, I will not have time to address every single one
of these issues (not to mention I am hardly the expert in MTD/NAND). I'm happy to
think along with designing a sustainable solution, but I will need someone to chime
in when it comes to carrying solutions upstream.

Roy

Quoted 1 line

-Scott

[1] https://github.com/bbrezillon/linux-sunxi/commits/sunxi-nand

Signature · 6 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#5 lore raw

[U-Boot] [linux-sunxi] Re: [RFC 02/11] mtd/nand: add ONFI timing mode to nand_timings converter

Quoted 30 lines · Roy Spliet

Hello Scott et al.,

Op 06-06-15 om 00:02 schreef Scott Wood:

On Fri, 2015-06-05 at 13:52 +0200, Roy Spliet wrote:

From: yassin <[email protected]>

---
 drivers/mtd/nand/Makefile       |   2 +-
 drivers/mtd/nand/nand_timings.c | 252
++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h        |   3 +
 3 files changed, 256 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/nand/nand_timings.c

This code comes from Linux and yet I see no acknowledgement of that, much less a statement of which version of Linux this was pulled from.

Correct, my apologies as I should have clarified that "work by Boris Brezillon" does not
mean "upsteam work". The code comes from Boris' github tree[1] and contains work
that was not yet brought upstream, yet is required for NAND on sunxi to work.

It would probably be better to handle this as part of a general sync with the Linux mtd code.

Quoted 8 lines

Ideally yes, but. In upstream Linux MTD we have a few issues to address as shown
by Boris' patch-set, most importantly:
- NAND chip timings (patch 1 to 3)
- Randomisation support (patch 6)
- Per-partition settings for ECC and randomisation (left out of my RFC, highly desirable
but not strictly required for U-boot booting)

Hello,

as I understand it the ECC and randomisation settings for the bootloader part of the nand are suboptimal or unusable for ubifs so if u-boot SPL is to read the u-boot binary and later u-boot the kernel from an ubifs volume it has to support non-uniform settings. Alternatively the bootloader part can be extended to contain partitions for u-boot binary and kernel image written to raw partition without filesystem much like what Andriod usually does.

Thanks

Michal

author
#6 lore raw

[U-Boot] [linux-sunxi] Re: [RFC 02/11] mtd/nand: add ONFI timing mode to nand_timings converter

Hello Michal,

Op 08-06-15 om 10:34 schreef Michal Suchanek:

Quoted 41 lines · Roy Spliet
Quoted 30 lines

Hello Scott et al.,

Op 06-06-15 om 00:02 schreef Scott Wood:

On Fri, 2015-06-05 at 13:52 +0200, Roy Spliet wrote:

From: yassin <[email protected]>

---
  drivers/mtd/nand/Makefile       |   2 +-
  drivers/mtd/nand/nand_timings.c | 252
++++++++++++++++++++++++++++++++++++++++
  include/linux/mtd/nand.h        |   3 +
  3 files changed, 256 insertions(+), 1 deletion(-)

create mode 100644 drivers/mtd/nand/nand_timings.c

This code comes from Linux and yet I see no acknowledgement of that, much less a statement of which version of Linux this was pulled from.

Correct, my apologies as I should have clarified that "work by Boris Brezillon" does not
mean "upsteam work". The code comes from Boris' github tree[1] and contains work
that was not yet brought upstream, yet is required for NAND on sunxi to work.

It would probably be better to handle this as part of a general sync with the Linux mtd code.

Quoted 8 lines

Ideally yes, but. In upstream Linux MTD we have a few issues to address as shown
by Boris' patch-set, most importantly:
- NAND chip timings (patch 1 to 3)
- Randomisation support (patch 6)
- Per-partition settings for ECC and randomisation (left out of my RFC, highly desirable
but not strictly required for U-boot booting)

Hello,

Quoted 7 lines

as I understand it the ECC and randomisation settings for the bootloader part of the nand are suboptimal or unusable for ubifs so if u-boot SPL is to read the u-boot binary and later u-boot the kernel from an ubifs volume it has to support non-uniform settings. Alternatively the bootloader part can be extended to contain partitions for u-boot binary and kernel image written to raw partition without filesystem much like what Andriod usually does.

SPL does not read U-boot from UBI. The SPL driver is separate, much smaller and
only reads in the same way BROM does. U-boot itself is not bound by the limitations
imposed by BROM, which means proper randomisation and ECC settings can be used
for "the UBI partition".
Yours,

Roy

Quoted 4 lines

Thanks

Michal

Signature · 6 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#7 lore raw

[U-Boot] [linux-sunxi] Re: [RFC 02/11] mtd/nand: add ONFI timing mode to nand_timings converter

Quoted 51 lines · On Mon, 08 Jun 2015 10:41:28 +0200 Roy Spliet <[email protected]> wrote:

Hello Michal,

Op 08-06-15 om 10:34 schreef Michal Suchanek:

Quoted 41 lines · Roy Spliet
Quoted 30 lines

Hello Scott et al.,

Op 06-06-15 om 00:02 schreef Scott Wood:

On Fri, 2015-06-05 at 13:52 +0200, Roy Spliet wrote:

From: yassin <[email protected]>

---
  drivers/mtd/nand/Makefile       |   2 +-
  drivers/mtd/nand/nand_timings.c | 252
++++++++++++++++++++++++++++++++++++++++
  include/linux/mtd/nand.h        |   3 +
  3 files changed, 256 insertions(+), 1 deletion(-)

create mode 100644 drivers/mtd/nand/nand_timings.c

This code comes from Linux and yet I see no acknowledgement of that, much less a statement of which version of Linux this was pulled from.

Correct, my apologies as I should have clarified that "work by Boris Brezillon" does not
mean "upsteam work". The code comes from Boris' github tree[1] and contains work
that was not yet brought upstream, yet is required for NAND on sunxi to work.

It would probably be better to handle this as part of a general sync with the Linux mtd code.

Quoted 8 lines

Ideally yes, but. In upstream Linux MTD we have a few issues to address as shown
by Boris' patch-set, most importantly:
- NAND chip timings (patch 1 to 3)
- Randomisation support (patch 6)
- Per-partition settings for ECC and randomisation (left out of my RFC, highly desirable
but not strictly required for U-boot booting)

Hello,

Quoted 7 lines

as I understand it the ECC and randomisation settings for the bootloader part of the nand are suboptimal or unusable for ubifs so if u-boot SPL is to read the u-boot binary and later u-boot the kernel from an ubifs volume it has to support non-uniform settings. Alternatively the bootloader part can be extended to contain partitions for u-boot binary and kernel image written to raw partition without filesystem much like what Andriod usually does.

Quoted 7 lines

SPL does not read U-boot from UBI. The SPL driver is separate, much smaller and
only reads in the same way BROM does. U-boot itself is not bound by the limitations
imposed by BROM, which means proper randomisation and ECC settings can be used
for "the UBI partition".

Yep, I agree with Roy here: we shouldn't use the BROM config except for the SPL partition. Defining the same randomizer seed for all the pages in a given block is pretty much useless since it won't prevent the reproducible pattern issue, which is one of the cause of excessive bitblits in MLC NANDs.
The same goes for the ECC config used by the BROM, because in some cases it might prevent using the whole page (ECC config is stronger than required, and thus ECC bytes take more than what's available in the OOB area).

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#8 lore raw

RFC 2/11 mtd/nand: add ONFI timing mode to nand_timings converter

In reply to Roy Spliet
Quoted 24 lines · Roy Spliet

Hello Scott et al.,

Op 06-06-15 om 00:02 schreef Scott Wood:

Quoted 11 lines · Roy Spliet
Quoted 10 lines

From: yassin <[email protected]>

---
 drivers/mtd/nand/Makefile       |   2 +-
 drivers/mtd/nand/nand_timings.c | 252 
++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h        |   3 +
 3 files changed, 256 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/nand/nand_timings.c
Quoted 4 lines

This code comes from Linux and yet I see no acknowledgement of that,
much less a statement of which version of Linux this was pulled from.

Correct, my apologies as I should have clarified that "work by Boris Brezillon" does not
mean "upsteam work". The code comes from Boris' github tree[1] and contains work
that was not yet brought upstream, yet is required for NAND on sunxi to work.

Quoted 7 lines
Quoted 3 lines

It would probably be better to handle this as part of a general sync
with the Linux mtd code.

Ideally yes, but. In upstream Linux MTD we have a few issues to address as shown
by Boris' patch-set, most importantly:
- NAND chip timings (patch 1 to 3)

Patches 1-3 are already in Linux (if there are subtle differences needed those should be followup patches, with an explanation of why it needs to differ from Linux), except that patch 3 for some reason has "onfi_timing_mode_ds" where Linux has "onfi_timing_mode_default".

I will try to do a sync soon.

Quoted 15 lines

U-Boot has the additional challenge
- Partitioning is not done the upstream way, but rather in/around cmd_mtdparts

We started discussion on these topics in the #mtd IRC channel (OFTC), and several ideas
have come up. The way I see it these issues can currently either be addressed by
bolting/duct-taping/tie-wrapping more layers of indirection on top of upstream MTD
framework, but really I feel that it might require a bit more of a structural approach
that may or may not break existing drivers.
The code I posted as RFC is functional. If you wish to steer towards an MTD sync-up, I

Quoted 8 lines

highly suggest first getting these issues tackled, and then making sure that we extend
the U-boot side of MTD with OF support for everything. This trajectory should include
deprecating the current implementation of cmd_mtdparts and hook that command up
to the "new" upstream way. In other words: now is probably not the right moment.

I don't see why those things are a prerequisite for syncing MTD from Linux to U-Boot. If there are further changes in Linux after a sync that we want to bring in, we can sync again and it will be easier because the sync will contain fewer changes.

-Scott

#9 lore raw

RFC 2/11 mtd/nand: add ONFI timing mode to nand_timings converter

In reply to Scott Wood

Hi Scott,

On June 8, 2015, 8:24 p.m., Scott Wood wrote:

<snip>

Quoted 14 lines
Quoted 6 lines

Correct, my apologies as I should have clarified that "work by Boris Brezillon" does not
mean "upsteam work". The code comes from Boris' github tree[1] and contains work
that was not yet brought upstream, yet is required for NAND on sunxi to work.

Quoted 7 lines
Quoted 3 lines

It would probably be better to handle this as part of a general sync
with the Linux mtd code.

Ideally yes, but. In upstream Linux MTD we have a few issues to address as shown
by Boris' patch-set, most importantly:
- NAND chip timings (patch 1 to 3)

Quoted 6 lines

Patches 1-3 are already in Linux (if there are subtle differences needed those should be followup patches, with an explanation of why it needs to differ from Linux), except that patch 3 for some reason has "onfi_timing_mode_ds" where Linux has "onfi_timing_mode_default".

I will try to do a sync soon.

If you could do that that would be great, that should at least shrink the size of this patch-set by 3 patches.

I assume that you will not be sending a pull-req for this sync for v2015.07, if you can make a git branch with the sync available somewhere for us to build on top of, then that would be great.

Thanks & Regards,

Hans

#10 lore raw

RFC 2/11 mtd/nand: add ONFI timing mode to nand_timings converter

Quoted 30 lines · Hans de Goede

Hi Scott,

On June 8, 2015, 8:24 p.m., Scott Wood wrote:

<snip>

Quoted 1 line
Quoted 1 line

Correct, my apologies as I should have clarified that "work by

Boris

Quoted 2 lines
Quoted 2 lines

Brezillon" does not
mean "upsteam work". The code comes from Boris' github tree[1]

and

Quoted 2 lines
Quoted 2 lines

contains work
that was not yet brought upstream, yet is required for NAND on

sunxi

Quoted 11 lines
Quoted 8 lines

to work.

Quoted 3 lines

It would probably be better to handle this as part of a general sync
with the Linux mtd code.

Ideally yes, but. In upstream Linux MTD we have a few issues to address as shown
by Boris' patch-set, most importantly:
- NAND chip timings (patch 1 to 3)

Patches 1-3 are already in Linux (if there are subtle differences needed those should be followup patches, with an explanation of

why it

Quoted 1 line

needs to differ from Linux), except that patch 3 for some reason

has

Quoted 2 lines

"onfi_timing_mode_ds" where Linux has "onfi_timing_mode_default".

Quoted 7 lines
Quoted 1 line

I will try to do a sync soon.

If you could do that that would be great, that should at least shrink the size of this patch-set by 3 patches.

I assume that you will not be sending a pull-req for this sync for v2015.07,

No, it's too late for that even if I had it ready now.

Quoted 2 lines

if you can make a git branch with the sync available
somewhere for us to build on top of, then that would be great.

OK.

-Scott

author
#11 lore raw

RFC 3/11 mtd/nand: support ONFI timing mode retrieval for non-ONFI

In reply to Roy Spliet

From: yassin <[email protected]>

---
 drivers/mtd/nand/nand_base.c | 1 +
 include/linux/mtd/nand.h     | 7 +++++++
 2 files changed, 8 insertions(+)
drivers/mtd/nand/nand_base.c +1 -0
index c0e381a..dbeb092 100644
@@ -3709,6 +3709,7 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
 		chip->options |= type->options;
 		chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
 		chip->ecc_step_ds = NAND_ECC_STEP(type);
+		chip->onfi_timing_mode_ds = type->onfi_timing_mode_ds;
 
 		*busw = type->options & NAND_BUSWIDTH_16;
 
include/linux/mtd/nand.h +7 -0
index abda5c3..0cdb3b9 100644
@@ -634,6 +634,7 @@ struct nand_buffers {
  * @ecc_step_ds:	[INTERN] ECC step required by the @ecc_strength_ds,
  *                      also from the datasheet. It is the recommended ECC step
  *			size, if known; if unknown, set to zero.
+ * @onfi_timing_mode_ds:[INTERN] ONFI timing mode deduced from datasheet.
  * @numchips:		[INTERN] number of physical chips
  * @chipsize:		[INTERN] the size of one chip for multichip arrays
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
@@ -718,6 +719,7 @@ struct nand_chip {
 	uint8_t bits_per_cell;
 	uint16_t ecc_strength_ds;
 	uint16_t ecc_step_ds;
+	int onfi_timing_mode_ds;
 	int badblockpos;
 	int badblockbits;
 
@@ -822,6 +824,10 @@ struct nand_chip {
  *               @ecc_step_ds in nand_chip{}, also from the datasheet.
  *               For example, the "4bit ECC for each 512Byte" can be set with
  *               NAND_ECC_INFO(4, 512).
+ * @onfi_timing_mode_ds: the ONFI timing mode supported by this NAND chip. This
+ *                       should be deduced from timings described in the
+ *                       datasheet.
+ *
  */
 struct nand_flash_dev {
 	char *name;
@@ -842,6 +848,7 @@ struct nand_flash_dev {
 		uint16_t strength_ds;
 		uint16_t step_ds;
 	} ecc;
+	int onfi_timing_mode_ds;
 };
 
 /**
Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#12 lore raw

RFC 3/11 mtd/nand: support ONFI timing mode retrieval for non-ONFI

On Fri, 5 Jun 2015 13:52:36 +0200
Roy Spliet <[email protected]> wrote:

That one has been accepted, so I guess it will be taken by Scott during his sync with the last mainline kernel.

Quoted 59 lines

From: yassin <[email protected]>

---
 drivers/mtd/nand/nand_base.c | 1 +
 include/linux/mtd/nand.h     | 7 +++++++
 2 files changed, 8 insertions(+)
drivers/mtd/nand/nand_base.c +1 -0
index c0e381a..dbeb092 100644
@@ -3709,6 +3709,7 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
 		chip->options |= type->options;
 		chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
 		chip->ecc_step_ds = NAND_ECC_STEP(type);
+		chip->onfi_timing_mode_ds = type->onfi_timing_mode_ds;
 
 		*busw = type->options & NAND_BUSWIDTH_16;
 
include/linux/mtd/nand.h +7 -0
index abda5c3..0cdb3b9 100644
@@ -634,6 +634,7 @@ struct nand_buffers {
  * @ecc_step_ds:	[INTERN] ECC step required by the @ecc_strength_ds,
  *                      also from the datasheet. It is the recommended ECC step
  *			size, if known; if unknown, set to zero.
+ * @onfi_timing_mode_ds:[INTERN] ONFI timing mode deduced from datasheet.
  * @numchips:		[INTERN] number of physical chips
  * @chipsize:		[INTERN] the size of one chip for multichip arrays
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
@@ -718,6 +719,7 @@ struct nand_chip {
 	uint8_t bits_per_cell;
 	uint16_t ecc_strength_ds;
 	uint16_t ecc_step_ds;
+	int onfi_timing_mode_ds;
 	int badblockpos;
 	int badblockbits;
 
@@ -822,6 +824,10 @@ struct nand_chip {
  *               @ecc_step_ds in nand_chip{}, also from the datasheet.
  *               For example, the "4bit ECC for each 512Byte" can be set with
  *               NAND_ECC_INFO(4, 512).
+ * @onfi_timing_mode_ds: the ONFI timing mode supported by this NAND chip. This
+ *                       should be deduced from timings described in the
+ *                       datasheet.
+ *
  */
 struct nand_flash_dev {
 	char *name;
@@ -842,6 +848,7 @@ struct nand_flash_dev {
 		uint16_t strength_ds;
 		uint16_t step_ds;
 	} ecc;
+	int onfi_timing_mode_ds;
 };
 
 /**
Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
author
#13 lore raw

RFC 4/11 mtd/nand: add page status table (pst)

In reply to Roy Spliet

From: yassin <[email protected]>

---
 drivers/mtd/nand/nand_base.c | 154 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h     |  21 ++++++
 2 files changed, 175 insertions(+)
drivers/mtd/nand/nand_base.c +154 -0
index dbeb092..1c514a0 100644
@@ -1185,6 +1185,138 @@ EXPORT_SYMBOL(nand_lock);
 #endif
 
 /**
+ * nand_page_is_empty - check wether a NAND page contains only FFs
+ * @mtd:	mtd info
+ * @data:	data buffer
+ * @oob:	oob buffer
+ *
+ * Reads the data stored in the databuf buffer and check if it contains only
+ * FFs.
+ *
+ * Return true if it does else return false.
+ */
+bool nand_page_is_empty(struct mtd_info *mtd, void *data, void *oob)
+{
+	u8 *buf;
+	int length;
+	u32 pattern = 0xffffffff;
+	int bitflips = 0;
+	int cnt;
+
+	buf = data;
+	length = mtd->writesize;
+	while (length) {
+		cnt = length < sizeof(pattern) ? length : sizeof(pattern);
+		if (memcmp(&pattern, buf, cnt)) {
+			int i;
+			for (i = 0; i < cnt * 8; i++) {
+				if (!(buf[i / 8] &
+				      (1 << (i % 8)))) {
+					bitflips++;
+					if (bitflips > mtd->ecc_strength)
+						return false;
+				}
+			}
+		}
+
+		buf += sizeof(pattern);
+		length -= sizeof(pattern);
+	}
+
+	buf = oob;
+	length = mtd->oobsize;
+	while (length) {
+		cnt = length < sizeof(pattern) ? length : sizeof(pattern);
+		if (memcmp(&pattern, buf, cnt)) {
+			int i;
+			for (i = 0; i < cnt * 8; i++) {
+				if (!(buf[i / 8] &
+				      (1 << (i % 8)))) {
+					bitflips++;
+					if (bitflips > mtd->ecc_strength)
+						return false;
+				}
+			}
+		}
+
+		buf += sizeof(pattern);
+		length -= sizeof(pattern);
+	}
+
+	return true;
+}
+EXPORT_SYMBOL(nand_page_is_empty);
+
+/**
+ * nand_page_get_status - retrieve page status from the page status table (pst)
+ * @mtd:	mtd info
+ * @page:	page you want to get status on
+ *
+ * Return the page status.
+ */
+int nand_page_get_status(struct mtd_info *mtd, int page)
+{
+	struct nand_chip *chip = mtd->priv;
+	u8 shift = (page % 4) * 2;
+	uint64_t offset = page / 4;
+	int ret = NAND_PAGE_STATUS_UNKNOWN;
+
+	if (chip->pst)
+		ret = (chip->pst[offset] >> shift) & 0x3;
+
+	return ret;
+}
+EXPORT_SYMBOL(nand_page_get_status);
+
+/**
+ * nand_page_set_status - assign page status from in the page status table
+ * @mtd:	mtd info
+ * @page:	page you want to get status on
+ * @status:	new status to assign
+ */
+void nand_page_set_status(struct mtd_info *mtd, int page,
+			  enum nand_page_status status)
+{
+	struct nand_chip *chip = mtd->priv;
+	u8 shift;
+	uint64_t offset;
+
+	if (!chip->pst)
+		return;
+
+	shift = (page % 4) * 2;
+	offset = page / 4;
+	chip->pst[offset] &= ~(0x3 << shift);
+	chip->pst[offset] |= (status & 0x3) << shift;
+}
+EXPORT_SYMBOL(nand_page_set_status);
+
+/**
+ * nand_pst_create - create a page status table
+ * @mtd:	mtd info
+ *
+ * Allocate a page status table and assign it to the mtd device.
+ *
+ * Returns 0 in case of success or -ERRNO in case of error.
+ */
+int nand_pst_create(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	if (chip->pst)
+		return 0;
+
+	chip->pst = kzalloc(mtd->size >>
+			    (chip->page_shift + mtd->subpage_sft + 2),
+			    GFP_KERNEL);
+	if (!chip->pst)
+		return -ENOMEM;
+
+	return 0;
+}
+EXPORT_SYMBOL(nand_pst_create);
+
+/**
  * nand_read_page_raw - [INTERN] read raw page data without ecc
  * @mtd: mtd info structure
  * @chip: nand chip info structure
@@ -2521,6 +2653,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 		int bytes = mtd->writesize;
 		int cached = writelen > bytes && page != blockmask;
 		uint8_t *wbuf = buf;
+		int subpage;
 
 		WATCHDOG_RESET();
 		/* Partial page write? */
@@ -2547,6 +2680,14 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 		if (ret)
 			break;
 
+		for (subpage = column / chip->subpagesize;
+		     subpage < (column + writelen) / chip->subpagesize;
+		     subpage++)
+			nand_page_set_status(mtd,
+					     (page << mtd->subpage_sft) +
+					     subpage,
+					     NAND_PAGE_FILLED);
+
 		writelen -= bytes;
 		if (!writelen)
 			break;
@@ -2804,6 +2945,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 	int page, status, pages_per_block, ret, chipnr;
 	struct nand_chip *chip = mtd->priv;
 	loff_t len;
+	int i;
 
 	pr_debug("%s: start = 0x%012llx, len = %llu\n",
 			__func__, (unsigned long long)instr->addr,
@@ -2880,6 +3022,18 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 			goto erase_exit;
 		}
 
+		for (i = 0; i < pages_per_block; i++) {
+			int subpage;
+			for (subpage = 0;
+			     subpage < 1 << mtd->subpage_sft;
+			     subpage++) {
+				nand_page_set_status(mtd,
+					((page + i) << mtd->subpage_sft) +
+					subpage,
+					NAND_PAGE_EMPTY);
+			}
+		}
+
 		/* Increment page address and decrement length */
 		len -= (1ULL << chip->phys_erase_shift);
 		page += pages_per_block;
include/linux/mtd/nand.h +21 -0
index 0cdb3b9..ef6a783 100644
@@ -547,6 +547,24 @@ struct nand_ecc_ctrl {
 			int page);
 };
 
+/*
+ * Constants for page status
+ */
+enum nand_page_status {
+	NAND_PAGE_STATUS_UNKNOWN,
+	NAND_PAGE_EMPTY,
+	NAND_PAGE_FILLED,
+};
+
+bool nand_page_is_empty(struct mtd_info *mtd, void *data, void *oob);
+
+int nand_page_get_status(struct mtd_info *mtd, int page);
+
+void nand_page_set_status(struct mtd_info *mtd, int page,
+			  enum nand_page_status status);
+
+int nand_pst_create(struct mtd_info *mtd);
+
 /**
  * struct nand_buffers - buffer structure for read/write
  * @ecccalc:	buffer pointer for calculated ECC, size is oobsize.
@@ -660,6 +678,7 @@ struct nand_buffers {
  * @bbt_md:		[REPLACEABLE] bad block table mirror descriptor
  * @badblock_pattern:	[REPLACEABLE] bad block scan pattern used for initial
  *			bad block scan.
+ * @pst:		[INTERN] page status table
  * @controller:		[REPLACEABLE] a pointer to a hardware controller
  *			structure which is shared among multiple independent
  *			devices.
@@ -750,6 +769,8 @@ struct nand_chip {
 
 	struct nand_bbt_descr *badblock_pattern;
 
+	uint8_t *pst;
+
 	void *priv;
 };
 
Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#14 lore raw

RFC 4/11 mtd/nand: add page status table (pst)

On Fri, 5 Jun 2015 13:52:37 +0200
Roy Spliet <[email protected]> wrote:

Ditto (this work hasn't been accepted in Linux).

Quoted 247 lines

From: yassin <[email protected]>

---
 drivers/mtd/nand/nand_base.c | 154 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h     |  21 ++++++
 2 files changed, 175 insertions(+)
drivers/mtd/nand/nand_base.c +154 -0
index dbeb092..1c514a0 100644
@@ -1185,6 +1185,138 @@ EXPORT_SYMBOL(nand_lock);
 #endif
 
 /**
+ * nand_page_is_empty - check wether a NAND page contains only FFs
+ * @mtd:	mtd info
+ * @data:	data buffer
+ * @oob:	oob buffer
+ *
+ * Reads the data stored in the databuf buffer and check if it contains only
+ * FFs.
+ *
+ * Return true if it does else return false.
+ */
+bool nand_page_is_empty(struct mtd_info *mtd, void *data, void *oob)
+{
+	u8 *buf;
+	int length;
+	u32 pattern = 0xffffffff;
+	int bitflips = 0;
+	int cnt;
+
+	buf = data;
+	length = mtd->writesize;
+	while (length) {
+		cnt = length < sizeof(pattern) ? length : sizeof(pattern);
+		if (memcmp(&pattern, buf, cnt)) {
+			int i;
+			for (i = 0; i < cnt * 8; i++) {
+				if (!(buf[i / 8] &
+				      (1 << (i % 8)))) {
+					bitflips++;
+					if (bitflips > mtd->ecc_strength)
+						return false;
+				}
+			}
+		}
+
+		buf += sizeof(pattern);
+		length -= sizeof(pattern);
+	}
+
+	buf = oob;
+	length = mtd->oobsize;
+	while (length) {
+		cnt = length < sizeof(pattern) ? length : sizeof(pattern);
+		if (memcmp(&pattern, buf, cnt)) {
+			int i;
+			for (i = 0; i < cnt * 8; i++) {
+				if (!(buf[i / 8] &
+				      (1 << (i % 8)))) {
+					bitflips++;
+					if (bitflips > mtd->ecc_strength)
+						return false;
+				}
+			}
+		}
+
+		buf += sizeof(pattern);
+		length -= sizeof(pattern);
+	}
+
+	return true;
+}
+EXPORT_SYMBOL(nand_page_is_empty);
+
+/**
+ * nand_page_get_status - retrieve page status from the page status table (pst)
+ * @mtd:	mtd info
+ * @page:	page you want to get status on
+ *
+ * Return the page status.
+ */
+int nand_page_get_status(struct mtd_info *mtd, int page)
+{
+	struct nand_chip *chip = mtd->priv;
+	u8 shift = (page % 4) * 2;
+	uint64_t offset = page / 4;
+	int ret = NAND_PAGE_STATUS_UNKNOWN;
+
+	if (chip->pst)
+		ret = (chip->pst[offset] >> shift) & 0x3;
+
+	return ret;
+}
+EXPORT_SYMBOL(nand_page_get_status);
+
+/**
+ * nand_page_set_status - assign page status from in the page status table
+ * @mtd:	mtd info
+ * @page:	page you want to get status on
+ * @status:	new status to assign
+ */
+void nand_page_set_status(struct mtd_info *mtd, int page,
+			  enum nand_page_status status)
+{
+	struct nand_chip *chip = mtd->priv;
+	u8 shift;
+	uint64_t offset;
+
+	if (!chip->pst)
+		return;
+
+	shift = (page % 4) * 2;
+	offset = page / 4;
+	chip->pst[offset] &= ~(0x3 << shift);
+	chip->pst[offset] |= (status & 0x3) << shift;
+}
+EXPORT_SYMBOL(nand_page_set_status);
+
+/**
+ * nand_pst_create - create a page status table
+ * @mtd:	mtd info
+ *
+ * Allocate a page status table and assign it to the mtd device.
+ *
+ * Returns 0 in case of success or -ERRNO in case of error.
+ */
+int nand_pst_create(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	if (chip->pst)
+		return 0;
+
+	chip->pst = kzalloc(mtd->size >>
+			    (chip->page_shift + mtd->subpage_sft + 2),
+			    GFP_KERNEL);
+	if (!chip->pst)
+		return -ENOMEM;
+
+	return 0;
+}
+EXPORT_SYMBOL(nand_pst_create);
+
+/**
  * nand_read_page_raw - [INTERN] read raw page data without ecc
  * @mtd: mtd info structure
  * @chip: nand chip info structure
@@ -2521,6 +2653,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 		int bytes = mtd->writesize;
 		int cached = writelen > bytes && page != blockmask;
 		uint8_t *wbuf = buf;
+		int subpage;
 
 		WATCHDOG_RESET();
 		/* Partial page write? */
@@ -2547,6 +2680,14 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 		if (ret)
 			break;
 
+		for (subpage = column / chip->subpagesize;
+		     subpage < (column + writelen) / chip->subpagesize;
+		     subpage++)
+			nand_page_set_status(mtd,
+					     (page << mtd->subpage_sft) +
+					     subpage,
+					     NAND_PAGE_FILLED);
+
 		writelen -= bytes;
 		if (!writelen)
 			break;
@@ -2804,6 +2945,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 	int page, status, pages_per_block, ret, chipnr;
 	struct nand_chip *chip = mtd->priv;
 	loff_t len;
+	int i;
 
 	pr_debug("%s: start = 0x%012llx, len = %llu\n",
 			__func__, (unsigned long long)instr->addr,
@@ -2880,6 +3022,18 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 			goto erase_exit;
 		}
 
+		for (i = 0; i < pages_per_block; i++) {
+			int subpage;
+			for (subpage = 0;
+			     subpage < 1 << mtd->subpage_sft;
+			     subpage++) {
+				nand_page_set_status(mtd,
+					((page + i) << mtd->subpage_sft) +
+					subpage,
+					NAND_PAGE_EMPTY);
+			}
+		}
+
 		/* Increment page address and decrement length */
 		len -= (1ULL << chip->phys_erase_shift);
 		page += pages_per_block;
include/linux/mtd/nand.h +21 -0
index 0cdb3b9..ef6a783 100644
@@ -547,6 +547,24 @@ struct nand_ecc_ctrl {
 			int page);
 };
 
+/*
+ * Constants for page status
+ */
+enum nand_page_status {
+	NAND_PAGE_STATUS_UNKNOWN,
+	NAND_PAGE_EMPTY,
+	NAND_PAGE_FILLED,
+};
+
+bool nand_page_is_empty(struct mtd_info *mtd, void *data, void *oob);
+
+int nand_page_get_status(struct mtd_info *mtd, int page);
+
+void nand_page_set_status(struct mtd_info *mtd, int page,
+			  enum nand_page_status status);
+
+int nand_pst_create(struct mtd_info *mtd);
+
 /**
  * struct nand_buffers - buffer structure for read/write
  * @ecccalc:	buffer pointer for calculated ECC, size is oobsize.
@@ -660,6 +678,7 @@ struct nand_buffers {
  * @bbt_md:		[REPLACEABLE] bad block table mirror descriptor
  * @badblock_pattern:	[REPLACEABLE] bad block scan pattern used for initial
  *			bad block scan.
+ * @pst:		[INTERN] page status table
  * @controller:		[REPLACEABLE] a pointer to a hardware controller
  *			structure which is shared among multiple independent
  *			devices.
@@ -750,6 +769,8 @@ struct nand_chip {
 
 	struct nand_bbt_descr *badblock_pattern;
 
+	uint8_t *pst;
+
 	void *priv;
 };
 
Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
author
#15 lore raw

RFC 5/11 mtd/nand: take nand_ecc_ctrl initialization out of nand_scan_tail

In reply to Roy Spliet

From: yassin <[email protected]>

---
 drivers/mtd/nand/nand_base.c | 101 ++++++++++++++++++++++++++-----------------
 1 file changed, 61 insertions(+), 40 deletions(-)
drivers/mtd/nand/nand_base.c +61 -40
index 1c514a0..83586cc 100644
@@ -4114,47 +4114,15 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
 }
 EXPORT_SYMBOL(nand_scan_ident);
 
-
-/**
- * nand_scan_tail - [NAND Interface] Scan for the NAND device
- * @mtd: MTD device structure
- *
- * This is the second phase of the normal nand_scan() function. It fills out
- * all the uninitialized function pointers with the defaults and scans for a
- * bad block table if appropriate.
+/*
+ * Initialize ECC struct:
+ *  - fill ECC struct with default function/values when these ones are undefined
+ *  - fill ECC infos based on MTD device
  */
-int nand_scan_tail(struct mtd_info *mtd)
+static int nand_ecc_ctrl_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc)
 {
 	int i;
-	struct nand_chip *chip = mtd->priv;
-	struct nand_ecc_ctrl *ecc = &chip->ecc;
-	struct nand_buffers *nbuf;
 
-	/* New bad blocks should be marked in OOB, flash-based BBT, or both */
-	BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
-			!(chip->bbt_options & NAND_BBT_USE_FLASH));
-
-	if (!(chip->options & NAND_OWN_BUFFERS)) {
-#ifndef __UBOOT__
-		nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
-				+ mtd->oobsize * 3, GFP_KERNEL);
-		if (!nbuf)
-			return -ENOMEM;
-		nbuf->ecccalc = (uint8_t *)(nbuf + 1);
-		nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
-		nbuf->databuf = nbuf->ecccode + mtd->oobsize;
-#else
-		nbuf = kzalloc(sizeof(struct nand_buffers), GFP_KERNEL);
-#endif
-
-		chip->buffers = nbuf;
-	} else {
-		if (!chip->buffers)
-			return -ENOMEM;
-	}
-
-	/* Set the internal oob buffer location, just after the page data */
-	chip->oob_poi = chip->buffers->databuf + mtd->writesize;
 
 	/*
 	 * If no default placement scheme is given, select an appropriate one.
@@ -4180,9 +4148,6 @@ int nand_scan_tail(struct mtd_info *mtd)
 		}
 	}
 
-	if (!chip->write_page)
-		chip->write_page = nand_write_page;
-
 	/*
 	 * Check ECC mode, default to software if 3byte/512byte hardware ECC is
 	 * selected and we have 256 byte pagesize fallback to software ECC
@@ -4349,6 +4314,62 @@ int nand_scan_tail(struct mtd_info *mtd)
 	}
 	ecc->total = ecc->steps * ecc->bytes;
 
+	return 0;
+}
+
+/**
+ * nand_scan_tail - [NAND Interface] Scan for the NAND device
+ * @mtd: MTD device structure
+ *
+ * This is the second phase of the normal nand_scan() function. It fills out
+ * all the uninitialized function pointers with the defaults and scans for a
+ * bad block table if appropriate.
+ */
+int nand_scan_tail(struct mtd_info *mtd)
+{
+	int ret;
+	struct nand_chip *chip = mtd->priv;
+	struct nand_ecc_ctrl *ecc = &chip->ecc;
+	struct nand_buffers *nbuf;
+
+	/* New bad blocks should be marked in OOB, flash-based BBT, or both */
+	BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
+			!(chip->bbt_options & NAND_BBT_USE_FLASH));
+
+	if (!(chip->options & NAND_OWN_BUFFERS)) {
+#ifndef __UBOOT__
+		nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
+				+ mtd->oobsize * 3, GFP_KERNEL);
+		if (!nbuf)
+			return -ENOMEM;
+		nbuf->ecccalc = (uint8_t *)(nbuf + 1);
+		nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
+		nbuf->databuf = nbuf->ecccode + mtd->oobsize;
+#else
+		nbuf = kzalloc(sizeof(struct nand_buffers), GFP_KERNEL);
+#endif
+
+		chip->buffers = nbuf;
+	} else {
+		if (!chip->buffers)
+			return -ENOMEM;
+	}
+
+	/* Set the internal oob buffer location, just after the page data */
+	chip->oob_poi = chip->buffers->databuf + mtd->writesize;
+
+	if (!chip->write_page)
+		chip->write_page = nand_write_page;
+
+	/* Initialize ECC struct */
+	ret = nand_ecc_ctrl_init(mtd, ecc);
+	if (ret) {
+		if (!(chip->options & NAND_OWN_BUFFERS))
+			kfree(chip->buffers);
+
+		return ret;
+	}
+
 	/* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
 	if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
 		switch (ecc->steps) {
Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#16 lore raw

RFC 5/11 mtd/nand: take nand_ecc_ctrl initialization out of nand_scan_tail

On Fri, 5 Jun 2015 13:52:38 +0200
Roy Spliet <[email protected]> wrote:

Ditto (work not mainlined yet, so we'd better either get rid of it). BTW, a commit message would help understanding what you're doing in this patch (even if I'm probably the one who omit the commit message in the first place, that doesn't mean you should do the same ;-))

Quoted 137 lines

From: yassin <[email protected]>

---
 drivers/mtd/nand/nand_base.c | 101 ++++++++++++++++++++++++++-----------------
 1 file changed, 61 insertions(+), 40 deletions(-)
drivers/mtd/nand/nand_base.c +61 -40
index 1c514a0..83586cc 100644
@@ -4114,47 +4114,15 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
 }
 EXPORT_SYMBOL(nand_scan_ident);
 
-
-/**
- * nand_scan_tail - [NAND Interface] Scan for the NAND device
- * @mtd: MTD device structure
- *
- * This is the second phase of the normal nand_scan() function. It fills out
- * all the uninitialized function pointers with the defaults and scans for a
- * bad block table if appropriate.
+/*
+ * Initialize ECC struct:
+ *  - fill ECC struct with default function/values when these ones are undefined
+ *  - fill ECC infos based on MTD device
  */
-int nand_scan_tail(struct mtd_info *mtd)
+static int nand_ecc_ctrl_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc)
 {
 	int i;
-	struct nand_chip *chip = mtd->priv;
-	struct nand_ecc_ctrl *ecc = &chip->ecc;
-	struct nand_buffers *nbuf;
 
-	/* New bad blocks should be marked in OOB, flash-based BBT, or both */
-	BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
-			!(chip->bbt_options & NAND_BBT_USE_FLASH));
-
-	if (!(chip->options & NAND_OWN_BUFFERS)) {
-#ifndef __UBOOT__
-		nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
-				+ mtd->oobsize * 3, GFP_KERNEL);
-		if (!nbuf)
-			return -ENOMEM;
-		nbuf->ecccalc = (uint8_t *)(nbuf + 1);
-		nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
-		nbuf->databuf = nbuf->ecccode + mtd->oobsize;
-#else
-		nbuf = kzalloc(sizeof(struct nand_buffers), GFP_KERNEL);
-#endif
-
-		chip->buffers = nbuf;
-	} else {
-		if (!chip->buffers)
-			return -ENOMEM;
-	}
-
-	/* Set the internal oob buffer location, just after the page data */
-	chip->oob_poi = chip->buffers->databuf + mtd->writesize;
 
 	/*
 	 * If no default placement scheme is given, select an appropriate one.
@@ -4180,9 +4148,6 @@ int nand_scan_tail(struct mtd_info *mtd)
 		}
 	}
 
-	if (!chip->write_page)
-		chip->write_page = nand_write_page;
-
 	/*
 	 * Check ECC mode, default to software if 3byte/512byte hardware ECC is
 	 * selected and we have 256 byte pagesize fallback to software ECC
@@ -4349,6 +4314,62 @@ int nand_scan_tail(struct mtd_info *mtd)
 	}
 	ecc->total = ecc->steps * ecc->bytes;
 
+	return 0;
+}
+
+/**
+ * nand_scan_tail - [NAND Interface] Scan for the NAND device
+ * @mtd: MTD device structure
+ *
+ * This is the second phase of the normal nand_scan() function. It fills out
+ * all the uninitialized function pointers with the defaults and scans for a
+ * bad block table if appropriate.
+ */
+int nand_scan_tail(struct mtd_info *mtd)
+{
+	int ret;
+	struct nand_chip *chip = mtd->priv;
+	struct nand_ecc_ctrl *ecc = &chip->ecc;
+	struct nand_buffers *nbuf;
+
+	/* New bad blocks should be marked in OOB, flash-based BBT, or both */
+	BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
+			!(chip->bbt_options & NAND_BBT_USE_FLASH));
+
+	if (!(chip->options & NAND_OWN_BUFFERS)) {
+#ifndef __UBOOT__
+		nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
+				+ mtd->oobsize * 3, GFP_KERNEL);
+		if (!nbuf)
+			return -ENOMEM;
+		nbuf->ecccalc = (uint8_t *)(nbuf + 1);
+		nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
+		nbuf->databuf = nbuf->ecccode + mtd->oobsize;
+#else
+		nbuf = kzalloc(sizeof(struct nand_buffers), GFP_KERNEL);
+#endif
+
+		chip->buffers = nbuf;
+	} else {
+		if (!chip->buffers)
+			return -ENOMEM;
+	}
+
+	/* Set the internal oob buffer location, just after the page data */
+	chip->oob_poi = chip->buffers->databuf + mtd->writesize;
+
+	if (!chip->write_page)
+		chip->write_page = nand_write_page;
+
+	/* Initialize ECC struct */
+	ret = nand_ecc_ctrl_init(mtd, ecc);
+	if (ret) {
+		if (!(chip->options & NAND_OWN_BUFFERS))
+			kfree(chip->buffers);
+
+		return ret;
+	}
+
 	/* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
 	if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
 		switch (ecc->steps) {
Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
author
#17 lore raw

RFC 6/11 mtd/nand: Add randomisation layer

In reply to Roy Spliet

Based on BBrezillons work, minus per-partition support. Changes to support that would be quite invasive while it hasn't been solved yet for Linux.

---
 drivers/mtd/nand/nand_base.c | 255 ++++++++++++++++++++++++++++++++++---------
 include/linux/mtd/nand.h     |  96 ++++++++++++++++
 2 files changed, 299 insertions(+), 52 deletions(-)
drivers/mtd/nand/nand_base.c +203 -52
index 83586cc..5196c0c 100644
@@ -1185,6 +1185,62 @@ EXPORT_SYMBOL(nand_lock);
 #endif
 
 /**
+ * nand_rnd_is_activ - check wether a region of a NAND page requires NAND
+ *		       randomizer to be disabled
+ * @mtd:	mtd info
+ * @page:	NAND page
+ * @column:	offset within the page
+ * @len:	len of the region
+ *
+ * Returns 1 if the randomizer should be enabled, 0 if not, or -ERR in case of
+ * error.
+ *
+ * In case of success len will contain the size of the region:
+ *  - if the requested region fits in a NAND random region len will not change
+ *  - else len will be replaced by the available length within the NAND random
+ *    region
+ */
+int nand_rnd_is_activ(struct mtd_info *mtd, int page, int column, int *len)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct nand_rnd_layout *layout = chip->rnd.layout;
+	struct nand_rndfree *range;
+	int ret = 1;
+	int tmp;
+	int i;
+
+	if (!len || *len < 0 || column < 0 ||
+	    column + *len > mtd->writesize + mtd->oobsize)
+		return -EINVAL;
+
+	if (layout) {
+		for (i = 0; i < layout->nranges; i++) {
+			range = &layout->ranges[i];
+			if (column + *len <= range->offset) {
+				break;
+			} else if (column >= range->offset + range->length) {
+				continue;
+			} else if (column < range->offset) {
+				tmp = range->offset - column;
+				if (*len > tmp)
+					*len = tmp;
+				break;
+			} else {
+				tmp = range->offset + range->length - column;
+				if (*len > tmp)
+					*len = tmp;
+				ret = 0;
+				break;
+			}
+
+		}
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(nand_rnd_is_activ);
+
+/**
  * nand_page_is_empty - check wether a NAND page contains only FFs
  * @mtd:	mtd info
  * @data:	data buffer
@@ -1329,9 +1385,13 @@ EXPORT_SYMBOL(nand_pst_create);
 static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 			      uint8_t *buf, int oob_required, int page)
 {
-	chip->read_buf(mtd, buf, mtd->writesize);
-	if (oob_required)
-		chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	nand_rnd_config(mtd, page, 0, NAND_RND_READ);
+	nand_rnd_read_buf(mtd, buf, mtd->writesize);
+	if (oob_required){
+		nand_rnd_config(mtd, page, mtd->writesize, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	}
+	nand_rnd_config(mtd, -1, -1, NAND_RND_READ);
 	return 0;
 }
 
@@ -1352,29 +1412,40 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
 	int eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
 	uint8_t *oob = chip->oob_poi;
-	int steps, size;
+	int steps, size, column = 0;
 
 	for (steps = chip->ecc.steps; steps > 0; steps--) {
-		chip->read_buf(mtd, buf, eccsize);
+		nand_rnd_config(mtd, page, column, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, buf, eccsize);
 		buf += eccsize;
+		column += eccsize;
 
 		if (chip->ecc.prepad) {
-			chip->read_buf(mtd, oob, chip->ecc.prepad);
+			nand_rnd_config(mtd, page, column, NAND_RND_READ);
+			nand_rnd_read_buf(mtd, oob, chip->ecc.prepad);
 			oob += chip->ecc.prepad;
+			column += chip->ecc.prepad;
 		}
 
-		chip->read_buf(mtd, oob, eccbytes);
+		nand_rnd_config(mtd, page, column, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, oob, eccbytes);
 		oob += eccbytes;
+		column += eccbytes;
 
 		if (chip->ecc.postpad) {
-			chip->read_buf(mtd, oob, chip->ecc.postpad);
+			nand_rnd_config(mtd, page, column, NAND_RND_READ);
+			nand_rnd_read_buf(mtd, oob, chip->ecc.postpad);
 			oob += chip->ecc.postpad;
+			column += chip->ecc.postpad;
 		}
 	}
 
 	size = mtd->oobsize - (oob - chip->oob_poi);
-	if (size)
-		chip->read_buf(mtd, oob, size);
+	if (size) {
+		nand_rnd_config(mtd, page, column, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, oob, size);
+	}
+	nand_rnd_config(mtd, -1, -1, NAND_RND_READ);
 
 	return 0;
 }
@@ -1462,7 +1533,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1);
 
 	p = bufpoi + data_col_addr;
-	chip->read_buf(mtd, p, datafrag_len);
+	nand_rnd_config(mtd, -1, data_col_addr, NAND_RND_READ);
+	nand_rnd_read_buf(mtd, p, datafrag_len);
 
 	/* Calculate ECC */
 	for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
@@ -1481,7 +1553,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 	if (gaps) {
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
-		chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+		nand_rnd_config(mtd, -1, mtd->writesize, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 	} else {
 		/*
 		 * Send the command to read the particular ECC bytes take care
@@ -1496,7 +1569,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
 					mtd->writesize + aligned_pos, -1);
-		chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
+		nand_rnd_config(mtd, -1, mtd->writesize + aligned_pos, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
 	}
 
 	for (i = 0; i < eccfrag_len; i++)
@@ -1515,6 +1589,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 			max_bitflips = max_t(unsigned int, max_bitflips, stat);
 		}
 	}
+	nand_rnd_config(mtd, -1, -1, NAND_RND_READ);
+
 	return max_bitflips;
 }
 
@@ -1539,13 +1615,17 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *ecc_code = chip->buffers->ecccode;
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	unsigned int max_bitflips = 0;
+	int column = 0;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		chip->ecc.hwctl(mtd, NAND_ECC_READ);
-		chip->read_buf(mtd, p, eccsize);
+		nand_rnd_config(mtd, page, column, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, p, eccsize);
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+		column += eccsize;
 	}
-	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	nand_rnd_config(mtd, page, column, NAND_RND_READ);
+	nand_rnd_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 	for (i = 0; i < chip->ecc.total; i++)
 		ecc_code[i] = chip->oob_poi[eccpos[i]];
@@ -1564,6 +1644,8 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 			max_bitflips = max_t(unsigned int, max_bitflips, stat);
 		}
 	}
+	nand_rnd_config(mtd, -1, -1, NAND_RND_READ);
+
 	return max_bitflips;
 }
 
@@ -1592,11 +1674,14 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	unsigned int max_bitflips = 0;
+	int column = 0;
 
 	/* Read the OOB area first */
 	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
-	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	nand_rnd_config(mtd, page, mtd->writesize, NAND_RND_READ);
+	nand_rnd_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+	column = 0;
 
 	for (i = 0; i < chip->ecc.total; i++)
 		ecc_code[i] = chip->oob_poi[eccpos[i]];
@@ -1605,7 +1690,8 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 		int stat;
 
 		chip->ecc.hwctl(mtd, NAND_ECC_READ);
-		chip->read_buf(mtd, p, eccsize);
+		nand_rnd_config(mtd, page, column, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, p, eccsize);
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
@@ -1616,6 +1702,8 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 			max_bitflips = max_t(unsigned int, max_bitflips, stat);
 		}
 	}
+	nand_rnd_config(mtd, -1, -1, NAND_RND_READ);
+
 	return max_bitflips;
 }
 
@@ -1639,20 +1727,26 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *p = buf;
 	uint8_t *oob = chip->oob_poi;
 	unsigned int max_bitflips = 0;
+	int column = 0;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		int stat;
 
 		chip->ecc.hwctl(mtd, NAND_ECC_READ);
-		chip->read_buf(mtd, p, eccsize);
+		nand_rnd_config(mtd, page, column, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, p, eccsize);
+		column += eccsize;
 
 		if (chip->ecc.prepad) {
-			chip->read_buf(mtd, oob, chip->ecc.prepad);
+			nand_rnd_config(mtd, page, column, NAND_RND_READ);
+			nand_rnd_read_buf(mtd, oob, chip->ecc.prepad);
 			oob += chip->ecc.prepad;
 		}
 
 		chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
-		chip->read_buf(mtd, oob, eccbytes);
+		nand_rnd_config(mtd, page, column, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, oob, eccbytes);
+		column += eccbytes;
 		stat = chip->ecc.correct(mtd, p, oob, NULL);
 
 		if (stat < 0) {
@@ -1665,15 +1759,20 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 		oob += eccbytes;
 
 		if (chip->ecc.postpad) {
-			chip->read_buf(mtd, oob, chip->ecc.postpad);
+			nand_rnd_config(mtd, page, column, NAND_RND_READ);
+			nand_rnd_read_buf(mtd, oob, chip->ecc.postpad);
+			column += chip->ecc.postpad;
 			oob += chip->ecc.postpad;
 		}
 	}
 
 	/* Calculate remaining oob bytes */
 	i = mtd->oobsize - (oob - chip->oob_poi);
-	if (i)
-		chip->read_buf(mtd, oob, i);
+	if (i) {
+		nand_rnd_config(mtd, page, column, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, oob, i);
+	}
+	nand_rnd_config(mtd, -1, -1, NAND_RND_READ);
 
 	return max_bitflips;
 }
@@ -1685,9 +1784,11 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
  * @ops: oob ops structure
  * @len: size of oob to transfer
  */
-static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
+static uint8_t *nand_transfer_oob(struct mtd_info *mtd, uint8_t *oob,
 				  struct mtd_oob_ops *ops, size_t len)
 {
+	struct nand_chip *chip = mtd->priv;
+
 	switch (ops->mode) {
 
 	case MTD_OPS_PLACE_OOB:
@@ -1804,6 +1905,7 @@ read_retry:
 			 * Now read the page into the buffer.  Absent an error,
 			 * the read methods return max bitflips per ecc step.
 			 */
+			nand_rnd_config(mtd, page, -1, NAND_RND_READ);
 			if (unlikely(ops->mode == MTD_OPS_RAW))
 				ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
 							      oob_required,
@@ -1816,6 +1918,8 @@ read_retry:
 			else
 				ret = chip->ecc.read_page(mtd, chip, bufpoi,
 							  oob_required, page);
+			nand_rnd_config(mtd, -1, -1, NAND_RND_READ);
+
 			if (ret < 0) {
 				if (!aligned)
 					/* Invalidate page cache */
@@ -1843,7 +1947,7 @@ read_retry:
 				int toread = min(oobreadlen, max_oobsize);
 
 				if (toread) {
-					oob = nand_transfer_oob(chip,
+					oob = nand_transfer_oob(mtd,
 						oob, ops, toread);
 					oobreadlen -= toread;
 				}
@@ -1960,7 +2064,9 @@ static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
 			     int page)
 {
 	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
-	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	nand_rnd_config(mtd, page, mtd->writesize, NAND_RND_READ);
+	nand_rnd_read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	nand_rnd_config(mtd, -1, -1, NAND_RND_READ);
 	return 0;
 }
 
@@ -1979,7 +2085,7 @@ static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 	int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
 	int eccsize = chip->ecc.size;
 	uint8_t *bufpoi = buf;
-	int i, toread, sndrnd = 0, pos;
+	int i, toread, sndrnd = 0, pos = eccsize;
 
 	chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page);
 	for (i = 0; i < chip->ecc.steps; i++) {
@@ -1992,12 +2098,17 @@ static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 		} else
 			sndrnd = 1;
 		toread = min_t(int, length, chunk);
-		chip->read_buf(mtd, bufpoi, toread);
+		nand_rnd_config(mtd, page, pos, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, bufpoi, toread);
 		bufpoi += toread;
 		length -= toread;
 	}
-	if (length > 0)
-		chip->read_buf(mtd, bufpoi, length);
+	if (length > 0){
+		pos = mtd->writesize + mtd->oobsize - length;
+		nand_rnd_config(mtd, page, pos, NAND_RND_READ);
+		nand_rnd_read_buf(mtd, bufpoi, length);
+	}
+	nand_rnd_config(mtd, -1, -1, NAND_RND_READ);
 
 	return 0;
 }
@@ -2016,7 +2127,9 @@ static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
 	int length = mtd->oobsize;
 
 	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
-	chip->write_buf(mtd, buf, length);
+	nand_rnd_config(mtd, page, mtd->writesize, NAND_RND_WRITE);
+	nand_rnd_write_buf(mtd, buf, length);
+	nand_rnd_config(mtd, -1, -1, NAND_RND_WRITE);
 	/* Send command to program the OOB data */
 	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 
@@ -2071,12 +2184,18 @@ static int nand_write_oob_syndrome(struct mtd_info *mtd,
 		} else
 			sndcmd = 1;
 		len = min_t(int, length, chunk);
-		chip->write_buf(mtd, bufpoi, len);
+		nand_rnd_config(mtd, page, pos, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, bufpoi, len);
 		bufpoi += len;
 		length -= len;
 	}
-	if (length > 0)
-		chip->write_buf(mtd, bufpoi, length);
+
+	if (length > 0){
+		pos = mtd->writesize + mtd->oobsize - length;
+		nand_rnd_config(mtd, page, pos, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, bufpoi, length);
+	}
+	nand_rnd_config(mtd, -1, -1, NAND_RND_WRITE);
 
 	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 	status = chip->waitfunc(mtd, chip);
@@ -2147,7 +2266,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 			break;
 
 		len = min(len, readlen);
-		buf = nand_transfer_oob(chip, buf, ops, len);
+		buf = nand_transfer_oob(mtd, buf, ops, len);
 
 		if (chip->options & NAND_NEED_READRDY) {
 			/* Apply delay or wait for ready/busy pin */
@@ -2265,29 +2384,39 @@ static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
 	int eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
 	uint8_t *oob = chip->oob_poi;
-	int steps, size;
+	int steps, size, column = 0;
 
 	for (steps = chip->ecc.steps; steps > 0; steps--) {
-		chip->write_buf(mtd, buf, eccsize);
+		nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, buf, eccsize);
 		buf += eccsize;
+		column += eccsize;
 
 		if (chip->ecc.prepad) {
-			chip->write_buf(mtd, oob, chip->ecc.prepad);
+			nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+			nand_rnd_write_buf(mtd, oob, chip->ecc.prepad);
 			oob += chip->ecc.prepad;
+			column += chip->ecc.prepad;
 		}
 
-		chip->write_buf(mtd, oob, eccbytes);
+		nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, oob, eccbytes);
 		oob += eccbytes;
+		column += eccbytes;
 
 		if (chip->ecc.postpad) {
-			chip->write_buf(mtd, oob, chip->ecc.postpad);
+			nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+			nand_rnd_write_buf(mtd, oob, chip->ecc.postpad);
 			oob += chip->ecc.postpad;
+			column += chip->ecc.postpad;
 		}
 	}
 
 	size = mtd->oobsize - (oob - chip->oob_poi);
-	if (size)
-		chip->write_buf(mtd, oob, size);
+	if (size) {
+		nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, oob, size);
+	}
 
 	return 0;
 }
@@ -2334,17 +2463,21 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	const uint8_t *p = buf;
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	int column = 0;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
-		chip->write_buf(mtd, p, eccsize);
+		nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, p, eccsize);
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+		column += eccsize;
 	}
 
 	for (i = 0; i < chip->ecc.total; i++)
 		chip->oob_poi[eccpos[i]] = ecc_calc[i];
 
-	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+	nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+	nand_rnd_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 	return 0;
 }
@@ -2380,7 +2513,10 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
 
 		/* write data (untouched subpages already masked by 0xFF) */
-		chip->write_buf(mtd, buf, ecc_size);
+		nand_rnd_config(mtd, -1, offset, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, buf, ecc_size);
+		offset += ecc_size;
+
 
 		/* mask ECC of un-touched subpages by padding 0xFF */
 		if ((step < start_step) || (step > end_step))
@@ -2405,7 +2541,8 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 		chip->oob_poi[eccpos[i]] = ecc_calc[i];
 
 	/* write OOB buffer to NAND device */
-	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+	nand_rnd_config(mtd, -1, offset, NAND_RND_WRITE);
+	nand_rnd_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 	return 0;
 }
@@ -2430,31 +2567,42 @@ static int nand_write_page_syndrome(struct mtd_info *mtd,
 	int eccsteps = chip->ecc.steps;
 	const uint8_t *p = buf;
 	uint8_t *oob = chip->oob_poi;
+	int column = 0;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 
 		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
-		chip->write_buf(mtd, p, eccsize);
+		nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, p, eccsize);
+		column += eccsize;
 
 		if (chip->ecc.prepad) {
-			chip->write_buf(mtd, oob, chip->ecc.prepad);
+			nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+			nand_rnd_write_buf(mtd, oob, chip->ecc.prepad);
 			oob += chip->ecc.prepad;
+			column += chip->ecc.prepad;
 		}
 
 		chip->ecc.calculate(mtd, p, oob);
-		chip->write_buf(mtd, oob, eccbytes);
+		nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, oob, eccbytes);
 		oob += eccbytes;
+		column += eccbytes;
 
 		if (chip->ecc.postpad) {
-			chip->write_buf(mtd, oob, chip->ecc.postpad);
+			nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+			nand_rnd_write_buf(mtd, oob, chip->ecc.postpad);
 			oob += chip->ecc.postpad;
+			column += chip->ecc.postpad;
 		}
 	}
 
 	/* Calculate remaining oob bytes */
 	i = mtd->oobsize - (oob - chip->oob_poi);
-	if (i)
-		chip->write_buf(mtd, oob, i);
+	if (i) {
+		nand_rnd_config(mtd, -1, column, NAND_RND_WRITE);
+		nand_rnd_write_buf(mtd, oob, i);
+	}
 
 	return 0;
 }
@@ -2485,6 +2633,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 
+	nand_rnd_config(mtd, page, 0, NAND_RND_WRITE);
 	if (unlikely(raw))
 		status = chip->ecc.write_page_raw(mtd, chip, buf,
 							oob_required);
@@ -2494,6 +2643,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 	else
 		status = chip->ecc.write_page(mtd, chip, buf, oob_required);
 
+	nand_rnd_config(mtd, -1, -1, NAND_RND_WRITE);
+
 	if (status < 0)
 		return status;
 
include/linux/mtd/nand.h +96 -0

114 lines not on this page · raw message

Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#18 lore raw

RFC 6/11 mtd/nand: Add randomisation layer

Quoted 2 lines · On Fri, 5 Jun 2015 13:52:39 +0200 Roy Spliet <[email protected]> wrote:

Based on BBrezillons work, minus per-partition support. Changes to support that would be quite invasive while it hasn't been solved yet for Linux.

Same comment as in other patches: this work hasn't been accepted yet in mainline Linux, so maybe we should keep this code in the sunxi-nand driver until it is merged in Linux.

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
author
#19 lore raw

RFC 7/11 mtd/nand Add Sunxi NAND driver

In reply to Roy Spliet

Heavily based on BBrezillon's (downstream) driver. Most noticable differences
- No per-partition ECC settings. Partitions in U-boot are quite different from Linux
- U-boot register definitions, shared with sunxi_nand_spl
- FDT parsing in-line, there's no framework method yet

---
 arch/arm/include/asm/arch-sunxi/nand.h |   46 +-
 board/sunxi/board.c                    |    5 +
 drivers/mtd/nand/Makefile              |    1 +
 drivers/mtd/nand/sunxi_nand.c          | 1887 ++++++++++++++++++++++++++++++++
 include/fdtdec.h                       |   13 +
 lib/fdtdec.c                           |   17 +
 6 files changed, 1966 insertions(+), 3 deletions(-)
 create mode 100644 drivers/mtd/nand/sunxi_nand.c
arch/arm/include/asm/arch-sunxi/nand.h +43 -3
index 22844d8..d0fae80 100644
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2015 Roy Spliet <[email protected]>
+ * (C) Copyright 2015 Roy Spliet <[email protected]>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -27,8 +27,7 @@ struct sunxi_nand
 	u32 ecc_ctl;		/* 0x034 ECC configure and control */
 	u32 ecc_st;		/* 0x038 ECC status and operation info */
 	u32 efr;		/* 0x03C Enhanced feature */
-	u32 err_cnt0;		/* 0x040 Corrected error bit counter 0 */
-	u32 err_cnt1;		/* 0x044 Corrected error bit counter 1 */
+	u32 err_cnt[4];		/* 0x040[4] Corrected error bit counter 0 */
 	u32 user_data[16];	/* 0x050[16] User data field */
 	u32 efnand_st;		/* 0x090 EFNAND status */
 	u32 res0[3];
@@ -40,28 +39,69 @@ struct sunxi_nand
 	u32 res1[3];
 	u32 mdma_addr;		/* 0x0C0 MBUS DMA Address */
 	u32 mdma_cnt;		/* 0x0C4 MBUS DMA data counter */
+	u32 res2[206];
+	u32 ram0_base;
 };
 
 #define SUNXI_NAND_CTL_EN			(1 << 0)
 #define SUNXI_NAND_CTL_RST			(1 << 1)
+#define SUNXI_NAND_BUS_WIDTH			(1 << 2)
+#define SUNXI_NAND_CTL_RB_SEL_MASK		(0x3 << 3)
+#define SUNXI_NAND_CTL_RB_SEL(a)		((a) << 3)
+#define SUNXI_NAND_CTL_CE_ACT			(1 << 6)
+#define SUNXI_NAND_CTL_PAGE_SIZE_MASK		(0xf << 8)
 #define SUNXI_NAND_CTL_PAGE_SIZE(a)		((fls(a) - 11) << 8)
 #define SUNXI_NAND_CTL_RAM_METHOD_DMA		(1 << 14)
+#define SUNXI_NAND_CTL_CE_SEL_MASK		(0xf << 24)
+#define SUNXI_NAND_CTL_CE_SEL(a)		(a << 24)
+#define SUNXI_NAND_CTL_DEBUG			(1 << 31)
 
+#define SUNXI_NAND_ST_RB_B2R			(1 << 0)
 #define SUNXI_NAND_ST_CMD_INT			(1 << 1)
 #define SUNXI_NAND_ST_DMA_INT			(1 << 2)
 #define SUNXI_NAND_ST_FIFO_FULL			(1 << 3)
+#define SUNXI_NAND_ST_BUSY			(1 << 4)
+#define SUNXI_NAND_ST_RB_STATE0			(1 << 8)
+#define SUNXI_NAND_ST_RB_STATE1			(1 << 9)
+#define SUNXI_NAND_ST_RB_STATE2			(1 << 10)
+#define SUNXI_NAND_ST_RB_STATE3			(1 << 11)
 
+
+#define SUNXI_NAND_INT_B2R_ENABLE		(1 << 0)
+#define SUNXI_NAND_INT_CMD_ENABLE		(1 << 1)
+#define SUNXI_NAND_INT_DMA_ENABLE		(1 << 2)
+#define SUNXI_NAND_INT_MASK	(SUNXI_NAND_INT_B2R_ENABLE | \
+				 SUNXI_NAND_INT_CMD_ENABLE | \
+				 SUNXI_NAND_INT_DMA_ENABLE)
+
+#define SUNXI_NAND_CMD_LOW_BYTE(a)		(a & 0xff)
+#define SUNXI_NAND_CMD_HIGH_BYTE(a)		((a & 0xff) << 8)
 #define SUNXI_NAND_CMD_ADDR_CYCLES(a)		((a - 1) << 16);
+#define SUNXI_NAND_CMD_SEND_ADR			(1 << 19)
+#define SUNXI_NAND_CMD_ACCESS_RD		0
+#define SUNXI_NAND_CMD_ACCESS_WR		(1 << 20)
+#define SUNXI_NAND_CMD_DATA_TRANS		(1 << 21)
 #define SUNXI_NAND_CMD_SEND_CMD1		(1 << 22)
 #define SUNXI_NAND_CMD_WAIT_FLAG		(1 << 23)
+#define SUNXI_NAND_CMD_SEND_CMD2		(1 << 24)
 #define SUNXI_NAND_CMD_ORDER_INTERLEAVE		0
 #define SUNXI_NAND_CMD_ORDER_SEQ		(1 << 25)
+#define SUNXI_NAND_CMD_DATA_SWAP_METHOD		(1 << 26)
+#define SUNXI_NAND_CMD_ROW_AUTO_INC		(1 << 27)
+#define SUNXI_NAND_CMD_SEND_CMD3		(1 << 28)
+#define SUNXI_NAND_CMD_SEND_CMD4		(1 << 29)
 
 #define SUNXI_NAND_ECC_CTL_ECC_EN		(1 << 0)
 #define SUNXI_NAND_ECC_CTL_PIPELINE		(1 << 3)
+#define SUNXI_NAND_ECC_CTL_EXCEPTION		(1 << 4)
 #define SUNXI_NAND_ECC_CTL_BS_512B		(1 << 5)
 #define SUNXI_NAND_ECC_CTL_RND_EN		(1 << 9)
+#define SUNXI_NAND_ECC_CTL_RND_DIRECTION	(1 << 10)
+#define SUNXI_NAND_ECC_CTL_MODE_MASK		(0xf << 12)
 #define SUNXI_NAND_ECC_CTL_MODE(a)		((a) << 12)
+#define SUNXI_NAND_ECC_CTL_RND_SEED_MASK	(0xffff << 16)
 #define SUNXI_NAND_ECC_CTL_RND_SEED(a)		((a) << 16)
 
+extern void sunxi_nand_init(void);
+
 #endif /* _SUNXI_NAND_H */
board/sunxi/board.c +5 -0
index d5bed30..e37209d 100644
@@ -31,6 +31,7 @@
 #include <asm/arch/dram.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
+#include <asm/arch/nand.h>
 #include <asm/arch/usb_phy.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
@@ -329,6 +330,10 @@ void board_nand_init(void)
 
 	for (pin = 0; pin < ARRAY_SIZE(ports); pin++)
 		sunxi_gpio_set_cfgpin(SUNXI_GPC(ports[pin]), SUNXI_GPC_NAND);
+
+#ifndef CONFIG_SPL_BUILD
+	sunxi_nand_init();
+#endif
 }
 
 void i2c_init_board(void)
drivers/mtd/nand/Makefile +1 -0
index f194493..c2368bc 100644
@@ -66,6 +66,7 @@ obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
 obj-$(CONFIG_NAND_PLAT) += nand_plat.o
 obj-$(CONFIG_NAND_DOCG4) += docg4.o
+obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o
 
 else  # minimal SPL drivers
 
drivers/mtd/nand/sunxi_nand.c new file +1887 -0

1,887 lines not on this page · raw message

include/fdtdec.h +13 -0
index 6590470..c0662d9 100644
@@ -177,6 +177,7 @@ enum fdt_compat_id {
 	COMPAT_INTEL_QRK_MRC,		/* Intel Quark MRC */
 	COMPAT_SOCIONEXT_XHCI,		/* Socionext UniPhier xHCI */
 	COMPAT_INTEL_PCH,		/* Intel PCH */
+	COMPAT_SUNXI_NAND,		/* SUNXI NAND controller */
 
 	COMPAT_COUNT,
 };
@@ -567,6 +568,18 @@ const char *fdtdec_get_compatible(enum fdt_compat_id id);
 int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name);
 
 /**
+ * @param blob		FDT blob
+ * @param node		node to examine
+ * @param prop_name	name of property to find
+ * @param array		array to fill with data
+ * @param count		number of array elements
+ * @return 0 if ok, or -FDT_ERR_NOTFOUND if the property is not found,
+ *		or -FDT_ERR_BADLAYOUT if not enough data
+ */
+int fdtdec_get_u16_array(const void *blob, int node, const char *prop_name,
+		u16 *array, int count);
+
+/**
  * Look up a property in a node and return its contents in an integer
  * array of given length. The property must have at least enough data for
  * the array (4*count bytes). It may have more, but this will be ignored.
lib/fdtdec.c +17 -0
index 80b897a..45dc9fd 100644
@@ -76,6 +76,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
 	COMPAT(SOCIONEXT_XHCI, "socionext,uniphier-xhci"),
 	COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"),
+	COMPAT(COMPAT_SUNXI_NAND, "allwinner,sun4i-nand"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
@@ -618,6 +619,22 @@ static const void *get_prop_check_min_len(const void *blob, int node,
 	return cell;
 }
 
+int fdtdec_get_u16_array(const void *blob, int node, const char *prop_name,
+		u16 *array, int count)
+{
+	const u16 *cell;
+	int i, err = 0;
+
+	debug("%s: %s\n", __func__, prop_name);
+	cell = get_prop_check_min_len(blob, node, prop_name,
+				      sizeof(u16) * count, &err);
+	if (!err) {
+		for (i = 0; i < count; i++)
+			array[i] =  be16_to_cpu(cell[i]);
+	}
+	return err;
+}
+
 int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
 		u32 *array, int count)
 {
Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#20 lore raw

RFC 7/11 mtd/nand Add Sunxi NAND driver

Quoted 7 lines · On Fri, 5 Jun 2015 13:52:40 +0200 Roy Spliet <[email protected]> wrote:

Heavily based on BBrezillon's (downstream) driver. Most noticable differences
- No per-partition ECC settings. Partitions in U-boot are quite different from Linux
- U-boot register definitions, shared with sunxi_nand_spl
- FDT parsing in-line, there's no framework method yet

I'll try to review this driver next week.

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#21 lore raw

RFC 7/11 mtd/nand Add Sunxi NAND driver

Quoted 11 lines · On Sun, 14 Jun 2015 13:42:12 +0200 Boris Brezillon…
Quoted 7 lines · On Fri, 5 Jun 2015 13:52:40 +0200 Roy Spliet <[email protected]> wrote:

Heavily based on BBrezillon's (downstream) driver. Most noticable differences
- No per-partition ECC settings. Partitions in U-boot are quite different from Linux
- U-boot register definitions, shared with sunxi_nand_spl
- FDT parsing in-line, there's no framework method yet

Quoted 2 lines

I'll try to review this driver next week.

BTW, I don't know if you've based you work on Yassin's work, but if that's the case, then you should at least mention it in the license header, and maybe you should consider adding a S-o-B line with his name.

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
author
#22 lore raw

RFC 8/11 mtd/nand: Add DT definitions for Olimex Lime

In reply to Roy Spliet
---
 arch/arm/dts/sun7i-a20-olinuxino-lime.dts | 41 ++++++++++++++
 arch/arm/dts/sun7i-a20.dtsi               | 90 +++++++++++++++++++++++++++++++
 2 files changed, 131 insertions(+)
arch/arm/dts/sun7i-a20-olinuxino-lime.dts +41 -0
index 6592cb2..cc5e65d 100644
@@ -181,3 +181,44 @@
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
 };
+
+&nfc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+	status = "okay";
+
+	nand at 0 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		reg = <0>;
+		allwinner,rb = <0>;
+		nand-ecc-mode = "hw";
+		nand-ecc-strength = <40>;
+		nand-ecc-step-size = <1024>;
+		nand-rnd-mode = "hw";
+		nand-randomizer-seeds = /bits/ 16 <
+			0x2b75 0x0bd0 0x5ca3 0x62d1 0x1c93 0x07e9 0x2162 0x3a72
+			0x0d67 0x67f9 0x1be7 0x077d 0x032f 0x0dac 0x2716 0x2436
+			0x7922 0x1510 0x3860 0x5287 0x480f 0x4252 0x1789 0x5a2d
+			0x2a49 0x5e10 0x437f 0x4b4e 0x2f45 0x216e 0x5cb7 0x7130
+			0x2a3f 0x60e4 0x4dc9 0x0ef0 0x0f52 0x1bb9 0x6211 0x7a56
+			0x226d 0x4ea7 0x6f36 0x3692 0x38bf 0x0c62 0x05eb 0x4c55
+			0x60f4 0x728c 0x3b6f 0x2037 0x7f69 0x0936 0x651a 0x4ceb
+			0x6218 0x79f3 0x383f 0x18d9 0x4f05 0x5c82 0x2912 0x6f17
+			0x6856 0x5938 0x1007 0x61ab 0x3e7f 0x57c2 0x542f 0x4f62
+			0x7454 0x2eac 0x7739 0x42d4 0x2f90 0x435a 0x2e52 0x2064
+			0x637c 0x66ad 0x2c90 0x0bad 0x759c 0x0029 0x0986 0x7126
+			0x1ca7 0x1605 0x386a 0x27f5 0x1380 0x6d75 0x24c3 0x0f8e
+			0x2b7a 0x1418 0x1fd1 0x7dc1 0x2d8e 0x43af 0x2267 0x7da3
+			0x4e3d 0x1338 0x50db 0x454d 0x764d 0x40a3 0x42e6 0x262b
+			0x2d2e 0x1aea 0x2e17 0x173d 0x3a6e 0x71bf 0x25f9 0x0a5d
+			0x7c57 0x0fbe 0x46ce 0x4939 0x6b17 0x37bb 0x3e91 0x76db>;
+		onfi,nand-timing-mode = <0x1f>;
+/*
+		main at 400000 {
+			label = "main";
+			reg = /bits/ 64 <0x400000 0xffc00000>;
+		};
+*/
+	};
+};
arch/arm/dts/sun7i-a20.dtsi +90 -0

102 lines not on this page · raw message

Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#23 lore raw

RFC 8/11 mtd/nand: Add DT definitions for Olimex Lime

Quoted 37 lines · On Fri, 5 Jun 2015 13:52:41 +0200 Roy Spliet <[email protected]> wrote:
---
 arch/arm/dts/sun7i-a20-olinuxino-lime.dts | 41 ++++++++++++++
 arch/arm/dts/sun7i-a20.dtsi               | 90 +++++++++++++++++++++++++++++++
 2 files changed, 131 insertions(+)
arch/arm/dts/sun7i-a20-olinuxino-lime.dts +23 -0
index 6592cb2..cc5e65d 100644
@@ -181,3 +181,44 @@
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
 };
+
+&nfc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+	status = "okay";
+
+	nand at 0 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		reg = <0>;
+		allwinner,rb = <0>;
+		nand-ecc-mode = "hw";
+		nand-ecc-strength = <40>;
+		nand-ecc-step-size = <1024>;
+		nand-rnd-mode = "hw";
+		nand-randomizer-seeds = /bits/ 16 <
+			0x2b75 0x0bd0 0x5ca3 0x62d1 0x1c93 0x07e9 0x2162 0x3a72
+			0x0d67 0x67f9 0x1be7 0x077d 0x032f 0x0dac 0x2716 0x2436
+			0x7922 0x1510 0x3860 0x5287 0x480f 0x4252 0x1789 0x5a2d
+			0x2a49 0x5e10 0x437f 0x4b4e 0x2f45 0x216e 0x5cb7 0x7130
+			0x2a3f 0x60e4 0x4dc9 0x0ef0 0x0f52 0x1bb9 0x6211 0x7a56
+			0x226d 0x4ea7 0x6f36 0x3692 0x38bf 0x0c62 0x05eb 0x4c55
+			0x60f4 0x728c 0x3b6f 0x2037 0x7f69 0x0936 0x651a 0x4ceb

arch/arm/dts/sun7i-a20-olinuxino-lime.dts line 216

Quoted 10 lines
arch/arm/dts/sun7i-a20-olinuxino-lime.dts +10 -0
+			0x6218 0x79f3 0x383f 0x18d9 0x4f05 0x5c82 0x2912 0x6f17
+			0x6856 0x5938 0x1007 0x61ab 0x3e7f 0x57c2 0x542f 0x4f62
+			0x7454 0x2eac 0x7739 0x42d4 0x2f90 0x435a 0x2e52 0x2064
+			0x637c 0x66ad 0x2c90 0x0bad 0x759c 0x0029 0x0986 0x7126
+			0x1ca7 0x1605 0x386a 0x27f5 0x1380 0x6d75 0x24c3 0x0f8e
+			0x2b7a 0x1418 0x1fd1 0x7dc1 0x2d8e 0x43af 0x2267 0x7da3
+			0x4e3d 0x1338 0x50db 0x454d 0x764d 0x40a3 0x42e6 0x262b
+			0x2d2e 0x1aea 0x2e17 0x173d 0x3a6e 0x71bf 0x25f9 0x0a5d
+			0x7c57 0x0fbe 0x46ce 0x4939 0x6b17 0x37bb 0x3e91 0x76db>;
+		onfi,nand-timing-mode = <0x1f>;

Can we use the same binding we have in mainline Linux (not my branch). In mainline, the onfi,nand-timing-mode has been dropped in favor of ONFI timing mode definition in the nand_ids table.
ECC strength and step size should also be extracted from the nand_ids table, unless you want to force something different (which doesn't seem to be the case here).
Moreover, the randomizer stuff haven't been reviewed/accepted yet. To support the randomizer stuff in the meantime, you could define the randomizer-seeds table in the board config header and use sunxi specific commands to select the randomizer mode and randomizer seeds table (if you have several tables).

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
author
#24 lore raw

RFC 9/11 sunxi/nand: Enable UBI and NAND commands

In reply to Roy Spliet
---
 board/sunxi/Kconfig            |  8 +++-----
 drivers/mtd/Makefile           |  1 +
 include/configs/sunxi-common.h | 33 +++++++++++++++++++++++++--------
 3 files changed, 29 insertions(+), 13 deletions(-)
board/sunxi/Kconfig +3 -5
index cf58d73..37bbd0f 100644
@@ -269,17 +269,15 @@ config MMC_SUNXI_SLOT_EXTRA
 	slot or emmc on mmc1 - mmc3. Setting this to 1, 2 or 3 will enable
 	support for this.
 
-config SPL_NAND_SUPPORT
-	bool "SPL/NAND mode support"
+config NAND_SUNXI
+	bool "NAND support"
 	depends on SPL
 	default n
 	---help---
 	  This enables support for booting from NAND internal
 	  memory. U-Boot SPL doesn't detect where is it load from,
 	  therefore this option is needed to properly load image from
-	  flash. Option also disables MMC functionality on U-Boot due to
-	  initialization errors encountered, when both controllers are
-	  enabled.
+	  flash.
 
 config USB0_VBUS_PIN
 	string "Vbus enable pin for usb0 (otg)"
drivers/mtd/Makefile +1 -0
index 5467a95..124b0f9 100644
@@ -18,3 +18,4 @@ obj-$(CONFIG_FTSMC020) += ftsmc020.o
 obj-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o
 obj-$(CONFIG_MW_EEPROM) += mw_eeprom.o
 obj-$(CONFIG_ST_SMI) += st_smi.o
+obj-$(CONFIG_MTD_UBI) += ubi/
include/configs/sunxi-common.h +25 -8
index cce0441..ec28c40 100644
@@ -113,7 +113,7 @@
 #endif
 
 /* 4MB of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (4 << 20))
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (64 << 20))
 
 /*
  * Miscellaneous configurable options
@@ -326,10 +326,31 @@ extern int soft_i2c_gpio_scl;
 #define CONFIG_ENV_IS_NOWHERE
 #endif
 
-#ifdef CONFIG_SPL_NAND_SUPPORT
+#ifdef CONFIG_NAND_SUNXI
+#ifndef CONFIG_NAND_SUNXI_GPC_PORTS
+#error "No NAND GPC ports defined, NAND unsupported"
+#endif /* CONFIG_NAND_SUNXI_GPC_PORTS */
 #define CONFIG_NAND
 #define CONFIG_SYS_NAND_SELF_INIT
-#define CONFIG_NAND_SUNXI
+#define CONFIG_SYS_MAX_NAND_DEVICE 8
+
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+
+/* Requirements for UBI */
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_MTD_DEVICE
+
+#define CONFIG_SPL_NAND_SUPPORT
+
+#define CONFIG_MTD_PARTITIONS
+/*
+#define CONFIG_MTD_DEBUG
+#define CONFIG_MTD_DEBUG_VERBOSE		MTD_DEBUG_LEVEL3
+*/
 #define CONFIG_CMD_SPL_WRITE_SIZE		0x000400
 #define CONFIG_SYS_NAND_U_BOOT_OFFS		0x008000
 
@@ -338,11 +359,7 @@ extern int soft_i2c_gpio_scl;
 #define CONFIG_NAND_SUNXI_ECC_STEP		1024
 #define CONFIG_NAND_SUNXI_ECC_STRENGTH		40
 #define CONFIG_NAND_SUNXI_ADDR_CYCLES		5
-
-#ifndef CONFIG_NAND_SUNXI_GPC_PORTS
-#error "No NAND GPC ports defined, NAND unsupported"
-#endif
-#endif /* CONFIG_SPL_NAND_SUPPORT */
+#endif /* CONFIG_NAND_SUNXI */
 
 #define CONFIG_MISC_INIT_R
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#25 lore raw

RFC 9/11 sunxi/nand: Enable UBI and NAND commands

Hi,

Quoted 46 lines · Roy Spliet
---
  board/sunxi/Kconfig            |  8 +++-----
  drivers/mtd/Makefile           |  1 +
  include/configs/sunxi-common.h | 33 +++++++++++++++++++++++++--------
  3 files changed, 29 insertions(+), 13 deletions(-)
board/sunxi/Kconfig +3 -5
index cf58d73..37bbd0f 100644
@@ -269,17 +269,15 @@ config MMC_SUNXI_SLOT_EXTRA
  	slot or emmc on mmc1 - mmc3. Setting this to 1, 2 or 3 will enable
  	support for this.
 
-config SPL_NAND_SUPPORT
-	bool "SPL/NAND mode support"
+config NAND_SUNXI
+	bool "NAND support"
  	depends on SPL
  	default n
  	---help---
  	  This enables support for booting from NAND internal
  	  memory. U-Boot SPL doesn't detect where is it load from,
  	  therefore this option is needed to properly load image from
-	  flash. Option also disables MMC functionality on U-Boot due to
-	  initialization errors encountered, when both controllers are
-	  enabled.
+	  flash.
 
  config USB0_VBUS_PIN
  	string "Vbus enable pin for usb0 (otg)"
drivers/mtd/Makefile +1 -0
index 5467a95..124b0f9 100644
@@ -18,3 +18,4 @@ obj-$(CONFIG_FTSMC020) += ftsmc020.o
  obj-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o
  obj-$(CONFIG_MW_EEPROM) += mw_eeprom.o
  obj-$(CONFIG_ST_SMI) += st_smi.o
+obj-$(CONFIG_MTD_UBI) += ubi/
include/configs/sunxi-common.h +0 -0
index cce0441..ec28c40 100644

include/configs/sunxi-common.h line 119

Quoted 8 lines
include/configs/sunxi-common.h +1 -1
@@ -113,7 +113,7 @@
  #endif
 
  /* 4MB of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (4 << 20))
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (64 << 20))
 
  /*
   * Miscellaneous configurable options

Please update the comment about malloc_pool size to match :)

Regards,

Hans

Quoted 48 lines
include/configs/sunxi-common.h +24 -7
@@ -326,10 +326,31 @@ extern int soft_i2c_gpio_scl;
  #define CONFIG_ENV_IS_NOWHERE
  #endif
 
-#ifdef CONFIG_SPL_NAND_SUPPORT
+#ifdef CONFIG_NAND_SUNXI
+#ifndef CONFIG_NAND_SUNXI_GPC_PORTS
+#error "No NAND GPC ports defined, NAND unsupported"
+#endif /* CONFIG_NAND_SUNXI_GPC_PORTS */
  #define CONFIG_NAND
  #define CONFIG_SYS_NAND_SELF_INIT
-#define CONFIG_NAND_SUNXI
+#define CONFIG_SYS_MAX_NAND_DEVICE 8
+
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+
+/* Requirements for UBI */
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_MTD_DEVICE
+
+#define CONFIG_SPL_NAND_SUPPORT
+
+#define CONFIG_MTD_PARTITIONS
+/*
+#define CONFIG_MTD_DEBUG
+#define CONFIG_MTD_DEBUG_VERBOSE		MTD_DEBUG_LEVEL3
+*/
  #define CONFIG_CMD_SPL_WRITE_SIZE		0x000400
  #define CONFIG_SYS_NAND_U_BOOT_OFFS		0x008000
 
@@ -338,11 +359,7 @@ extern int soft_i2c_gpio_scl;
  #define CONFIG_NAND_SUNXI_ECC_STEP		1024
  #define CONFIG_NAND_SUNXI_ECC_STRENGTH		40
  #define CONFIG_NAND_SUNXI_ADDR_CYCLES		5
-
-#ifndef CONFIG_NAND_SUNXI_GPC_PORTS
-#error "No NAND GPC ports defined, NAND unsupported"
-#endif
-#endif /* CONFIG_SPL_NAND_SUPPORT */
+#endif /* CONFIG_NAND_SUNXI */
 
  #define CONFIG_MISC_INIT_R
  #define CONFIG_SYS_CONSOLE_IS_IN_ENV
#26 lore raw

RFC 9/11 sunxi/nand: Enable UBI and NAND commands

Quoted 11 lines · Hans de Goede

include/configs/sunxi-common.h line 119

Quoted 9 lines
include/configs/sunxi-common.h +1 -1
@@ -113,7 +113,7 @@
  #endif
 
  /* 4MB of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (4 << 20))
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (64 << 20))
 
  /*
   * Miscellaneous configurable options

Please update the comment about malloc_pool size to match :)

...and explain in the commit log why this needs increasing as part of this change.

Ian.

author
#27 lore raw

RFC 9/11 sunxi/nand: Enable UBI and NAND commands

Oh yes, thanks for pointing this one out. I increased the malloc pool during debugging as google hinted towards UBI being rather memory-hungry, but forgot to double-check whether it was required. I just did, and as it turns out it really only needs to be increased to 8MiB for UBI to work in my set-up. As we have plenty of memory anyway, should I allocate some extra headroom for set-ups I haven't tested (e.g. many partitions, large bad-block tables etc.) and go for 16MiB instead?

Roy

Op 06-06-15 om 17:36 schreef Ian Campbell:

Quoted 16 lines · Hans de Goede
Quoted 10 lines

include/configs/sunxi-common.h line 119

Quoted 9 lines
include/configs/sunxi-common.h +1 -1
@@ -113,7 +113,7 @@
   #endif
 
   /* 4MB of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (4 << 20))
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (64 << 20))
 
   /*
    * Miscellaneous configurable options

Please update the comment about malloc_pool size to match :)

...and explain in the commit log why this needs increasing as part of this change.

Ian.

Signature · 6 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#28 lore raw

RFC 9/11 sunxi/nand: Enable UBI and NAND commands

On Mon, 2015-06-08 at 09:38 +0200, Roy Spliet wrote:

Please try and avoid sending HTML Mail as well as top posting.

Quoted 8 lines

Oh yes, thanks for pointing this one out. I increased the malloc pool during debugging as google hinted towards UBI being rather memory-hungry, but forgot to double-check whether it was required. I just did, and as it turns out it really only needs to be increased to 8MiB for UBI to work in my set-up. As we have plenty of memory anyway, should I allocate some extra headroom for set-ups I haven't tested (e.g. many partitions, large bad-block tables etc.) and go for 16MiB instead?

Either value WFM if the rationale for it is in the commit message.

Ian.

author
#29 lore raw

RFC 10/11 mtd/nand: Define bootcmd for nand

In reply to Roy Spliet

Assumes a UBI partition called boot

---
 include/config_distro_bootcmd.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
include/config_distro_bootcmd.h +26 -0
index 3a360ca4..361b914 100644
@@ -72,6 +72,21 @@
 	BOOT_TARGET_DEVICES_references_MMC_without_CONFIG_CMD_MMC
 #endif
 
+#ifdef CONFIG_CMD_NAND
+#define BOOTENV_DEV_NAND(devtypeu, devtypel, instance) \
+	"bootcmd_nand="                                                   \
+		"ubi part " #devtypel #instance "_main; "                 \
+		"ubifsmount ubi:boot; "                                   \
+		"run scan_ubifs_for_script\0"
+#define BOOTENV_DEV_NAME_NAND(devtypeu, devtypel, instance)	#devtypel " "
+#else
+#define BOOTENV_SHARED_NAND
+#define BOOTENV_DEV_NAND \
+	BOOT_TARGET_DEVICES_references_NAND_without_CONFIG_CMD_NAND
+#define BOOTENV_DEV_NAME_NAND \
+	BOOT_TARGET_DEVICES_references_NAND_without_CONFIG_CMD_NAND
+#endif
+
 #ifdef CONFIG_CMD_SATA
 #define BOOTENV_SHARED_SATA	BOOTENV_SHARED_BLKDEV(sata)
 #define BOOTENV_DEV_SATA	BOOTENV_DEV_BLKDEV
@@ -202,6 +217,17 @@
 			"echo SCRIPT FAILED: continuing...; "             \
 		"fi\0"                                                    \
 	\
+	"scan_ubifs_for_script="                                          \
+		"for script in ${boot_scripts}; do "                      \
+			"for prefix in ${boot_prefixes}; do "             \
+				"if ubifsload ${scriptaddr} "             \
+				"${prefix}${script}; then "               \
+					"echo Found U-Boot script "       \
+						"${prefix}${script}; "    \
+					"source ${scriptaddr}; "	  \
+				"fi; "                                    \
+			"done; "                                          \
+		"done\0"                                                  \
 	"boot_a_script="                                                  \
 		"load ${devtype} ${devnum}:${bootpart} "                  \
 			"${scriptaddr} ${prefix}${script}; "              \
Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
author
#30 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

In reply to Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
 include/configs/sunxi-common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +9 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
 	BOOT_TARGET_DEVICES_MMC(func) \
+	BOOT_TARGET_DEVICES_NAND(func) \
 	BOOT_TARGET_DEVICES_SCSI(func) \
 	BOOT_TARGET_DEVICES_USB(func) \
 	func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
 	MEM_LAYOUT_ENV_SETTINGS \
 	"fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
 	"console=ttyS0,115200\0" \
+	"mtdids=nand0=mtd2\0" \
+	"mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
 	BOOTENV
 
 #else /* ifndef CONFIG_SPL_BUILD */
Signature · 12 lines
2.4.2


-- 


IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#31 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Hello,

Quoted 28 lines · Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
 include/configs/sunxi-common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +7 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
        BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
        BOOT_TARGET_DEVICES_SCSI(func) \
        BOOT_TARGET_DEVICES_USB(func) \
        func(PXE, pxe, na) \

include/configs/sunxi-common.h extern int soft_i2c_gpio_scl; · line 453

Quoted 6 lines
include/configs/sunxi-common.h +2 -0
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
        MEM_LAYOUT_ENV_SETTINGS \
        "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
        "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
        BOOTENV

From what I heard the nand boot partition size should be specified in nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

I did not find any document regarding the nand boot partition layout so I would like to see some input from somebody familiar with the driver.

While it is fine for testing to hand-edit the environment the final nand support should have

1) way to express the boot partition size in nand pages
2) way to make the main partition start at the end of boot partition and extend to the end of the flash

This should probably also go to Linux.

Thanks

Michal

author
#32 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Hello Michal,

Op 07-06-15 om 18:48 schreef Michal Suchanek:

Quoted 32 lines

Hello,

Quoted 29 lines · Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
  include/configs/sunxi-common.h | 9 +++++++++
  1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +7 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
  #define BOOT_TARGET_DEVICES_USB(func)
  #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
  #define BOOT_TARGET_DEVICES(func) \
         BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
         BOOT_TARGET_DEVICES_SCSI(func) \
         BOOT_TARGET_DEVICES_USB(func) \
         func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
         MEM_LAYOUT_ENV_SETTINGS \
Quoted 8 lines

include/configs/sunxi-common.h extern int soft_i2c_gpio_scl; · line 453

Quoted 5 lines
include/configs/sunxi-common.h +2 -0
         "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
         "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
         BOOTENV

From what I heard the nand boot partition size should be specified in
nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Although I believe you have the facts mostly right, they do not apply in this situation.
What you are looking for is the partition definition for U-boot. At this point the boot
rom (BROM) is no longer active and thus it's inner workings are mostly irrelevant.
The NAND partition lay-out for the boards I have seen (various Olimex + Cubietruck..)
are as follows:
0-2MB U-Boot-SPL + U-Boot
2-4MB U-Boot SPL + U-Boot (for recovery)
4MB+ Main file system

The mtdparts env variable defines only the main file system because that's the only
place with relevant files for U-Boot.
This said: I have replaced the default file system with a "custom" UBI FS containing
just a boot and a rootfs partition. I am unsure whether these defaults apply for the
Android image that ships with the Olimex boards. But then again: that image also
ships with a boot-loader, so do we care?

Quoted 4 lines

I did not find any document regarding the nand boot partition layout so I would like to see some input from somebody familiar with the driver.

Quoted 8 lines

While it is fine for testing to hand-edit the environment the final nand support should have

1) way to express the boot partition size in nand pages
2) way to make the main partition start at the end of boot partition and extend to the end of the flash

This should probably also go to Linux.

Linux can define partitions in the device tree. I'd prefer to carry this approach to U-boot,
but current U-Boot has the partitioning part of the MTD code hacked away and replaced by
custom mtdparts code without OF support. Doing this proper requires getting rid of the
latter, which will likely break a lot of legacy. So as far as I agree, I have to warn that is
a longer-term project, extended further by the ongoing (justified) discussion we are having
regarding the MTD partitioning code in upstream Linux that may or may not lead to parts
of the framework being re-architected.

Roy

Quoted 3 lines

Thanks

Michal

Signature · 6 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#33 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Quoted 48 lines · Roy Spliet

Hello Michal,

Op 07-06-15 om 18:48 schreef Michal Suchanek:

Hello,

On 5 June 2015 at 13:52, Roy Spliet <[email protected]> wrote:

Based on the default layout of the android image used at least on Olimex Lime

---
 include/configs/sunxi-common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +9 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
        BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
        BOOT_TARGET_DEVICES_SCSI(func) \
        BOOT_TARGET_DEVICES_USB(func) \
        func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
        MEM_LAYOUT_ENV_SETTINGS \
        "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
        "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
        BOOTENV
 

From what I heard the nand boot partition size should be specified in nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Quoted 10 lines

Although I believe you have the facts mostly right, they do not apply in this situation.
What you are looking for is the partition definition for U-boot. At this point the boot
rom (BROM) is no longer active and thus it's inner workings are mostly irrelevant.
The NAND partition lay-out for the boards I have seen (various Olimex + Cubietruck..)
are as follows:
0-2MB U-Boot-SPL + U-Boot

OK, so 0-2 MB has to be read (at least in part) by brom to load the SPL so it must be in the format brom understands. The part containing the SPL which is read by brom has certain number of pages. The u-boot part can contain whatever we define.

Quoted 2 lines

2-4MB U-Boot SPL + U-Boot (for recovery)
4MB+ Main file system

The main filesystem has to be in format suitable for UBIFS. It has to follow u-boot part possibly with some space in between.

If support for non-uniform flash format is not available then there are basically two options:

1) SPL supports brom format and u-boot binary is part of boot partition. SPL can read/write itself and u-boot and u-boot can read/write the main partition

2) SPL and u-boot support the main partition format. While u-boot is written to the boot partition its pages are written in the format suitable for ubifs. This will get hairy when you want to actually write u-boot and SPL.

The problem with counting the partition sizes in bytes is obvious - whatever you do the brom reads predefined number of pages from the start of the nand to load the SPL and unless you know maximum page size of every nand ever made that is compatible with Allwinner brom you cannot tell what is even the maximum size of this part in bytes.

Thanks

Michal

author
#34 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Dear Michal,

Op 08-06-15 om 10:54 schreef Michal Suchanek:

Quoted 81 lines · Roy Spliet
Quoted 48 lines

Hello Michal,

Op 07-06-15 om 18:48 schreef Michal Suchanek:

Hello,

On 5 June 2015 at 13:52, Roy Spliet <[email protected]> wrote:

Based on the default layout of the android image used at least on Olimex Lime

---
  include/configs/sunxi-common.h | 9 +++++++++
  1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +9 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
  #define BOOT_TARGET_DEVICES_USB(func)
  #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
  #define BOOT_TARGET_DEVICES(func) \
         BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
         BOOT_TARGET_DEVICES_SCSI(func) \
         BOOT_TARGET_DEVICES_USB(func) \
         func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
         MEM_LAYOUT_ENV_SETTINGS \
         "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
         "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
         BOOTENV
 
 From what I heard the nand boot partition size should be specified in

nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Quoted 10 lines

Although I believe you have the facts mostly right, they do not apply in this situation.
What you are looking for is the partition definition for U-boot. At this point the boot
rom (BROM) is no longer active and thus it's inner workings are mostly irrelevant.
The NAND partition lay-out for the boards I have seen (various Olimex + Cubietruck..)
are as follows:
0-2MB U-Boot-SPL + U-Boot

OK, so 0-2 MB has to be read (at least in part) by brom to load the SPL so it must be in the format brom understands. The part containing the SPL which is read by brom has certain number of pages. The u-boot part can contain whatever we define.

Quoted 2 lines

2-4MB U-Boot SPL + U-Boot (for recovery)
4MB+ Main file system

The main filesystem has to be in format suitable for UBIFS. It has to follow u-boot part possibly with some space in between.

If support for non-uniform flash format is not available then there are basically two options:

1) SPL supports brom format and u-boot binary is part of boot partition. SPL can read/write itself and u-boot and u-boot can read/write the main partition

2) SPL and u-boot support the main partition format. While u-boot is written to the boot partition its pages are written in the format suitable for ubifs. This will get hairy when you want to actually write u-boot and SPL.

Quoted 5 lines

The problem with counting the partition sizes in bytes is obvious - whatever you do the brom reads predefined number of pages from the start of the nand to load the SPL and unless you know maximum page size of every nand ever made that is compatible with Allwinner brom you cannot tell what is even the maximum size of this part in bytes.]

The solution already implemented now and carried to Hans' tree is 1) with the size of SPL aligned to 8KB blocks (the largest of the page sizes attempted). The modes tried by BROM are listed in [1]. SPL currently tries only a single mode whose params are defined in sunxi-common.h, but this is likely to change to a "brute-force" approach to resemble BROM in the near future.
Yours,

Roy

Quoted 4 lines

Thanks

Michal

[1] https://linux-sunxi.org/NAND

Signature · 6 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#35 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Hi Roy
Thank you for working on this, I would like to suggest if you could implement separate control commands to switch ECC and Randomisation modes per partitions. I know this is not the best approach but it will provide more controls.

Quoted 120 lines · Roy Spliet

Dear Michal,

Op 08-06-15 om 10:54 schreef Michal Suchanek:

Quoted 81 lines · Roy Spliet
Quoted 48 lines

Hello Michal,

Op 07-06-15 om 18:48 schreef Michal Suchanek:

Hello,

On 5 June 2015 at 13:52, Roy Spliet <[email protected]> wrote:

Based on the default layout of the android image used at least on Olimex Lime

---
 include/configs/sunxi-common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +9 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
        BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
        BOOT_TARGET_DEVICES_SCSI(func) \
        BOOT_TARGET_DEVICES_USB(func) \
        func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
        MEM_LAYOUT_ENV_SETTINGS \
        "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
        "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
        BOOTENV
 

From what I heard the nand boot partition size should be specified in nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Quoted 10 lines

Although I believe you have the facts mostly right, they do not apply in this situation.
What you are looking for is the partition definition for U-boot. At this point the boot
rom (BROM) is no longer active and thus it's inner workings are mostly irrelevant.
The NAND partition lay-out for the boards I have seen (various Olimex + Cubietruck..)
are as follows:
0-2MB U-Boot-SPL + U-Boot

OK, so 0-2 MB has to be read (at least in part) by brom to load the SPL so it must be in the format brom understands. The part containing the SPL which is read by brom has certain number of pages. The u-boot part can contain whatever we define.

Quoted 2 lines

2-4MB U-Boot SPL + U-Boot (for recovery)
4MB+ Main file system

The main filesystem has to be in format suitable for UBIFS. It has to follow u-boot part possibly with some space in between.

If support for non-uniform flash format is not available then there are basically two options:

1) SPL supports brom format and u-boot binary is part of boot partition. SPL can read/write itself and u-boot and u-boot can read/write the main partition

2) SPL and u-boot support the main partition format. While u-boot is written to the boot partition its pages are written in the format suitable for ubifs. This will get hairy when you want to actually write u-boot and SPL.

Quoted 5 lines

The problem with counting the partition sizes in bytes is obvious - whatever you do the brom reads predefined number of pages from the start of the nand to load the SPL and unless you know maximum page size of every nand ever made that is compatible with Allwinner brom you cannot tell what is even the maximum size of this part in bytes.]

The solution already implemented now and carried to Hans' tree is 1) with the size of SPL aligned to 8KB blocks (the largest of the page sizes attempted). The modes tried by BROM are listed in [1]. SPL currently tries only a single mode whose params are defined in sunxi-common.h, but this is likely to change to a "brute-force" approach to resemble BROM in the near future.
Yours,

Roy

Quoted 4 lines

Thanks

Michal

[1] https://linux-sunxi.org/NAND

Signature · 10 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook <http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe at googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
author
#36 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Hello Yassin,

Op 08-06-15 om 12:48 schreef Yassin:

Quoted 2 lines

Hi Roy
Thank you for working on this, I would like to suggest if you could implement separate control commands to switch ECC and Randomisation modes per partitions. I know this is not the best approach but it will provide more controls.

Thanks for the suggestion. However, for now I do not see the immediate need for this in U-boot. U-boot should really only care about one thing:
load Linux. Therefore, the only partition it needs to be able to read is whatever partition is used for storing boot data on. And if we only care about one NAND partition, we don't need per-partition settings. I agree that it would be nice to have eventually, but I think this problem first needs to be solved in Linux properly. Then in U-boot we can sync MTD up with Linux and we get the support we need "for free". I'd personally recommend to take this approach over now first hacking up all sorts of new commands in U-boot, as the latter will create more problems with syncing up MTD and doing the right thing on the longer run. Yours,

Roy

Quoted 120 lines
Quoted 120 lines · Roy Spliet

Dear Michal,

Op 08-06-15 om 10:54 schreef Michal Suchanek:

Quoted 81 lines · Roy Spliet
Quoted 48 lines

Hello Michal,

Op 07-06-15 om 18:48 schreef Michal Suchanek:

Hello,

On 5 June 2015 at 13:52, Roy Spliet <[email protected]> wrote:

Based on the default layout of the android image used at least on Olimex Lime

---
  include/configs/sunxi-common.h | 9 +++++++++
  1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +9 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
  #define BOOT_TARGET_DEVICES_USB(func)
  #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
  #define BOOT_TARGET_DEVICES(func) \
         BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
         BOOT_TARGET_DEVICES_SCSI(func) \
         BOOT_TARGET_DEVICES_USB(func) \
         func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
         MEM_LAYOUT_ENV_SETTINGS \
         "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
         "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
         BOOTENV
 
 From what I heard the nand boot partition size should be specified in

nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Quoted 10 lines

Although I believe you have the facts mostly right, they do not apply in this situation.
What you are looking for is the partition definition for U-boot. At this point the boot
rom (BROM) is no longer active and thus it's inner workings are mostly irrelevant.
The NAND partition lay-out for the boards I have seen (various Olimex + Cubietruck..)
are as follows:
0-2MB U-Boot-SPL + U-Boot

OK, so 0-2 MB has to be read (at least in part) by brom to load the SPL so it must be in the format brom understands. The part containing the SPL which is read by brom has certain number of pages. The u-boot part can contain whatever we define.

Quoted 2 lines

2-4MB U-Boot SPL + U-Boot (for recovery)
4MB+ Main file system

The main filesystem has to be in format suitable for UBIFS. It has to follow u-boot part possibly with some space in between.

If support for non-uniform flash format is not available then there are basically two options:

1) SPL supports brom format and u-boot binary is part of boot partition. SPL can read/write itself and u-boot and u-boot can read/write the main partition

2) SPL and u-boot support the main partition format. While u-boot is written to the boot partition its pages are written in the format suitable for ubifs. This will get hairy when you want to actually write u-boot and SPL.

Quoted 5 lines

The problem with counting the partition sizes in bytes is obvious - whatever you do the brom reads predefined number of pages from the start of the nand to load the SPL and unless you know maximum page size of every nand ever made that is compatible with Allwinner brom you cannot tell what is even the maximum size of this part in bytes.]

The solution already implemented now and carried to Hans' tree is 1) with the size of SPL aligned to 8KB blocks (the largest of the page sizes attempted). The modes tried by BROM are listed in [1]. SPL currently tries only a single mode whose params are defined in sunxi-common.h, but this is likely to change to a "brute-force" approach to resemble BROM in the near future.
Yours,

Roy

Quoted 3 lines

Thanks

Michal

[1] https://linux-sunxi.org/NAND

Signature · 10 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook <http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe at googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Signature · 6 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#37 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Roy, Yassin,

Quoted 5 lines · On Mon, 08 Jun 2015 13:35:04 +0200 Roy Spliet <[email protected]> wrote:

Hello Yassin,

Op 08-06-15 om 12:48 schreef Yassin:

Quoted 2 lines

Hi Roy
Thank you for working on this, I would like to suggest if you could implement separate control commands to switch ECC and Randomisation modes per partitions. I know this is not the best approach but it will provide more controls.

Quoted 11 lines

Thanks for the suggestion. However, for now I do not see the immediate need for this in U-boot. U-boot should really only care about one thing:
load Linux. Therefore, the only partition it needs to be able to read is whatever partition is used for storing boot data on. And if we only care about one NAND partition, we don't need per-partition settings. I agree that it would be nice to have eventually, but I think this problem first needs to be solved in Linux properly. Then in U-boot we can sync MTD up with Linux and we get the support we need "for free". I'd personally recommend to take this approach over now first hacking up all sorts of new commands in U-boot, as the latter will create more problems with syncing up MTD and doing the right thing on the longer run.

Actually, the more I think about the more I agree with Yassin's suggestion. We currently don't have any standard way to attach a specific setting to a partition (even in Linux, and I hope I'll be able to work on this aspect soon).
So for now, I really think we should reuse the existing/standard way of declaring partitions in u-boot (mtdparts + mtdids variables + the mtdparts command) and a sunxi specific commands to configure the ECC and Randomizer config.
Once we have settled on something in Linux, we will be able to port it to u-boot and get rid of these sunxi specific command, but in the meantime this will allow us to boot a linux kernel (and even flash an SPL) from u-boot without introducing heavy changes in the u-boot MTD layer.

Best Regards,

Boris

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#38 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Hi,

Quoted 22 lines · Boris Brezillon

Roy, Yassin,

Quoted 5 lines · On Mon, 08 Jun 2015 13:35:04 +0200 Roy Spliet <[email protected]> wrote:

Hello Yassin,

Op 08-06-15 om 12:48 schreef Yassin:

Quoted 2 lines

Hi Roy
Thank you for working on this, I would like to suggest if you could implement separate control commands to switch ECC and Randomisation modes per partitions. I know this is not the best approach but it will provide more controls.

Quoted 11 lines

Thanks for the suggestion. However, for now I do not see the immediate need for this in U-boot. U-boot should really only care about one thing:
load Linux. Therefore, the only partition it needs to be able to read is whatever partition is used for storing boot data on. And if we only care about one NAND partition, we don't need per-partition settings. I agree that it would be nice to have eventually, but I think this problem first needs to be solved in Linux properly. Then in U-boot we can sync MTD up with Linux and we get the support we need "for free". I'd personally recommend to take this approach over now first hacking up all sorts of new commands in U-boot, as the latter will create more problems with syncing up MTD and doing the right thing on the longer run.

Quoted 13 lines

Actually, the more I think about the more I agree with Yassin's suggestion. We currently don't have any standard way to attach a specific setting to a partition (even in Linux, and I hope I'll be able to work on this aspect soon).
So for now, I really think we should reuse the existing/standard way of declaring partitions in u-boot (mtdparts + mtdids variables + the mtdparts command) and a sunxi specific commands to configure the ECC and Randomizer config.
Once we have settled on something in Linux, we will be able to port it to u-boot and get rid of these sunxi specific command, but in the meantime this will allow us to boot a linux kernel (and even flash an SPL) from u-boot without introducing heavy changes in the u-boot MTD layer.

Ack, note we do not even need any sunxi specific commands, we will have separate nand code for the SPL and uboot itself, since the SPL needs a simple mini read-only implementation. So we can compile the parameters for the boot block vs the rest into the spl resp. uboot binary directly.

Regards,

Hans

#39 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

In reply to Roy Spliet

Hi Roy,

Quoted 69 lines · Roy Spliet

Hello Michal,

Op 07-06-15 om 18:48 schreef Michal Suchanek:

Quoted 32 lines

Hello,

Quoted 29 lines · Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
  include/configs/sunxi-common.h | 9 +++++++++
  1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +7 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
  #define BOOT_TARGET_DEVICES_USB(func)
  #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
  #define BOOT_TARGET_DEVICES(func) \
         BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
         BOOT_TARGET_DEVICES_SCSI(func) \
         BOOT_TARGET_DEVICES_USB(func) \
         func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
         MEM_LAYOUT_ENV_SETTINGS \
Quoted 8 lines

include/configs/sunxi-common.h extern int soft_i2c_gpio_scl; · line 453

Quoted 5 lines
include/configs/sunxi-common.h +2 -0
         "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
         "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
         BOOTENV

From what I heard the nand boot partition size should be specified in
nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Although I believe you have the facts mostly right, they do not apply in this situation. What you are looking for is the partition definition for U-boot. At this point the boot rom (BROM) is no longer active and thus it's inner workings are mostly irrelevant. The NAND partition lay-out for the boards I have seen (various Olimex + Cubietruck..) are as follows:
0-2MB U-Boot-SPL + U-Boot
2-4MB U-Boot SPL + U-Boot (for recovery)
4MB+ Main file system

The mtdparts env variable defines only the main file system because that's the only place with relevant files for U-Boot.
This said: I have replaced the default file system with a "custom" UBI FS containing just a boot and a rootfs partition. I am unsure whether these defaults apply for the Android image that ships with the Olimex boards. But then again: that image also ships with a boot-loader, so do we care?

Quoted 11 lines

I did not find any document regarding the nand boot partition layout so I would like to see some input from somebody familiar with the driver.

While it is fine for testing to hand-edit the environment the final nand support should have

1) way to express the boot partition size in nand pages
2) way to make the main partition start at the end of boot partition and extend to the end of the flash

Quoted 8 lines
Quoted 1 line

This should probably also go to Linux.

Linux can define partitions in the device tree. I'd prefer to carry this approach to U-boot, but current U-Boot has the partitioning part of the MTD code hacked away and replaced by custom mtdparts code without OF support. Doing this proper requires getting rid of the latter, which will likely break a lot of legacy. So as far as I agree, I have to warn that is a longer-term project, extended further by the ongoing (justified) discussion we are having regarding the MTD partitioning code in upstream Linux that may or may not lead to parts of the framework being re-architected.

Last time I discussed this with some kernel people, they pointed me to the fact that the kernel actually parses partition info provided by u-boot through the u-boot mtdparts command, and that that is the preferred way to pass partition info to the kernel, so rather then adding dts partition info to u-boot we would need to teach the existing kernel mtdpart code to deal with separate ecc / random setting and maybe use a list of hardcoded partitition names for which to use the brom compatible settings. These are all things which we need to figure out on the kernel side, it would be good to get a discussion started on this with the kernel mtd people.

Note that we will also need to have a u-boot env partition somewhare either at the nandpart level, or as a ubi volume, assuming the u-boot env code can deal with ubi volumes (we are in the full u-boot environment when reading the env.)

Regards,

Hans

Quoted 7 lines

Roy

Quoted 3 lines

Thanks

Michal

author
#40 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Hello Hans,

Op 08-06-15 om 15:16 schreef Hans de Goede:

Quoted 97 lines

Hi Roy,

Quoted 80 lines · Roy Spliet

Hello Michal,

Op 07-06-15 om 18:48 schreef Michal Suchanek:

Quoted 34 lines

Hello,

Quoted 31 lines · Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
  include/configs/sunxi-common.h | 9 +++++++++
  1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +7 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
  #define BOOT_TARGET_DEVICES_USB(func)
  #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
  #define BOOT_TARGET_DEVICES(func) \
         BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
         BOOT_TARGET_DEVICES_SCSI(func) \
         BOOT_TARGET_DEVICES_USB(func) \
         func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
         MEM_LAYOUT_ENV_SETTINGS \
Quoted 8 lines

include/configs/sunxi-common.h extern int soft_i2c_gpio_scl; · line 453

Quoted 5 lines
include/configs/sunxi-common.h +2 -0
         "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
         "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+ "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
         BOOTENV

From what I heard the nand boot partition size should be specified in
nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Although I believe you have the facts mostly right, they do not apply in this situation.
What you are looking for is the partition definition for U-boot. At this point the boot
rom (BROM) is no longer active and thus it's inner workings are mostly irrelevant.
The NAND partition lay-out for the boards I have seen (various Olimex
+ Cubietruck..)
are as follows:
0-2MB U-Boot-SPL + U-Boot
2-4MB U-Boot SPL + U-Boot (for recovery)
4MB+ Main file system

The mtdparts env variable defines only the main file system because that's the only
place with relevant files for U-Boot.
This said: I have replaced the default file system with a "custom" UBI FS containing
just a boot and a rootfs partition. I am unsure whether these defaults apply for the
Android image that ships with the Olimex boards. But then again: that image also
ships with a boot-loader, so do we care?

Quoted 4 lines

I did not find any document regarding the nand boot partition layout so I would like to see some input from somebody familiar with the driver.

Quoted 8 lines

While it is fine for testing to hand-edit the environment the final nand support should have

1) way to express the boot partition size in nand pages
2) way to make the main partition start at the end of boot partition and extend to the end of the flash

This should probably also go to Linux.

Quoted 13 lines

Linux can define partitions in the device tree. I'd prefer to carry this approach to U-boot,
but current U-Boot has the partitioning part of the MTD code hacked away and replaced by
custom mtdparts code without OF support. Doing this proper requires getting rid of the
latter, which will likely break a lot of legacy. So as far as I agree, I have to warn that is
a longer-term project, extended further by the ongoing (justified) discussion we are having
regarding the MTD partitioning code in upstream Linux that may or may not lead to parts
of the framework being re-architected.

Quoted 15 lines

Last time I discussed this with some kernel people, they pointed me to the fact that
the kernel actually parses partition info provided by u-boot through the u-boot mtdparts
command, and that that is the preferred way to pass partition info to the kernel, so rather
then adding dts partition info to u-boot we would need to teach the existing kernel mtdpart
code to deal with separate ecc / random setting and maybe use a list of hardcoded
partitition names for which to use the brom compatible settings. These are all things
which we need to figure out on the kernel side, it would be good to get a discussion
started on this with the kernel mtd people.

I am unaware of the kernel developers' preferences, but [1] shows that the kernel
gained OF (DTS) partition parsing in 2008. We do need to teach the kernel (and U-Boot)
the trick of parsing mtd partitions, but with ARM/Linaro pushing DTS as the preferred way
to describe hardware we might have to consider this a separate discussion point.

Quoted 6 lines

Note that we will also need to have a u-boot env partition somewhare either at the
nandpart level, or as a ubi volume, assuming the u-boot env code can deal with
ubi volumes (we are in the full u-boot environment when reading the env.)

Thanks, this is a relevant addition and something that needs investigation. Unfortunately I can probably not pull this wagon too much further, given I am about to continue my career in academics starting next month. I'd be happy to
think along and start the discussion, but I might not be around long enough to work
much on the implementation.
Yours,

Roy

Quoted 14 lines

Regards,

Hans

Quoted 7 lines

Roy

Quoted 3 lines

Thanks

Michal

Signature · 6 lines
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook 
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
#41 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

In reply to Michal Suchanek

Hi Michal,

Quoted 33 lines · On Sun, 7 Jun 2015 18:48:26 +0200 Michal Suchanek <[email protected]> wrote:

Hello,

Quoted 30 lines · Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
 include/configs/sunxi-common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +7 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
        BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
        BOOT_TARGET_DEVICES_SCSI(func) \
        BOOT_TARGET_DEVICES_USB(func) \
        func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
        MEM_LAYOUT_ENV_SETTINGS \
        "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
Quoted 8 lines

include/configs/sunxi-common.h extern int soft_i2c_gpio_scl; · line 453

Quoted 4 lines
include/configs/sunxi-common.h +2 -0
        "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
        BOOTENV

From what I heard the nand boot partition size should be specified in nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

AFAIK, the mtdparts format only allows you to express partition offsets and sizes in bytes, and even if we had to change for something else, we should choose NAND blocks rather than NAND pages.
The reason partitions should be block aligned in because the you can't erase specific pages in a block, which means that if you define 2 partitions sharing the same block, you won't be able to update one partition without potentially corrupting the other one.

Quoted 4 lines

I did not find any document regarding the nand boot partition layout so I would like to see some input from somebody familiar with the driver.

AFAIR, the mtd partition code checks for block alignment anyway, so you shouldn't be allowed to create two partitions sharing the same block.

Quoted 5 lines

While it is fine for testing to hand-edit the environment the final nand support should have

1) way to express the boot partition size in nand pages

Why should we add that ? The conversion from a number of blocks to a number bytes is pretty straightforward (number_of_blocks * block_size_in_bytes).

Quoted 2 lines

2) way to make the main partition start at the end of boot partition and extend to the end of the flash

Again, that's not a good idea, the main partition should be aligned on a block (see the above explanation).

Best Regards,

Boris

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#42 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Quoted 47 lines · Boris Brezillon

Hi Michal,

Quoted 33 lines · On Sun, 7 Jun 2015 18:48:26 +0200 Michal Suchanek <[email protected]> wrote:

Hello,

Quoted 30 lines · Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
 include/configs/sunxi-common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +7 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
        BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
        BOOT_TARGET_DEVICES_SCSI(func) \
        BOOT_TARGET_DEVICES_USB(func) \
        func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
        MEM_LAYOUT_ENV_SETTINGS \
        "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
Quoted 8 lines

include/configs/sunxi-common.h extern int soft_i2c_gpio_scl; · line 453

Quoted 4 lines
include/configs/sunxi-common.h +2 -0
        "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
        BOOTENV

From what I heard the nand boot partition size should be specified in nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Quoted 7 lines

AFAIK, the mtdparts format only allows you to express partition offsets and sizes in bytes, and even if we had to change for something else, we should choose NAND blocks rather than NAND pages.
The reason partitions should be block aligned in because the you can't erase specific pages in a block, which means that if you define 2 partitions sharing the same block, you won't be able to update one partition without potentially corrupting the other one.

However, if the number of pages the boot0 partition takes up is not block aligned it means we cannot use the medium for booting and can just use 1 big partition anyway.

Quoted 10 lines
Quoted 5 lines

I did not find any document regarding the nand boot partition layout so I would like to see some input from somebody familiar with the driver.

AFAIR, the mtd partition code checks for block alignment anyway, so you shouldn't be allowed to create two partitions sharing the same block.

Quoted 1 line
Quoted 8 lines
Quoted 4 lines

While it is fine for testing to hand-edit the environment the final nand support should have

1) way to express the boot partition size in nand pages

Why should we add that ? The conversion from a number of blocks to a number bytes is pretty straightforward (number_of_blocks * block_size_in_bytes).

Because the block size is not the same on all flash chips, obviously.

If there is only one block size that can ever be reasonably supported due to other constraints then it's fine to just hardcode it.

Quoted 6 lines
Quoted 3 lines

2) way to make the main partition start at the end of boot partition and extend to the end of the flash

Again, that's not a good idea, the main partition should be aligned on a block (see the above explanation).

Since these are block aligned anyway there should be no problem.

And if you can express the size in blocks you can just make the main partition start the next block after boot0. What is missing is the ability to extend to the end of medium to be feature compatible with Chinese software that uses this to flash same firmware to tablets with different nand size. I think this is generally desirable anyway.

Thanks

Michal

#43 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Quoted 57 lines · On Sun, 14 Jun 2015 13:56:56 +0200 Michal Suchanek <[email protected]> wrote:
Quoted 47 lines · Boris Brezillon

Hi Michal,

Quoted 33 lines · On Sun, 7 Jun 2015 18:48:26 +0200 Michal Suchanek <[email protected]> wrote:

Hello,

Quoted 30 lines · Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
 include/configs/sunxi-common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +7 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
        BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
        BOOT_TARGET_DEVICES_SCSI(func) \
        BOOT_TARGET_DEVICES_USB(func) \
        func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
        MEM_LAYOUT_ENV_SETTINGS \
        "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
Quoted 8 lines

include/configs/sunxi-common.h extern int soft_i2c_gpio_scl; · line 453

Quoted 4 lines
include/configs/sunxi-common.h +2 -0
        "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
        BOOTENV

From what I heard the nand boot partition size should be specified in nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Quoted 7 lines

AFAIK, the mtdparts format only allows you to express partition offsets and sizes in bytes, and even if we had to change for something else, we should choose NAND blocks rather than NAND pages.
The reason partitions should be block aligned in because the you can't erase specific pages in a block, which means that if you define 2 partitions sharing the same block, you won't be able to update one partition without potentially corrupting the other one.

Quoted 4 lines

However, if the number of pages the boot0 partition takes up is not block aligned it means we cannot use the medium for booting and can just use 1 big partition anyway.

Hm, I don't get your point.
You can have a boot0 partition taking one NAND block, and several other partitions used for other purpose (though having a single UBI partition is a better approach).

Quoted 13 lines
Quoted 13 lines
Quoted 5 lines

I did not find any document regarding the nand boot partition layout so I would like to see some input from somebody familiar with the driver.

AFAIR, the mtd partition code checks for block alignment anyway, so you shouldn't be allowed to create two partitions sharing the same block.

Quoted 4 lines

While it is fine for testing to hand-edit the environment the final nand support should have

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

1) way to express the boot partition size in nand pages

Why should we add that ? The conversion from a number of blocks to a number bytes is pretty straightforward (number_of_blocks * block_size_in_bytes).

Because the block size is not the same on all flash chips, obviously.

And that's why partitions are defined in the board dts, and not the SoC dtsi...

Quoted 3 lines

If there is only one block size that can ever be reasonably supported due to other constraints then it's fine to just hardcode it.

I think we already had this discussion on the #linux-sunxi channel, and you're trying to use a generic config from things that are really board specific.
What's the problem with having different partition layout depending on the board ?
Note that once you have defined your boot0 + u-boot + u-boot-env + UBI partitions, if you want to have a generic layout in the UBI device, you can define standard names for you UBI volumes.

Quoted 8 lines
Quoted 7 lines
Quoted 4 lines

2) way to make the main partition start at the end of boot partition and extend to the end of the flash

Again, that's not a good idea, the main partition should be aligned on a block (see the above explanation).

Quoted 7 lines

Since these are block aligned anyway there should be no problem.

And if you can express the size in blocks you can just make the main partition start the next block after boot0. What is missing is the ability to extend to the end of medium to be feature compatible with Chinese software that uses this to flash same firmware to tablets with different nand size. I think this is generally desirable anyway.

If they decide to use one single dtb for all their board revisions (even when they decide to change the NAND chip type), then yes, they should define a boot0 partition taking at least the size of the maximum block size.
But that's only my opinion, so if MTD maintainers (both u-boot and linux ones) accept to support MTD partition offsets and sizes defined in number blocks, then go for it.

Best Regards,

Boris

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#44 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Quoted 65 lines · Boris Brezillon
Quoted 57 lines · On Sun, 14 Jun 2015 13:56:56 +0200 Michal Suchanek <[email protected]> wrote:
Quoted 47 lines · Boris Brezillon

Hi Michal,

Quoted 33 lines · On Sun, 7 Jun 2015 18:48:26 +0200 Michal Suchanek <[email protected]> wrote:

Hello,

Quoted 30 lines · Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
 include/configs/sunxi-common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +7 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
        BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
        BOOT_TARGET_DEVICES_SCSI(func) \
        BOOT_TARGET_DEVICES_USB(func) \
        func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
        MEM_LAYOUT_ENV_SETTINGS \
        "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
Quoted 8 lines

include/configs/sunxi-common.h extern int soft_i2c_gpio_scl; · line 453

Quoted 4 lines
include/configs/sunxi-common.h +2 -0
        "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
        BOOTENV

From what I heard the nand boot partition size should be specified in nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Quoted 7 lines

AFAIK, the mtdparts format only allows you to express partition offsets and sizes in bytes, and even if we had to change for something else, we should choose NAND blocks rather than NAND pages.
The reason partitions should be block aligned in because the you can't erase specific pages in a block, which means that if you define 2 partitions sharing the same block, you won't be able to update one partition without potentially corrupting the other one.

Quoted 4 lines

However, if the number of pages the boot0 partition takes up is not block aligned it means we cannot use the medium for booting and can just use 1 big partition anyway.

Quoted 4 lines

Hm, I don't get your point.
You can have a boot0 partition taking one NAND block, and several other partitions used for other purpose (though having a single UBI partition is a better approach).

and how do you tell the kernel that these partitions follow the boot0 taking up one block when you only count in bytes?

Quoted 26 lines
Quoted 14 lines
Quoted 14 lines
Quoted 6 lines

I did not find any document regarding the nand boot partition layout so I would like to see some input from somebody familiar with the driver.

AFAIR, the mtd partition code checks for block alignment anyway, so you shouldn't be allowed to create two partitions sharing the same block.

Quoted 4 lines

While it is fine for testing to hand-edit the environment the final nand support should have

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

1) way to express the boot partition size in nand pages

Why should we add that ? The conversion from a number of blocks to a number bytes is pretty straightforward (number_of_blocks * block_size_in_bytes).

Because the block size is not the same on all flash chips, obviously.

And that's why partitions are defined in the board dts, and not the SoC dtsi...

Quoted 1 line
Quoted 8 lines
Quoted 2 lines

If there is only one block size that can ever be reasonably supported due to other constraints then it's fine to just hardcode it.

I think we already had this discussion on the #linux-sunxi channel, and you're trying to use a generic config from things that are really board specific.
What's the problem with having different partition layout depending on the board ?

Why do we have nand chip detection then?

We can just write the chip parameters in DT and have everything in one place at least.

If we cannot use the detected parameters to infer the related values in DT then the detection is useless for DT based archs.

Thanks

Michal

#45 lore raw

RFC 11/11 mtd/nand: Sunxi NAND boot partition definitions

Quoted 67 lines · On Sun, 14 Jun 2015 19:42:58 +0200 Michal Suchanek <[email protected]> wrote:
Quoted 65 lines · Boris Brezillon
Quoted 61 lines · On Sun, 14 Jun 2015 13:56:56 +0200 Michal Suchanek <[email protected]> wrote:
Quoted 47 lines · Boris Brezillon

Hi Michal,

Quoted 33 lines · On Sun, 7 Jun 2015 18:48:26 +0200 Michal Suchanek <[email protected]> wrote:

Hello,

Quoted 30 lines · Roy Spliet

Based on the default layout of the android image used at least on Olimex Lime

---
 include/configs/sunxi-common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/sunxi-common.h +7 -0
index ec28c40..b38f2f5 100644
@@ -404,8 +404,15 @@ extern int soft_i2c_gpio_scl;
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+#ifdef CONFIG_NAND
+#define BOOT_TARGET_DEVICES_NAND(func) func(NAND, nand , 0)
+#else
+#define BOOT_TARGET_DEVICES_NAND(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
        BOOT_TARGET_DEVICES_MMC(func) \
+       BOOT_TARGET_DEVICES_NAND(func) \
        BOOT_TARGET_DEVICES_SCSI(func) \
        BOOT_TARGET_DEVICES_USB(func) \
        func(PXE, pxe, na) \
@@ -441,6 +448,8 @@ extern int soft_i2c_gpio_scl;
        MEM_LAYOUT_ENV_SETTINGS \
        "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
Quoted 8 lines

include/configs/sunxi-common.h extern int soft_i2c_gpio_scl; · line 453

Quoted 4 lines
include/configs/sunxi-common.h +2 -0
        "console=ttyS0,115200\0" \
+       "mtdids=nand0=mtd2\0" \
+       "mtdparts=mtdparts=mtd2:0xffc00000 at 0x400000(nand0_main)\0" \
        BOOTENV

From what I heard the nand boot partition size should be specified in nand pages rather than bytes because the boot rom loads a fixed number of pages and just uses the start of each page regardless of page size.

Quoted 7 lines

AFAIK, the mtdparts format only allows you to express partition offsets and sizes in bytes, and even if we had to change for something else, we should choose NAND blocks rather than NAND pages.
The reason partitions should be block aligned in because the you can't erase specific pages in a block, which means that if you define 2 partitions sharing the same block, you won't be able to update one partition without potentially corrupting the other one.

However, if the number of pages the boot0 partition takes up is not block aligned it means we cannot use the medium for booting and can just use 1 big partition anyway.

Quoted 7 lines
Quoted 4 lines

Hm, I don't get your point.
You can have a boot0 partition taking one NAND block, and several other partitions used for other purpose (though having a single UBI partition is a better approach).

and how do you tell the kernel that these partitions follow the boot0 taking up one block when you only count in bytes?

Oh come on! You just specify the appropriate size and offset in bytes.

Quoted 29 lines
Quoted 29 lines
Quoted 14 lines
Quoted 14 lines
Quoted 6 lines

I did not find any document regarding the nand boot partition layout so I would like to see some input from somebody familiar with the driver.

AFAIR, the mtd partition code checks for block alignment anyway, so you shouldn't be allowed to create two partitions sharing the same block.

Quoted 4 lines

While it is fine for testing to hand-edit the environment the final nand support should have

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

1) way to express the boot partition size in nand pages

Why should we add that ? The conversion from a number of blocks to a number bytes is pretty straightforward (number_of_blocks * block_size_in_bytes).

Because the block size is not the same on all flash chips, obviously.

And that's why partitions are defined in the board dts, and not the SoC dtsi...

Quoted 3 lines

If there is only one block size that can ever be reasonably supported due to other constraints then it's fine to just hardcode it.

Quoted 7 lines
Quoted 5 lines

I think we already had this discussion on the #linux-sunxi channel, and you're trying to use a generic config from things that are really board specific.
What's the problem with having different partition layout depending on the board ?

Why do we have nand chip detection then?

There are a lot of other stuff detected from the NAND chip ID (or ONFI or JEDEC standard), but remember that the partition stuff are supposed to be common to all the MTD devices, and I'm not sure all of them can use the erase size (or block size unit) to express their partitions offsets/sizes.
Moreover, having the partition layout expressed in bytes is IMO clearer than having it expressed in blocks.

Quoted 3 lines

We can just write the chip parameters in DT and have everything in one place at least.

Yes, and we could also declare USB devices in the DT.

Quoted 3 lines

If we cannot use the detected parameters to infer the related values in DT then the detection is useless for DT based archs.

Again, you're not fair, the chip detection is used for a lot of things (including detecting the NAND block size), and the fact that this information is not used for partition definition, is really a minor detail.

This being said, if you really want to change that, then propose a new DT binding and a new formalism for the mtdparts parameter, and discuss it with the MTD maintainers.
We don't need these changes for the sunxi NAND driver to work, so I'll let you deal with that aspect.

Best Regards,

Boris

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#46 lore raw
In reply to Roy Spliet

Hi Roy,

Thanks for your work on this!

Quoted 4 lines · Roy Spliet

Following up on earlier SPL patches, here a series based on Yassin Jaffer's work to bring NAND support to U-boot. RFC because I know that the sunxi nand configuration options are dependent on a work-in-progress by Daniel - trying to deliver a single SPL for both MMC and NAND boot.

I've just tested Daniel's patches on a board with an eMMC, fixed 2 small bugs related to eMMC handling and merged them into u-boot-sunxi/next.

So it would probably be best to base your next version of the patches on top of u-boot-sunxi/next which other then having Daniel's patches is following u-boot/master atm.

Quoted 10 lines

Given I have spent the past few weeks learning how Boris' original driver works, I have probably grown a bit blind for potentially existing issues. Please provide plenty of feedback so I can bring this in good shape.

Patches tested on an Olimex Lime with 4GB Hynix nand. Has a partition as defined in sunxi-common.h with two UBIFS partitions (boot, rootfs) set up in Linux. To me it feels self-explanatory how to set this up, but I've spent the last few weeks full-time on this, implying my view of the world and how it revolves around MTD is rather distorted. Feel free to ask directed questions if you desire assistance in setting up and/or testing.

From the sunxi side these patches look good, I've one quite minor nitpick which
I will explain in a reply to the patch in question. I think the most work here is getting the generic mtd patches ready and accepted by Scott Wood (the u-boot mtd maintainer), so please coordinate this further with him.

Once those bits are in I'm more then happy to merge the sunxi side of things.

As for merging the mtd bits, since the u-boot mtd code is somewhat of a copy of the Linux mtd code it may be best to simply sync the existing mtd code up with the upstream kernel mtd code, and work on getting the missing mtd bits merged into the upstream kernel first, and then merge the changes back into the u-boot mtd code, that assumes that the u-boot mtd code still is somewhat in sync with the kernel code atm though, and from your comments I'm getting the impression that it is not...

Anyways I will leave figuring this out between you and Scott. Note that we could use some help with upstreaming the kernel bits regardless of this. If you plan to work on this, please coordinate with Boris as Boris will likely start working on the mtd kernel code again soonish.

Regards,

Hans

#47 lore raw
In reply to Roy Spliet

Hi,

Quoted 8 lines · Roy Spliet

Following up on earlier SPL patches, here a series based on Yassin Jaffer's work to bring NAND support to U-boot. RFC because I know that the sunxi nand configuration options are dependent on a work-in-progress by Daniel - trying to deliver a single SPL for both MMC and NAND boot.
Given I have spent the past few weeks learning how Boris' original driver works, I have probably grown a bit blind for potentially existing issues. Please provide plenty of feedback so I can bring this in good shape.

Quoted 6 lines

Patches tested on an Olimex Lime with 4GB Hynix nand. Has a partition as defined in sunxi-common.h with two UBIFS partitions (boot, rootfs) set up in Linux. To me it feels self-explanatory how to set this up, but I've spent the last few weeks full-time on this, implying my view of the world and how it revolves around MTD is rather distorted. Feel free to ask directed questions if youdesire assistance in setting up and/or testing.

p.s.

If you want me to I can merge this, or the next version into my sunxi-wip branch so that people can play with it. Chances are I will do that anyways one of these days to play with it myself.

Talking about playing with this, can you provide a quick step by step on howto setup the ubifs stuff under Linux, assuming a kernel + dts with working nand support are present ?

Regards,

Hans

#48 lore raw
In reply to Roy Spliet

Hi All,

I'm eventually joining the discussion (better late than never ;-)).

You'll find my comments in each patch (or answers to those patches).

Quoted 8 lines · On Fri, 5 Jun 2015 13:52:33 +0200 Roy Spliet <[email protected]> wrote:

Following up on earlier SPL patches, here a series based on Yassin Jaffer's work to bring NAND support to U-boot. RFC because I know that the sunxi nand configuration options are dependent on a work-in-progress by Daniel - trying to deliver a single SPL for both MMC and NAND boot.
Given I have spent the past few weeks learning how Boris' original driver works, I have probably grown a bit blind for potentially existing issues. Please provide plenty of feedback so I can bring this in good shape.

Quoted 7 lines

Patches tested on an Olimex Lime with 4GB Hynix nand. Has a partition as defined in sunxi-common.h with two UBIFS partitions (boot, rootfs) set up in Linux. To me it feels self-explanatory how to set this up, but I've spent the last few weeks full-time on this, implying my view of the world and how it revolves around MTD is rather distorted. Feel free to ask directed questions if you desire assistance in setting up and/or testing.
Thanks!

That would be great to have a summary of the changelog in the cover letter (you can generate it with --cover-letter when you generate your patches using git format-patch).

Best Regards,

Boris

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com