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

📄 pflash.c

📁 SigmDesign SMP8634 media decode chip development SDK
💻 C
📖 第 1 页 / 共 3 页
字号:
	if ((ret = cfi_chip_setup(h, pcfi)) != RM_OK)		return ret;	// Reset	cfi_send_cmd(h, pcfi->buswidth, 0xf0, 0, pcfi->gbus_address);	// internal settings: command set 0002	if (pcfi->ident.primary_id == 0x2)		cfi_cmdset_0002(pcfi);	return RM_OK;}static RMstatus cfi_query_present(struct gbus  *h, RMuint32 base, RMuint32 bwidth){	RMuint32 c1=cfi_read(h,  base + cfi_build_cmd_addr(0x10), bwidth) == cfi_build_cmd('Q',bwidth),	c2=cfi_read(h,  base + cfi_build_cmd_addr(0x11), bwidth) == cfi_build_cmd('R',bwidth),	c3=cfi_read(h,  base + cfi_build_cmd_addr(0x12), bwidth) == cfi_build_cmd('Y',bwidth);	// garbled by sdio --- force true	return  (c1&c2&c3) ? RM_OK:RM_NOT_FOUND;}static RMstatus cfi_chip_setup(struct gbus  *h, cfi_info *pcfi){	RMuint32 i;	RMuint32 num_erase_regions = cfi_read(h,  pcfi->gbus_address + cfi_build_cmd_addr(0x2c), pcfi->buswidth);	RMuint32 start;	if (num_erase_regions == 0)		return RM_NOT_SUPPORTED;	for (i = 0; i < (sizeof pcfi->ident) - (sizeof pcfi->ident.erase_region_info) + (num_erase_regions * 4); ++i) {		((RMuint8 *) &pcfi->ident)[i] = cfi_read(h,  pcfi->gbus_address + cfi_build_cmd_addr(0x10 + i), pcfi->buswidth);	}	//((RMuint8 *) &pcfi->ident)[0]='Q';	//((RMuint8 *) &pcfi->ident)[1]='R';	if (pcfi->ident.primary_id != 0x2) /* Not using command set 0002 */		RMDBGLOG((LOCALDBG,"warning: not using command set 0002\n"));	for (i = 0, start = 0; i < num_erase_regions; ++i) {		pcfi->erase_regions[i].start = start;		pcfi->erase_regions[i].size = 0x100 * ((pcfi->ident.erase_region_info[i] >> 16) & 0xffff);		pcfi->erase_regions[i].blocks = (pcfi->ident.erase_region_info[i] & 0xffff) + 1;		start += pcfi->erase_regions[i].size * pcfi->erase_regions[i].blocks;	}	pcfi->size = 1 << pcfi->ident.device_size;	return RM_OK;}static void cfi_cmdset_0002(cfi_info *pcfi){	switch (CFIDEV_DEVTYPE) {	case 1 : 		pcfi->addr_unlock1 = 0x555;		pcfi->addr_unlock2 = 0x2aa;		break;	case 2 : 		pcfi->addr_unlock1 = 0xaaa;		if (pcfi->buswidth == CFIDEV_BUSWIDTH_8)			pcfi->addr_unlock2 = 0x555;		else //(CFIDEV_BUSWIDTH_16 )			pcfi->addr_unlock2 = 0x554;		break;	case 4 :		pcfi->addr_unlock1 = 0x1555;		pcfi->addr_unlock2 = 0xaaa;		break;	}}//otherstatic RMint32 flash_erase_oneblock(struct gbus *h, cfi_info *pcfi, RMuint32 addr,void(*cb_usleep)(struct gbus *,RMuint32)){	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, 0x30, addr - pcfi->gbus_address, pcfi->gbus_address);	if ( flash_use_DQX )		dqx_wait(h, addr, pcfi->buswidth, 0xff, 1000*(1<<pcfi->ident.timeout_block_erase), cb_usleep);	else {		if(pcfi->ident.timeout_block_erase > 0)			(*cb_usleep)(h,1000*(1 << pcfi->ident.timeout_block_erase)); 		else //not support pcfi->ident.timeout_block_erase. 			(*cb_usleep)(h,2*1000*1000); // 2 sec	}	if ((cfi_read(h, addr, pcfi->buswidth) & 0xff) != 0xff)		return RM_ERROR;		return RM_OK;}// writing :suppose 16 bits writingstatic RMstatus flash_writable(struct gbus *h, RMuint32 addr, RMint32 len){	RMint32 i;	while (addr & 0x3) {		if ( gbus_read_remapped_uint8(h, addr++) != 0xff) {			RMDBGLOG((DISABLE,"Unwritable: 0x%x = 0x%x\n",addr-1,gbus_read_remapped_uint8(h, addr-1)));			return RM_ERROR;		}		--len;	}	for (i = 0; i < (len-3); i+=4, addr+=4) {		if ( gbus_read_remapped_uint32(h, addr) != 0xffffffff) {			RMDBGLOG((DISABLE,"Unwritable: 0x%x = 0x%x\n",addr,gbus_read_remapped_uint32(h, addr)));			return RM_ERROR;		}	}	while ((len & 0x3) > 0) {		if ( gbus_read_remapped_uint8(h, addr++) != 0xff) {			RMDBGLOG((DISABLE,"Unwritable: 0x%x = 0x%x\n",addr-1,gbus_read_remapped_uint8(h, addr-1)));			return RM_ERROR;		}		--len;	}	return RM_OK;}static RMstatus flash_write_onebyte(struct gbus  *h, cfi_info *pcfi, RMuint32 addr, RMuint32 data, void(*cb_usleep)(struct gbus *,RMuint32)){	RMuint32 curdata;	RMuint32 olddata=0, newaddr=0, newdata=0;	if(pcfi->buswidth == CFIDEV_BUSWIDTH_8) {		newaddr = addr;		olddata = curdata = cfi_read(h,  newaddr, pcfi->buswidth);		newdata = data;	} else if (pcfi->buswidth == CFIDEV_BUSWIDTH_16) {		newaddr = addr & ~0x01;		curdata = cfi_read(h,  newaddr, pcfi->buswidth);		if (addr & 0x01) {			olddata = (curdata & 0xff00) >> 8;			newdata = (curdata & 0x00ff) | ((data & 0xff) << 8);		} else {			olddata = (curdata & 0x00ff);			newdata = (curdata & 0xff00) | (data & 0xff);		}	}	if (~olddata & data) 		return RM_ERROR;	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, 0xa0, pcfi->addr_unlock1, pcfi->gbus_address);	cfi_write(h, pcfi->buswidth, newdata, newaddr);	if( flash_use_DQX )		dqx_wait(h, newaddr, pcfi->buswidth, newdata, 1<<pcfi->ident.timeout_single_write, cb_usleep);	else 		(*cb_usleep)(h, 1 << pcfi->ident.timeout_single_write);	if (cfi_read(h, newaddr, pcfi->buswidth) != newdata)		return RM_ERROR;	return RM_OK;}static RMstatus flash_write_data_internal(struct gbus *h, RMuint32 addr, RMuint16 *data, RMint32 nwords, cfi_info *pcfi, void(*cb_usleep)(struct gbus*,RMuint32)){	RMint32 i;#ifdef CFIDEV_UNLOCK_BYPASS	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, 0x20, pcfi->addr_unlock1, pcfi->gbus_address);	if (pcfi->buswidth == CFIDEV_BUSWIDTH_8) {		for (i = 0; i < (nwords << 1); ++i) {			cfi_send_cmd(h, pcfi->buswidth, 0xa0, 0, pcfi->gbus_address);			cfi_write(h, pcfi->buswidth, ((RMuint8 *) data)[i], addr + i);			if(flash_use_DQX) 				dqx_wait(h, addr + i, pcfi->buswidth, ((unsigned char *)data)[i], 1<<pcfi->ident.timeout_single_write, cb_usleep);			else 				(*cb_usleep)(h, (1<<pcfi->ident.timeout_single_write));			if (cfi_read(h, addr + i, pcfi->buswidth) != ((unsigned char *)data)[i])				return RM_ERROR;		}	} else if (pcfi->buswidth == CFIDEV_BUSWIDTH_16) {		for (i = 0; i < nwords; ++i) {			cfi_send_cmd(h, pcfi->buswidth, 0xa0, 0, pcfi->gbus_address);			cfi_write(h, pcfi->buswidth, data[i], addr + (i << 1));			if(flash_use_DQX) 				dqx_wait(h, addr + (i<<1), pcfi->buswidth, data[i], 1<<pcfi->ident.timeout_single_write, cb_usleep);			else 				(*cb_usleep)(h, (1<<pcfi->ident.timeout_single_write));			if (cfi_read(h, addr + (i<<1), pcfi->buswidth) != data[i])				return RM_ERROR;		}	}	cfi_send_cmd(h, pcfi->buswidth, 0x90, 0, pcfi->gbus_address);	cfi_send_cmd(h, pcfi->buswidth, 0x00, 0, pcfi->gbus_address);#else //CFIDEV_UNLOCK_BYPASS	if (pcfi->buswidth == CFIDEV_BUSWIDTH_8) {		for (i = 0; i < (nwords << 1); ++i) {			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, 0xa0, pcfi->addr_unlock1, pcfi->gbus_address);			cfi_write(h, pcfi->buswidth, ((RMuint8 *) data)[i], addr + i);			if(flash_use_DQX) 				dqx_wait(h, addr + i, pcfi->buswidth, ((unsigned char *)data)[i], 1<<pcfi->ident.timeout_single_write, cb_usleep);			else 				(*cb_usleep)(h, (1<<pcfi->ident.timeout_single_write));			if (cfi_read(h, addr + i, pcfi->buswidth) != ((unsigned char *)data)[i])				return RM_ERROR;		}	} else if (pcfi->buswidth == CFIDEV_BUSWIDTH_16) {		for (i = 0; i < nwords; ++i) {			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, 0xa0, pcfi->addr_unlock1, pcfi->gbus_address);			cfi_write(h, pcfi->buswidth, data[i], addr + (i << 1));			if(flash_use_DQX)				dqx_wait(h, addr + (i<<1), pcfi->buswidth, ((unsigned char *)data)[i], 1<<pcfi->ident.timeout_single_write, cb_usleep);			else 				(*cb_usleep)(h, (1<<pcfi->ident.timeout_single_write));						if (cfi_read(h, addr + (i<<1), pcfi->buswidth) != ((unsigned char *)data)[i])				return RM_ERROR;		}	}#endif //CFIDEV_UNLOCK_BYPASS	return RM_OK;}//// miscellaneous//#if (defined _DEBUG) || (defined YAMON)static char *cfi_get_idname(RMuint32 vendor){	switch (vendor) {	case CFI_PRIMARY_ID_NULL :		return "None";	case CFI_PRIMARY_ID_INTEL_EXT :		return "Intel/Sharp Extended";	case CFI_PRIMARY_ID_AMD_STD :		return "AMD/Fujitsu Standard";	case CFI_PRIMARY_ID_INTEL_STD :		return "Intel/Sharp Standard";	case CFI_PRIMARY_ID_AMD_EXT :		return "AMD/Fujitsu Extended";	case CFI_PRIMARY_ID_MITSUBISHI_STD :		return "Mitsubishi Standard";	case CFI_PRIMARY_ID_MITSUBISHI_EXT :		return "Mitsubishi Extended";	case CFI_PRIMARY_ID_SST :		return "Page Write Command Set";	case CFI_PRIMARY_ID_RESERVED :		return "Not Allowed / Reserved for Future Use";	default:		return "Unknown";	}}#endifstatic void flash_list(cfi_info *pcfi){	RMint32 j;	RMDBGLOG((ENABLE,"Parallel Flash address: 0x%x, bus width: %d\n", pcfi->gbus_address, pcfi->buswidth));	RMDBGLOG((ENABLE,"  ID : %s\n", cfi_get_idname(pcfi->ident.primary_id)));	RMDBGLOG((ENABLE,"  Size : %d KB (0x%x)\n", pcfi->size >> 10, pcfi->size)); 	RMDBGLOG((ENABLE,"  Buffer Size : %d\n", pcfi->ident.max_multibyte_write));	RMDBGLOG((ENABLE,"  Regions : %d\n", pcfi->ident.num_erase_regions));	for (j = 0; j < pcfi->ident.num_erase_regions; ++j) {		RMDBGLOG((ENABLE,"	%d : 0x%x - 0x%x * 0x%x\n", j, pcfi->erase_regions[j].start, pcfi->erase_regions[j].size,		pcfi->erase_regions[j].blocks));	}#if 0	RMDBGLOG((ENABLE,"\n"));	RMDBGLOG((ENABLE,"  timeout_single_write(typical*max)(us) : "));	if(pcfi->ident.timeout_single_write)		RMDBGLOG((ENABLE,"%d * %d\n", 1<<pcfi->ident.timeout_single_write, 1<<pcfi->ident.max_timeout_single_write));	else		RMDBGLOG((ENABLE,"not supported\n"));	RMDBGLOG((ENABLE,"  timeout_block_erase(typical*max)(ms) : "));	if(pcfi->ident.timeout_block_erase)		RMDBGLOG((ENABLE,"%d * %d\n", 1<<pcfi->ident.timeout_block_erase, 1<<pcfi->ident.max_timeout_block_erase));	else		RMDBGLOG((ENABLE,"not supported\n"));	RMDBGLOG((ENABLE,"  timeout_chip_erase(typical*max)(ms) : "));	if(pcfi->ident.timeout_chip_erase)		RMDBGLOG((ENABLE,"%d * %d\n", 1<<pcfi->ident.timeout_chip_erase, 1<<pcfi->ident.max_timeout_chip_erase));	else		RMDBGLOG((ENABLE,"not supported\n"));#endif}#ifdef YAMON //emdbg.c#define RM_MAX_STRING 512extern int vsprintf(char *buf, const char *fmt, va_list ap);#ifndef RMDBGLOG_implementationvoid RMDBGLOG_implementation(RMbool active,const RMascii *filename,RMint32 line,const RMascii *text,...){  	if (active) {		va_list ap;		char str[RM_MAX_STRING];				//snprintf((char *)str,RM_MAX_STRING,"[%s:%ld] ",(char *)filename,line);		va_start(ap, text);		//vsnprintf((char *)(str+strlen(str)), RM_MAX_STRING-strlen(str), text, ap); 		vsprintf((char *)(str), text, ap); 		va_end(ap);						//fprintf(stderr,str);		emprintk("%s",str);	}}#endif // RMDBGLOG_implementation#ifndef RMDBGPRINT_implementationvoid RMDBGPRINT_implementation(RMbool active,const RMascii *filename,RMint32 line,const RMascii *text,...){	if (active) {		va_list ap;		char str[RM_MAX_STRING];				va_start(ap, text);		//vsnprintf((char *)str,RM_MAX_STRING,text,ap); 		vsprintf((char *)str,text,ap); 		va_end(ap);				//fprintf(stderr,str);		emprintk("%s",str);	}}#endif // RMDBGPRINT_implementation#endif

⌨️ 快捷键说明

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