Patchwork [U-Boot] driver/mtd:IFC NAND:Initialise internal SRAM before any write

login
register
mail settings
Submitter Prabhakar Kushwaha
Date Sept. 13, 2012, 8:26 a.m.
Message ID <1347524765-19174-1-git-send-email-prabhakar@freescale.com>
Download mbox | patch
Permalink /patch/183550/
State Accepted
Delegated to: Scott Wood
Headers show

Comments

Prabhakar Kushwaha - Sept. 13, 2012, 8:26 a.m.
IFC-1.1.0 uses 28nm techenology for SRAM. This tech has known limitaion for
SRAM i.e. "byte select" is not supported. Hence Read Modify Write is
implemented in IFC for any "system side write" into sram buffer. Reading an
uninitialized memory results in ECC Error from sram wrapper.

Hence we must initialize/prefill SRAM buffer by any data before writing
anything in SRAM from system side. To initialize SRAM user can use "READID"
NAND command with read bytes equal to SRAM size. It will be a one time
activity post boot

Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
---
Based upon git://git.denx.de/u-boot.git (branch master)

This patchs depends upon following patch
    http://patchwork.ozlabs.org/patch/178332/

 drivers/mtd/nand/fsl_ifc_nand.c |   62 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)
Scott Wood - Nov. 15, 2012, 11:54 p.m.
On Wed, Sep 12, 2012 at 10:26:05PM -0000, Prabhakar Kushwaha wrote:
> IFC-1.1.0 uses 28nm techenology for SRAM. This tech has known limitaion for
> SRAM i.e. "byte select" is not supported. Hence Read Modify Write is
> implemented in IFC for any "system side write" into sram buffer. Reading an
> uninitialized memory results in ECC Error from sram wrapper.
> 
> Hence we must initialize/prefill SRAM buffer by any data before writing
> anything in SRAM from system side. To initialize SRAM user can use "READID"
> NAND command with read bytes equal to SRAM size. It will be a one time
> activity post boot
> 
> Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
> 
> ---
> Based upon git://git.denx.de/u-boot.git (branch master)
> 
> This patchs depends upon following patch
>     http://patchwork.ozlabs.org/patch/178332/
> 
>  drivers/mtd/nand/fsl_ifc_nand.c |   62 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 61 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
> index a518526..140fdc7 100644
> --- a/drivers/mtd/nand/fsl_ifc_nand.c
> +++ b/drivers/mtd/nand/fsl_ifc_nand.c
> @@ -30,6 +30,7 @@
>  #include <asm/errno.h>
>  #include <asm/fsl_ifc.h>
>  
> +#define FSL_IFC_V1_1_0	0x01010000
>  #define MAX_BANKS	4
>  #define ERR_BYTE	0xFF /* Value returned for read bytes
>  				when read failed */
> @@ -738,11 +739,66 @@ static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
>  {
>  }
>  
> +static void fsl_ifc_sram_init()

fsl_ifc_nand.c:742:13: warning: function declaration isn't a prototype

Fixed and applied to u-boot-nand-flash

-Scott

Patch

diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index a518526..140fdc7 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -30,6 +30,7 @@ 
 #include <asm/errno.h>
 #include <asm/fsl_ifc.h>
 
+#define FSL_IFC_V1_1_0	0x01010000
 #define MAX_BANKS	4
 #define ERR_BYTE	0xFF /* Value returned for read bytes
 				when read failed */
@@ -738,11 +739,66 @@  static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
 {
 }
 
+static void fsl_ifc_sram_init()
+{
+	struct fsl_ifc *ifc = ifc_ctrl->regs;
+	uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
+	long long end_tick;
+
+	cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT;
+
+	/* Save CSOR and CSOR_ext */
+	csor = in_be32(&ifc_ctrl->regs->csor_cs[cs].csor);
+	csor_ext = in_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext);
+
+	/* chage PageSize 8K and SpareSize 1K*/
+	csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
+	out_be32(&ifc_ctrl->regs->csor_cs[cs].csor, csor_8k);
+	out_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, 0x0000400);
+
+	/* READID */
+	out_be32(&ifc->ifc_nand.nand_fir0,
+			(IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) |
+			(IFC_FIR_OP_UA  << IFC_NAND_FIR0_OP1_SHIFT) |
+			(IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT));
+	out_be32(&ifc->ifc_nand.nand_fcr0,
+			NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT);
+	out_be32(&ifc->ifc_nand.row3, 0x0);
+
+	out_be32(&ifc->ifc_nand.nand_fbcr, 0x0);
+
+	/* Program ROW0/COL0 */
+	out_be32(&ifc->ifc_nand.row0, 0x0);
+	out_be32(&ifc->ifc_nand.col0, 0x0);
+
+	/* set the chip select for NAND Transaction */
+	out_be32(&ifc->ifc_nand.nand_csel, ifc_ctrl->cs_nand);
+
+	/* start read seq */
+	out_be32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
+
+	/* wait for NAND Machine complete flag or timeout */
+	end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
+
+	while (end_tick > get_ticks()) {
+		ifc_ctrl->status = in_be32(&ifc->ifc_nand.nand_evter_stat);
+
+		if (ifc_ctrl->status & IFC_NAND_EVTER_STAT_OPC)
+			break;
+	}
+
+	out_be32(&ifc->ifc_nand.nand_evter_stat, ifc_ctrl->status);
+
+	/* Restore CSOR and CSOR_ext */
+	out_be32(&ifc_ctrl->regs->csor_cs[cs].csor, csor);
+	out_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, csor_ext);
+}
+
 int board_nand_init(struct nand_chip *nand)
 {
 	struct fsl_ifc_mtd *priv;
 	struct nand_ecclayout *layout;
-	uint32_t cspr = 0, csor = 0;
+	uint32_t cspr = 0, csor = 0, ver = 0;
 
 	if (!ifc_ctrl) {
 		fsl_ifc_ctrl_init();
@@ -860,5 +916,9 @@  int board_nand_init(struct nand_chip *nand)
 		nand->ecc.mode = NAND_ECC_SOFT;
 	}
 
+	ver = in_be32(&ifc_ctrl->regs->ifc_rev);
+	if (ver == FSL_IFC_V1_1_0)
+		fsl_ifc_sram_init();
+
 	return 0;
 }