⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mx37_nfc.h

📁 freescale atk source code
💻 H
字号:
/*****************************************************************************
** mx37_nfc.h
**
** Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
**
** This file contains copyrighted material. Use of this file is
** restricted by the provisions of a Freescale Software License
** Agreement, which has either been electronically accepted by
** you or has been expressly executed between the parties.
**
** Description: Explanation for the usage of this file.
**
** Revision History:
** -----------------
*****************************************************************************/

#ifndef __MX37_NFC_H__
#define __MX37_NFC_H__

#include "type.h"
#include "flash_lib.h"

#define CCM_BASE_ADDR  		(0xE3F8C000)
#define CCM_CBCDR7          (CCM_BASE_ADDR+0x2C)
#define CCM_CCDR            (CCM_BASE_ADDR+0x4)

#define NFC_BASE_ADDR	    (0x7FFF0000)
#define NFC_IP_BASE			(0xE3FDB000)

#define NFC_MAB0_BASE       (NFC_BASE_ADDR+0x000)
#define NFC_MAB1_BASE       (NFC_BASE_ADDR+0x200)
#define NFC_MAB2_BASE       (NFC_BASE_ADDR+0x400)
#define NFC_MAB3_BASE       (NFC_BASE_ADDR+0x600)
#define NFC_MAB4_BASE       (NFC_BASE_ADDR+0x800)
#define NFC_MAB5_BASE       (NFC_BASE_ADDR+0xA00)
#define NFC_MAB6_BASE       (NFC_BASE_ADDR+0xC00)
#define NFC_MAB7_BASE       (NFC_BASE_ADDR+0xE00)

#define NFC_SAB0_BASE       (NFC_BASE_ADDR+0x1000)
#define NFC_SAB1_BASE       (NFC_BASE_ADDR+0x1040)
#define NFC_SAB2_BASE       (NFC_BASE_ADDR+0x1080)
#define NFC_SAB3_BASE       (NFC_BASE_ADDR+0x10C0)
#define NFC_SAB4_BASE       (NFC_BASE_ADDR+0x1100)
#define NFC_SAB5_BASE       (NFC_BASE_ADDR+0x1140)
#define NFC_SAB6_BASE       (NFC_BASE_ADDR+0x1180)
#define NFC_SAB7_BASE       (NFC_BASE_ADDR+0x11C0)
#define NFC_SAB_LEN         (64)
#define NFC_SAB_COUNT       (8)

#define NFC_REG_BASE            (NFC_BASE_ADDR+0x1E00)
#define NFC_FLASH_ADDR_CMD      (NFC_REG_BASE+0x00)
#define NFC_NF_CONFIG1          (NFC_REG_BASE+0x04)
#define NFC_ECC_STAT_RSLT       (NFC_REG_BASE+0x08)
#define NFC_LAUNCH_NFC          (NFC_REG_BASE+0x0C)

#define NFC_NF_WR_PROT    (NFC_IP_BASE+0x00)
#define NFC_ULOCK_BLK0    (NFC_IP_BASE+0x04)
#define NFC_ULOCK_BLK1    (NFC_IP_BASE+0x08)
#define NFC_ULOCK_BLK2    (NFC_IP_BASE+0x0C)
#define NFC_ULOCK_BLK3    (NFC_IP_BASE+0x10)
#define NFC_NF_CONFIG2    (NFC_IP_BASE+0x14)
#define NFC_IPC			  (NFC_IP_BASE+0x18)
#define NFC_AXI_ERR_ADD	  (NFC_IP_BASE+0x1c)

#define NAND_CMD_READ              (0x00)
#define NAND_CMD_READ1             (0x01)
#define NAND_CMD_READ2             (0x50)
#define NAND_CMD_READ_CONFIRM      (0x30)
#define NAND_CMD_PAGE_PROG         (0x80)
#define NAND_CMD_PAGE_PROG_CONFIRM (0x10)
#define NAND_CMD_ERASE             (0x60)
#define NAND_CMD_ERASE_CONFIRM     (0xD0)
#define NAND_CMD_READID            (0x90)
#define NAND_CMD_RESET             (0xFFFF)
#define NAND_CMD_READ_STATUS       (0x70)
/* nand status marco */
#define NAND_STATUS_READY          (0x40)
#define NAND_STATUS_NOT_PROTECT    (0x80)
#define NAND_STATUS_PROG_ERROR     (0x01)
/* FMS & bus width */
#define NF_FMS_2KB                 (0x00000100)
#define NF_4KB					   (0x00000200)
#define NF_16BIT                   (0x00004000)
#define NFC_OPS_STAT			   (1 << 31)
#define NFC_IPC_CREQ			   (1 << 0)
#define NFC_IPC_ACK				   (1<<1)
#define NFC_ECC_MODE_4    		   (1<<6)
#define NFC_ECC_MODE_8			   ~(1<<6)
#define RBA_RESET			  	   ~(7 << 4)
#define SPAS_MASK			      (0xFF00FFFF)
#define RBA_BUFFER0			      (0 << 4)
#define RBA_BUFFER0			      (0 << 4)
#define RBA_BUFFER1			      (1 << 4)
#define RBA_BUFFER2			      (2 << 4)
#define RBA_BUFFER3			      (3 << 4)

