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

📄 pflash.c

📁 SigmDesign SMP8634 media decode chip development SDK
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************** Copyright (c) 2003-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* * pflash.c  */#include <string.h>#ifdef YAMON#include <stdarg.h>#include <util.h>#else#define ALLOW_OS_CODE 1#include "../llad/include/gbus.h"#include "../emhwlib_hal/include/emhwlib_registers.h"#endif#include <pflash.h>/************************************************************************ *      Definitions ************************************************************************///for dqx_wait#define FLASH_WAIT_DIV	2 /* 1 for the board without IORDY lifted, it'll try the full cycle; or more than 1 for others*/// to enable or disable the debug messages of this source file, put 1 or 0 below#if 1#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif/* * based on CFI (Common Flash Memory Interface) Specification 2.0 * supports multiple flashes, supports command set 2 (AMD standard) * * Parallel flash memory base should be remapped address base, * no cpu remap register be used inside this program. */#define CFIDEV_INTERLEAVE   1   // paired device. unused (no pair)#define CFIDEV_DEVTYPE	  2   // type : x8 = 1, x16 = 2, x32 = 4 //==2 (16 bits capable device)#define CFIDEV_UNLOCK_BYPASS	// Using unlock bypass #define PB_cs_config_CS2_8bit	4//PB_cs_config CS2 8/16bit/************************************************************************ *  Macro Definitions*************************************************************************/// for matching endian between CPU and CFI interface// CFI and HOST use same endian#define cpu_to_cfi8(x)				 (x)#define cfi8_to_cpu(x)				 (x)#define cpu_to_cfi16(x)				 (x)#define cfi16_to_cpu(x)				 (x)#define cpu_to_cfi32(x)				 (x)#define cfi32_to_cpu(x)				 (x)/************************************************************************ *  Public variables ************************************************************************/#define MAXREGIONSIZE 0x20000 //AMD:0x10000, STRARA:0x20000/************************************************************************ *  Static variables ************************************************************************//* Use DQx toggling bit to detect programming status *//* flash_use_DQX defined when R12 is not on the board, so IORDY disconnected*/static RMuint8 flash_use_DQX; static RMuint32  flash_wait_div = FLASH_WAIT_DIV;/************************************************************************ *  Static function prototypes ************************************************************************/#ifdef YAMON#define gbus_read_remapped_uint8(h,x) gbus_read_uint8(h,sigmaremap(x))#define gbus_read_remapped_uint16(h,x) gbus_read_uint16(h,sigmaremap(x))#define gbus_read_remapped_uint32(h,x) gbus_read_uint32(h,sigmaremap(x))#define gbus_write_remapped_uint8(h,x,y) gbus_write_uint8(h,sigmaremap(x),y)#define gbus_write_remapped_uint16(h,x,y) gbus_write_uint16(h,sigmaremap(x),y)#define gbus_write_remapped_uint32(h,x,y) gbus_write_uint32(h,sigmaremap(x),y)#else#define gbus_read_remapped_uint8(h,x) gbus_read_uint8(h,x)#define gbus_read_remapped_uint16(h,x) gbus_read_uint16(h,x)#define gbus_read_remapped_uint32(h,x) gbus_read_uint32(h,x)#define gbus_write_remapped_uint8(h,x,y) gbus_write_uint8(h,x,y)#define gbus_write_remapped_uint16(h,x,y) gbus_write_uint16(h,x,y)#define gbus_write_remapped_uint32(h,x,y) gbus_write_uint32(h,x,y)#endifstatic void dqx_wait(struct gbus *h, RMuint32 addr, RMuint32 buswidth, RMuint32 datum, RMuint32 wait, void(*cb_usleep)(struct gbus *,RMuint32));// CFI basic I/O -- base on CFIDEV_BUSWIDTH, read/write datastatic RMuint32 cfi_read(struct gbus  *h, RMuint32 addr, RMuint32 bwidth);static void cfi_write(struct gbus  *h, RMuint32 bwidth, RMuint32 val, RMuint32 addr);// CFI advanced I/O//base on CFIDEV_DEVTYPE,CFIDEV_INTERLEAVEstatic RMuint32 cfi_build_cmd_addr(RMuint32 addr);//base on CFIDEV_BUSWIDTH,CFIDEV_INTERLEAVEstatic RMuint32 cfi_build_cmd(RMuint32 cmd, RMuint32 bwidth);static void cfi_send_cmd(struct gbus  *h, RMuint32 bwidth, RMuint32 cmd, RMuint32 cmd_addr, RMuint32 base);// probing & setupstatic RMstatus cfi_probe_chip(struct gbus  *h, cfi_info *pcfi);static RMstatus cfi_query_present(struct gbus  *h, RMuint32 base, RMuint32 bwidth);static RMstatus cfi_chip_setup(struct gbus  *h, cfi_info *pcfi);static void cfi_cmdset_0002(cfi_info *pcfi);// others#if (defined _DEBUG) || (defined YAMON)static char *cfi_get_idname(RMuint32 vendor);#endifstatic RMint32 flash_erase_oneblock(struct gbus *h, cfi_info *pcfi, RMuint32 addr,void(*cb_usleep)(struct gbus *,RMuint32));static RMstatus flash_writable(struct gbus *h, RMuint32 addr, RMint32 len);static RMstatus flash_write_onebyte(struct gbus  *h, cfi_info *pcfi, RMuint32 addr, RMuint32 data, void(*cb_usleep)(struct gbus *,RMuint32));static RMstatus flash_write_data_internal(struct gbus *h, RMuint32 addr, RMuint16 *data, RMint32 nwords, cfi_info *pcfi, void(*cb_usleep)(struct gbus*,RMuint32));static void flash_list(cfi_info *pcfi);/************************************************************************ *      Implementation : Public functions ************************************************************************//******************************************* RMstatus flash_init(struct gbus *h, cfi_info *pcfi, RMuint32 gbus_addr, RMuint32 buswidth, RMuint8 dq56mark, RMbool disp)** Description :* Initialization parallel flash  * This function will modify CPU_remap4 register.* Only one parallel flash can be use at same time.** Input parameters:* pcfi: Pointer to parallel flash structure;* gbus_addr: Parallel flash address;* buswidth: Parallel flash bus width, 8 or 16;** Return values:* RMstatus ******************************************/RMstatus flash_init(struct gbus *h, cfi_info *pcfi, RMuint32 gbus_addr, RMuint32 buswidth, RMuint8 dq56mark, RMbool disp){	RMint32 ret;	RMint32 data;	if ( (buswidth == CFIDEV_BUSWIDTH_8) || (buswidth == CFIDEV_BUSWIDTH_16) ) {		pcfi->buswidth = buswidth; 		data = gbus_read_uint32(h,REG_BASE_host_interface + PB_CS_config);		if( (buswidth == CFIDEV_BUSWIDTH_8) && ((data & PB_cs_config_CS2_8bit)==0) ) {			data |= PB_cs_config_CS2_8bit;			gbus_write_uint32(h,REG_BASE_host_interface + PB_CS_config, data);		} else if( (buswidth == CFIDEV_BUSWIDTH_16) && ((data & PB_cs_config_CS2_8bit)!=0) ){			data &= (~PB_cs_config_CS2_8bit);			gbus_write_uint32(h,REG_BASE_host_interface + PB_CS_config, data);		}	} else		return RM_ERROR;	flash_use_DQX = dq56mark;#if (RMARCHID==RMARCHID_MIPS)	if(disp)		RMDBGLOG((ENABLE,"CPU_remap4 map to 0x%08lx\n",gbus_addr));	gbus_write_uint32(h, REG_BASE_cpu_block + CPU_remap4, gbus_addr);#endif	pcfi->gbus_address = gbus_addr;	if ((ret = cfi_probe_chip(h, pcfi)) != RM_OK) {		RMDBGLOG((LOCALDBG,"flash does not exist at address 0x%08x, bus width 0x%x\n", pcfi->gbus_address, pcfi->buswidth));		return RM_ERROR;	}	if(disp)		flash_list(pcfi);	pcfi->exist = 1;	return RM_OK;}/******************************************* RMstatus flash_erase_chip(struct gbus *h,  cfi_info *pcfi, void(*cb_usleep)(struct gbus*, RMuint32))** Description :* Erase specified parallel flash chip** Input parameters:* pcfi: Pointer to parallel flash structure** Return values:* OK: operation successful; * fail: error message******************************************/RMstatus flash_erase_chip(struct gbus *h,  cfi_info *pcfi, void(*cb_usleep)(struct gbus*, RMuint32)){	if (!pcfi->exist)		return RM_NOT_FOUND;	cfi_send_cmd(h, pcfi->buswidth, 0xaa, pcfi->addr_unlock1, pcfi->gbus_address);	cfi_send_cmd(h, pcfi->buswidth, 0x55, pcfi->addr_unlock2, pcfi->gbus_address);	cfi_send_cmd(h, pcfi->buswidth, 0x80, pcfi->addr_unlock1, pcfi->gbus_address);	cfi_send_cmd(h, pcfi->buswidth, 0xaa, pcfi->addr_unlock1, pcfi->gbus_address);	cfi_send_cmd(h, pcfi->buswidth, 0x55, pcfi->addr_unlock2, pcfi->gbus_address);	cfi_send_cmd(h, pcfi->buswidth, 0x10, pcfi->addr_unlock1, pcfi->gbus_address);	if ( flash_use_DQX ) {		if (pcfi->ident.timeout_chip_erase != 0)			dqx_wait(h, pcfi->gbus_address, pcfi->buswidth, 0xff, 1000*(1<<pcfi->ident.timeout_chip_erase), cb_usleep);		else 			dqx_wait(h, pcfi->gbus_address, pcfi->buswidth, 0xff, 1000*40, cb_usleep); //40ms	} else {		if (pcfi->ident.timeout_chip_erase != 0)			(*cb_usleep)(h, 1000*(1<<pcfi->ident.max_timeout_chip_erase)*(1<<pcfi->ident.timeout_chip_erase));		else {			RMint32 j, delay = 0;			for (j = 0; j < pcfi->ident.num_erase_regions; ++j) 				delay += pcfi->erase_regions[j].blocks;			RMDBGPRINT((LOCALDBG,"Please wait %d ms...\n",delay*(1<<pcfi->ident.timeout_block_erase)));			(*cb_usleep)(h, 1000*delay*(1<<pcfi->ident.timeout_block_erase));		}	}		if ((cfi_read(h, pcfi->gbus_address, pcfi->buswidth) & 0xff) != 0xff) {		RMDBGPRINT((LOCALDBG," erase chip fail.\n"));		return RM_ERROR;	}	return RM_OK;}/******************************************* RMstatus flash_erase_region(struct gbus *h, cfi_info *pcfi, RMuint32 addroffs, RMuint32 length, void(*cb_usleep)(struct gbus*, RMuint32))** Description :* Erase a region of specified parallel flash chip ** Input parameters:* pcfi: Pointer to parallel flash structure* addroffs: start offset address of parallel flash erase region  (0 - pflash size)* length: erase length** Return values:* OK: operation successful; * fail: error message******************************************/RMstatus flash_erase_region(struct gbus *h, cfi_info *pcfi, RMuint32 addroffs, RMuint32 length, void(*cb_usleep)(struct gbus*, RMuint32)){	RMuint32 start, blocksize;	if (length == 0)		return RM_OK;	if (!pcfi->exist)		return RM_NOT_FOUND;	if (flash_calcblock(h, pcfi, addroffs, &start, &blocksize) < 0)		return RM_NOT_FOUND;	do {		//RMDBGLOG((LOCALDBG,"erasing offset 0x%08lx (%dbytes)\n",start,blocksize));		flash_erase_oneblock(h, pcfi, start + pcfi->gbus_address, cb_usleep);		start += blocksize;		if (flash_calcblock(h, pcfi, start, &start, &blocksize) < 0)			break;	} while (start < addroffs + length);	return RM_OK;}static RMuint8 savebuf[MAXREGIONSIZE];RMstatus flash_save_erase_region(struct gbus *h,cfi_info *pcfi,RMuint32 addroffs, RMuint32 length,void(*cb_usleep)(struct gbus*,RMuint32)){	RMuint32 start, blocksize;	RMuint32 wraddr,wrlen;	if (length == 0)		return RM_OK;	if (!pcfi->exist)		return RM_NOT_FOUND;	if (flash_calcblock(h, pcfi, addroffs, &start, &blocksize) < 0)		return RM_NOT_FOUND;	do {		wraddr = addroffs - start;		wrlen = (length <= blocksize - wraddr ? length : blocksize - wraddr );		if(addroffs > start || length < blocksize) {			//read & save first			if (blocksize > MAXREGIONSIZE) {				RMDBGPRINT((LOCALDBG,"Please increase save buffer size!!\n"));				return !RM_OK;			}			flash_read_data(h, pcfi, start, savebuf, blocksize);			memset( &savebuf[wraddr], 0xff, wrlen);			if( flash_erase_oneblock(h, pcfi, start + pcfi->gbus_address, cb_usleep) != RM_OK)				return RM_ERROR;			if( flash_write_data(h, pcfi, start, savebuf, blocksize, cb_usleep) != RM_OK)				return RM_ERROR;		} else {			//just erase			if( flash_erase_oneblock(h, pcfi, start + pcfi->gbus_address, cb_usleep) != RM_OK)				return RM_ERROR;		}		start += blocksize;		if (flash_calcblock(h, pcfi, start, &start, &blocksize) < 0)			break;		addroffs += wrlen;		length -= wrlen;	} while (start < addroffs + length);	return RM_OK;}// read / writing (suppose 16 bits writing)/******************************************* RMint32 flash_read_data(struct gbus  *h, cfi_info *pcfi, RMuint32 addroffs, void *data, RMuint32 length)** Description :* Read a region of specified parallel flash chip ** Input parameters:* pcfi: Pointer to parallel flash structure* addroffs: start offset address of parallel flash read region  (0 - pflash size)* *data: destination address of read data* length: read length** Return values:* OK: operation successful; * fail: error message******************************************/RMstatus flash_read_data(struct gbus  *h, cfi_info *pcfi, RMuint32 addroffs, void *data, RMuint32 length){	RMuint32 ii;	if (!pcfi->exist)		return RM_NOT_FOUND;	if( (addroffs & 0x3) != ((RMuint32)data & 0x3) ) {		for (ii = 0; ii < length; ii++) {			*(RMuint8 *)(data + ii) = gbus_read_remapped_uint8(h, pcfi->gbus_address + addroffs + ii );		}	} else {		while (addroffs & 0x3) {			*(RMuint8 *)(data++) = gbus_read_remapped_uint8(h, pcfi->gbus_address + addroffs);			addroffs++; 			length--;

⌨️ 快捷键说明

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