summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/northbridge/intel/sandybridge/pei_data.h12
-rw-r--r--src/southbridge/intel/bd82x6x/acpi/globalnvs.asl14
-rw-r--r--src/southbridge/intel/bd82x6x/acpi/pch.asl23
-rw-r--r--src/southbridge/intel/bd82x6x/acpi/usb.asl69
-rw-r--r--src/southbridge/intel/bd82x6x/early_usb.c9
-rw-r--r--src/southbridge/intel/bd82x6x/nvs.h4
-rw-r--r--src/southbridge/intel/bd82x6x/pch.h7
-rw-r--r--src/southbridge/intel/bd82x6x/smihandler.c14
8 files changed, 140 insertions, 12 deletions
diff --git a/src/northbridge/intel/sandybridge/pei_data.h b/src/northbridge/intel/sandybridge/pei_data.h
index 8c907c1db8..fb56873d2b 100644
--- a/src/northbridge/intel/sandybridge/pei_data.h
+++ b/src/northbridge/intel/sandybridge/pei_data.h
@@ -30,8 +30,16 @@
#ifndef PEI_DATA_H
#define PEI_DATA_H
+typedef struct {
+ uint16_t mode; // 0: Disable, 1: Enable, 2: Auto, 3: Smart Auto
+ uint16_t hs_port_switch_mask; // 4 bit mask, 1: switchable, 0: not switchable
+ uint16_t preboot_support; // 0: No xHCI preOS driver, 1: xHCI preOS driver
+ uint16_t xhci_streams; // 0: Disable, 1: Enable
+} pch_usb3_controller_settings;
+
typedef void (*tx_byte_func)(unsigned char byte);
-#define PEI_VERSION 4
+#define PEI_VERSION 5
+
struct pei_data
{
uint32_t pei_version;
@@ -92,6 +100,8 @@ struct pei_data
* < 0x150 = Setting 3 (back panel, 13-15in, higest tx amplitude)
*/
uint16_t usb_port_config[16][3];
+ /* See the usb3 struct above for details */
+ pch_usb3_controller_settings usb3;
/* SPD data array for onboard RAM. Specify address 0xf0,
* 0xf1, 0xf2, 0xf3 to index one of the 4 slots in
* spd_address for a given "DIMM".
diff --git a/src/southbridge/intel/bd82x6x/acpi/globalnvs.asl b/src/southbridge/intel/bd82x6x/acpi/globalnvs.asl
index 2fe092d952..99edc317cf 100644
--- a/src/southbridge/intel/bd82x6x/acpi/globalnvs.asl
+++ b/src/southbridge/intel/bd82x6x/acpi/globalnvs.asl
@@ -136,6 +136,9 @@ Field (GNVS, ByteAcc, NoLock, Preserve)
GTF2, 56, // 0xa4 - GTF task file buffer for port 2
IDEM, 8, // 0xab - IDE mode (compatible / enhanced)
IDET, 8, // 0xac - IDE
+ /* XHCI */
+ Offset (0xb2),
+ XHCI, 8,
/* IGD OpRegion */
Offset (0xb4),
ASLB, 32, // 0xb4 - IGD OpRegion Base Address
@@ -223,6 +226,17 @@ Method (S3GD)
Store (Zero, \S33G)
}
+/* Set XHCI Mode enable */
+Method (XHCE)
+{
+ Store (One, \XHCI)
+}
+
+/* Set XHCI Mode disable */
+Method (XHCD)
+{
+ Store (Zero, \XHCI)
+}
External (\_TZ.THRM)
External (\_TZ.SKIN)
diff --git a/src/southbridge/intel/bd82x6x/acpi/pch.asl b/src/southbridge/intel/bd82x6x/acpi/pch.asl
index 8632ad849e..2f75fdc3f7 100644
--- a/src/southbridge/intel/bd82x6x/acpi/pch.asl
+++ b/src/southbridge/intel/bd82x6x/acpi/pch.asl
@@ -245,7 +245,7 @@ Scope(\)
// PCI Express Ports 0:1c.x
#include "pcie.asl"
-// USB 0:1d.0 and 0:1a.0
+// USB EHCI 0:1d.0 and 0:1a.0, XHCI 0:14.0
#include "usb.asl"
// LPC Bridge 0:1f.0
@@ -259,17 +259,22 @@ Scope(\)
Method (_OSC, 4)
{
- /* Check for proper GUID */
- If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
+ /* Check for XHCI */
+ If (LEqual (Arg0, ToUUID("7c9512a9-1705-4cb4-af7d-506a2423ab71")))
{
- /* Let OS control everything */
- Return (Arg3)
+ Return (^XHC.POSC(Arg1, Arg2, Arg3))
}
- Else
+
+ /* Check for PCIe */
+ If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
{
- /* Unrecognized UUID */
- CreateDWordField (Arg3, 0, CDW1)
- Or (CDW1, 4, CDW1)
+ /* Let OS control everything */
Return (Arg3)
}
+
+ /* Else Return Unrecognized UUID */
+ CreateDWordField (Arg3, 0, CDW1)
+ Or (CDW1, 4, CDW1)
+ Return (Arg3)
+
}
diff --git a/src/southbridge/intel/bd82x6x/acpi/usb.asl b/src/southbridge/intel/bd82x6x/acpi/usb.asl
index cf3e6a049f..f19d3685ae 100644
--- a/src/southbridge/intel/bd82x6x/acpi/usb.asl
+++ b/src/southbridge/intel/bd82x6x/acpi/usb.asl
@@ -89,3 +89,72 @@ Device (EHC2)
}
}
+Device (XHC)
+{
+ Name(_ADR, 0x00140000)
+ OperationRegion(XDEV, PCI_Config, 0, 256)
+ Field(XDEV, DWordAcc, NoLock, Preserve)
+ {
+ Offset(0xD0),
+ X2PR, 32, // XUSB2PR
+ PRM2, 32, // XUSB2PRM
+ SSEN, 32, // USB3_PSSEN
+ RPM3, 32, // USB3PRM
+ XPRT, 32, // XHCI Ports
+ }
+
+ Name (_PRW, Package(){ 13, 4 }) // Power Resources for Wake
+
+ Method(POSC,3,Serialized)
+ {
+ // Create DWord field from the Capabilities Buffer
+ CreateDWordField(Arg2,0,CDW1)
+
+ // Check revision
+ If(LNotEqual(Arg1,One)) {
+ // Set unknown revision bit
+ Or(CDW1,0x8,CDW1)
+ }
+
+ // Set failure if xHCI is disabled by coreboot
+ If(LEqual(XHCI, 0)) {
+ Or(CDW1,0x2,CDW1)
+ }
+
+ // Query flag clear and xHCI in auto mode
+ If(LAnd(LNot(And(CDW1,0x1)),LOr(LEqual(XHCI ,2), LEqual(XHCI ,3)))) {
+ Store ("XHCI Switch", Debug)
+ Store(Zero, Local0)
+ And(XPRT, 0x3, Local0)
+ If(LOr(LEqual(Local0, 0), LEqual(Local0, 1))) {
+ Store(0xF, Local1)
+ }
+ ElseIf(LEqual(Local0, 2)) {
+ Store(0x3, Local1)
+ }
+ ElseIf(LEqual(Local0, 3)) {
+ Store(Zero, Local1)
+ }
+ And(RPM3, 0xFFFFFFF0, Local0)
+ Or(Local0, Local1, RPM3)
+ And(PRM2, 0xFFFFFFF0, Local0)
+ Or(Local0, Local1, PRM2)
+ And(SSEN, 0xFFFFFFF0, Local0)
+ Or(Local0, Local1, SSEN)
+ And(X2PR, 0xFFFFFFF0, Local0)
+ Or(Local0, Local1, X2PR)
+ }
+ Return(Arg2)
+ }
+
+ // Leave USB ports on for to allow Wake from USB
+ Method(_S3D,0) // Highest D State in S3 State
+ {
+ Return (2)
+ }
+
+ Method(_S4D,0) // Highest D State in S4 State
+ {
+ Return (2)
+ }
+}
diff --git a/src/southbridge/intel/bd82x6x/early_usb.c b/src/southbridge/intel/bd82x6x/early_usb.c
index b2e009123e..bbe792f908 100644
--- a/src/southbridge/intel/bd82x6x/early_usb.c
+++ b/src/southbridge/intel/bd82x6x/early_usb.c
@@ -27,6 +27,7 @@
#define PCH_EHCI1_TEMP_BAR0 0xe8000000
#define PCH_EHCI2_TEMP_BAR0 0xe8000400
+#define PCH_XHCI_TEMP_BAR0 0xe8001000
/*
* Setup USB controller MMIO BAR to prevent the
@@ -39,6 +40,7 @@ void enable_usb_bar(void)
{
device_t usb0 = PCH_EHCI1_DEV;
device_t usb1 = PCH_EHCI2_DEV;
+ device_t usb3 = PCH_XHCI_DEV;
u32 cmd;
/* USB Controller 1 */
@@ -54,4 +56,11 @@ void enable_usb_bar(void)
cmd = pci_read_config32(usb1, PCI_COMMAND);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_write_config32(usb1, PCI_COMMAND, cmd);
+
+ /* USB3 Controller */
+ pci_write_config32(usb3, PCI_BASE_ADDRESS_0,
+ PCH_XHCI_TEMP_BAR0);
+ cmd = pci_read_config32(usb3, PCI_COMMAND);
+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config32(usb3, PCI_COMMAND, cmd);
}
diff --git a/src/southbridge/intel/bd82x6x/nvs.h b/src/southbridge/intel/bd82x6x/nvs.h
index b8506d4db4..7b8b6c9e9c 100644
--- a/src/southbridge/intel/bd82x6x/nvs.h
+++ b/src/southbridge/intel/bd82x6x/nvs.h
@@ -113,7 +113,9 @@ typedef struct {
u8 gtf2[7];
u8 idem;
u8 idet;
- u8 rsvd11[7];
+ u8 rsvd11[6];
+ /* XHCI */
+ u8 xhci;
/* IGD OpRegion (not implemented yet) */
u32 aslb; /* 0xb4 - IGD OpRegion Base Address */
u8 ibtt; /* 0xb8 - IGD boot type */
diff --git a/src/southbridge/intel/bd82x6x/pch.h b/src/southbridge/intel/bd82x6x/pch.h
index 13ffe3a2a6..ca54418914 100644
--- a/src/southbridge/intel/bd82x6x/pch.h
+++ b/src/southbridge/intel/bd82x6x/pch.h
@@ -95,6 +95,7 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer);
#define PCH_EHCI1_DEV PCI_DEV(0, 0x1d, 0)
#define PCH_EHCI2_DEV PCI_DEV(0, 0x1a, 0)
+#define PCH_XHCI_DEV PCI_DEV(0, 0x14, 0)
#define PCH_ME_DEV PCI_DEV(0, 0x16, 0)
#define PCH_PCIE_DEV_SLOT 28
@@ -365,6 +366,8 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer);
#define D22IP_IDERIP 8 /* IDE-R Pin */
#define D22IP_MEI2IP 4 /* MEI #2 Pin */
#define D22IP_MEI1IP 0 /* MEI #1 Pin */
+#define D20IP 0x3128 /* 32bit */
+#define D20IP_XHCIIP 0
#define D31IR 0x3140 /* 16bit */
#define D30IR 0x3142 /* 16bit */
#define D29IR 0x3144 /* 16bit */
@@ -373,6 +376,7 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer);
#define D26IR 0x314c /* 16bit */
#define D25IR 0x3150 /* 16bit */
#define D22IR 0x315c /* 16bit */
+#define D20IR 0x3160 /* 16bit */
#define OIC 0x31fe /* 16bit */
#define SOFT_RESET_CTRL 0x38f4
#define SOFT_RESET_DATA 0x38f8
@@ -392,7 +396,7 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer);
#define CG 0x341c /* 32bit */
/* Function Disable 1 RCBA 0x3418 */
-#define PCH_DISABLE_ALWAYS ((1 << 0)|(1 << 26)|(1 << 27))
+#define PCH_DISABLE_ALWAYS ((1 << 0)|(1 << 26))
#define PCH_DISABLE_P2P (1 << 1)
#define PCH_DISABLE_SATA1 (1 << 2)
#define PCH_DISABLE_SMBUS (1 << 3)
@@ -403,6 +407,7 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer);
#define PCH_DISABLE_PCIE(x) (1 << (16 + x))
#define PCH_DISABLE_THERMAL (1 << 24)
#define PCH_DISABLE_SATA2 (1 << 25)
+#define PCH_DISABLE_XHCI (1 << 27)
/* Function Disable 2 RCBA 0x3428 */
#define PCH_DISABLE_KT (1 << 4)
diff --git a/src/southbridge/intel/bd82x6x/smihandler.c b/src/southbridge/intel/bd82x6x/smihandler.c
index 420c5db211..093da5c60a 100644
--- a/src/southbridge/intel/bd82x6x/smihandler.c
+++ b/src/southbridge/intel/bd82x6x/smihandler.c
@@ -326,6 +326,17 @@ static void southbridge_gate_memory_reset(void)
outl(reg32, gpiobase + GP_LVL2);
}
+static void xhci_sleep(u8 slp_typ)
+{
+ u32 reg32;
+
+ if (slp_typ == SLP_TYP_S5) {
+ reg32 = pcie_read_config32(PCH_XHCI_DEV, 0x74);
+ reg32 |= (1 << 8 | 0x03 );
+ pcie_write_config32(PCH_XHCI_DEV, 0x74, reg32);
+ }
+}
+
static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save)
{
u8 reg8;
@@ -353,6 +364,9 @@ static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *stat
printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
slp_typ = (reg32 >> 10) & 7;
+ if (smm_get_gnvs()->xhci)
+ xhci_sleep(slp_typ);
+
/* Do any mainboard sleep handling */
tseg_relocate((void **)&mainboard_sleep);
if (mainboard_sleep)