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

📄 flash_drv_intel.c

📁 MTK手机平台下载工具FLASHTOOL驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
};

const NOR_Die_Layout_S		INTEL_W_B_32 = {
	
	0x00400000,

	{
		 { 0x00000000,	8,		0x2000 }
		,{ 0x00010000,	63,		0x10000 }
		,{ 0, 0, 0 }
		,{ 0, 0, 0 }
	}
};

const NOR_Die_Layout_S		INTEL_W_B_64 = {
	
	0x00800000,

	{
		 { 0x00000000,	8,		0x2000 }
		,{ 0x00010000,	127,	0x10000 }
		,{ 0, 0, 0 }
		,{ 0, 0, 0 }
	}
};

const NOR_Die_Layout_S		INTEL_W_B_128 = {
	
	0x01000000,

	{
		 { 0x00000000,	8,		0x2000 }
		,{ 0x00010000,	255,	0x10000 }
		,{ 0, 0, 0 }
		,{ 0, 0, 0 }
	}
};

// W18/W30 series (Dual Boot) 
const NOR_Die_Layout_S		INTEL_W_TB_32 = {
	
	0x00400000,

	{
		 { 0x00000000,	8,		0x2000 }
		,{ 0x00010000,	62,		0x10000 }
		,{ 0x003F0000,	8,		0x2000 }
		,{ 0, 0, 0 }
	}
};

const NOR_Die_Layout_S		INTEL_W_TB_64 = {
	
	0x00800000,

	{
		 { 0x00000000,	8,		0x2000 }
		,{ 0x00010000,	126,	0x10000 }
		,{ 0x007F0000,	8,		0x2000 }
		,{ 0, 0, 0 }
	}
};

const NOR_Die_Layout_S		INTEL_W_TB_128 = {
	
	0x01000000,

	{
		 { 0x00000000,	8,		0x2000 }
		,{ 0x00010000,	254,	0x10000 }
		,{ 0x00FF0000,	8,		0x2000 }
		,{ 0, 0, 0 }
	}
};

// Sibley series (pure 128KW sectors) 
const NOR_Die_Layout_S		INTEL_M18_128 = {
	
	0x01000000,

	{
		 { 0x00000000,	64,		0x40000 }
		,{ 0, 0, 0 }
		,{ 0, 0, 0 }
		,{ 0, 0, 0 }
	}
};

const NOR_Die_Layout_S		INTEL_M18_256 = {
	
	0x02000000,

	{
		 { 0x00000000,	128,	0x40000 }
		,{ 0, 0, 0 }
		,{ 0, 0, 0 }
		,{ 0, 0, 0 }
	}
};

const NOR_Die_Layout_S		INTEL_M18_512 = {
	
	0x04000000,

	{
		 { 0x00000000,	256,	0x40000 }
		,{ 0, 0, 0 }
		,{ 0, 0, 0 }
		,{ 0, 0, 0 }
	}
};

//------------------------------------------------------------------------------
// Check Device ID Callback Function                                            
//------------------------------------------------------------------------------
bool INTEL_CheckDevID(const uint16 dev, volatile uint16 *die1_addr, volatile uint16 *die2_addr) {

	uint16	die1_manufacture_code;
	uint16	die1_dev_code;
	uint16	die2_manufacture_code;
	uint16	die2_dev_code;
	uint16	die_count = 0;
	bool	ret;

	// clear status register first 
	die1_addr[0x0] = INTEL_CMD_CLR_SR;

	// issue device id command 
	die1_addr[0x0] = INTEL_CMD_READ_ID;

	// read manufacture id and device code 
	die1_manufacture_code = die1_addr[0x0];
	die1_dev_code = die1_addr[0x01];

	// compare id 
	if( g_FlashDevTbl[dev].m_hw_info.m_manufacture_code != die1_manufacture_code )
		goto not_match;

	// if manufacture code exist, temporarily record flash id to g_HW_DetectionResult 
	g_HW_DetectionResult.m_flash_dev_code_1 = die1_manufacture_code;
	g_HW_DetectionResult.m_flash_dev_code_2 = die1_dev_code;

	if( g_FlashDevTbl[dev].m_hw_info.m_dev_code != die1_dev_code )
		goto not_match;

	// die1 id matched, continue to check if this flash is dual stack 
	if( 0 != memcmp((void *)die1_addr, (void *)die2_addr, 64) ) {
		// if it's dual stack, the 2nd die baseaddr won't enter auto-select mode, 
		// the data locate in die1 and die2 address won't be the same. 
		die_count = 2;
	}
	else {
		// otherwise the 2nd baseaddr will enter auto-select mode due to address wrap, 
		// the data locate in die1 and die2 address will be the same. 
		die_count = 1;
	}

	// if die count matched, return true 
	if( die_count == FLASH_DIE_COUNT(dev) ) {
		// compare die2 id 
		if( (2 == FLASH_DIE_COUNT(dev)) && 
			(0 != g_FlashDevTbl[dev].m_hw_info.m_ext_dev_code1) && 
			(0 != g_FlashDevTbl[dev].m_hw_info.m_ext_dev_code2)
		) {
			// clear status register first 
			die2_addr[0x0] = INTEL_CMD_CLR_SR;

			// issue device id command 
			die2_addr[0x0] = INTEL_CMD_READ_ID;

			// read manufacture id and device code 
			die2_manufacture_code = die2_addr[0x0];
			die2_dev_code = die2_addr[0x01];

			// compare id 
			if( g_FlashDevTbl[dev].m_hw_info.m_ext_dev_code1 != die2_manufacture_code )
				goto not_match;

			// if manufacture code exist, temporarily record flash id to g_HW_DetectionResult 
			g_HW_DetectionResult.m_flash_dev_code_3 = die2_manufacture_code;
			g_HW_DetectionResult.m_flash_dev_code_4 = die2_dev_code;

			if( g_FlashDevTbl[dev].m_hw_info.m_ext_dev_code2 != die2_dev_code )
				goto not_match;
		}

		// found 
		goto match;
	}

not_match:
	ret = FALSE;
	goto end;

match:
	ret = TRUE;

end:
	// reset die1 to read mode 
	die1_addr[0x0] = INTEL_CMD_READ_ARRAY;
	// reset die2 to read mode 
	die2_addr[0x0] = INTEL_CMD_READ_ARRAY;

	return ret;
}


