diff mbox

[U-Boot,v2] mtd: nand: allow to skip BBT scanning during NAND inititialization

Message ID 1414067128-16857-1-git-send-email-yamada.m@jp.panasonic.com
State Rejected
Delegated to: Scott Wood
Headers show

Commit Message

Masahiro Yamada Oct. 23, 2014, 12:25 p.m. UTC
Since commit ff94bc40af34 (mtd, ubi, ubifs: resync with Linux-3.14),
chip->scan_bbt() is called at the end of nand_scan_tail().
It means the first read access happens immediately after the generic
NAND initialization process.

It causes a problem to some SoCs of UniPhier platform because some of
their register values need to be fixed up after the general
initialization procedure has been finished.  Otherwise, read asccess
fails.  Such a fix-up is SoC-specific enough to be written in a board
file rather than in driver code.

One of possible and clean enough ways to work around this issue is
postpone the BBT scanning until necessary fix-up is done in
board_late_init() or somewhere else.

CONFIG_MTD_NAND_SKIP_BBTSCAN, if enabled, allows to skip the BBT
scanning at the end of nand_scan_tail().

Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
Cc: Scott Wood <scottwood@freescale.com>
---

If this patch is accepted, I will turn on this config option
for my boards.


Changes in v2:
  - Bug fix ( "config" was missing from v1)

 drivers/mtd/nand/Kconfig | 13 +++++++++++++
 drivers/mtd/nand/nand.c  |  4 ++++
 2 files changed, 17 insertions(+)

Comments

Scott Wood Nov. 3, 2014, 9:40 p.m. UTC | #1
On Thu, 2014-10-23 at 21:25 +0900, Masahiro Yamada wrote:
> Since commit ff94bc40af34 (mtd, ubi, ubifs: resync with Linux-3.14),
> chip->scan_bbt() is called at the end of nand_scan_tail().
> It means the first read access happens immediately after the generic
> NAND initialization process.
> 
> It causes a problem to some SoCs of UniPhier platform because some of
> their register values need to be fixed up after the general
> initialization procedure has been finished.  Otherwise, read asccess
> fails.  Such a fix-up is SoC-specific enough to be written in a board
> file rather than in driver code.
> 
> One of possible and clean enough ways to work around this issue is
> postpone the BBT scanning until necessary fix-up is done in
> board_late_init() or somewhere else.
> 
> CONFIG_MTD_NAND_SKIP_BBTSCAN, if enabled, allows to skip the BBT
> scanning at the end of nand_scan_tail().
> 
> Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
> Cc: Scott Wood <scottwood@freescale.com>
> ---

Rotislav Lisovy already posted a patch to fix the regression, but I
don't think you should be relying on this for your problem.  Why don't
you want to put SoC-specific knowledge in the driver?  At least make it
a callback from the driver to an SoC file, rather than hoping the NAND
won't be touched for a certain amount of time after the driver has told
the subsystem "I'm here and ready to be used".

-Scott
Scott Wood Nov. 3, 2014, 9:47 p.m. UTC | #2
On Mon, 2014-11-03 at 15:40 -0600, Scott Wood wrote:
> On Thu, 2014-10-23 at 21:25 +0900, Masahiro Yamada wrote:
> > Since commit ff94bc40af34 (mtd, ubi, ubifs: resync with Linux-3.14),
> > chip->scan_bbt() is called at the end of nand_scan_tail().
> > It means the first read access happens immediately after the generic
> > NAND initialization process.
> > 
> > It causes a problem to some SoCs of UniPhier platform because some of
> > their register values need to be fixed up after the general
> > initialization procedure has been finished.  Otherwise, read asccess
> > fails.  Such a fix-up is SoC-specific enough to be written in a board
> > file rather than in driver code.
> > 
> > One of possible and clean enough ways to work around this issue is
> > postpone the BBT scanning until necessary fix-up is done in
> > board_late_init() or somewhere else.
> > 
> > CONFIG_MTD_NAND_SKIP_BBTSCAN, if enabled, allows to skip the BBT
> > scanning at the end of nand_scan_tail().
> > 
> > Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
> > Cc: Scott Wood <scottwood@freescale.com>
> > ---
> 
> Rotislav Lisovy already posted a patch to fix the regression, but I
> don't think you should be relying on this for your problem.  Why don't
> you want to put SoC-specific knowledge in the driver?  At least make it
> a callback from the driver to an SoC file, rather than hoping the NAND
> won't be touched for a certain amount of time after the driver has told
> the subsystem "I'm here and ready to be used".

