aboutsummaryrefslogtreecommitdiff
path: root/src/southbridge/intel/i82801gx/early_smbus.c
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2017-04-12 17:01:31 +0200
committerMartin Roth <martinroth@google.com>2017-08-06 23:26:15 +0000
commit16fe79048f5254661ff2342aa481cbb44657b7ff (patch)
tree5ad72bc5c5a97ca9a7a47f5ab24bbe622f12e9e9 /src/southbridge/intel/i82801gx/early_smbus.c
parent12d010306b3892b01350e96d83275206215d9f31 (diff)
sb/intel/*: Use common SMBus functions
All Intel southbridges implement the same SMBus functions. This patch replaces all these similar and mostly identical implementations with a common file. This also makes i2c block read available to all those southbridges. If the northbridge has to read a lot of SPD bytes sequentially, using this function can reduce the time being spent to read SPD five-fold. Change-Id: I93bb186e04e8c32dff04fc1abe4b5ecbc4c9c962 Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/19258 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Diffstat (limited to 'src/southbridge/intel/i82801gx/early_smbus.c')
-rw-r--r--src/southbridge/intel/i82801gx/early_smbus.c51
1 files changed, 2 insertions, 49 deletions
diff --git a/src/southbridge/intel/i82801gx/early_smbus.c b/src/southbridge/intel/i82801gx/early_smbus.c
index b8852e91ab..5d204e9527 100644
--- a/src/southbridge/intel/i82801gx/early_smbus.c
+++ b/src/southbridge/intel/i82801gx/early_smbus.c
@@ -18,8 +18,8 @@
#include <console/console.h>
#include <device/pci_ids.h>
#include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
#include "i82801gx.h"
-#include "smbus.h"
void enable_smbus(void)
{
@@ -57,52 +57,5 @@ int smbus_read_byte(unsigned int device, unsigned int address)
int i2c_block_read(unsigned int device, unsigned int offset, u32 bytes, u8 *buf)
{
- u8 status;
- int bytes_read = 0;
- if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0)
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
- /* Setup transaction */
- /* Disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
- /* Set the device I'm talking to */
- outb((device & 0x7f) << 1, SMBUS_IO_BASE + SMBXMITADD);
-
- /* SPD offset */
- outb(offset, SMBUS_IO_BASE + SMBHSTDAT1);
-
- /* Set up for a i2c block data read */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xc3) | (0x6 << 2),
- (SMBUS_IO_BASE + SMBHSTCTL));
-
- /* Clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
- /* Start the command */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
- SMBUS_IO_BASE + SMBHSTCTL);
-
- while (!(inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1))
- ;
- /* Poll for transaction completion */
- do {
- status = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if (status & ((1 << 4) | /* FAILED */
- (1 << 3) | /* BUS ERR */
- (1 << 2))) /* DEV ERR */
- return SMBUS_ERROR;
-
- if (status & 0x80) { /* Byte done */
- *buf = inb(SMBUS_IO_BASE + SMBBLKDAT);
- buf++;
- bytes_read++;
- if (--bytes == 1) {
- /* indicate that next byte is the last one */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x20,
- SMBUS_IO_BASE + SMBHSTCTL);
- }
- outb(status, SMBUS_IO_BASE + SMBHSTSTAT);
- }
- } while (status & 0x01);
-
- return bytes_read;
+ return do_i2c_block_read(SMBUS_IO_BASE, device, offset, bytes, buf);
}