SPI: Fix and enable Fast Read support
- Fix handling of 5-byte Fast Read command in the ICH SPI driver. This fix is ported from the U-boot driver. - Allow CONFIG_SPI_FLASH_NO_FAST_READ to be overridden by defining a name for the bool in Kconfig and removing the forced select in southbridge config - Fix use of CONFIG_SPI_FLASH_NO_FAST_READ in SPI drivers to use #if instead of #ifdef - Relocate flash functions in SMM so they are usable. This really only needs to happen for read function pointer since it uses a global function rather than a static one from the chip, but it is good to ensure the rest are set up correctly as well. Change-Id: Ic1bb0764cb111f96dd8a389d83b39fe8f5e72fbd Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/1775 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
a571c70c14
commit
23b0053586
|
@ -80,7 +80,7 @@ config SPI_FLASH_WINBOND
|
||||||
data in the SPI flash and your SPI flash is made by Winbond.
|
data in the SPI flash and your SPI flash is made by Winbond.
|
||||||
|
|
||||||
config SPI_FLASH_NO_FAST_READ
|
config SPI_FLASH_NO_FAST_READ
|
||||||
bool
|
bool "Disable Fast Read command"
|
||||||
default n
|
default n
|
||||||
depends on SPI_FLASH
|
depends on SPI_FLASH
|
||||||
help
|
help
|
||||||
|
|
|
@ -154,7 +154,7 @@ static int gigadevice_write(struct spi_flash *flash, u32 offset,
|
||||||
cmd[3] = offset & 0xff;
|
cmd[3] = offset & 0xff;
|
||||||
#if CONFIG_DEBUG_SPI_FLASH
|
#if CONFIG_DEBUG_SPI_FLASH
|
||||||
printk(BIOS_SPEW,
|
printk(BIOS_SPEW,
|
||||||
"PP gigadevice.c: %#p => cmd = { %#02x %#02x%02x%02x }"
|
"PP gigadevice.c: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x }"
|
||||||
" chunk_len = %zu\n", buf + actual,
|
" chunk_len = %zu\n", buf + actual,
|
||||||
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
@ -226,7 +226,7 @@ struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode)
|
||||||
|
|
||||||
stm->flash.write = gigadevice_write;
|
stm->flash.write = gigadevice_write;
|
||||||
stm->flash.erase = gigadevice_erase;
|
stm->flash.erase = gigadevice_erase;
|
||||||
#ifdef CONFIG_SPI_FLASH_NO_FAST_READ
|
#if CONFIG_SPI_FLASH_NO_FAST_READ
|
||||||
stm->flash.read = spi_flash_cmd_read_slow;
|
stm->flash.read = spi_flash_cmd_read_slow;
|
||||||
#else
|
#else
|
||||||
stm->flash.read = spi_flash_cmd_read_fast;
|
stm->flash.read = spi_flash_cmd_read_fast;
|
||||||
|
|
|
@ -210,7 +210,7 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
|
||||||
|
|
||||||
mcx->flash.write = macronix_write;
|
mcx->flash.write = macronix_write;
|
||||||
mcx->flash.erase = macronix_erase;
|
mcx->flash.erase = macronix_erase;
|
||||||
#ifdef CONFIG_SPI_FLASH_NO_FAST_READ
|
#if CONFIG_SPI_FLASH_NO_FAST_READ
|
||||||
mcx->flash.read = spi_flash_cmd_read_slow;
|
mcx->flash.read = spi_flash_cmd_read_slow;
|
||||||
#else
|
#else
|
||||||
mcx->flash.read = spi_flash_cmd_read_fast;
|
mcx->flash.read = spi_flash_cmd_read_fast;
|
||||||
|
|
|
@ -281,7 +281,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
|
||||||
/* search the table for matches in shift and id */
|
/* search the table for matches in shift and id */
|
||||||
for (i = 0; i < ARRAY_SIZE(flashes); ++i)
|
for (i = 0; i < ARRAY_SIZE(flashes); ++i)
|
||||||
if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
|
if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
|
||||||
#ifdef __SMM__
|
#if CONFIG_SMM_TSEG && defined(__SMM__)
|
||||||
/* Need to relocate this function */
|
/* Need to relocate this function */
|
||||||
tseg_relocate((void **)&flashes[i].probe);
|
tseg_relocate((void **)&flashes[i].probe);
|
||||||
#endif
|
#endif
|
||||||
|
@ -296,6 +296,14 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
|
||||||
goto err_manufacturer_probe;
|
goto err_manufacturer_probe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_SMM_TSEG && defined(__SMM__)
|
||||||
|
/* Ensure flash handlers are valid for TSEG */
|
||||||
|
tseg_relocate((void **)&flash->read);
|
||||||
|
tseg_relocate((void **)&flash->write);
|
||||||
|
tseg_relocate((void **)&flash->erase);
|
||||||
|
tseg_relocate((void **)&flash->name);
|
||||||
|
#endif
|
||||||
|
|
||||||
printk(BIOS_INFO, "SF: Detected %s with page size %x, total %x\n",
|
printk(BIOS_INFO, "SF: Detected %s with page size %x, total %x\n",
|
||||||
flash->name, flash->sector_size, flash->size);
|
flash->name, flash->sector_size, flash->size);
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
|
||||||
|
|
||||||
stm->flash.write = winbond_write;
|
stm->flash.write = winbond_write;
|
||||||
stm->flash.erase = winbond_erase;
|
stm->flash.erase = winbond_erase;
|
||||||
#ifdef CONFIG_SPI_FLASH_NO_FAST_READ
|
#if CONFIG_SPI_FLASH_NO_FAST_READ
|
||||||
stm->flash.read = spi_flash_cmd_read_slow;
|
stm->flash.read = spi_flash_cmd_read_slow;
|
||||||
#else
|
#else
|
||||||
stm->flash.read = spi_flash_cmd_read_fast;
|
stm->flash.read = spi_flash_cmd_read_fast;
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
/* SPI opcodes */
|
/* SPI opcodes */
|
||||||
#define SPI_OPCODE_WREN 0x06
|
#define SPI_OPCODE_WREN 0x06
|
||||||
|
#define SPI_OPCODE_FAST_READ 0x0b
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
* Representation of a SPI slave, i.e. what we're communicating with.
|
* Representation of a SPI slave, i.e. what we're communicating with.
|
||||||
|
|
|
@ -34,7 +34,6 @@ config SOUTH_BRIDGE_OPTIONS # dummy
|
||||||
select PCIEXP_ASPM
|
select PCIEXP_ASPM
|
||||||
select PCIEXP_COMMON_CLOCK
|
select PCIEXP_COMMON_CLOCK
|
||||||
select SPI_FLASH
|
select SPI_FLASH
|
||||||
select SPI_FLASH_NO_FAST_READ
|
|
||||||
|
|
||||||
config EHCI_BAR
|
config EHCI_BAR
|
||||||
hex
|
hex
|
||||||
|
|
|
@ -484,6 +484,12 @@ static void spi_setup_type(spi_transaction *trans)
|
||||||
if (trans->bytesout == 4) { /* and bytesin is > 0 */
|
if (trans->bytesout == 4) { /* and bytesin is > 0 */
|
||||||
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fast read command is called with 5 bytes instead of 4 */
|
||||||
|
if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
|
||||||
|
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
||||||
|
--trans->bytesout;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spi_setup_opcode(spi_transaction *trans)
|
static int spi_setup_opcode(spi_transaction *trans)
|
||||||
|
|
Loading…
Reference in New Issue