Also, if you did have a valid reason to set NAND_SKIP_BBTSCAN, why would
you want to set it from nand.c rather than from your driver's init
function?

-Scott
Masahiro Yamada Nov. 5, 2014, 3:39 a.m. UTC | #3
Hi Scott,


On Mon, 3 Nov 2014 15:40:59 -0600
Scott Wood <scottwood@freescale.com> wrote:

> On Thu, 2014-10-23 at 21:25 +0900, Masahiro Yamada wrote:
> > Since commit ff94bc40af34 (mtd, ubi, ubifs: resync with Linux-3.14),
> > chip->scan_bbt() is called at the end of nand_scan_tail().
> > It means the first read access happens immediately after the generic
> > NAND initialization process.
> > 
> > It causes a problem to some SoCs of UniPhier platform because some of
> > their register values need to be fixed up after the general
> > initialization procedure has been finished.  Otherwise, read asccess
> > fails.  Such a fix-up is SoC-specific enough to be written in a board
> > file rather than in driver code.
> > 
> > One of possible and clean enough ways to work around this issue is
> > postpone the BBT scanning until necessary fix-up is done in
> > board_late_init() or somewhere else.
> > 
> > CONFIG_MTD_NAND_SKIP_BBTSCAN, if enabled, allows to skip the BBT
> > scanning at the end of nand_scan_tail().
> > 
> > Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
> > Cc: Scott Wood <scottwood@freescale.com>
> > ---
> 
> Rotislav Lisovy already posted a patch to fix the regression, but I
> don't think you should be relying on this for your problem.

If you are willing to apply Rostislav's patch, I am fine.
There is no reason (at least) for me to insist on this patch any more.


>Why don't
> you want to put SoC-specific knowledge in the driver?


There are two reasons:

[1] This problem occurs on some of Panasonic UniPhier SoCs.
Denali driver (drivers/mtd/nand/denali.c) is used by SOCFPGA
as well as UniPhier.
I do not think it is a good idea to put dirty and SoC-specific
work around into the driver.

[2] There is no good place to insert a callback to an SoC file.
I need to write parameters such as page_size to hardware registers.
(You can see my code, nand_denali_fixup() in arch/arm/cpu/armv7/uniphier/board_late_init.c)

   The NAND init procedure of U-Boot is like this:

   (1) board_nand_init()   (drivers/mtd/nand/denali.c)
   (2) nand_scan_ident()   (drivers/mtd/nand/nand_base.c)
   (3) nand_scan_tail()    (drivers/mtd/nand/nand_base.c)



  (2) detects the device size and set mtd->write_size,
   mtd->erase_size, mtd->oob_size.
  I need to set these values to the Denali hardware, but
  the Denali driver code is called at (1) which is called
  before the detection of the device size.

   In Linux, nand_scan_ident() and nand_scan_tail() are called
   from each of NAND drivers, so we can use the values which
   have been set during nand_scan_ident().

   In U-Boot, I think it is impossible.




> At least make it
> a callback from the driver to an SoC file, rather than hoping the NAND
> won't be touched for a certain amount of time after the driver has told
> the subsystem "I'm here and ready to be used".
> 
> -Scott
> 

