diff options
-rw-r--r-- | src/cpu/amd/agesa/s3_resume.c | 12 | ||||
-rw-r--r-- | src/drivers/spi/eon.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/gigadevice.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/macronix.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/spansion.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/spi_flash.c | 3 | ||||
-rw-r--r-- | src/drivers/spi/sst.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/stmicro.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/winbond.c | 1 | ||||
-rw-r--r-- | src/include/spi.h | 6 | ||||
-rw-r--r-- | src/southbridge/amd/agesa/hudson/spi.c | 25 | ||||
-rw-r--r-- | src/southbridge/amd/cimx/sb800/spi.c | 57 |
12 files changed, 109 insertions, 1 deletions
diff --git a/src/cpu/amd/agesa/s3_resume.c b/src/cpu/amd/agesa/s3_resume.c index 6302c3d304..42e950f26b 100644 --- a/src/cpu/amd/agesa/s3_resume.c +++ b/src/cpu/amd/agesa/s3_resume.c @@ -165,6 +165,9 @@ void OemAgesaSaveMtrr(void) return; } + flash->spi->rw = SPI_WRITE_FLAG; + spi_claim_bus(flash->spi); + /* Enable access to AMD RdDram and WrDram extension bits */ msr_data = rdmsr(SYS_CFG); msr_data.lo |= SYSCFG_MSR_MtrrFixDramModEn; @@ -233,6 +236,9 @@ void OemAgesaSaveMtrr(void) flash->write(flash, nvram_pos, 4, &msr_data.hi); nvram_pos += 4; + flash->spi->rw = SPI_WRITE_FLAG; + spi_release_bus(flash->spi); + #endif } @@ -273,6 +279,9 @@ u32 OemAgesaSaveS3Info(S3_DATA_TYPE S3DataType, u32 DataSize, void *Data) return AGESA_SUCCESS; } + flash->spi->rw = SPI_WRITE_FLAG; + spi_claim_bus(flash->spi); + if (S3DataType == S3DataTypeNonVolatile) { flash->erase(flash, S3_DATA_NONVOLATILE_POS, 0x1000); } else { @@ -287,6 +296,9 @@ u32 OemAgesaSaveS3Info(S3_DATA_TYPE S3DataType, u32 DataSize, void *Data) flash->write(flash, nvram_pos + pos + 4, sizeof(u32), (u32 *)(Data + nvram_pos)); } + flash->spi->rw = SPI_WRITE_FLAG; + spi_release_bus(flash->spi); + return AGESA_SUCCESS; } #endif diff --git a/src/drivers/spi/eon.c b/src/drivers/spi/eon.c index 2215a74d8a..21103ae221 100644 --- a/src/drivers/spi/eon.c +++ b/src/drivers/spi/eon.c @@ -70,6 +70,7 @@ static int eon_write(struct spi_flash *flash, page_addr = offset / page_size; byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/gigadevice.c b/src/drivers/spi/gigadevice.c index ece6978c2b..5a8f82f053 100644 --- a/src/drivers/spi/gigadevice.c +++ b/src/drivers/spi/gigadevice.c @@ -131,6 +131,7 @@ static int gigadevice_write(struct spi_flash *flash, u32 offset, page_size = min(1 << stm->params->l2_page_size, CONTROLLER_PAGE_LIMIT); byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, diff --git a/src/drivers/spi/macronix.c b/src/drivers/spi/macronix.c index 0a0d62bdac..910b874cd4 100644 --- a/src/drivers/spi/macronix.c +++ b/src/drivers/spi/macronix.c @@ -134,6 +134,7 @@ static int macronix_write(struct spi_flash *flash, page_size = min(mcx->params->page_size, CONTROLLER_PAGE_LIMIT); byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/spansion.c b/src/drivers/spi/spansion.c index 328892ccb1..37bf5a859c 100644 --- a/src/drivers/spi/spansion.c +++ b/src/drivers/spi/spansion.c @@ -147,6 +147,7 @@ static int spansion_write(struct spi_flash *flash, page_addr = offset / page_size; byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index 75a5c21619..6b658f894d 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -69,6 +69,7 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, struct spi_slave *spi = flash->spi; int ret; + spi->rw = SPI_READ_FLAG; spi_claim_bus(spi); ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len); spi_release_bus(spi); @@ -148,6 +149,7 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u8 erase_cmd, return -1; } + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); @@ -258,6 +260,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, return NULL; } + spi->rw = SPI_READ_FLAG; ret = spi_claim_bus(spi); if (ret) { printk(BIOS_WARNING, "SF: Failed to claim SPI bus: %d\n", ret); diff --git a/src/drivers/spi/sst.c b/src/drivers/spi/sst.c index 2609591723..8cf3f964fd 100644 --- a/src/drivers/spi/sst.c +++ b/src/drivers/spi/sst.c @@ -153,6 +153,7 @@ sst_write(struct spi_flash *flash, u32 offset, size_t len, const void *buf) int ret; u8 cmd[4]; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/stmicro.c b/src/drivers/spi/stmicro.c index d10429b2c4..b741d30feb 100644 --- a/src/drivers/spi/stmicro.c +++ b/src/drivers/spi/stmicro.c @@ -148,6 +148,7 @@ static int stmicro_write(struct spi_flash *flash, page_addr = offset / page_size; byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/winbond.c b/src/drivers/spi/winbond.c index 28786756ae..c44afea832 100644 --- a/src/drivers/spi/winbond.c +++ b/src/drivers/spi/winbond.c @@ -117,6 +117,7 @@ static int winbond_write(struct spi_flash *flash, page_size = min(1 << stm->params->l2_page_size, CONTROLLER_PAGE_LIMIT); byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/include/spi.h b/src/include/spi.h index 5fbe51e1ab..d394531712 100644 --- a/src/include/spi.h +++ b/src/include/spi.h @@ -48,6 +48,9 @@ #define SPI_OPCODE_WREN 0x06 #define SPI_OPCODE_FAST_READ 0x0b +#define SPI_READ_FLAG 0x01 +#define SPI_WRITE_FLAG 0x02 + /*----------------------------------------------------------------------- * Representation of a SPI slave, i.e. what we're communicating with. * @@ -55,16 +58,17 @@ * * bus: ID of the bus that the slave is attached to. * cs: ID of the chip select connected to the slave. + * rw: Read or Write flag */ struct spi_slave { unsigned int bus; unsigned int cs; + unsigned int rw; }; /*----------------------------------------------------------------------- * Initialization, must be called once on start up. * - * TODO: I don't think we really need this. */ void spi_init(void); diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c index 3b54490117..aebe4b5cec 100644 --- a/src/southbridge/amd/agesa/hudson/spi.c +++ b/src/southbridge/amd/agesa/hudson/spi.c @@ -25,6 +25,12 @@ #include <device/pci.h> #include <device/pci_ops.h> +#if defined (CONFIG_HUDSON_IMC_FWM) +#include "FchPlatform.h" + +static int bus_claimed = 0; +#endif + static u32 spibar; static void reset_internal_fifo_pointer(void) @@ -92,11 +98,30 @@ int spi_xfer(struct spi_slave *slave, const void *dout, } int spi_claim_bus(struct spi_slave *slave) { +#if defined (CONFIG_HUDSON_IMC_FWM) + + if (slave->rw == SPI_WRITE_FLAG) { + bus_claimed++; + if (bus_claimed == 1) + ImcSleep(NULL); + } +#endif + return 0; } void spi_release_bus(struct spi_slave *slave) { +#if defined (CONFIG_HUDSON_IMC_FWM) + + if (slave->rw == SPI_WRITE_FLAG) { + bus_claimed--; + if (bus_claimed <= 0) { + bus_claimed = 0; + ImcWakeup(NULL); + } + } +#endif } void spi_cs_activate(struct spi_slave *slave) diff --git a/src/southbridge/amd/cimx/sb800/spi.c b/src/southbridge/amd/cimx/sb800/spi.c index 3b54490117..46cc7419ba 100644 --- a/src/southbridge/amd/cimx/sb800/spi.c +++ b/src/southbridge/amd/cimx/sb800/spi.c @@ -25,6 +25,13 @@ #include <device/pci.h> #include <device/pci_ops.h> +#if defined (CONFIG_SB800_IMC_FWM) +#include "SBPLATFORM.h" +#include <vendorcode/amd/cimx/sb800/ECfan.h> + +static int bus_claimed = 0; +#endif + static u32 spibar; static void reset_internal_fifo_pointer(void) @@ -90,13 +97,63 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return 0; } + +#if defined (CONFIG_SB800_IMC_FWM) + +static void ImcSleep(void) +{ + u8 cmd_val = 0x96; /* Kick off IMC Mailbox command 96 */ + u8 reg0_val = 0; /* clear response register */ + u8 reg1_val = 0xB4; /* request ownership flag */ + + WriteECmsg (MSG_REG0, AccWidthUint8, ®0_val); + WriteECmsg (MSG_REG1, AccWidthUint8, ®1_val); + WriteECmsg (MSG_SYS_TO_IMC, AccWidthUint8, &cmd_val); + + WaitForEcLDN9MailboxCmdAck(); +} + + +static void ImcWakeup(void) +{ + u8 cmd_val = 0x96; /* Kick off IMC Mailbox command 96 */ + u8 reg0_val = 0;; /* clear response register */ + u8 reg1_val = 0xB5; /* release ownership flag */ + + WriteECmsg (MSG_REG0, AccWidthUint8, ®0_val); + WriteECmsg (MSG_REG1, AccWidthUint8, ®1_val); + WriteECmsg (MSG_SYS_TO_IMC, AccWidthUint8, &cmd_val); + + WaitForEcLDN9MailboxCmdAck(); +} +#endif + int spi_claim_bus(struct spi_slave *slave) { +#if defined (CONFIG_SB800_IMC_FWM) + + if (slave->rw == SPI_WRITE_FLAG) { + bus_claimed++; + if (bus_claimed == 1) + ImcSleep(); + } +#endif + return 0; } void spi_release_bus(struct spi_slave *slave) { +#if defined (CONFIG_SB800_IMC_FWM) + + if (slave->rw == SPI_WRITE_FLAG) { + bus_claimed--; + if (bus_claimed <= 0) { + bus_claimed = 0; + ImcWakeup(); + } + } +#endif } void spi_cs_activate(struct spi_slave *slave) |