diff options
Diffstat (limited to 'src/southbridge')
-rw-r--r-- | src/southbridge/amd/agesa/hudson/spi.c | 25 | ||||
-rw-r--r-- | src/southbridge/amd/cimx/sb800/spi.c | 57 |
2 files changed, 82 insertions, 0 deletions
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) |