diff options
author | Furquan Shaikh <furquan@chromium.org> | 2016-11-20 21:04:00 -0800 |
---|---|---|
committer | Furquan Shaikh <furquan@google.com> | 2016-11-22 17:32:09 +0100 |
commit | c28984d9ea08e7d995ef9fc8064c10ec0c0d9d77 (patch) | |
tree | c113582c3d2d8fb8d54a4c9a53375340fcc302d5 /src/southbridge | |
parent | 282c8322791800ee0d732fdaa5eb2cd8f7effd58 (diff) | |
download | coreboot-c28984d9ea08e7d995ef9fc8064c10ec0c0d9d77.tar.xz |
spi: Clean up SPI flash driver interface
RW flag was added to spi_slave structure to get around a requirement on
some AMD flash controllers that need to group together all spi volatile
operations (write/erase). This rw flag is not a property or attribute of
the SPI slave or controller. Thus, instead of saving it in spi_slave
structure, clean up the SPI flash driver interface. This allows
chipsets/mainboards (that require volatile operations to be grouped) to
indicate beginning and end of such grouped operations.
New user APIs are added to allow users to perform probe, read, write,
erase, volatile group begin and end operations. Callbacks defined in
spi_flash structure are expected to be used only by the SPI flash
driver. Any chipset that requires grouping of volatile operations can
select the newly added Kconfig option SPI_FLASH_HAS_VOLATILE_GROUP and
define callbacks for chipset_volatile_group_{begin,end}.
spi_claim_bus/spi_release_bus calls have been removed from the SPI flash
chip drivers which end up calling do_spi_flash_cmd since it already has
required calls for claiming and releasing SPI bus before performing a
read/write operation.
BUG=None
BRANCH=None
TEST=Compiles successfully.
Change-Id: Idfc052e82ec15b6c9fa874cee7a61bd06e923fbf
Signed-off-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: https://review.coreboot.org/17462
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/southbridge')
-rw-r--r-- | src/southbridge/amd/agesa/hudson/Kconfig | 1 | ||||
-rw-r--r-- | src/southbridge/amd/agesa/hudson/spi.c | 43 | ||||
-rw-r--r-- | src/southbridge/amd/cimx/sb800/Kconfig | 1 | ||||
-rw-r--r-- | src/southbridge/amd/cimx/sb800/spi.c | 46 | ||||
-rw-r--r-- | src/southbridge/intel/common/spi.c | 18 |
5 files changed, 53 insertions, 56 deletions
diff --git a/src/southbridge/amd/agesa/hudson/Kconfig b/src/southbridge/amd/agesa/hudson/Kconfig index fd79a3f034..eed83ae53f 100644 --- a/src/southbridge/amd/agesa/hudson/Kconfig +++ b/src/southbridge/amd/agesa/hudson/Kconfig @@ -64,6 +64,7 @@ config HUDSON_XHCI_FWM config HUDSON_IMC_FWM bool "Add imc firmware" default y if USE_BLOBS + select SPI_FLASH_HAS_VOLATILE_GROUP if SPI_FLASH help Add Hudson 2/3/4 IMC Firmware to support the onboard fan control diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c index 31160bdcd9..f1a82e9022 100644 --- a/src/southbridge/amd/agesa/hudson/spi.c +++ b/src/southbridge/amd/agesa/hudson/spi.c @@ -17,17 +17,14 @@ #include <string.h> #include <arch/io.h> #include <console/console.h> +#include <spi_flash.h> #include <spi-generic.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ops.h> -#if IS_ENABLED (CONFIG_HUDSON_IMC_FWM) #include <Proc/Fch/FchPlatform.h> -static int bus_claimed = 0; -#endif - #define SPI_REG_OPCODE 0x0 #define SPI_REG_CNTRL01 0x1 #define SPI_REG_CNTRL02 0x2 @@ -149,32 +146,34 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return 0; } + int spi_claim_bus(struct spi_slave *slave) { -#if IS_ENABLED (CONFIG_HUDSON_IMC_FWM) + /* Nothing is required. */ + return 0; +} - if (slave->rw == SPI_WRITE_FLAG) { - bus_claimed++; - if (bus_claimed == 1) - ImcSleep(NULL); - } -#endif +void spi_release_bus(struct spi_slave *slave) +{ + /* Nothing is required. */ +} + +int chipset_volatile_group_begin(const struct spi_flash *flash) +{ + if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM)) + return 0; + ImcSleep(NULL); return 0; } -void spi_release_bus(struct spi_slave *slave) +int chipset_volatile_group_end(const struct spi_flash *flash) { -#if IS_ENABLED (CONFIG_HUDSON_IMC_FWM) - - if (slave->rw == SPI_WRITE_FLAG) { - bus_claimed--; - if (bus_claimed <= 0) { - bus_claimed = 0; - ImcWakeup(NULL); - } - } -#endif + if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM)) + return 0; + + ImcWakeup(NULL); + return 0; } struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) diff --git a/src/southbridge/amd/cimx/sb800/Kconfig b/src/southbridge/amd/cimx/sb800/Kconfig index a48b93a67c..07232f1a74 100644 --- a/src/southbridge/amd/cimx/sb800/Kconfig +++ b/src/southbridge/amd/cimx/sb800/Kconfig @@ -123,6 +123,7 @@ endif config SB800_IMC_FWM bool "Add IMC firmware" default n + select SPI_FLASH_HAS_VOLATILE_GROUP if SPI_FLASH help Add SB800 / Hudson 1 IMC Firmware to support the onboard fan control. diff --git a/src/southbridge/amd/cimx/sb800/spi.c b/src/southbridge/amd/cimx/sb800/spi.c index f6898926e3..726d8e0129 100644 --- a/src/southbridge/amd/cimx/sb800/spi.c +++ b/src/southbridge/amd/cimx/sb800/spi.c @@ -17,18 +17,15 @@ #include <string.h> #include <arch/io.h> #include <console/console.h> +#include <spi_flash.h> #include <spi-generic.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ops.h> -#if IS_ENABLED (CONFIG_SB800_IMC_FWM) #include "SBPLATFORM.h" #include <vendorcode/amd/cimx/sb800/ECfan.h> -static int bus_claimed = 0; -#endif - #define AMD_SB_SPI_TX_LEN 8 static uintptr_t spibar; @@ -114,8 +111,6 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return 0; } -#if IS_ENABLED (CONFIG_SB800_IMC_FWM) - static void ImcSleep(void) { u8 cmd_val = 0x96; /* Kick off IMC Mailbox command 96 */ @@ -142,34 +137,35 @@ static void ImcWakeup(void) WaitForEcLDN9MailboxCmdAck(); } -#endif int spi_claim_bus(struct spi_slave *slave) { -#if IS_ENABLED (CONFIG_SB800_IMC_FWM) + /* Nothing is required. */ + return 0; +} - if (slave->rw == SPI_WRITE_FLAG) { - bus_claimed++; - if (bus_claimed == 1) - ImcSleep(); - } -#endif +void spi_release_bus(struct spi_slave *slave) +{ + /* Nothing is required. */ + return; +} + +int chipset_volatile_group_begin(const struct spi_flash *flash) +{ + if (!IS_ENABLED(CONFIG_SB800_IMC_FWM)) + return 0; + ImcSleep(); return 0; } -void spi_release_bus(struct spi_slave *slave) +int chipset_volatile_group_end(const struct spi_flash *flash) { -#if IS_ENABLED (CONFIG_SB800_IMC_FWM) - - if (slave->rw == SPI_WRITE_FLAG) { - bus_claimed--; - if (bus_claimed <= 0) { - bus_claimed = 0; - ImcWakeup(); - } - } -#endif + if (!IS_ENABLED(CONFIG_SB800_IMC_FWM)) + return 0; + + ImcWakeup(); + return 0; } struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index 1ab151b79e..e0414220c6 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -737,7 +737,8 @@ static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout, } -static int ich_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) +static int ich_hwseq_erase(const struct spi_flash *flash, u32 offset, + size_t len) { u32 start, end, erase_size; int ret; @@ -750,7 +751,6 @@ static int ich_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) return -1; } - flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_ERR, "SF: Unable to claim SPI bus\n"); @@ -801,8 +801,8 @@ static void ich_read_data(uint8_t *data, int len) } } -static int ich_hwseq_read(struct spi_flash *flash, - u32 addr, size_t len, void *buf) +static int ich_hwseq_read(const struct spi_flash *flash, u32 addr, size_t len, + void *buf) { uint16_t hsfc; uint16_t timeout = 100 * 60; @@ -869,8 +869,8 @@ static void ich_fill_data(const uint8_t *data, int len) writel_(temp32, cntlr.data + (i - (i % 4))); } -static int ich_hwseq_write(struct spi_flash *flash, - u32 addr, size_t len, const void *buf) +static int ich_hwseq_write(const struct spi_flash *flash, u32 addr, size_t len, + const void *buf) { uint16_t hsfc; uint16_t timeout = 100 * 60; @@ -934,9 +934,9 @@ static struct spi_flash *spi_flash_hwseq(struct spi_slave *spi) flash->spi = spi; flash->name = "Opaque HW-sequencing"; - flash->write = ich_hwseq_write; - flash->erase = ich_hwseq_erase; - flash->read = ich_hwseq_read; + flash->internal_write = ich_hwseq_write; + flash->internal_erase = ich_hwseq_erase; + flash->internal_read = ich_hwseq_read; ich_hwseq_set_addr (0); switch ((cntlr.hsfs >> 3) & 3) { |