From 60d711879f7d288b5b8e5594af87fce85475d4b0 Mon Sep 17 00:00:00 2001 From: Carl-Daniel Hailfinger Date: Sat, 11 Jul 2009 19:28:36 +0000 Subject: 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 Tested-by: Jakob Bornecrantz Acked-by: Jakob Bornecrantz --- spi.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 18 deletions(-) (limited to 'spi.c') diff --git a/spi.c b/spi.c index 16dfe36..c5ace17 100644 --- a/spi.c +++ b/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. -- cgit v1.1