#define IS_4BIT_ECC			\
	((raw_read(NFC_NF_CONFIG2) & NFC_ECC_MODE_4)>>6)

#define WRITE_NFC_IP_REG(val,reg) \
	do {	 \
		raw_write(NFC_IPC_CREQ, NFC_IPC); \
		while(!((*(volatile u32*)NFC_IPC & NFC_IPC_ACK)>>1));\
		raw_write(val, reg);\
		raw_write(0, NFC_IPC);\
	}while(0)

#define NFC_SET_RBA(val, buf_id)       \
	val = ((raw_read(NFC_NF_CONFIG1) & RBA_RESET) | buf_id);

#define SET_SPAS(v)			\
	raw_write(((raw_read(NFC_NF_CONFIG2) & SPAS_MASK) | ((v)<<16)),NFC_NF_CONFIG2)

#define NFC_SEL_RAM_BUFFER(val) \
	raw_write(((raw_read(NFC_NF_CONFIG1) & RBA_RESET) | val), NFC_NF_CONFIG1);

#define SPAS_64		(32) /* half word */
#define SPAS_128    (64) /* half word */

/*marco to detect the busy status*/
#define NFC_BUSY  (!( *(volatile u32 *)NFC_IPC & 0x80000000 ))

/*marco to define the raw_read/write*/
#define raw_read(addr) *(u32 *)((addr))
#define raw_write(val,addr) *((u32 *)(addr)) = (val)

/* main area for bad block marker*/
#define BAD_BLK_MARKER_OFFS      \
	(NAND_MAIN_BYTESIZE - (((((NAND_SPARE_BYTESIZE /(NAND_MAIN_BYTESIZE >> 9)) >> 1)) << 1) * \
	((NAND_MAIN_BYTESIZE >> 9) -1 )))
#define BAD_BLK_MARKER_MAIN 	(*((volatile u16 *)(NFC_MAB0_BASE + BAD_BLK_MARKER_OFFS)))
/* spare area for swapped main area data */
#define BAD_BLK_MARKER_SP_OFFS     \
	(((NAND_MAIN_BYTESIZE >> 9) - 1) * NFC_SAB_LEN)
#define BAD_BLK_MARKER_SP_0     (*((volatile u16 *)(NFC_SAB0_BASE + BAD_BLK_MARKER_SP_OFFS)))

#define NAND_MAIN_BYTESIZE          (nand->page_size)
extern nand_t* nand;

/*!
 * Function to wait for basic NFC operation completion
 */
static u8 nfc_wait(void)
{
	while (1) {
		if (raw_read(NFC_IPC) & NFC_OPS_STAT) {
			WRITE_NFC_IP_REG((raw_read(NFC_IPC) & ~NFC_OPS_STAT), NFC_IPC);
			break;
		}

	}
	return 0;
}

/*!
 * Function to input address
 */
static void nfc_address_input(u32 address)
{
	*(volatile u32 *)NFC_FLASH_ADDR_CMD = address<<16;
	*(volatile u32 *)NFC_LAUNCH_NFC = 0x0002;
	nfc_wait();
}

/*!
 * Function to write flash address cycle
 */
static void nfc_address_cycle(u32 Address, u8 NumOfCycle)
{
	u8 i;

	for(i=0; i<NumOfCycle; i++)
		nfc_address_input( (u16)( (Address>>(i*8))&0xFF ) );
}

/*!
 * Function to input command
 */
static void nfc_command_input(u16 command)
{
	*(volatile u32 *)NFC_FLASH_ADDR_CMD  = command;
	*(volatile u32 *)NFC_LAUNCH_NFC      = 0x0001;
	nfc_wait();
}

/*!
 * Function to input data
 */
static void nfc_flash_data_input(void)
{
	*(volatile u32 *)NFC_LAUNCH_NFC = 0x0004;
	nfc_wait();
}

/*!
 * Function to output data
 */
static void nfc_flash_data_output(void)
{
	*(volatile u32 *)NFC_LAUNCH_NFC = 0x0008;
	nfc_wait();
}

/*!
 * Function to send command to read page
 */
void send_read_page(void)
{
	NFC_SEL_RAM_BUFFER(RBA_BUFFER0);
	nfc_flash_data_output();
}

