sb/intel/common: Wrap inb/outb()

On Intel, accessing the SMBus register banks can be done via
IO and, since at least ICH10, via MMIO. We may want to use the
latter in the future.

Change-Id: I67fcbc7b6f6be61c93bc608e556a577ef9e52325
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38150
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Kyösti Mälkki 2020-01-02 16:36:56 +02:00
parent bbcf1a0878
commit b49638dbe4
1 changed files with 41 additions and 32 deletions

View File

@ -72,6 +72,16 @@ static void smbus_delay(void)
inb(0x80); inb(0x80);
} }
static void host_outb(unsigned int base, u8 reg, u8 value)
{
outb(value, base + reg);
}
static u8 host_inb(unsigned int base, u8 reg)
{
return inb(base + reg);
}
static int host_completed(u8 status) static int host_completed(u8 status)
{ {
if (status & SMBHSTSTS_HOST_BUSY) if (status & SMBHSTSTS_HOST_BUSY)
@ -111,7 +121,7 @@ static int setup_command(unsigned int smbus_base, u8 ctrl, u8 xmitadd)
do { do {
smbus_delay(); smbus_delay();
host_busy = inb(smbus_base + SMBHSTSTAT) & SMBHSTSTS_HOST_BUSY; host_busy = host_inb(smbus_base, SMBHSTSTAT) & SMBHSTSTS_HOST_BUSY;
} while (--loops && host_busy); } while (--loops && host_busy);
if (loops == 0) if (loops == 0)
@ -119,14 +129,14 @@ static int setup_command(unsigned int smbus_base, u8 ctrl, u8 xmitadd)
SMBUS_WAIT_UNTIL_READY_TIMEOUT); SMBUS_WAIT_UNTIL_READY_TIMEOUT);
/* Clear any lingering errors, so the transaction will run. */ /* Clear any lingering errors, so the transaction will run. */
outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT); host_outb(smbus_base, SMBHSTSTAT, host_inb(smbus_base, SMBHSTSTAT));
/* Set up transaction */ /* Set up transaction */
/* Disable interrupts */ /* Disable interrupts */
outb(ctrl, (smbus_base + SMBHSTCTL)); host_outb(smbus_base, SMBHSTCTL, ctrl);
/* Set the device I'm talking to. */ /* Set the device I'm talking to. */
outb(xmitadd, smbus_base + SMBXMITADD); host_outb(smbus_base, SMBXMITADD, xmitadd);
return 0; return 0;
} }
@ -137,8 +147,7 @@ static int execute_command(unsigned int smbus_base)
u8 status; u8 status;
/* Start the command. */ /* Start the command. */
outb((inb(smbus_base + SMBHSTCTL) | SMBHSTCNT_START), host_outb(smbus_base, SMBHSTCTL, host_inb(smbus_base, SMBHSTCTL) | SMBHSTCNT_START);
smbus_base + SMBHSTCTL);
/* Poll for it to start. */ /* Poll for it to start. */
do { do {
@ -147,7 +156,7 @@ static int execute_command(unsigned int smbus_base)
/* If we poll too slow, we could miss HOST_BUSY flag /* If we poll too slow, we could miss HOST_BUSY flag
* set and detect INTR or x_ERR flags instead here. * set and detect INTR or x_ERR flags instead here.
*/ */
status = inb(smbus_base + SMBHSTSTAT); status = host_inb(smbus_base, SMBHSTSTAT);
status &= ~(SMBHSTSTS_SMBALERT_STS | SMBHSTSTS_INUSE_STS); status &= ~(SMBHSTSTS_SMBALERT_STS | SMBHSTSTS_INUSE_STS);
} while (--loops && status == 0); } while (--loops && status == 0);
@ -165,7 +174,7 @@ static int complete_command(unsigned int smbus_base)
do { do {
smbus_delay(); smbus_delay();
status = inb(smbus_base + SMBHSTSTAT); status = host_inb(smbus_base, SMBHSTSTAT);
} while (--loops && !host_completed(status)); } while (--loops && !host_completed(status));
if (loops == 0) if (loops == 0)
@ -187,11 +196,11 @@ static int smbus_read_cmd(unsigned int smbus_base, u8 ctrl, u8 device,
return ret; return ret;
/* Set the command/address... */ /* Set the command/address... */
outb(address, smbus_base + SMBHSTCMD); host_outb(smbus_base, SMBHSTCMD, address);
/* Clear the data bytes... */ /* Clear the data bytes... */
outb(0, smbus_base + SMBHSTDAT0); host_outb(smbus_base, SMBHSTDAT0, 0);
outb(0, smbus_base + SMBHSTDAT1); host_outb(smbus_base, SMBHSTDAT1, 0);
/* Start the command */ /* Start the command */
ret = execute_command(smbus_base); ret = execute_command(smbus_base);
@ -204,9 +213,9 @@ static int smbus_read_cmd(unsigned int smbus_base, u8 ctrl, u8 device,
return ret; return ret;
/* Read results of transaction */ /* Read results of transaction */
word = inb(smbus_base + SMBHSTDAT0); word = host_inb(smbus_base, SMBHSTDAT0);
if (ctrl == I801_WORD_DATA) if (ctrl == I801_WORD_DATA)
word |= inb(smbus_base + SMBHSTDAT1) << 8; word |= host_inb(smbus_base, SMBHSTDAT1) << 8;
return word; return word;
} }
@ -222,12 +231,12 @@ static int smbus_write_cmd(unsigned int smbus_base, u8 ctrl, u8 device,
return ret; return ret;
/* Set the command/address... */ /* Set the command/address... */
outb(address, smbus_base + SMBHSTCMD); host_outb(smbus_base, SMBHSTCMD, address);
/* Set the data bytes... */ /* Set the data bytes... */
outb(data & 0xff, smbus_base + SMBHSTDAT0); host_outb(smbus_base, SMBHSTDAT0, data & 0xff);
if (ctrl == I801_WORD_DATA) if (ctrl == I801_WORD_DATA)
outb(data >> 8, smbus_base + SMBHSTDAT1); host_outb(smbus_base, SMBHSTDAT1, data >> 8);
/* Start the command */ /* Start the command */
ret = execute_command(smbus_base); ret = execute_command(smbus_base);
@ -256,16 +265,16 @@ static int block_cmd_loop(unsigned int smbus_base,
* was really updated with the transaction. */ * was really updated with the transaction. */
if (!sw_drives_nak) { if (!sw_drives_nak) {
if (is_write_cmd) if (is_write_cmd)
outb(max_bytes, smbus_base + SMBHSTDAT0); host_outb(smbus_base, SMBHSTDAT0, max_bytes);
else else
outb(0, smbus_base + SMBHSTDAT0); host_outb(smbus_base, SMBHSTDAT0, 0);
} }
/* Send first byte from buffer, bytes_sent increments after /* Send first byte from buffer, bytes_sent increments after
* hardware acknowledges it. * hardware acknowledges it.
*/ */
if (is_write_cmd) if (is_write_cmd)
outb(*buf++, smbus_base + SMBBLKDAT); host_outb(smbus_base, SMBBLKDAT, *buf++);
/* Start the command */ /* Start the command */
ret = execute_command(smbus_base); ret = execute_command(smbus_base);
@ -274,24 +283,24 @@ static int block_cmd_loop(unsigned int smbus_base,
/* Poll for transaction completion */ /* Poll for transaction completion */
do { do {
status = inb(smbus_base + SMBHSTSTAT); status = host_inb(smbus_base, SMBHSTSTAT);
if (status & SMBHSTSTS_BYTE_DONE) { /* Byte done */ if (status & SMBHSTSTS_BYTE_DONE) { /* Byte done */
if (is_write_cmd) { if (is_write_cmd) {
bytes++; bytes++;
if (bytes < max_bytes) if (bytes < max_bytes)
outb(*buf++, smbus_base + SMBBLKDAT); host_outb(smbus_base, SMBBLKDAT, *buf++);
} else { } else {
if (bytes < max_bytes) if (bytes < max_bytes)
*buf++ = inb(smbus_base + SMBBLKDAT); *buf++ = host_inb(smbus_base, SMBBLKDAT);
bytes++; bytes++;
/* Indicate that next byte is the last one. */ /* Indicate that next byte is the last one. */
if (sw_drives_nak && (bytes + 1 >= max_bytes)) { if (sw_drives_nak && (bytes + 1 >= max_bytes)) {
outb(inb(smbus_base + SMBHSTCTL) host_outb(smbus_base, SMBHSTCTL,
| SMBHSTCNT_LAST_BYTE, host_inb(smbus_base, SMBHSTCTL) |
smbus_base + SMBHSTCTL); SMBHSTCNT_LAST_BYTE);
} }
} }
@ -300,7 +309,7 @@ static int block_cmd_loop(unsigned int smbus_base,
* and clears HOST_BUSY flag once the byte count * and clears HOST_BUSY flag once the byte count
* has been reached or LAST_BYTE was set. * has been reached or LAST_BYTE was set.
*/ */
outb(SMBHSTSTS_BYTE_DONE, smbus_base + SMBHSTSTAT); host_outb(smbus_base, SMBHSTSTAT, SMBHSTSTS_BYTE_DONE);
} }
} while (--loops && !host_completed(status)); } while (--loops && !host_completed(status));
@ -354,7 +363,7 @@ int do_smbus_block_read(unsigned int smbus_base, u8 device, u8 cmd,
return ret; return ret;
/* Set the command/address... */ /* Set the command/address... */
outb(cmd, smbus_base + SMBHSTCMD); host_outb(smbus_base, SMBHSTCMD, cmd);
/* Execute block transaction. */ /* Execute block transaction. */
ret = block_cmd_loop(smbus_base, buf, max_bytes, BLOCK_READ); ret = block_cmd_loop(smbus_base, buf, max_bytes, BLOCK_READ);
@ -362,7 +371,7 @@ int do_smbus_block_read(unsigned int smbus_base, u8 device, u8 cmd,
return ret; return ret;
/* Post-check we received complete message. */ /* Post-check we received complete message. */
slave_bytes = inb(smbus_base + SMBHSTDAT0); slave_bytes = host_inb(smbus_base, SMBHSTDAT0);
if (ret < slave_bytes) if (ret < slave_bytes)
return SMBUS_ERROR; return SMBUS_ERROR;
@ -383,7 +392,7 @@ int do_smbus_block_write(unsigned int smbus_base, u8 device, u8 cmd,
return ret; return ret;
/* Set the command/address... */ /* Set the command/address... */
outb(cmd, smbus_base + SMBHSTCMD); host_outb(smbus_base, SMBHSTCMD, cmd);
/* Execute block transaction. */ /* Execute block transaction. */
ret = block_cmd_loop(smbus_base, (u8 *)buf, bytes, BLOCK_WRITE); ret = block_cmd_loop(smbus_base, (u8 *)buf, bytes, BLOCK_WRITE);
@ -425,7 +434,7 @@ int do_i2c_eeprom_read(unsigned int smbus_base, u8 device,
return ret; return ret;
/* device offset */ /* device offset */
outb(offset, smbus_base + SMBHSTDAT1); host_outb(smbus_base, SMBHSTDAT1, offset);
/* Execute block transaction. */ /* Execute block transaction. */
ret = block_cmd_loop(smbus_base, buf, bytes, BLOCK_READ | BLOCK_I2C); ret = block_cmd_loop(smbus_base, buf, bytes, BLOCK_READ | BLOCK_I2C);
@ -468,8 +477,8 @@ int do_i2c_block_write(unsigned int smbus_base, u8 device,
*/ */
cmd = *buf++; cmd = *buf++;
bytes--; bytes--;
outb(cmd, smbus_base + SMBHSTCMD); host_outb(smbus_base, SMBHSTCMD, cmd);
outb(cmd, smbus_base + SMBHSTDAT1); host_outb(smbus_base, SMBHSTDAT1, cmd);
/* Execute block transaction. */ /* Execute block transaction. */
ret = block_cmd_loop(smbus_base, buf, bytes, BLOCK_WRITE); ret = block_cmd_loop(smbus_base, buf, bytes, BLOCK_WRITE);