summaryrefslogtreecommitdiffstats
path: root/src/southbridge/intel/i82371eb
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/i82371eb
parent12d010306b3892b01350e96d83275206215d9f31 (diff)
downloadcoreboot-16fe79048f5254661ff2342aa481cbb44657b7ff.tar.gz
coreboot-16fe79048f5254661ff2342aa481cbb44657b7ff.tar.bz2
coreboot-16fe79048f5254661ff2342aa481cbb44657b7ff.zip
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/i82371eb')
-rw-r--r--src/southbridge/intel/i82371eb/Kconfig2
-rw-r--r--src/southbridge/intel/i82371eb/early_smbus.c4
-rw-r--r--src/southbridge/intel/i82371eb/smbus.c2
-rw-r--r--src/southbridge/intel/i82371eb/smbus.h112
4 files changed, 5 insertions, 115 deletions
diff --git a/src/southbridge/intel/i82371eb/Kconfig b/src/southbridge/intel/i82371eb/Kconfig
index 5466b12d50d9..f22c6e90fc07 100644
--- a/src/southbridge/intel/i82371eb/Kconfig
+++ b/src/southbridge/intel/i82371eb/Kconfig
@@ -1,4 +1,6 @@
config SOUTHBRIDGE_INTEL_I82371EB
+ select SOUTHBRIDGE_INTEL_COMMON
+ select SOUTHBRIDGE_INTEL_COMMON_SMBUS
bool
config BOOTBLOCK_SOUTHBRIDGE_INIT
diff --git a/src/southbridge/intel/i82371eb/early_smbus.c b/src/southbridge/intel/i82371eb/early_smbus.c
index af6b14b643b4..89ed9c8e5740 100644
--- a/src/southbridge/intel/i82371eb/early_smbus.c
+++ b/src/southbridge/intel/i82371eb/early_smbus.c
@@ -19,8 +19,8 @@
#include <console/console.h>
#include <device/pci_ids.h>
#include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
#include "i82371eb.h"
-#include "smbus.h"
void enable_smbus(void)
{
@@ -46,7 +46,7 @@ void enable_smbus(void)
pci_write_config16(dev, PCI_COMMAND, reg16);
/* Clear any lingering errors, so the transaction will run. */
- outb(inb(SMBUS_IO_BASE + SMBHST_STATUS), SMBUS_IO_BASE + SMBHST_STATUS);
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
}
int smbus_read_byte(u8 device, u8 address)
diff --git a/src/southbridge/intel/i82371eb/smbus.c b/src/southbridge/intel/i82371eb/smbus.c
index 9231402cd05c..3477c52c3209 100644
--- a/src/southbridge/intel/i82371eb/smbus.c
+++ b/src/southbridge/intel/i82371eb/smbus.c
@@ -24,8 +24,8 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/smbus.h>
+#include <southbridge/intel/common/smbus.h>
#include "i82371eb.h"
-#include "smbus.h"
static void pwrmgt_enable(struct device *dev)
{
diff --git a/src/southbridge/intel/i82371eb/smbus.h b/src/southbridge/intel/i82371eb/smbus.h
deleted file mode 100644
index de34504aff28..000000000000
--- a/src/southbridge/intel/i82371eb/smbus.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#include <device/smbus_def.h>
-#include "i82371eb.h"
-
-#define SMBHST_STATUS 0x0
-#define SMBHST_CTL 0x2
-#define SMBHST_CMD 0x3
-#define SMBHST_ADDR 0x4
-#define SMBHST_DAT 0x5
-
-#define SMBUS_TIMEOUT (100*1000*10)
-#define SMBUS_STATUS_MASK 0x1e
-#define SMBUS_ERROR_FLAG (1<<2)
-
-int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address);
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
- outb(0x80, 0x80);
- outb(0x80, 0x80);
- outb(0x80, 0x80);
- outb(0x80, 0x80);
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_ready(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(smbus_io_base + SMBHST_STATUS);
- if ((val & 0x1) == 0) {
- break;
- }
-#if 0
- if (loops == (SMBUS_TIMEOUT / 2)) {
- outw(inw(smbus_io_base + SMBHST_STATUS),
- smbus_io_base + SMBHST_STATUS);
- }
-#endif
- } while (--loops);
- return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-}
-
-static int smbus_wait_until_done(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned short val;
- smbus_delay();
-
- val = inb(smbus_io_base + SMBHST_STATUS);
- // Make sure the command is done
- if ((val & 0x1) != 0) {
- continue;
- }
- // Don't break out until one of the interrupt
- // flags is set.
- if (val & 0xfe) {
- break;
- }
- } while (--loops);
- return loops?0:SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-}
-
-int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
-{
- unsigned status_register;
- unsigned byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
- }
-
- /* setup transaction */
-
- /* clear any lingering errors, so the transaction will run */
- outb(0x1e, smbus_io_base + SMBHST_STATUS);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHST_ADDR);
-
- /* set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHST_CMD);
-
- /* clear the data word...*/
- outb(0, smbus_io_base + SMBHST_DAT);
-
- /* start a byte read with interrupts disabled */
- outb( (0x02 << 2)|(1<<6), smbus_io_base + SMBHST_CTL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
- }
-
- status_register = inw(smbus_io_base + SMBHST_STATUS);
-
- /* read results of transaction */
- byte = inw(smbus_io_base + SMBHST_DAT) & 0xff;
-
- if (status_register & 0x04) {
-#if 0
- printk(BIOS_DEBUG, "Read fail %04x\n", status_register);
-#endif
- return SMBUS_ERROR;
- }
- return byte;
-}