Keith Hui has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41735 )
Change subject: sb/intel/i82371eb: Implement SMBus Control Method Interface support ......................................................................
sb/intel/i82371eb: Implement SMBus Control Method Interface support
Upcoming ACPI support for asus/p3b-f mainboard contains ASL code to manipulate its AS99127F chip over SMBus before and after suspend, to blink front panel lights, turn off fans, among other things. This code caused an ACPI/PCI resource conflict that disabled access to the entire SMBus, rendering its hardware monitor inoperative, and all resolution attempts so far have not worked.
This is an attempt to expand the ASL SMBus routines into a complete SMBus Control Method Interface (SCMI), that Linux kernel can use via the i2c-scmi driver, sidestepping this conflict.
Because SCMI methods begin with an underscore, which iasl considers "unknown reserved name", on which our build process errors out, it must also be told to ignore this particular warning, at least for asus/p3b-f.
Change-Id: I97deb2d292af25e42068474f48e11c94a7480be6 Signed-off-by: Keith Hui buurin@gmail.com --- M Makefile.inc M src/southbridge/intel/i82371eb/acpi/i82371eb.asl 2 files changed, 183 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/35/41735/1
diff --git a/Makefile.inc b/Makefile.inc index 210e9cf..d1aebd3 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -253,11 +253,17 @@ # "Multiple types (Device object requires either a _HID or _ADR, but not both)" MULTIPLE_TYPES_WARNING = 3073
+UNKNOWN_RESERVED_NAME = 3133 + ifeq ($(CONFIG_SOUTHBRIDGE_INTEL_LYNXPOINT)$(CONFIG_SOC_INTEL_BROADWELL),y) IGNORED_IASL_WARNINGS = -vw $(EMPTY_RESOURCE_TEMPLATE_WARNING) -vw $(REDUNDANT_OFFSET_REMARK) -vw $(MULTIPLE_TYPES_WARNING) else +ifeq ($(CONFIG_BOARD_ASUS_P3B_F),y) +IGNORED_IASL_WARNINGS = -vw $(EMPTY_RESOURCE_TEMPLATE_WARNING) -vw $(REDUNDANT_OFFSET_REMARK) -vw $(UNKNOWN_RESERVED_NAME) +else IGNORED_IASL_WARNINGS = -vw $(EMPTY_RESOURCE_TEMPLATE_WARNING) -vw $(REDUNDANT_OFFSET_REMARK) endif +endif
define asl_template $(CONFIG_CBFS_PREFIX)/$(1).aml-file = $(obj)/$(1).aml diff --git a/src/southbridge/intel/i82371eb/acpi/i82371eb.asl b/src/southbridge/intel/i82371eb/acpi/i82371eb.asl index b64036e..27c2a3c 100644 --- a/src/southbridge/intel/i82371eb/acpi/i82371eb.asl +++ b/src/southbridge/intel/i82371eb/acpi/i82371eb.asl @@ -2,6 +2,8 @@
#include "southbridge/intel/i82371eb/i82371eb.h"
+#define SCMI_MUTEX SBX0 + /* Declares assorted devices that falls under this southbridge. */ Device (PX40) { @@ -135,4 +137,179 @@ }) Return (BUF1) } +/* Begin SCMI implementation */ + Mutex(SCMI_MUTEX, 1) + + Device (SMB0) + { + OperationRegion (SM00, SystemIO, SMBUS_IO_BASE, 7) + /* Should have been SMBUS01, but Intel iasl won't accept */ + Name (_HID, "SMB0001") + + Field (SM00, ByteAcc, NoLock, Preserve) + { + HSTS, 8, + Offset (0x02), + CTLR, 8, + CMDR, 8, + ADDR, 8, + DAT0, 8, + DAT1, 8 + } + Method (_CRS, 0, NotSerialized) + { + Name (BUF1, ResourceTemplate () + { + /* SMBus register ports */ + IO (Decode16, SMBUS_IO_BASE, SMBUS_IO_BASE, 0x01, 0x10, ) + }) + Return (BUF1) + } + /** + * SCMI: SMBus Information + * + * @return SMBus information buffer + */ + Method (_SBI, 0) + { + Local0 = Package(2) {0x10, Buffer() + { + 0x10, 0x10, /* SCMI and SMBus versions, both 1.0 */ + 0, 0, + 3, /* Device count */ + 0x2d, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0x48, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0x49, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 + } + }; + return (Local0) + } + /** + * Read from a SMBus device. + * + * @param Arg0 Protocol + * @param Arg1 Slave address + * @param Arg2 Command (register index in our case) + * @return Package (status code, data length, data) + */ + Method (_SBR, 3) { + Local2 = Package(3) {0, 0, 0} + if (Arg0 == 0x07) + { + Local0 = 0x48 /* Start a byte data R/W access */ + Local3 = 1; /* 1 byte */ + } + elseif (Arg0 == 0x09) + { + Local0 = 0x4c /* Start a word data R/W access */ + } + else + { + Index(Local2, 0) = 0x19 // Protocol not supported + return (Local2) + } + if (HSTS & 0x01) + { + Index(Local2, 0) = 0x1a // Bus busy + return (Local2) + } + if (Acquire(SCMI_MUTEX, 100)) + { + Index(Local2, 0) = 0x18 // Timeout + } else { + ADDR = (Arg1 << 1) | 0x01 /* Set bit 0, this is a read */ + CMDR = Arg2 + HSTS = 0xFF + CTLR = Local0 + + while (HSTS & 0x01) + { + Stall(1) + } + if (HSTS & 0x06) + { + Index(Local2, 0) = 0x11 /* Device error */ + } + else + { + Local1 = DAT0 + /* Get high byte of word read */ + if (Arg0 == 0x09) + { + Local1 |= (DAT1 << 8) + Local3 = 2 /* 2 bytes */ + } + Index(Local2, 1) = Local3 + Index(Local2, 2) = Local1 + } + Release(SCMI_MUTEX); + } + return (Local2); + } + /** + * Write to a SMBus device. + * + * @param Arg0 Protocol + * @param Arg1 Slave address + * @param Arg2 Command (register index in our case) + * @param Arg3 Data length + * @param Arg4 Data + * @return Status code + */ + Method (_SBW, 5) { + if (Arg0 == 0x06) + { + Local0 = 0x48 /* Start a byte data R/W access */ + } + elseif (Arg0 == 0x08) + { + Local0 = 0x4c /* Start a word data R/W access */ + } + else + { + Return (0x19) //* Protocol not supported */ + } + if (HSTS & 0x01) + { + Return (0x1a) /* Bus busy */ + } + if (Acquire(SCMI_MUTEX, 100)) + { + Local1 = 0x18 /* Timeout */ + } + else + { + Local1 = 0 + ADDR = Arg1 << 1 + CMDR = Arg2 + DAT0 = Arg4 + if (Arg0 == 0x08) { + DAT1 = Arg4 >> 8 + } + HSTS = 0xFF + CTLR = Local0 + while (HSTS & 0x01) + { + Stall(1) + } + if (HSTS & 0x06) + { + Local1 = 0x11 /* Device error */ + } + Release(SCMI_MUTEX) + } + return (Local1); + } + /* _SBT, _SBA not implemented */ + } +/* End SCMI implementation */ }