Exemplo n.º 1
0
int jz_sfc_set_address_mode(struct spi_flash *flash, int on)
{
	unsigned char cmd[3];
	unsigned int  buf = 0;
	int err = 0;

	if(flash->addr_size == 4){
		cmd[0] = CMD_WREN;
		if(on == 1){
			cmd[1] = CMD_EN4B;
		}else{
			cmd[1] = CMD_EX4B;
		}
		cmd[2] = CMD_RDSR;

		sfc_send_cmd(&cmd[0],0,0,0,0,0,1);

		sfc_send_cmd(&cmd[1],0,0,0,0,0,1);

		sfc_send_cmd(&cmd[2], 1,0,0,0,1,0);

		sfc_read_data(&buf, 1);
		while(buf & CMD_SR_WIP) {
			sfc_send_cmd(&cmd[2], 1,0,0,0,1,0);
			sfc_read_data(&buf, 1);
		}
	}
	return 0;
}
Exemplo n.º 2
0
static void jz_sfcnand_ext_init(void )
{
	unsigned char cmd[COMMAND_MAX_LENGTH];
	unsigned int x=0;
	/* disable write protect */
	unsigned int add;
	cmd[0]=0x1f;//get feature
	add=0xa0;

	sfc_send_cmd(&cmd[0],1,add,1,0,1,1);
	sfc_nand_write_data(&x,1);

	cmd[0]=0x1f;//get feature
	add=0xb0;
	x=0x10;
	sfc_send_cmd(&cmd[0],1,add,1,0,1,1);
	sfc_nand_write_data(&x,1);

	x=0;
	cmd[0]=CMD_GET_FEATURE;//get feature
	add=0xa0;
	sfc_send_cmd(&cmd[0],1,add,1,0,1,0);
	sfc_nand_read_data(&x,1);
	x=x&0x000000ff;
	printf("read status 0xa0 : %x\n", x);

	x=0;
	cmd[0]=CMD_GET_FEATURE;//get feature
	add=0xb0;
	sfc_send_cmd(&cmd[0],1,add,1,0,1,0);
	sfc_nand_read_data(&x,1);
	x=x&0x000000ff;
	printf("read status 0xb0 : %x\n", x);

}
Exemplo n.º 3
0
static int sfcnand_read_oob(struct mtd_info *mtd,loff_t addr,struct mtd_oob_ops *ops)
{
	int len = ops->ooblen;
	int column = mtd->writesize;
	unsigned char cmd[COMMAND_MAX_LENGTH];
	volatile unsigned int read_buf;
	int page_size = mtd->writesize;
	int page = addr / page_size;
	u_char *buffer = ops->oobbuf;
	/* the paraterms is
	* cmd , len, addr,addr_len
	* dummy_byte, daten
	* dir 0,read 1.write
	*
	* */
	cmd[0] = CMD_PARD;//write en
	sfc_send_cmd(&cmd[0],0,page,3,0,0,0);
	udelay(t_read);

	cmd[0]=CMD_GET_FEATURE;//get feature
	sfc_send_cmd(&cmd[0],1,FEATURE_ADDR,1,0,1,0);
	sfc_nand_read_data(&read_buf,1);



	while(read_buf & 0x1)
	{
		cmd[0]=CMD_GET_FEATURE;//get feature
		sfc_send_cmd(&cmd[0],1,FEATURE_ADDR,1,0,1,0);
		sfc_nand_read_data(&read_buf,1);
	}
	if((read_buf & 0x30) == 0x20) {
		printf("%s %d read error pageid = %d!!!\n",__func__,__LINE__,page);
		return 1;
	}
        switch(column_cmdaddr_bits){
        	case 24:
			cmd[0]=CMD_R_CACHE;//get feature
			column=(column<<8)&0xffffff00;
			sfc_send_cmd(&cmd[0],len,column,3,0,1,0);
			sfc_nand_read_data(buffer,len);
			break;
		case 32:
			cmd[0]=CMD_FR_CACHE;//get feature
			column=(column<<8)&0xffffff00;
			sfc_send_cmd(&cmd[0],len,column,4,0,1,0);
			sfc_nand_read_data(buffer,len);
			break;
		default:
			printk("can't support the column addr format !!!\n");
			break;
	}

	return 0;
}
Exemplo n.º 4
0
int sfc_nand_erase(struct mtd_info *mtd,int addr)
{
	unsigned char cmd[COMMAND_MAX_LENGTH];
	int erase_cmd;
	int page = addr / mtd->writesize;
	int block_size = mtd->erasesize;

	switch(block_size){
		case 4 * 1024:
			erase_cmd = CMD_ERASE_4K;
			break;
		case 32 * 1024:
			erase_cmd = CMD_ERASE_32K;
			break;
		case 64 * 1024:
			erase_cmd = CMD_ERASE_64K;
			break;
		case 128 * 1024:
			erase_cmd = CMD_ERASE_128K;
			break;
		default:
			printf("WARNING: don't support the erase size !\n");
			break;
	}

	/* the paraterms is
	* cmd , len, addr,addr_len
	* dummy_byte, daten
	* dir 0,read 1.write
	*
	* */
	volatile unsigned int x;
	cmd[0] = CMD_WREN;//write en
	sfc_send_cmd(&cmd[0],0,0,0,0,0,0);
	memset(cmd,COMMAND_MAX_LENGTH,0);
	cmd[0]=erase_cmd;//erase
	sfc_send_cmd(&cmd[0],0,page,3,0,0,0);
	memset(cmd,COMMAND_MAX_LENGTH,0);

	cmd[0]=CMD_GET_FEATURE;//get feature
	sfc_send_cmd(&cmd[0],1,0xc0,1,0,1,0);
	sfc_nand_read_data(&x,1);
	x=x&0x000000ff;
	while(x & 0x1)
	{
		x=0;
		sfc_send_cmd(&cmd[0],1,0xc0,1,0,1,0);
		sfc_nand_read_data(&x,1);
	}
	if(x & E_FAIL)
		return -1;

	return 0;
}
Exemplo n.º 5
0
int jz_sfc_chip_erase()
{

	/* the paraterms is
	 * cmd , len, addr,addr_len
	 * dummy_byte, daten
	 * dir
	 *
	 * */

	unsigned char cmd[6];
	cmd[0] = CMD_WREN;
	cmd[1] = CMD_ERASE_CE;
	cmd[5] = CMD_RDSR;
	unsigned int  buf = 0;
	int err = 0;

	if(sfc_is_init == 0){
		err = sfc_init();
		if(err < 0){
			printf("the quad mode is not support\n");
			return -1;
		}
	}

	if(sfc_quad_mode == 1){
		if(quad_mode_is_set == 0){
			sfc_set_quad_mode();
		}
	}

	jz_sfc_writel(1 << 2,SFC_TRIG);
	sfc_send_cmd(&cmd[0],0,0,0,0,0,1);

	sfc_send_cmd(&cmd[1],0,0,0,0,0,1);

	sfc_send_cmd(&cmd[5], 1,0,0,0,1,0);
	sfc_read_data(&buf, 1);
	printf("sfc start chip erase\n");
	while(buf & CMD_SR_WIP) {
		sfc_send_cmd(&cmd[5], 1,0,0,0,1,0);
		sfc_read_data(&buf, 1);
	}
	printf("########## chip erase ok ######### \n");
	return 0;
}
Exemplo n.º 6
0
int jz_sfc_read(struct spi_flash *flash, u32 offset, size_t len, void *data)
{
	unsigned char cmd[5];
	unsigned long read_len;
	unsigned int words_of_len = 0;
	unsigned int i;

	jz_sfc_set_address_mode(flash,1);

	if(sfc_quad_mode == 1){
		cmd[0]  = quad_mode->cmd_read;
		mode = quad_mode->sfc_mode;
	}else{
		cmd[0]  = CMD_READ;
		mode = TRAN_SPI_STANDARD;
	}

	for(i = 0; i < flash->addr_size; i++){
		cmd[i + 1] = offset >> (flash->addr_size - i - 1) * 8;
	}

	read_len = flash->size - offset;

	if(len < read_len)
		read_len = len;
	/* the paraterms is
		 * cmd , len, addr,addr_len
		 * dummy_byte, daten
		 * dir
		 *
		 * */

	if(sfc_quad_mode == 1){
		sfc_send_cmd(&cmd[0],read_len,offset,flash->addr_size,quad_mode->dummy_byte,1,0);
	}else{
		sfc_send_cmd(&cmd[0],read_len,offset,flash->addr_size,0,1,0);
	}
	//	dump_sfc_reg();
	sfc_read_data(data, len);

	jz_sfc_set_address_mode(flash,0);

	return 0;
}
Exemplo n.º 7
0
int sfc_nand_read_page(u_char *buffer,int page,int column,size_t rlen)
{
	unsigned char cmd[COMMAND_MAX_LENGTH];
	volatile unsigned int read_buf;

	cmd[0]=CMD_PARD;//
	sfc_send_cmd(&cmd[0],0,page,3,0,0,0);

	cmd[0]=CMD_GET_FEATURE;//get feature
	sfc_send_cmd(&cmd[0],1,FEATURE_ADDR,1,0,1,0);
	sfc_nand_read_data(&read_buf,1);
	//	printf("read_buf=%08x\n",read_buf);
	while(read_buf & 0x1)
	{
		cmd[0]=CMD_GET_FEATURE;//get feature
		sfc_send_cmd(&cmd[0],1,FEATURE_ADDR,1,0,1,0);
		sfc_nand_read_data(&read_buf,1);
	}
	if((read_buf & 0x30) == 0x20) {
		printf("%s %d read error pageid = %d!!!\n",__func__,__LINE__,page);
		return -1;
	}
	switch(column_cmdaddr_bits){
			case 24:
				cmd[0]=CMD_R_CACHE;//get feature
				column=(column<<8)&0xffffff00;
				sfc_send_cmd(&cmd[0],rlen,column,3,0,1,0);
				sfc_nand_read_data(buffer,rlen);
			break;
		case 32:
			cmd[0]=CMD_FR_CACHE;//get feature
			column=(column<<8)&0xffffff00;
			sfc_send_cmd(&cmd[0],rlen,column,4,0,1,0);
			sfc_nand_read_data(buffer,rlen);
			break;
		default:
			printk("can't support the column addr format !!!\n");
			break;
	}

	return 0;
}
Exemplo n.º 8
0
void sfc_nor_RDID(unsigned int *idcode)
{
	/* the paraterms is
	 * cmd , len, addr,addr_len
	 * dummy_byte, daten
	 * dir
	 *
	 * */
	unsigned char cmd[1];
//	unsigned char chip_id[4];
	unsigned int chip_id = 0;
	cmd[0] = CMD_RDID;
	sfc_send_cmd(&cmd[0],3,0,0,0,1,0);
	sfc_read_data(&chip_id, 1);
//	*idcode = chip_id[0];
	*idcode = chip_id & 0x00ffffff;
}
Exemplo n.º 9
0
static int sfcnand_write_oob(struct mtd_info *mtd,loff_t addr,struct mtd_oob_ops *ops)
{
	unsigned char cmd[COMMAND_MAX_LENGTH];
	int page = addr / mtd->writesize;
	int ret;

	cmd[0]=CMD_PARD;//get feature
	sfc_send_cmd(&cmd[0],0,page,3,0,0,0);
	udelay(t_read);

	ret = sfc_nand_write(mtd,addr,mtd->writesize,ops->ooblen,ops->oobbuf);
	if(ret){
		printf("WARNING: Mark bad block fail !\n");
		return -1;
	}

	return 0;
}
Exemplo n.º 10
0
void sfc_set_quad_mode()
{
	/* the paraterms is
	 * cmd , len, addr,addr_len
	 * dummy_byte, daten
	 * dir
	 *
	 * */
	unsigned char cmd[5];
	unsigned int buf = 0;
	unsigned int tmp = 0;
	int i = 10;

	if(quad_mode != NULL){
		cmd[0] = CMD_WREN;
		cmd[1] = quad_mode->WRSR_CMD;
		cmd[2] = quad_mode->RDSR_CMD;
		cmd[3] = CMD_RDSR;

		sfc_send_cmd(&cmd[0],0,0,0,0,0,1);

		sfc_send_cmd(&cmd[1],quad_mode->WD_DATE_SIZE,0,0,0,1,1);
		sfc_write_data(&quad_mode->WRSR_DATE,1);

		sfc_send_cmd(&cmd[3],1,0,0,0,1,0);
		sfc_read_data(&tmp, 1);

		while(tmp & CMD_SR_WIP) {
			sfc_send_cmd(&cmd[3],1,0,0,0,1,0);
			sfc_read_data(&tmp, 1);
		}

		sfc_send_cmd(&cmd[2], quad_mode->RD_DATE_SIZE,0,0,0,1,0);
		sfc_read_data(&buf, 1);
		while(!(buf & quad_mode->RDSR_DATE)&&((i--) > 0)) {
			sfc_send_cmd(&cmd[2], quad_mode->RD_DATE_SIZE,0,0,0,1,0);
			sfc_read_data(&buf, 1);
		}

		quad_mode_is_set = 1;
		printf("set quad mode is enable.the buf = %x\n",buf);
	}else{

		printf("the quad_mode is NULL,the nor flash id we not support\n");
	}
}
Exemplo n.º 11
0
static int jz_sfc_read_norflash_params(struct spi_flash *flash, u32 offset, size_t len, void *data)
{
	unsigned char cmd[5];
	unsigned long read_len;
	unsigned int i;

	cmd[0]  = CMD_READ;
	mode = TRAN_SPI_STANDARD;

	for(i = 0; i < flash->addr_size; i++){
		cmd[i + 1] = offset >> (flash->addr_size - i - 1) * 8;
	}

	read_len = flash->size - offset;

	if(len < read_len)
		read_len = len;

	sfc_send_cmd(&cmd[0],read_len,offset,flash->addr_size,0,1,0);
	sfc_read_data(data, len);

	return 0;
}
Exemplo n.º 12
0
static int sfc_nand_write(struct mtd_info *mtd,loff_t addr,int column,size_t len,u_char *buf)
{
	unsigned char state, cmd[COMMAND_MAX_LENGTH];
	int page_size = mtd->writesize;
	int page;// = addr / page_size;
	int wlen,i,write_num;
	int ops_len;
	u_char *buffer = buf;
	page = addr/page_size;

	write_num = (len + page_size - 1) / page_size;
	for(i = 0; i < write_num; i++)
	{
		if(len >= page_size)
			wlen = page_size;
		else
			wlen = len;

		/* the paraterms is
		* cmd , datelen,
		*addr,addr_len
		* dummy_byte, daten
		* dir 0,read 1.write
		*
		* */

		cmd[0]=CMD_PRO_LOAD;//get feature
		sfc_send_cmd(&cmd[0],wlen,column,2,0,1,1);

		ops_len = wlen;
	/*	while(ops_len) {
			if(ops_len > FIFI_THRESHOLD) {
				sfc_nand_write_data(buffer,FIFI_THRESHOLD);
				buffer += FIFI_THRESHOLD;
				ops_len -= FIFI_THRESHOLD;
			} else {
				sfc_nand_write_data(buffer,ops_len);
				buffer += ops_len;
				ops_len = 0;
			}
		}*/
		sfc_nand_write_data(buffer,ops_len);
		buffer += ops_len;
		cmd[0] = CMD_WREN;
		sfc_send_cmd(&cmd[0],0,0,0,0,0,0);

		cmd[0] = CMD_PE;
		sfc_send_cmd(&cmd[0],0,page,3,0,0,0);
		udelay(t_write);

		state=0;
		cmd[0] = CMD_GET_FEATURE;
		sfc_send_cmd(&cmd[0],1,FEATURE_ADDR,1,0,1,0);
		sfc_nand_read_data(&state,1);
		while(state & 0x1) ///////////////////////////////////////////
		{
			cmd[0] = CMD_GET_FEATURE;
			sfc_send_cmd(&cmd[0],1,FEATURE_ADDR,1,0,1,0);
			sfc_nand_read_data(&state,1);
		}

		if(state & P_FAIL){
			printf("WARNING: write fail !\n");
			return (len - i * wlen);
		}

		len -= wlen;
		page++;
	}
	return 0;
}
Exemplo n.º 13
0
int jz_sfc_erase(struct spi_flash *flash, u32 offset, size_t len)
{
	unsigned long erase_size;
	unsigned char cmd[7];
	unsigned int  buf = 0, i;


	jz_sfc_set_address_mode(flash,1);

	if((len >= 0x10000)&&((offset % 0x10000) == 0)){
		erase_size = 0x10000;
	}else if((len >= 0x8000)&&((offset % 0x8000) == 0)){
		erase_size = 0x8000;
	}else{
		erase_size = 0x1000;
	}

	if(len % erase_size != 0){
		len = len - (len % erase_size) + erase_size;
	}
//
//	if (len % erase_size) {
//		printf("Erase offset/length not multiple of erase size\n");
//		return -1;
//	}

	cmd[0] = CMD_WREN;

	switch(erase_size) {
	case 0x1000 :
		cmd[1] = CMD_ERASE_4K;
		break;
	case 0x8000 :
		cmd[1] = CMD_ERASE_32K;
		break;
	case 0x10000 :
		cmd[1] = CMD_ERASE_64K;
		break;
	default:
		printf("unknown erase size !\n");
		return -1;
	}

	cmd[flash->addr_size + 2] = CMD_RDSR;

	while(len > 0) {
		for(i = 0; i < flash->addr_size; i++){
			cmd[i+2] = offset >> (flash->addr_size - i - 1) * 8;
		}

		//	printf("erase %x %x %x %x %x %x %x \n", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], offset);

		/* the paraterms is
		 * cmd , len, addr,addr_len
		 * dummy_byte, daten
		 * dir
		 *
		 * */
		sfc_send_cmd(&cmd[0],0,0,0,0,0,1);

		sfc_send_cmd(&cmd[1],0,offset,flash->addr_size,0,0,1);

		sfc_send_cmd(&cmd[flash->addr_size + 2], 1,0,0,0,1,0);
		sfc_read_data(&buf, 1);
		while(buf & CMD_SR_WIP) {
			sfc_send_cmd(&cmd[flash->addr_size + 2], 1,0,0,0,1,0);
			sfc_read_data(&buf, 1);
		}

		offset += erase_size;
		len -= erase_size;
	}

	jz_sfc_set_address_mode(flash,0);
	return 0;
}
Exemplo n.º 14
0
int jz_sfc_write(struct spi_flash *flash, u32 offset, size_t length, const void *buf)
{
	unsigned char cmd[7];
	unsigned tmp = 0;
	int chunk_len, actual, i;
	unsigned long byte_addr;
	unsigned char *send_buf = (unsigned char *)buf;
	unsigned int pagelen = 0,len = 0,retlen = 0;

	jz_sfc_set_address_mode(flash,1);

	if (offset + length > flash->size) {
		printf("Data write overflow this chip\n");
		return -1;
	}

	cmd[0] = CMD_WREN;

	if(sfc_quad_mode == 1){
		cmd[1]  = CMD_QPP;
		mode = TRAN_SPI_QUAD;
	}else{
		cmd[1]  = CMD_PP;
		mode = TRAN_SPI_STANDARD;
	}

	cmd[flash->addr_size + 2] = CMD_RDSR;

	while (length) {
		if (length >= flash->page_size)
			pagelen = 0;
		else
			pagelen = length % flash->page_size;

		/* the paraterms is
		 * cmd , len, addr,addr_len
		 * dummy_byte, daten
		 * dir
		 *
		 * */
		sfc_send_cmd(&cmd[0],0,0,0,0,0,1);

		if (!pagelen || pagelen > flash->page_size)
			len = flash->page_size;
		else
			len = pagelen;

		if (offset % flash->page_size + len > flash->page_size)
			len -= offset % flash->page_size + len - flash->page_size;

		for(i = 0; i < flash->addr_size; i++){
			cmd[i+2] = offset >> (flash->addr_size - i - 1) * 8;
		}

		sfc_send_cmd(&cmd[1], len,offset,flash->addr_size,0,1,1);

	//	dump_sfc_reg();

		sfc_write_data(send_buf ,len);

		retlen = len;

		/*polling*/
		sfc_send_cmd(&cmd[flash->addr_size + 2],1,0,0,0,1,0);
		sfc_read_data(&tmp, 1);
		while(tmp & CMD_SR_WIP) {
			sfc_send_cmd(&cmd[flash->addr_size + 2],1,0,0,0,1,0);
			sfc_read_data(&tmp, 1);
		}

		if (!retlen) {
			printf("spi nor write failed\n");
			return -1;
		}

		offset += retlen;
		send_buf += retlen;
		length -= retlen;
	}

	jz_sfc_set_address_mode(flash,0);
	return 0;
}