[coreboot-gerrit] Change in coreboot[master]: sb/intel/i82801gx: Make smbus_block_read available in romstage
Arthur Heymans (Code Review)
gerrit at coreboot.org
Mon Mar 20 22:36:30 CET 2017
Arthur Heymans has uploaded a new change for review. ( https://review.coreboot.org/18927 )
Change subject: sb/intel/i82801gx: Make smbus_block_read available in romstage
......................................................................
sb/intel/i82801gx: Make smbus_block_read available in romstage
Using block_read might speed things up compared to reading each byte
one by one.
Change-Id: I6d768a2ba128329168f26445a4fca6921c0c8642
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
M src/southbridge/intel/i82801gx/early_smbus.c
M src/southbridge/intel/i82801gx/i82801gx.h
M src/southbridge/intel/i82801gx/smbus.c
M src/southbridge/intel/i82801gx/smbus.h
4 files changed, 56 insertions(+), 50 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/27/18927/1
diff --git a/src/southbridge/intel/i82801gx/early_smbus.c b/src/southbridge/intel/i82801gx/early_smbus.c
index 47fe5f6..7adedb5 100644
--- a/src/southbridge/intel/i82801gx/early_smbus.c
+++ b/src/southbridge/intel/i82801gx/early_smbus.c
@@ -55,3 +55,8 @@
{
return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
}
+
+int smbus_block_read(unsigned device, unsigned cmd, u8 bytes, u8 *buf)
+{
+ return do_smbus_block_read(SMBUS_IO_BASE, device, cmd, bytes, buf);
+}
diff --git a/src/southbridge/intel/i82801gx/i82801gx.h b/src/southbridge/intel/i82801gx/i82801gx.h
index d1441e8..703bc57 100644
--- a/src/southbridge/intel/i82801gx/i82801gx.h
+++ b/src/southbridge/intel/i82801gx/i82801gx.h
@@ -50,6 +50,7 @@
#else
void enable_smbus(void);
int smbus_read_byte(unsigned device, unsigned address);
+int smbus_block_read(unsigned device, unsigned cmd, u8 bytes, u8 *buf);
int southbridge_detect_s3_resume(void);
#endif
#endif
diff --git a/src/southbridge/intel/i82801gx/smbus.c b/src/southbridge/intel/i82801gx/smbus.c
index e6aa018..cbb3bfd 100644
--- a/src/southbridge/intel/i82801gx/smbus.c
+++ b/src/southbridge/intel/i82801gx/smbus.c
@@ -155,56 +155,6 @@
return do_smbus_block_write(res->base, device, cmd, bytes, buf);
}
-static int do_smbus_block_read(unsigned smbus_base, unsigned device,
- unsigned cmd, unsigned bytes, u8 *buf)
-{
- u8 status;
- int bytes_read = 0;
- if (smbus_wait_until_ready(smbus_base) < 0)
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
- /* Setup transaction */
- /* Disable interrupts */
- outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
- /* Set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
- /* Set the command/address... */
- outb(cmd & 0xff, smbus_base + SMBHSTCMD);
- /* Set up for a block data read */
- outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x5 << 2),
- (smbus_base + SMBHSTCTL));
- /* Clear any lingering errors, so the transaction will run */
- outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
- /* Start the command */
- outb((inb(smbus_base + SMBHSTCTL) | 0x40),
- smbus_base + SMBHSTCTL);
-
- while (!(inb(smbus_base + SMBHSTSTAT) & 1));
- /* Poll for transaction completion */
- do {
- status = inb(smbus_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_base + SMBBLKDAT);
- buf++;
- bytes_read++;
- outb(status, smbus_base + SMBHSTSTAT);
- if (--bytes == 1) {
- /* indicate that next byte is the last one */
- outb(inb(smbus_base + SMBHSTCTL) | 0x20,
- smbus_base + SMBHSTCTL);
- }
- }
- } while (status & 0x01);
-
- return bytes_read;
-}
-
static int lsmbus_block_read(device_t dev, u8 cmd, u8 bytes, u8 *buf)
{
u16 device;
diff --git a/src/southbridge/intel/i82801gx/smbus.h b/src/southbridge/intel/i82801gx/smbus.h
index 80456bc..5d63d43 100644
--- a/src/southbridge/intel/i82801gx/smbus.h
+++ b/src/southbridge/intel/i82801gx/smbus.h
@@ -93,3 +93,53 @@
}
return byte;
}
+
+static int do_smbus_block_read(unsigned smbus_base, unsigned device,
+ unsigned cmd, unsigned bytes, u8 *buf)
+{
+ u8 status;
+ int bytes_read = 0;
+ if (smbus_wait_until_ready(smbus_base) < 0)
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+
+ /* Setup transaction */
+ /* Disable interrupts */
+ outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
+ /* Set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
+ /* Set the command/address... */
+ outb(cmd & 0xff, smbus_base + SMBHSTCMD);
+ /* Set up for a block data read */
+ outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x5 << 2),
+ (smbus_base + SMBHSTCTL));
+ /* Clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
+
+ /* Start the command */
+ outb((inb(smbus_base + SMBHSTCTL) | 0x40),
+ smbus_base + SMBHSTCTL);
+
+ while (!(inb(smbus_base + SMBHSTSTAT) & 1));
+ /* Poll for transaction completion */
+ do {
+ status = inb(smbus_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_base + SMBBLKDAT);
+ buf++;
+ bytes_read++;
+ outb(status, smbus_base + SMBHSTSTAT);
+ if (--bytes == 1) {
+ /* indicate that next byte is the last one */
+ outb(inb(smbus_base + SMBHSTCTL) | 0x20,
+ smbus_base + SMBHSTCTL);
+ }
+ }
+ } while (status & 0x01);
+
+ return bytes_read;
+}
--
To view, visit https://review.coreboot.org/18927
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6d768a2ba128329168f26445a4fca6921c0c8642
Gerrit-PatchSet: 1
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>
More information about the coreboot-gerrit
mailing list