Richard Spiegel has uploaded this change for review. ( https://review.coreboot.org/29258
Change subject: soc/amd/stoneyridge: SMBUS access through MMIO ......................................................................
soc/amd/stoneyridge: SMBUS access through MMIO
Currently SMBUS registers are accessed through IO, but with stoneyridge they can be accessed through MMIO. This reduces the time of execution by a tiny amount (MMIO write is faster than IO write, though MMIO read is about as fast as IO read) as most of the time consumed is actually transaction time. Create a CONFIG parameter, so user can decide if they want to use IO (default) or MMIO when accessing SMBUS.
BUG=b:117754784 TEST=
Change-Id: Ibe1471d1d578611e7d666f70bc97de4c3b74d7f8 Signed-off-by: Richard Spiegel richard.spiegel@silverbackltd.com --- M src/soc/amd/stoneyridge/Kconfig M src/soc/amd/stoneyridge/include/soc/iomap.h M src/soc/amd/stoneyridge/include/soc/smbus.h M src/soc/amd/stoneyridge/smbus.c 4 files changed, 39 insertions(+), 22 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/58/29258/1
diff --git a/src/soc/amd/stoneyridge/Kconfig b/src/soc/amd/stoneyridge/Kconfig index 4411984..44295d4 100644 --- a/src/soc/amd/stoneyridge/Kconfig +++ b/src/soc/amd/stoneyridge/Kconfig @@ -385,4 +385,11 @@ return to S0. Otherwise the system will remain in S5 once power is restored.
+config STONEYRIDGE_MMIO_SMBUS + bool + default n + help + Set this option to y to access SMBUS registers through MMIO. + Otherwise it'll use standard IO access. + endif # SOC_AMD_STONEYRIDGE_FP4 || SOC_AMD_STONEYRIDGE_FT4 diff --git a/src/soc/amd/stoneyridge/include/soc/iomap.h b/src/soc/amd/stoneyridge/include/soc/iomap.h index 3e86564..0503052 100644 --- a/src/soc/amd/stoneyridge/include/soc/iomap.h +++ b/src/soc/amd/stoneyridge/include/soc/iomap.h @@ -37,6 +37,7 @@ #define APU_SMI_BASE 0xfed80200 #define PM_MMIO_BASE 0xfed80300 #define BIOSRAM_MMIO_BASE 0xfed80500 +#define SMBUS_MMIO_BASE 0xfed80a00 #define GPIO_IOMUX_MMIO_BASE 0xfed80d00 #define MISC_MMIO_BASE 0xfed80e00 #define XHCI_ACPI_PM_MMIO_BASE 0xfed81c00 diff --git a/src/soc/amd/stoneyridge/include/soc/smbus.h b/src/soc/amd/stoneyridge/include/soc/smbus.h index 1bb4346..58ee1c7 100644 --- a/src/soc/amd/stoneyridge/include/soc/smbus.h +++ b/src/soc/amd/stoneyridge/include/soc/smbus.h @@ -19,6 +19,15 @@ #include <stdint.h> #include <soc/iomap.h>
+#if IS_ENABLED(CONFIG_STONEYRIDGE_MMIO_SMBUS) + #define SMB_RD(base, reg) read8((void *)SMBUS_MMIO_BASE + reg) + #define SMB_WR(value, base, reg) write8((void *)SMBUS_MMIO_BASE + reg, \ + value) +#else + #define SMB_RD(base, reg) inb(base + reg) + #define SMB_WR(value, base, reg) outb(value, base + reg) +#endif + #define SMBHSTSTAT 0x0 #define SMBHST_STAT_FAILED 0x10 #define SMBHST_STAT_COLLISION 0x08 diff --git a/src/soc/amd/stoneyridge/smbus.c b/src/soc/amd/stoneyridge/smbus.c index 919a52e..9d1b899 100644 --- a/src/soc/amd/stoneyridge/smbus.c +++ b/src/soc/amd/stoneyridge/smbus.c @@ -23,12 +23,12 @@ loops = SMBUS_TIMEOUT; do { u8 val; - val = inb(smbus_io_base + SMBHSTSTAT); + val = SMB_RD(smbus_io_base, SMBHSTSTAT); val &= SMBHST_STAT_VAL_BITS; if (val == 0) { /* ready now */ return 0; } - outb(val, smbus_io_base + SMBHSTSTAT); + SMB_WR(val, smbus_io_base, SMBHSTSTAT); } while (--loops); return -2; /* time out */ } @@ -40,12 +40,12 @@ do { u8 val;
- val = inb(smbus_io_base + SMBHSTSTAT); + val = SMB_RD(smbus_io_base, SMBHSTSTAT); val &= SMBHST_STAT_VAL_BITS; /* mask off reserved bits */ if (val & SMBHST_STAT_ERROR_BITS) return -5; /* error */ if (val == SMBHST_STAT_NOERROR) { - outb(val, smbus_io_base + SMBHSTSTAT); /* clear sts */ + SMB_WR(val, smbus_io_base, SMBHSTSTAT); /* clear sts */ return 0; } } while (--loops); @@ -60,19 +60,19 @@ return -2; /* not ready */
/* set the device I'm talking to */ - outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR); + SMB_WR(((device & 0x7f) << 1) | 1, smbus_io_base, SMBHSTADDR);
- byte = inb(smbus_io_base + SMBHSTCTRL); + byte = SMB_RD(smbus_io_base, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BTE_RW; /* set mode, start */ - outb(byte, smbus_io_base + SMBHSTCTRL); + SMB_WR(byte, smbus_io_base, SMBHSTCTRL);
/* poll for transaction completion */ if (smbus_wait_until_done(smbus_io_base) < 0) return -3; /* timeout or error */
/* read results of transaction */ - byte = inb(smbus_io_base + SMBHSTDAT0); + byte = SMB_RD(smbus_io_base, SMBHSTDAT0);
return byte; } @@ -85,15 +85,15 @@ return -2; /* not ready */
/* set the command... */ - outb(val, smbus_io_base + SMBHSTDAT0); + SMB_WR(val, smbus_io_base, SMBHSTDAT0);
/* set the device I'm talking to */ - outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR); + SMB_WR(((device & 0x7f) << 1) | 0, smbus_io_base, SMBHSTADDR);
- byte = inb(smbus_io_base + SMBHSTCTRL); + byte = SMB_RD(smbus_io_base, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BTE_RW; /* set mode, start */ - outb(byte, smbus_io_base + SMBHSTCTRL); + SMB_WR(byte, smbus_io_base, SMBHSTCTRL);
/* poll for transaction completion */ if (smbus_wait_until_done(smbus_io_base) < 0) @@ -110,22 +110,22 @@ return -2; /* not ready */
/* set the command/address... */ - outb(address & 0xff, smbus_io_base + SMBHSTCMD); + SMB_WR(address & 0xff, smbus_io_base, SMBHSTCMD);
/* set the device I'm talking to */ - outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR); + SMB_WR(((device & 0x7f) << 1) | 1, smbus_io_base, SMBHSTADDR);
- byte = inb(smbus_io_base + SMBHSTCTRL); + byte = SMB_RD(smbus_io_base, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BDT_RW; /* set mode, start */ - outb(byte, smbus_io_base + SMBHSTCTRL); + SMB_WR(byte, smbus_io_base, SMBHSTCTRL);
/* poll for transaction completion */ if (smbus_wait_until_done(smbus_io_base) < 0) return -3; /* timeout or error */
/* read results of transaction */ - byte = inb(smbus_io_base + SMBHSTDAT0); + byte = SMB_RD(smbus_io_base, SMBHSTDAT0);
return byte; } @@ -138,18 +138,18 @@ return -2; /* not ready */
/* set the command/address... */ - outb(address & 0xff, smbus_io_base + SMBHSTCMD); + SMB_WR(address & 0xff, smbus_io_base, SMBHSTCMD);
/* set the device I'm talking to */ - outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR); + SMB_WR(((device & 0x7f) << 1) | 0, smbus_io_base, SMBHSTADDR);
/* output value */ - outb(val, smbus_io_base + SMBHSTDAT0); + SMB_WR(val, smbus_io_base, SMBHSTDAT0);
- byte = inb(smbus_io_base + SMBHSTCTRL); + byte = SMB_RD(smbus_io_base, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BDT_RW; /* set mode, start */ - outb(byte, smbus_io_base + SMBHSTCTRL); + SMB_WR(byte, smbus_io_base, SMBHSTCTRL);
/* poll for transaction completion */ if (smbus_wait_until_done(smbus_io_base) < 0)