示例#1
0
int spi_flash_write_aml(struct spi_flash *flash,u32 offset, size_t len, const void *buf){
	
	struct spi_slave *spi = flash->spi;
	int ret;
	unsigned temp_addr;
    int temp_length;
    temp_addr = offset;
    temp_length = len;	
	unsigned flags;
 	
	while(temp_length>0){
		
		flags=(temp_addr & 0xffffff)|( (temp_length>=32?32:temp_length) << SPI_FLASH_BYTES_LEN);
		
		spi_flash_adr_write(spi, flags);
		
		flags=SPI_XFER_WRITECACHE;

		spi_xfer(spi,(temp_length>=32?32:temp_length)*8,buf,NULL,flags);	

		
		flags=(1<<SPI_FLASH_WREN);
		spi_flash_cmd(spi,flags,NULL,0);
		
		flags=(1<<SPI_FLASH_PP);
		spi_flash_cmd(spi,flags,NULL,0);
		
		
		 ret=1;
   		 while ( (ret&1) == 1 ){
      
			flags=1<<SPI_FLASH_RDSR;
		
			spi_flash_cmd(spi,flags,&ret,2);		//2 byte status	

		
    	}
	 	
		
        temp_addr   += (temp_length>=32?32:temp_length);
		buf			+= (temp_length>=32?32:temp_length);
		temp_length -= (temp_length>=32?32:temp_length);
		 
	}	

#ifdef SPI_WRITE_PROTECT
        spi_enable_write_protect();
#endif

	return 0;


}
示例#2
0
int spi_flash_cmd_write_status_config(u8 *srcr)
{
	u8 cmd;
	int ret;
	size_t cmd_len = 1;
	size_t data_len = 2;

	ret = spi_flash_cmd(CMD_WRITE_ENABLE, NULL, 0);
	if (ret < 0) {
		print("SF: enabling write failed\n");
		return ret;
	}

	cmd = CMD_WRITE_STATUS;
	ret = spi_flash_read_write(&cmd, cmd_len, srcr, NULL, data_len);
	if (ret) {
		print("SF: fail to write status and config register\n");
		return ret;
	}
	
	ret = spi_flash_cmd_poll_bit(SPI_FLASH_PROG_TIMEOUT, CMD_READ_STATUS, STATUS_WIP);
	if (ret < 0) {
		print("SF: write status register timed out\n");
		return ret;
	}

	return 0;
}
示例#3
0
int spi_flash_read_aml(struct spi_flash *flash,u32 offset, size_t len, void *buf){

	struct spi_slave *spi = flash->spi;
	//int ret;
	u32 temp_addr;
    int temp_length;
    temp_addr = offset;
    temp_length = len;	
	unsigned flags;	
	

    /* 0x400000 ~ 0x7fffff */
    if(temp_addr + len > 0x400000 && temp_addr < 0x400000){

      flags=SPI_XFER_END|SPI_XFER_COPY;
      spi_xfer(spi,(0x400000-temp_addr)*8,&temp_addr,buf,flags);	  
      buf += (0x400000-temp_addr);
      temp_length = len - (0x400000-temp_addr);
      temp_addr = 0x400000;			
    }
    /* 0x000000 ~ 0x3fffff */
	else if(temp_addr < 0x400000){
	   flags=SPI_XFER_END|SPI_XFER_COPY;
       spi_xfer(spi,temp_length*8,&temp_addr,buf,flags);	  
	   return 0;
    }
		
	spi_claim_bus(spi);															/*FIXME for spi_xfer release bus*/	
	while(temp_length>0){
		
		flags=(temp_addr & 0xffffff)|( (temp_length>=32?32:temp_length) << SPI_FLASH_BYTES_LEN);
	
		spi_flash_adr_write(spi, flags);	
		
		flags=(1<<SPI_FLASH_READ);
		
		spi_flash_cmd(spi,flags,NULL,0);
		
		flags=SPI_XFER_READCACHE;

		spi_xfer(spi,(temp_length>=32?32:temp_length)*8,NULL,buf,flags);	

        temp_addr   += (temp_length>=32?32:temp_length);
		buf			+= (temp_length>=32?32:temp_length);	
		temp_length -= (temp_length>=32?32:temp_length);
			
	}	
		
	
	return 0;	

}
示例#4
0
struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
{
	const struct stmicro_spi_flash_params *params;
	struct spi_flash *flash;
	unsigned int i;

	if (idcode[0] == 0xff) {
		i = spi_flash_cmd(spi, CMD_M25PXX_RES, idcode, 4);
		if (i)
			return NULL;
		if ((idcode[3] & 0xf0) == 0x10) {
			idcode[0] = 0x20;
			idcode[1] = 0x20;
			idcode[2] = idcode[3] + 1;
		} else
			return NULL;
	}

	for (i = 0; i < ARRAY_SIZE(stmicro_spi_flash_table); i++) {
		params = &stmicro_spi_flash_table[i];
		if (params->idcode1 == idcode[2]) {
			break;
		}
	}

	if (i == ARRAY_SIZE(stmicro_spi_flash_table)) {
		debug("SF: Unsupported STMicro ID %02x\n", idcode[1]);
		return NULL;
	}

	flash = malloc(sizeof(*flash));
	if (!flash) {
		debug("SF: Failed to allocate memory\n");
		return NULL;
	}

	flash->spi = spi;
	flash->name = params->name;

	flash->write = spi_flash_cmd_write_multi;
	flash->erase = stmicro_erase;
	flash->read = spi_flash_cmd_read_fast;
	flash->page_size = params->page_size;
	flash->sector_size = params->page_size * params->pages_per_sector;
	flash->size = flash->sector_size * params->nr_sectors;
	flash->addr_cycles=params->addr_cycles;
	/* In first prove remove HW protection */
	if(params->protected)
		stmicro_protect(flash, 0);

	return flash;
}
示例#5
0
void spi_init(void)
{	
	u8 idcode[5];
	int ret;
	u8 cr, sr, srcr[2];
	
	/* QSPI initialize */
	writeb(0x08, &regs->spcr);
	writeb(0x00, &regs->sslp);
	writeb(0x06, &regs->sppcr);
	writeb(0x02, &regs->spbr);
	writeb(0x00, &regs->spdcr);
	writeb(0x00, &regs->spckd);
	writeb(0x00, &regs->sslnd);
	writeb(0x00, &regs->spnd);
	writew(0xe084, &regs->spcmd0);
	writew(0x8084, &regs->spcmd0);
	writeb(0xc0, &regs->spbfcr);
	writeb(0x30, &regs->spbfcr);
	writeb(0x00, &regs->spscr);
	writeb(0x48, &regs->spcr);
	
	/* Read the ID codes */
	ret = spi_flash_cmd(CMD_READ_ID, idcode, sizeof(idcode));
	if (ret)
		print("spi read id failed\n");
		
	/* enable quad transfer */
	spi_flash_cmd(CMD_READ_STATUS, &sr, 1);
	spi_flash_cmd(CMD_READ_CONFIG, &cr, 1);
	cr |= 0x02;
	srcr[0] = sr;
	srcr[1] = cr;
	if (spi_flash_cmd_write_status_config(srcr) < 0)
		print("spi_flash_cmd_write_status_config failed\n");
}
示例#6
0
static int stmicro_protect(struct spi_flash *flash, int enable)
{
	int ret;
	u8 cmd[2];

	ret = spi_claim_bus(flash->spi);
	if (ret) {
		debug("SF: Unable to claim SPI bus\n");
		return ret;
	}

	ret = 0;

	cmd[0] = CMD_M25PXX_WRSR;
	if (enable == 1)
		cmd[1] = STM_SRWD | STM_PROTECT_ALL;
	else
		cmd[1] = STM_SRWD;

	ret = spi_flash_cmd(flash->spi, CMD_M25PXX_WREN, NULL, 0);
	if (ret < 0) {
		debug("SF: Enabling Write failed\n");
		return ret;
	}

	ret = spi_flash_cmd_write(flash->spi, cmd, 2, NULL, 0);
	if (ret < 0) {
		debug("SF: STMicro Write Status Register failed\n");
		return ret;
	}

	ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
	if (ret < 0) {
		debug("SF: STMicro page programming timed out\n");
		return ret;
	}

	spi_release_bus(flash->spi);
	return ret;
}
struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
		unsigned int max_hz, unsigned int spi_mode)
{
	struct spi_slave *spi;
	struct spi_flash *flash;
	int ret;
	u8 idcode[5];

	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
	if (!spi) {
		debug("SF: Failed to set up slave\n");
		return NULL;
	}

	ret = spi_claim_bus(spi);
	if (ret) {
		debug("SF: Failed to claim SPI bus: %d\n", ret);
		goto err_claim_bus;
	}

	/* Read the ID codes */
	ret = spi_flash_cmd(spi, CMD_READ_ID, &idcode, sizeof(idcode));
	if (ret)
		goto err_read_id;

	debug("SF: Got idcode %02x %02x %02x %02x %02x\n", idcode[0],
			idcode[1], idcode[2], idcode[3], idcode[4]);

	switch (idcode[0]) {
#ifdef CONFIG_SPI_FLASH_SPANSION
	case 0x01:
		flash = spi_flash_probe_spansion(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_ATMEL
	case 0x1F:
		flash = spi_flash_probe_atmel(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_ESMT
    case 0x8c:
        flash = spi_flash_probe_esmt(spi, idcode);
        break;
#endif
#ifdef CONFIG_SPI_FLASH_MACRONIX
	case 0xc2:
		flash = spi_flash_probe_macronix(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_WINBOND
	case 0xef:
		flash = spi_flash_probe_winbond(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_GIGABYTE
	case 0xc8:
		flash = spi_flash_probe_gigabyte(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_STMICRO
	case 0x20:
		flash = spi_flash_probe_stmicro(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_SST
	case 0xBF:
		flash = spi_flash_probe_sst(spi, idcode);
		break;
#endif
	default:
		debug("SF: Unsupported manufacturer %02X\n", idcode[0]);
		flash = NULL;
		break;
	}

	if (!flash)
		goto err_manufacturer_probe;

	spi_release_bus(spi);

	return flash;

err_manufacturer_probe:
err_read_id:
	spi_release_bus(spi);
err_claim_bus:
	spi_free_slave(spi);
	return NULL;
}
示例#8
0
struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
		unsigned int max_hz, unsigned int spi_mode)
{
	struct spi_slave *spi;
	struct spi_flash *flash = NULL;
	int ret, i, shift;
	u8 idcode[IDCODE_LEN], *idp;

	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
	if (!spi) {
		printf("SF: Failed to set up slave\n");
		return NULL;
	}

	ret = spi_claim_bus(spi);
	if (ret) {
		debug("SF: Failed to claim SPI bus: %d\n", ret);
		goto err_claim_bus;
	}

	/* Read the ID codes */
	ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
	if (ret)
		goto err_read_id;

#ifdef DEBUG
	printf("SF: Got idcodes\n");
	print_buffer(0, idcode, 1, sizeof(idcode), 0);
#endif

	/* count the number of continuation bytes */
	for (shift = 0, idp = idcode;
	     shift < IDCODE_CONT_LEN && *idp == 0x7f;
	     ++shift, ++idp)
		continue;

	/* search the table for matches in shift and id */
	for (i = 0; i < ARRAY_SIZE(flashes); ++i)
		if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
			/* we have a match, call probe */
			flash = flashes[i].probe(spi, idp);
			if (flash)
				break;
		}

	if (!flash) {
		printf("SF: Unsupported manufacturer %02x\n", *idp);
		goto err_manufacturer_probe;
	}

	spi_release_bus(spi);

	return flash;

err_manufacturer_probe:
err_read_id:
	spi_release_bus(spi);
err_claim_bus:
	spi_free_slave(spi);
	return NULL;
}
示例#9
0
struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
		unsigned int max_hz, unsigned int spi_mode)
{
	struct spi_slave *spi;
	struct spi_flash *flash;
	int ret;
	u8 idcode[3];

	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
	if (!spi) {
		debug("SF: Failed to set up slave\n");
		return NULL;
	}

	ret = spi_claim_bus(spi);
	if (ret) {
		debug("SF: Failed to claim SPI bus: %d\n", ret);
		goto err_claim_bus;
	}

																				/* Read the ID codes */
	ret=spi_flash_cmd(spi,1<<SPI_FLASH_RDID,&idcode, sizeof(idcode));
	if (ret)
		goto err_read_id;

	debug("SF: Got idcode %02x %02x %02x\n", idcode[0],
			idcode[1], idcode[2]);

	switch (idcode[0]) {

#ifdef CONFIG_SPI_FLASH_ESMT
    case 0x8c:
        flash = spi_flash_probe_esmt(spi, idcode);
        break;
#endif

#ifdef CONFIG_SPI_FLASH_MACRONIX
	case 0xc2:
		flash=spi_flash_probe_mxic(spi,idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_SST
	case 0xbf:
		flash=spi_flash_probe_sst(spi,idcode);
		break;
#endif

#ifdef CONFIG_SPI_FLASH_SPANSION
	case 0x01:
		flash = spi_flash_probe_spansion(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_ATMEL
	case 0x1F:
		flash = spi_flash_probe_atmel(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_WINBOND
	case 0xef:
		flash = spi_flash_probe_winbond(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_STMICRO
	case 0x20:
		flash = spi_flash_probe_stmicro(spi, idcode);
		break;
#endif
#ifdef CONFIG_SPI_FLASH_EON:
    case 0x1c:
        flash = spi_flash_probe_eon(spi, idcode);
        break;
#endif
	default:
		debug("SF: Unsupported manufacturer %02X\n", idcode[0]);
		flash = NULL;
		break;
	}

	if (!flash)
		goto err_manufacturer_probe;
#ifdef SPI_WRITE_PROTECT
        if(spi_check_write_protect())
             printf("\nSPI NOR Flash have write protect!!!\n");
        else{
             printf("\nSPI NOR Flash NO write protect!!!, So I will enable it...\n");
             spi_enable_write_protect();
            }
#endif
	spi_release_bus(spi);

	return flash;

err_manufacturer_probe:
err_read_id:
	spi_release_bus(spi);
err_claim_bus:
	spi_free_slave(spi);
	return NULL;
}
示例#10
0
/**
 * spi_enable_quad_bit - Enable the QUAD bit for SPI flash
 *
 * This function will enable the quad bit in flash using
 * the QSPI controller. Supports only spansion.
 *
 * @spi : SPI slave structure
 */
void spi_enable_quad_bit(struct spi_slave *spi)
{
	int ret;
	u8 idcode[5];
	u8 rdid_cmd = 0x9f;	/* RDID */
	u8 rcr_data = 0;
	u8 rcr_cmd = 0x35;	/* RCR */
	u8 rdsr_cmd = 0x05;	/* RDSR */
	u8 wren_cmd = 0x06;	/* WREN */

	ret = spi_flash_cmd(spi, rdid_cmd, &idcode, sizeof(idcode));
	if (ret) {
		debug("SF error: Failed read RDID\n");
		return;
	}

	if ((idcode[0] == 0x01) || (idcode[0] == 0xef)) {
		/* Read config register */
		ret = spi_flash_cmd_read(spi, &rcr_cmd, sizeof(rcr_cmd),
					&rcr_data, sizeof(rcr_data));
		if (ret) {
			debug("SF error: Failed read RCR\n");
			return;
		}

		if (rcr_data & 0x2)
			debug("QUAD bit is already set..\n");
		else {
			debug("QUAD bit needs to be set ..\n");

			/* Write enable */
			ret = spi_flash_cmd(spi, wren_cmd, NULL, 0);
			if (ret) {
				debug("SF error: Failed write WREN\n");
				return;
			}

			/* Write QUAD bit */
			xqspips_write_quad_bit((void *)XPSS_QSPI_BASEADDR);

			/* Read RDSR */
			do {
				ret = spi_flash_cmd_read(spi, &rdsr_cmd,
						sizeof(rdsr_cmd), &rcr_data,
						sizeof(rcr_data));
			} while ((ret == 0) && (rcr_data != 0));

			/* Read config register */
			ret = spi_flash_cmd_read(spi, &rcr_cmd, sizeof(rcr_cmd),
						&rcr_data, sizeof(rcr_data));
			if (!(rcr_data & 0x2)) {
				printf("SF error: Fail to set QUAD enable bit"
					" 0x%x\n", rcr_data);
				return;
			} else
				debug("SF: QUAD enable bit is set 0x%x\n",
						rcr_data);
		}
	} else
		debug("SF: QUAD bit not enabled for 0x%x SPI flash\n",
					idcode[0]);

	return;
}