Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

driver/mtd:IFC NAND:Initialise internal SRAM before any write

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>
Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>

authored by

Prabhakar Kushwaha and committed by
Kumar Gala
10bfa766 59c58c32

+55 -1
+55 -1
drivers/mtd/nand/fsl_ifc_nand.c
··· 31 31 #include <linux/mtd/nand_ecc.h> 32 32 #include <asm/fsl_ifc.h> 33 33 34 + #define FSL_IFC_V1_1_0 0x01010000 34 35 #define ERR_BYTE 0xFF /* Value returned for read 35 36 bytes when read failed */ 36 37 #define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait ··· 774 773 return 0; 775 774 } 776 775 776 + static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv) 777 + { 778 + struct fsl_ifc_ctrl *ctrl = priv->ctrl; 779 + struct fsl_ifc_regs __iomem *ifc = ctrl->regs; 780 + uint32_t csor = 0, csor_8k = 0, csor_ext = 0; 781 + uint32_t cs = priv->bank; 782 + 783 + /* Save CSOR and CSOR_ext */ 784 + csor = in_be32(&ifc->csor_cs[cs].csor); 785 + csor_ext = in_be32(&ifc->csor_cs[cs].csor_ext); 786 + 787 + /* chage PageSize 8K and SpareSize 1K*/ 788 + csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000; 789 + out_be32(&ifc->csor_cs[cs].csor, csor_8k); 790 + out_be32(&ifc->csor_cs[cs].csor_ext, 0x0000400); 791 + 792 + /* READID */ 793 + out_be32(&ifc->ifc_nand.nand_fir0, 794 + (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) | 795 + (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | 796 + (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT)); 797 + out_be32(&ifc->ifc_nand.nand_fcr0, 798 + NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT); 799 + out_be32(&ifc->ifc_nand.row3, 0x0); 800 + 801 + out_be32(&ifc->ifc_nand.nand_fbcr, 0x0); 802 + 803 + /* Program ROW0/COL0 */ 804 + out_be32(&ifc->ifc_nand.row0, 0x0); 805 + out_be32(&ifc->ifc_nand.col0, 0x0); 806 + 807 + /* set the chip select for NAND Transaction */ 808 + out_be32(&ifc->ifc_nand.nand_csel, cs << IFC_NAND_CSEL_SHIFT); 809 + 810 + /* start read seq */ 811 + out_be32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT); 812 + 813 + /* wait for command complete flag or timeout */ 814 + wait_event_timeout(ctrl->nand_wait, ctrl->nand_stat, 815 + IFC_TIMEOUT_MSECS * HZ/1000); 816 + 817 + if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) 818 + printk(KERN_ERR "fsl-ifc: Failed to Initialise SRAM\n"); 819 + 820 + /* Restore CSOR and CSOR_ext */ 821 + out_be32(&ifc->csor_cs[cs].csor, csor); 822 + out_be32(&ifc->csor_cs[cs].csor_ext, csor_ext); 823 + } 824 + 777 825 static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) 778 826 { 779 827 struct fsl_ifc_ctrl *ctrl = priv->ctrl; 780 828 struct fsl_ifc_regs __iomem *ifc = ctrl->regs; 781 829 struct nand_chip *chip = &priv->chip; 782 830 struct nand_ecclayout *layout; 783 - u32 csor; 831 + u32 csor, ver; 784 832 785 833 /* Fill in fsl_ifc_mtd structure */ 786 834 priv->mtd.priv = chip; ··· 923 873 } else { 924 874 chip->ecc.mode = NAND_ECC_SOFT; 925 875 } 876 + 877 + ver = in_be32(&ifc->ifc_rev); 878 + if (ver == FSL_IFC_V1_1_0) 879 + fsl_ifc_sram_init(priv); 926 880 927 881 return 0; 928 882 }