//------------------------------------------------------------------------------
// Check If Device Is Idle Callback Function                                    
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Erase Related Callback Function                                              
//------------------------------------------------------------------------------
void INTEL_Erase_Block_CMD(const uint32 blockaddr)
{
	volatile uint16 *ba = (volatile uint16 *)blockaddr;

	// clear status register first 
	ba[0x0] = INTEL_CMD_CLR_SR;

	// unlock block first 
	ba[0x0] = INTEL_CMD_SW_UNLOCK_STEP1;
	ba[0x0] = INTEL_CMD_SW_UNLOCK_STEP2;

	// erase 
	ba[0x0] = INTEL_CMD_ERASE_STEP1;
	ba[0x0] = INTEL_CMD_ERASE_STEP2;
}

STATUS_E INTEL_Erase_CheckDone(const uint32 blockaddr)
{
	volatile uint16 *ba = (volatile uint16 *)blockaddr;
	volatile uint16 sr;

	// read SR 
	ba[0x0] = INTEL_CMD_READ_SR;
	sr = *ba;

	if( !(sr&INTEL_SR7_DWS_BIT) ) {
		return S_IN_PROGRESS;
	}
	else if(sr&INTEL_SR3_VPPS_BIT) {
		return S_VPP_RANGE_ERR;
	}
	else if( (sr&INTEL_SR4_PS_BIT) && (sr&INTEL_SR5_ES_BIT) ) {
		return S_CMD_ERR;
	}
	else if(sr&INTEL_SR5_ES_BIT) {
		return S_ERASE_FAILED;
	}
	else if(sr&INTEL_SR1_BLS_BIT) {
		return S_BLOCK_LOCKED_ERR;
	}

	// reset to read mode 
	ba[0x0] = INTEL_CMD_READ_ARRAY;
	return S_DONE;
}

//------------------------------------------------------------------------------
// Program Related Callback Function                                            
//------------------------------------------------------------------------------
void INTEL_PreProcess_32WORD_BUFPGM(const uint16 dev) {
	// set max buffered program size 
	g_FLASH_MAX_BUFPGM_SIZE_IN_BYTE = 64; // 32 WORDs 
}

void INTEL_Block_Unlock(const uint32 blockaddr)
{
	volatile uint16 *ba = (volatile uint16 *)blockaddr;
	
	// clear status register first 
	ba[0x0] = INTEL_CMD_CLR_SR;

	// unlock 
	ba[0x0] = INTEL_CMD_SW_UNLOCK_STEP1;
	ba[0x0] = INTEL_CMD_SW_UNLOCK_STEP2;

	// reset to read mode 
	ba[0x0] = INTEL_CMD_READ_ARRAY;
}

void INTEL_Word_Program(const uint32 blockaddr, const uint32 prog_addr, const uint16 data)
{
	volatile uint16 *pa = (volatile uint16 *)prog_addr;
	
	// clear status register first 
	*pa = INTEL_CMD_CLR_SR;

	// word program 
	*pa = INTEL_CMD_WORD_PGM;
	*pa = data;
}