Best Regards
Masahiro Yamada
Scott Wood Nov. 5, 2014, 5:45 a.m. UTC | #4
On Wed, 2014-11-05 at 12:39 +0900, Masahiro Yamada wrote:
> [2] There is no good place to insert a callback to an SoC file.
> I need to write parameters such as page_size to hardware registers.
> (You can see my code, nand_denali_fixup() in arch/arm/cpu/armv7/uniphier/board_late_init.c)
> 
>    The NAND init procedure of U-Boot is like this:
> 
>    (1) board_nand_init()   (drivers/mtd/nand/denali.c)
>    (2) nand_scan_ident()   (drivers/mtd/nand/nand_base.c)
>    (3) nand_scan_tail()    (drivers/mtd/nand/nand_base.c)
> 
> 
> 
>   (2) detects the device size and set mtd->write_size,
>    mtd->erase_size, mtd->oob_size.
>   I need to set these values to the Denali hardware, but
>   the Denali driver code is called at (1) which is called
>   before the detection of the device size.
> 
>    In Linux, nand_scan_ident() and nand_scan_tail() are called
>    from each of NAND drivers, so we can use the values which
>    have been set during nand_scan_ident().
> 
>    In U-Boot, I think it is impossible.

If you use CONFIG_SYS_NAND_SELF_INIT you can insert code between
nand_scan_ident() and nand_scan_tail(), just like in Linux.

-Scott
Masahiro Yamada Nov. 11, 2014, 1:10 p.m. UTC | #5
Hi Scott,

On Tue, 4 Nov 2014 23:45:44 -0600
Scott Wood <scottwood@freescale.com> wrote:

> On Wed, 2014-11-05 at 12:39 +0900, Masahiro Yamada wrote:
> > [2] There is no good place to insert a callback to an SoC file.
> > I need to write parameters such as page_size to hardware registers.
> > (You can see my code, nand_denali_fixup() in arch/arm/cpu/armv7/uniphier/board_late_init.c)
> > 
> >    The NAND init procedure of U-Boot is like this:
> > 
> >    (1) board_nand_init()   (drivers/mtd/nand/denali.c)
> >    (2) nand_scan_ident()   (drivers/mtd/nand/nand_base.c)
> >    (3) nand_scan_tail()    (drivers/mtd/nand/nand_base.c)
> > 
> > 
> > 
> >   (2) detects the device size and set mtd->write_size,
> >    mtd->erase_size, mtd->oob_size.
> >   I need to set these values to the Denali hardware, but
> >   the Denali driver code is called at (1) which is called
> >   before the detection of the device size.
> > 
> >    In Linux, nand_scan_ident() and nand_scan_tail() are called
> >    from each of NAND drivers, so we can use the values which
> >    have been set during nand_scan_ident().
> > 
> >    In U-Boot, I think it is impossible.
> 
> If you use CONFIG_SYS_NAND_SELF_INIT you can insert code between
> nand_scan_ident() and nand_scan_tail(), just like in Linux.
> 

Thanks for your advice!
I have posted patches:
http://patchwork.ozlabs.org/patch/409429/
http://patchwork.ozlabs.org/patch/409428/

Best Regards
Masahiro Yamada
diff mbox

Patch

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 75c2c06..e1d6fbc 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -2,6 +2,19 @@  menu "NAND Device Support"
 
 if !SPL_BUILD
 
+config MTD_NAND_SKIP_BBTSCAN
+	bool "Skip BBT scanning"
+	help
+	  The current implementation of nand_scan_tail() calls scan_bbt handler
+	  at the end of itself to build a bad block table.  It means the first
+	  read access happens in the initizalization procedure.  It causes a
+	  problem on some SoCs that need some extra SoC-specific settings
+	  before starting read/write access.
+
+	  If this option is enabled, bad block scanning is skipped during the
+	  nand device initialization.  You are resposible to build a bad block
+	  table lator.
+
 config NAND_DENALI
 	bool "Support Denali NAND controller"
 	help
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index 4cf4c1c..a249647 100644
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -88,6 +88,10 @@  static void nand_init_chip(int i)
 	mtd->priv = nand;
 	nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
 
+#ifdef CONFIG_MTD_NAND_SKIP_BBTSCAN
+	nand->options |= NAND_SKIP_BBTSCAN;
+#endif
+
 	if (board_nand_init(nand))
 		return;