Keith Hui has uploaded this change for review.

View Change

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 */
}

To view, visit change 41735. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I97deb2d292af25e42068474f48e11c94a7480be6
Gerrit-Change-Number: 41735
Gerrit-PatchSet: 1
Gerrit-Owner: Keith Hui <buurin@gmail.com>
Gerrit-MessageType: newchange