STATUS_E INTEL_Word_Program_CheckDone(const uint32 prog_addr)
{
	volatile uint16 *pa = (volatile uint16 *)prog_addr;
	volatile uint16 sr;

	// read SR 
	*pa = INTEL_CMD_READ_SR;
	sr = *pa;

	if( !(sr&INTEL_SR7_DWS_BIT) ) {
		return S_IN_PROGRESS;
	}
	else if(sr&INTEL_SR3_VPPS_BIT) {
		return S_VPP_RANGE_ERR;
	}
	else if(sr&INTEL_SR4_PS_BIT) {
		return S_PGM_FAILED;
	}
	else if(sr&INTEL_SR1_BLS_BIT) {
		return S_BLOCK_LOCKED_ERR;
	}

	// reset to read mode 
	*pa = INTEL_CMD_READ_ARRAY;

	return S_DONE;
}

void INTEL_Buf_Program(const uint32 blockaddr, const uint32 prog_addr, const uint16 *data, const uint32 length_in_word)
{
	//                                                                                     
	// Be careful!! Before you invoke this function, you must calculate a reasonable       
	// length_in_word and make sure the program data won't exceed the sector boundary.     
	//                                                                                     
	volatile uint16 *pa = (volatile uint16 *)prog_addr;
	uint32		i;

	// clear status register first 
	*pa = INTEL_CMD_CLR_SR;

	// enter buffered programming 
	*pa = INTEL_CMD_BUF_PGM;
		
	// set data count 
	*pa = length_in_word-1;

	for(i=0; i<length_in_word; i++) {
		// fill data to device buffer 
		pa[i] = data[i];
	}

	// set confirm command to flush buffer to flash 
	*pa = INTEL_CMD_BUF_PGM_CNF;
}

//------------------------------------------------------------------------------
// Sibley Related Callback Function                                             
//------------------------------------------------------------------------------
void INTEL_Sibley_PreProcess_1KB_BUFPGM(const uint16 dev) {
	// set max buffered program size 
	g_FLASH_MAX_BUFPGM_SIZE_IN_BYTE = INTEL_SIBLEY_PGM_REGION_SIZE_IN_BYTE; // 1KB 
}

STATUS_E INTEL_Sibley_Program_CheckDone(const uint32 prog_addr)
{
	volatile uint16 *pa = (volatile uint16 *)prog_addr;
	volatile uint16 sr;

	// read SR 
	*pa = INTEL_CMD_READ_SR;
	sr = *pa;

	if( !(sr&INTEL_SR7_DWS_BIT) ) {
		return S_IN_PROGRESS;
	}
	else if(sr&INTEL_SR3_VPPS_BIT) {
		return S_VPP_RANGE_ERR;
	}
	else if(sr&INTEL_SR4_PS_BIT) {
		switch(sr&INTEL_RPS_MASK) {
		case INTEL_RPS_REWRITE_OBJ_MODE_REGION:
			return S_SIBLEY_REWRITE_OBJ_MODE_REGION;
		case INTEL_RPS_WRITE_B_HALF_IN_CTRL_MODE_REGION:
			return S_SIBLEY_WRITE_B_HALF_IN_CTRL_MODE_REGION;
		case INTEL_RPS_ILLEGAL_CMD:
			return S_SIBLEY_ILLEGAL_CMD;
		default:
			return S_PGM_FAILED;
		}
	}
	else if(sr&INTEL_SR1_BLS_BIT) {
		return S_BLOCK_LOCKED_ERR;
	}

	// reset to read mode 
	*pa = INTEL_CMD_READ_ARRAY;

	return S_DONE;
}

void INTEL_Sibley_Buf_Program(const uint32 blockaddr, const uint32 prog_addr, const uint16 *data, const uint32 length_in_word)
{
	//                                                                                     
	// Be careful!! Before you invoke this function, you must calculate a reasonable       
	// length_in_word and make sure the program data won't exceed the sector boundary.     
	//                                                                                     
	volatile uint16 *pa = (volatile uint16 *)prog_addr;
	uint32		i;

	// clear status register first 
	*pa = INTEL_CMD_CLR_SR;

	// enter buffered programming 
	*pa = INTEL_CMD_SIBLEY_BUF_PGM;
		
	// set data count 
	*pa = length_in_word-1;

	for(i=0; i<length_in_word; i++) {
		// fill data to device buffer 
		pa[i] = data[i];
	}

	// set confirm command to flush buffer to flash 
	*pa = INTEL_CMD_BUF_PGM_CNF;
}

//------------------------------------------------------------------------------
// Protection Related Callback Function                                         
//------------------------------------------------------------------------------

⌨️ 快捷键说明

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