diff options
Diffstat (limited to 'drivers/mtd/nand/fsl_ifc_nand.c')
| -rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 64 | 
1 files changed, 62 insertions, 2 deletions
| diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index b3b7c705e..0878bece6 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(void) +{ +	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(); @@ -797,7 +853,7 @@ int board_nand_init(struct nand_chip *nand)  	/* set up nand options */  	nand->options = NAND_NO_READRDY | NAND_NO_AUTOINCR | -			NAND_USE_FLASH_BBT; +			NAND_USE_FLASH_BBT | NAND_NO_SUBPAGE_WRITE;  	if (cspr & CSPR_PORT_SIZE_16) {  		nand->read_byte = fsl_ifc_read_byte16; @@ -861,5 +917,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;  } |