mirror of
				https://review.coreboot.org/flashrom.git
				synced 2025-11-04 07:00:39 +01:00 
			
		
		
		
	Convert SPI chip erase to use the multicommand infrastructure
Once the ICH/VIA SPI driver is converted to multicommand, a lot of hacks can disappear. Corresponding to flashrom svn r647. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Tested-by: Jakob Bornecrantz <wallbraker@gmail.com> Acked-by: Jakob Bornecrantz <wallbraker@gmail.com>
This commit is contained in:
		
							
								
								
									
										80
									
								
								spi.c
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								spi.c
									
									
									
									
									
								
							@@ -61,12 +61,30 @@ int spi_send_command(unsigned int writecnt, unsigned int readcnt,
 | 
			
		||||
 | 
			
		||||
int spi_send_multicommand(struct spi_command *spicommands)
 | 
			
		||||
{
 | 
			
		||||
	int res = 0;
 | 
			
		||||
	while ((spicommands->writecnt || spicommands->readcnt) && !res) {
 | 
			
		||||
		res = spi_send_command(spicommands->writecnt, spicommands->readcnt,
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	while ((spicommands->writecnt || spicommands->readcnt) && !ret) {
 | 
			
		||||
		ret = spi_send_command(spicommands->writecnt, spicommands->readcnt,
 | 
			
		||||
				       spicommands->writearr, spicommands->readarr);
 | 
			
		||||
		/* This awful hack needs to be replaced with a multicommand
 | 
			
		||||
		 * capable ICH/VIA SPI driver.
 | 
			
		||||
		 */
 | 
			
		||||
		if ((ret == SPI_INVALID_OPCODE) &&
 | 
			
		||||
		    ((spicommands->writearr[0] == JEDEC_WREN) ||
 | 
			
		||||
		     (spicommands->writearr[0] == JEDEC_EWSR))) {
 | 
			
		||||
			switch (spi_controller) {
 | 
			
		||||
			case SPI_CONTROLLER_ICH7:
 | 
			
		||||
			case SPI_CONTROLLER_ICH9:
 | 
			
		||||
			case SPI_CONTROLLER_VIA:
 | 
			
		||||
				printf_debug(" due to SPI master limitation, ignoring"
 | 
			
		||||
					     " and hoping it will be run as PREOP\n");
 | 
			
		||||
				ret = 0;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		spicommands++;
 | 
			
		||||
	}
 | 
			
		||||
	return res;
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int spi_rdid(unsigned char *readarr, int bytes)
 | 
			
		||||
@@ -417,21 +435,34 @@ void spi_prettyprint_status_register(struct flashchip *flash)
 | 
			
		||||
 | 
			
		||||
int spi_chip_erase_60(struct flashchip *flash)
 | 
			
		||||
{
 | 
			
		||||
	const unsigned char cmd[JEDEC_CE_60_OUTSIZE] = {JEDEC_CE_60};
 | 
			
		||||
	int result;
 | 
			
		||||
	struct spi_command spicommands[] = {
 | 
			
		||||
	{
 | 
			
		||||
		.writecnt	= JEDEC_WREN_OUTSIZE,
 | 
			
		||||
		.writearr	= (const unsigned char[]){ JEDEC_WREN },
 | 
			
		||||
		.readcnt	= 0,
 | 
			
		||||
		.readarr	= NULL,
 | 
			
		||||
	}, {
 | 
			
		||||
		.writecnt	= JEDEC_CE_60_OUTSIZE,
 | 
			
		||||
		.writearr	= (const unsigned char[]){ JEDEC_CE_60 },
 | 
			
		||||
		.readcnt	= 0,
 | 
			
		||||
		.readarr	= NULL,
 | 
			
		||||
	}, {
 | 
			
		||||
		.writecnt	= 0,
 | 
			
		||||
		.writearr	= NULL,
 | 
			
		||||
		.readcnt	= 0,
 | 
			
		||||
		.readarr	= NULL,
 | 
			
		||||
	}};
 | 
			
		||||
	
 | 
			
		||||
	result = spi_disable_blockprotect();
 | 
			
		||||
	if (result) {
 | 
			
		||||
		printf_debug("spi_disable_blockprotect failed\n");
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	result = spi_write_enable();
 | 
			
		||||
	if (result)
 | 
			
		||||
		return result;
 | 
			
		||||
	/* Send CE (Chip Erase) */
 | 
			
		||||
	result = spi_send_command(sizeof(cmd), 0, cmd, NULL);
 | 
			
		||||
	
 | 
			
		||||
	result = spi_send_multicommand(spicommands);
 | 
			
		||||
	if (result) {
 | 
			
		||||
		printf_debug("spi_chip_erase_60 failed sending erase\n");
 | 
			
		||||
		printf_debug("%s failed during command execution\n", __func__);
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	/* Wait until the Write-In-Progress bit is cleared.
 | 
			
		||||
@@ -449,21 +480,34 @@ int spi_chip_erase_60(struct flashchip *flash)
 | 
			
		||||
 | 
			
		||||
int spi_chip_erase_c7(struct flashchip *flash)
 | 
			
		||||
{
 | 
			
		||||
	const unsigned char cmd[JEDEC_CE_C7_OUTSIZE] = { JEDEC_CE_C7 };
 | 
			
		||||
	int result;
 | 
			
		||||
	struct spi_command spicommands[] = {
 | 
			
		||||
	{
 | 
			
		||||
		.writecnt	= JEDEC_WREN_OUTSIZE,
 | 
			
		||||
		.writearr	= (const unsigned char[]){ JEDEC_WREN },
 | 
			
		||||
		.readcnt	= 0,
 | 
			
		||||
		.readarr	= NULL,
 | 
			
		||||
	}, {
 | 
			
		||||
		.writecnt	= JEDEC_CE_C7_OUTSIZE,
 | 
			
		||||
		.writearr	= (const unsigned char[]){ JEDEC_CE_C7 },
 | 
			
		||||
		.readcnt	= 0,
 | 
			
		||||
		.readarr	= NULL,
 | 
			
		||||
	}, {
 | 
			
		||||
		.writecnt	= 0,
 | 
			
		||||
		.writearr	= NULL,
 | 
			
		||||
		.readcnt	= 0,
 | 
			
		||||
		.readarr	= NULL,
 | 
			
		||||
	}};
 | 
			
		||||
 | 
			
		||||
	result = spi_disable_blockprotect();
 | 
			
		||||
	if (result) {
 | 
			
		||||
		printf_debug("spi_disable_blockprotect failed\n");
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	result = spi_write_enable();
 | 
			
		||||
	if (result)
 | 
			
		||||
		return result;
 | 
			
		||||
	/* Send CE (Chip Erase) */
 | 
			
		||||
	result = spi_send_command(sizeof(cmd), 0, cmd, NULL);
 | 
			
		||||
 | 
			
		||||
	result = spi_send_multicommand(spicommands);
 | 
			
		||||
	if (result) {
 | 
			
		||||
		printf_debug("spi_chip_erase_60 failed sending erase\n");
 | 
			
		||||
		printf_debug("%s failed during command execution\n", __func__);
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	/* Wait until the Write-In-Progress bit is cleared.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user