diff options
Diffstat (limited to 'nand_spl/nand_boot_fsl_nfc.c')
| -rw-r--r-- | nand_spl/nand_boot_fsl_nfc.c | 67 | 
1 files changed, 65 insertions, 2 deletions
| diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index 615e820bb..1096727ae 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -30,12 +30,18 @@  #include <asm/io.h>  #include <fsl_nfc.h> +#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)  static struct fsl_nfc_regs *const nfc = (void *)NFC_BASE_ADDR; +#elif defined(MXC_NFC_V3_2) +static struct fsl_nfc_regs *const nfc = (void *)NFC_BASE_ADDR_AXI; +static struct fsl_nfc_ip_regs *const nfc_ip = (void *)NFC_BASE_ADDR; +#endif  static void nfc_wait_ready(void)  {  	uint32_t tmp; +#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)  	while (!(readnfc(&nfc->config2) & NFC_V1_V2_CONFIG2_INT))  		; @@ -43,11 +49,56 @@ static void nfc_wait_ready(void)  	tmp = readnfc(&nfc->config2);  	tmp &= ~NFC_V1_V2_CONFIG2_INT;  	writenfc(tmp, &nfc->config2); +#elif defined(MXC_NFC_V3_2) +	while (!(readnfc(&nfc_ip->ipc) & NFC_V3_IPC_INT)) +		; + +	/* Reset interrupt flag */ +	tmp = readnfc(&nfc_ip->ipc); +	tmp &= ~NFC_V3_IPC_INT; +	writenfc(tmp, &nfc_ip->ipc); +#endif  }  static void nfc_nand_init(void)  { -#if defined(MXC_NFC_V2_1) +#if defined(MXC_NFC_V3_2) +	int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; +	int tmp; + +	tmp = (readnfc(&nfc_ip->config2) & ~(NFC_V3_CONFIG2_SPAS_MASK | +			NFC_V3_CONFIG2_EDC_MASK | NFC_V3_CONFIG2_PS_MASK)) | +		NFC_V3_CONFIG2_SPAS(CONFIG_SYS_NAND_SPARE_SIZE / 2) | +		NFC_V3_CONFIG2_INT_MSK | NFC_V3_CONFIG2_ECC_EN | +		NFC_V3_CONFIG2_ONE_CYCLE; +	if (CONFIG_SYS_NAND_PAGE_SIZE == 4096) +		tmp |= NFC_V3_CONFIG2_PS_4096; +	else if (CONFIG_SYS_NAND_PAGE_SIZE == 2048) +		tmp |= NFC_V3_CONFIG2_PS_2048; +	else if (CONFIG_SYS_NAND_PAGE_SIZE == 512) +		tmp |= NFC_V3_CONFIG2_PS_512; +	/* +	 * if spare size is larger that 16 bytes per 512 byte hunk +	 * then use 8 symbol correction instead of 4 +	 */ +	if (CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16) +		tmp |= NFC_V3_CONFIG2_ECC_MODE_8; +	else +		tmp &= ~NFC_V3_CONFIG2_ECC_MODE_8; +	writenfc(tmp, &nfc_ip->config2); + +	tmp = NFC_V3_CONFIG3_NUM_OF_DEVS(0) | +			NFC_V3_CONFIG3_NO_SDMA | +			NFC_V3_CONFIG3_RBB_MODE | +			NFC_V3_CONFIG3_SBB(6) | /* Reset default */ +			NFC_V3_CONFIG3_ADD_OP(0); +#ifndef CONFIG_SYS_NAND_BUSWIDTH_16 +	tmp |= NFC_V3_CONFIG3_FW8; +#endif +	writenfc(tmp, &nfc_ip->config3); + +	writenfc(0, &nfc_ip->delay_line); +#elif defined(MXC_NFC_V2_1)  	int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;  	int config1; @@ -123,7 +174,13 @@ static void nfc_nand_data_output(void)  	int i;  #endif +#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)  	writenfc(0, &nfc->buf_addr); +#elif defined(MXC_NFC_V3_2) +	int config1 = readnfc(&nfc->config1); +	config1 &= ~NFC_V3_CONFIG1_RBA_MASK; +	writenfc(config1, &nfc->config1); +#endif  	writenfc(NFC_OUTPUT, &nfc->operation);  	nfc_wait_ready();  #ifdef NAND_MXC_2K_MULTI_CYCLE @@ -144,7 +201,7 @@ static int nfc_nand_check_ecc(void)  #if defined(MXC_NFC_V1)  	u16 ecc_status = readw(&nfc->ecc_status_result);  	return (ecc_status & 0x3) == 2 || (ecc_status >> 2) == 2; -#elif defined(MXC_NFC_V2_1) +#elif defined(MXC_NFC_V2_1) || defined(MXC_NFC_V3_2)  	u32 ecc_status = readl(&nfc->ecc_status_result);  	int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;  	int err_limit = CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16 ? 8 : 4; @@ -163,7 +220,13 @@ static int nfc_nand_check_ecc(void)  static void nfc_nand_read_page(unsigned int page_address)  {  	/* read in first 0 buffer */ +#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)  	writenfc(0, &nfc->buf_addr); +#elif defined(MXC_NFC_V3_2) +	int config1 = readnfc(&nfc->config1); +	config1 &= ~NFC_V3_CONFIG1_RBA_MASK; +	writenfc(config1, &nfc->config1); +#endif  	nfc_nand_command(NAND_CMD_READ0);  	nfc_nand_page_address(page_address); |