/*!
 * Function to send command to write page
 */
void send_prog_page(void)
{
	NFC_SEL_RAM_BUFFER(RBA_BUFFER0);
	nfc_flash_data_input();
}

/*!
 * Function to read status from nand flash register
 */
u8 nand_read_status(void)
{
	NFC_SEL_RAM_BUFFER(RBA_BUFFER0);

	nfc_command_input(NAND_CMD_READ_STATUS);
	/* Read Status */
	*(volatile u32 *)NFC_LAUNCH_NFC = 0x0020;
	nfc_wait();

	return (u8)((*(volatile u32 *)(NFC_MAB0_BASE)) & 0xFF) ;
}
/*!
 * Function to wait nand ready
 */
void nand_wait(void)
{
	while(!(NAND_STATUS_READY  & nand_read_status()));
}

/*!
 * Function to check ecc status
 */
u8 nfc_ecc_uncorrectable_error(u32 page_size)
{
	u32 ecc_stat, err;
	int no_subpages = 1;
	int ret = 0;
	u8 ecc_bit_mask, err_limit;

	ecc_bit_mask = (IS_4BIT_ECC ? 0x7 : 0xf);
	err_limit = (IS_4BIT_ECC ? 0x4 : 0x8);

	no_subpages = page_size>>9;

	ecc_stat = *(volatile u32 *)NFC_ECC_STAT_RSLT;

	do {
		err = ecc_stat & ecc_bit_mask;
		if (err > err_limit) {
			ret = 1;
			break;
		}
		ecc_stat >>= 4;
	} while (--no_subpages);

	return ret;

}

/*!
 * Function to set nfc spare data
 */
void  set_nfc_spare(FLASH_FILE_FORMAT file_format )
{
	u32 i,j;
	/*this is for wince spare setting */
	if (FILE_FORMAT_NB0 == file_format) {
		/* fill internal RAM buffer */
        for(j=0;j<NFC_SAB_COUNT;j++) {
  		    for(i=0; i<NFC_SAB_LEN; i+=2){
   			    if((j== ((NAND_MAIN_BYTESIZE >> 9) - 1)) && (i==0))
				    *(volatile u16 *)(NFC_SAB0_BASE+i+j*NFC_SAB_LEN) = 0xFF00;
			    else
      			    *(volatile u16 *)(NFC_SAB0_BASE+i+j*NFC_SAB_LEN) = 0xFFFF;
		    }
        }
	} else if (FILE_FORMAT_NORMAL == file_format) {
  	    /* fill internal RAM buffer */
        for(j=0;j<NFC_SAB_COUNT;j++) {
  	        for(i=0; i<NFC_SAB_LEN; i+=2) {
		        *(volatile u16 *)(NFC_SAB0_BASE+i+j*NFC_SAB_LEN) = 0xFFFF;
  	        }
        }
	}
}

/*!
 * Function to init nfc
 */
void nfc_init(void)
{
	raw_write((raw_read(CCM_CBCDR7)& ~7) | 0x6,CCM_CBCDR7);
	raw_write(raw_read(CCM_CCDR)| 0x1,CCM_CCDR);

	/*clear spas size */
	*(volatile u32 *)NFC_NF_CONFIG2 &= SPAS_MASK;

	/* select Buffer 0 */
	NFC_SEL_RAM_BUFFER(RBA_BUFFER0);

	/* unlock the blk */
	*(volatile u32 *)NFC_ULOCK_BLK0 = (0xFFFF << 16);
	/* unlock the internal RAM buffer */
	*(volatile u32 *)NFC_NF_WR_PROT	= 0x20004;

	/* clear all operation */
	*(volatile u32 *)NFC_IPC = 0x80000000;

	/* 128pages,4bit ECC,little endian,enable ECC,disable interrupt,2Kpage*/
	*(volatile u32 *)NFC_NF_CONFIG2 = 0x1149;
}

/*!
 * Function to set FMS
 */
void set_fms(u8 bus_width, u32 page_size,u16 oob_size)
{
	if(page_size == 4096) {
		/* Set to 4K Page Size */
		*(volatile u32 *)NFC_NF_CONFIG2 &= ~3;
		*(volatile u32 *)NFC_NF_CONFIG2 |= 2;
	}
	/* set the spas size */
	SET_SPAS(oob_size >>1);

}

/*!
 * Function to read id
 */
void send_read_id(u32* tmp)
{
	nfc_command_input(0x90);
	nfc_address_input(0);
	NFC_SEL_RAM_BUFFER(RBA_BUFFER0);
	*(volatile u32 *)NFC_LAUNCH_NFC = 0x0010;
	nfc_wait();
	*tmp  = *(volatile u32 *)(NFC_MAB0_BASE);
}


#endif /* __MX37_NFC_H__ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -