aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/fsl_ifc_nand.c
diff options
context:
space:
mode:
authorPrabhakar Kushwaha <prabhakar@freescale.com>2012-09-13 04:54:49 -0400
committerKumar Gala <galak@kernel.crashing.org>2012-09-27 08:32:25 -0400
commit10bfa766efa19c23f72f50727952a26cb1512256 (patch)
tree0159c1ef2daeeab8f40c7e10e6c40ff375e26d87 /drivers/mtd/nand/fsl_ifc_nand.c
parent59c58c324a81cfb08c490384a7c292b82609673a (diff)
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>
Diffstat (limited to 'drivers/mtd/nand/fsl_ifc_nand.c')
-rw-r--r--drivers/mtd/nand/fsl_ifc_nand.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 9602c1b7e27e..01e2f2e87d8c 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -31,6 +31,7 @@
31#include <linux/mtd/nand_ecc.h> 31#include <linux/mtd/nand_ecc.h>
32#include <asm/fsl_ifc.h> 32#include <asm/fsl_ifc.h>
33 33
34#define FSL_IFC_V1_1_0 0x01010000
34#define ERR_BYTE 0xFF /* Value returned for read 35#define ERR_BYTE 0xFF /* Value returned for read
35 bytes when read failed */ 36 bytes when read failed */
36#define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait 37#define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait
@@ -773,13 +774,62 @@ static int fsl_ifc_chip_init_tail(struct mtd_info *mtd)
773 return 0; 774 return 0;
774} 775}
775 776
777static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
778{
779 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
780 struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
781 uint32_t csor = 0, csor_8k = 0, csor_ext = 0;
782 uint32_t cs = priv->bank;
783
784 /* Save CSOR and CSOR_ext */
785 csor = in_be32(&ifc->csor_cs[cs].csor);
786 csor_ext = in_be32(&ifc->csor_cs[cs].csor_ext);
787
788 /* chage PageSize 8K and SpareSize 1K*/
789 csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
790 out_be32(&ifc->csor_cs[cs].csor, csor_8k);
791 out_be32(&ifc->csor_cs[cs].csor_ext, 0x0000400);
792
793 /* READID */
794 out_be32(&ifc->ifc_nand.nand_fir0,
795 (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) |
796 (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
797 (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT));
798 out_be32(&ifc->ifc_nand.nand_fcr0,
799 NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT);
800 out_be32(&ifc->ifc_nand.row3, 0x0);
801
802 out_be32(&ifc->ifc_nand.nand_fbcr, 0x0);
803
804 /* Program ROW0/COL0 */
805 out_be32(&ifc->ifc_nand.row0, 0x0);
806 out_be32(&ifc->ifc_nand.col0, 0x0);
807
808 /* set the chip select for NAND Transaction */
809 out_be32(&ifc->ifc_nand.nand_csel, cs << IFC_NAND_CSEL_SHIFT);
810
811 /* start read seq */
812 out_be32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
813
814 /* wait for command complete flag or timeout */
815 wait_event_timeout(ctrl->nand_wait, ctrl->nand_stat,
816 IFC_TIMEOUT_MSECS * HZ/1000);
817
818 if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
819 printk(KERN_ERR "fsl-ifc: Failed to Initialise SRAM\n");
820
821 /* Restore CSOR and CSOR_ext */
822 out_be32(&ifc->csor_cs[cs].csor, csor);
823 out_be32(&ifc->csor_cs[cs].csor_ext, csor_ext);
824}
825
776static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) 826static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
777{ 827{
778 struct fsl_ifc_ctrl *ctrl = priv->ctrl; 828 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
779 struct fsl_ifc_regs __iomem *ifc = ctrl->regs; 829 struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
780 struct nand_chip *chip = &priv->chip; 830 struct nand_chip *chip = &priv->chip;
781 struct nand_ecclayout *layout; 831 struct nand_ecclayout *layout;
782 u32 csor; 832 u32 csor, ver;
783 833
784 /* Fill in fsl_ifc_mtd structure */ 834 /* Fill in fsl_ifc_mtd structure */
785 priv->mtd.priv = chip; 835 priv->mtd.priv = chip;
@@ -874,6 +924,10 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
874 chip->ecc.mode = NAND_ECC_SOFT; 924 chip->ecc.mode = NAND_ECC_SOFT;
875 } 925 }
876 926
927 ver = in_be32(&ifc->ifc_rev);
928 if (ver == FSL_IFC_V1_1_0)
929 fsl_ifc_sram_init(priv);
930
877 return 0; 931 return 0;
878} 932}
879 933