summaryrefslogtreecommitdiff
path: root/src/southbridge/amd
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge/amd')
-rw-r--r--src/southbridge/amd/agesa/hudson/spi.c69
1 files changed, 50 insertions, 19 deletions
diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c
index a46bf08be9..013bb21a08 100644
--- a/src/southbridge/amd/agesa/hudson/spi.c
+++ b/src/southbridge/amd/agesa/hudson/spi.c
@@ -31,23 +31,54 @@
static int bus_claimed = 0;
#endif
+#define SPI_REG_OPCODE 0x0
+#define SPI_REG_CNTRL01 0x1
+#define SPI_REG_CNTRL02 0x2
+ #define CNTRL02_FIFO_RESET (1 << 4)
+ #define CNTRL02_EXEC_OPCODE (1 << 0)
+#define SPI_REG_CNTRL03 0x3
+ #define CNTRL03_SPIBUSY (1 << 7)
+#define SPI_REG_FIFO 0xc
+#define SPI_REG_CNTRL11 0xd
+ #define CNTRL11_FIFOPTR_MASK 0x07
+
+
static u32 spibar;
+static inline uint8_t spi_read(uint8_t reg)
+{
+ return read8(spibar + reg);
+}
+
+static inline void spi_write(uint8_t reg, uint8_t val)
+{
+ write8(spibar + reg, val);
+}
+
static void reset_internal_fifo_pointer(void)
{
+ uint8_t reg8;
+
do {
- write8(spibar + 2, read8(spibar + 2) | 0x10);
- } while (read8(spibar + 0xD) & 0x7);
+ reg8 = spi_read(SPI_REG_CNTRL02);
+ reg8 |= CNTRL02_FIFO_RESET;
+ spi_write(SPI_REG_CNTRL02, reg8);
+ } while (spi_read(SPI_REG_CNTRL11) & CNTRL11_FIFOPTR_MASK);
}
static void execute_command(void)
{
- write8(spibar + 2, read8(spibar + 2) | 1);
+ uint8_t reg8;
+
+ reg8 = spi_read(SPI_REG_CNTRL02);
+ reg8 |= CNTRL02_EXEC_OPCODE;
+ spi_write(SPI_REG_CNTRL02, reg8);
- while ((read8(spibar + 2) & 1) && (read8(spibar+3) & 0x80));
+ while ((spi_read(SPI_REG_CNTRL02) & CNTRL02_EXEC_OPCODE) &&
+ (spi_read(SPI_REG_CNTRL03) & CNTRL03_SPIBUSY));
}
-void spi_init()
+void spi_init(void)
{
device_t dev;
@@ -59,13 +90,13 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
unsigned int bitsout, void *din, unsigned int bitsin)
{
/* First byte is cmd which can not being sent through FIFO. */
- u8 cmd = *(u8 *)dout++;
- u8 readoffby1;
+ uint8_t cmd = *(uint8_t *)dout++;
+ uint8_t readoffby1;
#if !CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE
- u8 readwrite;
+ uint8_t readwrite;
#endif
- u8 bytesout, bytesin;
- u8 count;
+ uint8_t bytesout, bytesin;
+ uint8_t count;
bitsout -= 8;
bytesout = bitsout / 8;
@@ -74,19 +105,19 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
readoffby1 = bytesout ? 0 : 1;
#if CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE
- write8(spibar + 0x1E, 5);
- write8(spibar + 0x1F, bytesout); /* SpiExtRegIndx [5] - TxByteCount */
- write8(spibar + 0x1E, 6);
- write8(spibar + 0x1F, bytesin); /* SpiExtRegIndx [6] - RxByteCount */
+ spi_write(0x1E, 5);
+ spi_write(0x1F, bytesout); /* SpiExtRegIndx [5] - TxByteCount */
+ spi_write(0x1E, 6);
+ spi_write(0x1F, bytesin); /* SpiExtRegIndx [6] - RxByteCount */
#else
readwrite = (bytesin + readoffby1) << 4 | bytesout;
- write8(spibar + 1, readwrite);
+ spi_write(SPI_REG_CNTRL01, readwrite);
#endif
- write8(spibar + 0, cmd);
+ spi_write(SPI_REG_OPCODE, cmd);
reset_internal_fifo_pointer();
for (count = 0; count < bytesout; count++, dout++) {
- write8(spibar + 0x0C, *(u8 *)dout);
+ spi_write(SPI_REG_FIFO, *(uint8_t *)dout);
}
reset_internal_fifo_pointer();
@@ -95,12 +126,12 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
reset_internal_fifo_pointer();
/* Skip the bytes we sent. */
for (count = 0; count < bytesout; count++) {
- cmd = read8(spibar + 0x0C);
+ cmd = spi_read(SPI_REG_FIFO);
}
reset_internal_fifo_pointer();
for (count = 0; count < bytesin; count++, din++) {
- *(u8 *)din = read8(spibar + 0x0C);
+ *(uint8_t *)din = spi_read(SPI_REG_FIFO);
}
return 0;