Add Intel Panther Point USB3 initialization

Add PEI updates and ACPI updates for supporting EHCI to XHCI
USB port support.

Change-Id: I9ace68a1b3950771aefb96c1319b8899291edd9a
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Reviewed-on: http://review.coreboot.org/2519
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth@se-eng.com>
This commit is contained in:
Marc Jones 2012-11-13 15:07:45 -07:00
parent 4733c647bc
commit e7ae96f488
8 changed files with 140 additions and 12 deletions

View File

@ -30,8 +30,16 @@
#ifndef PEI_DATA_H #ifndef PEI_DATA_H
#define 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); typedef void (*tx_byte_func)(unsigned char byte);
#define PEI_VERSION 4 #define PEI_VERSION 5
struct pei_data struct pei_data
{ {
uint32_t pei_version; uint32_t pei_version;
@ -92,6 +100,8 @@ struct pei_data
* < 0x150 = Setting 3 (back panel, 13-15in, higest tx amplitude) * < 0x150 = Setting 3 (back panel, 13-15in, higest tx amplitude)
*/ */
uint16_t usb_port_config[16][3]; 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, /* SPD data array for onboard RAM. Specify address 0xf0,
* 0xf1, 0xf2, 0xf3 to index one of the 4 slots in * 0xf1, 0xf2, 0xf3 to index one of the 4 slots in
* spd_address for a given "DIMM". * spd_address for a given "DIMM".

View File

@ -136,6 +136,9 @@ Field (GNVS, ByteAcc, NoLock, Preserve)
GTF2, 56, // 0xa4 - GTF task file buffer for port 2 GTF2, 56, // 0xa4 - GTF task file buffer for port 2
IDEM, 8, // 0xab - IDE mode (compatible / enhanced) IDEM, 8, // 0xab - IDE mode (compatible / enhanced)
IDET, 8, // 0xac - IDE IDET, 8, // 0xac - IDE
/* XHCI */
Offset (0xb2),
XHCI, 8,
/* IGD OpRegion */ /* IGD OpRegion */
Offset (0xb4), Offset (0xb4),
ASLB, 32, // 0xb4 - IGD OpRegion Base Address ASLB, 32, // 0xb4 - IGD OpRegion Base Address
@ -223,6 +226,17 @@ Method (S3GD)
Store (Zero, \S33G) 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.THRM)
External (\_TZ.SKIN) External (\_TZ.SKIN)

View File

@ -245,7 +245,7 @@ Scope(\)
// PCI Express Ports 0:1c.x // PCI Express Ports 0:1c.x
#include "pcie.asl" #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" #include "usb.asl"
// LPC Bridge 0:1f.0 // LPC Bridge 0:1f.0
@ -259,17 +259,22 @@ Scope(\)
Method (_OSC, 4) Method (_OSC, 4)
{ {
/* Check for proper GUID */ /* Check for XHCI */
If (LEqual (Arg0, ToUUID("7c9512a9-1705-4cb4-af7d-506a2423ab71")))
{
Return (^XHC.POSC(Arg1, Arg2, Arg3))
}
/* Check for PCIe */
If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
{ {
/* Let OS control everything */ /* Let OS control everything */
Return (Arg3) Return (Arg3)
} }
Else
{ /* Else Return Unrecognized UUID */
/* Unrecognized UUID */
CreateDWordField (Arg3, 0, CDW1) CreateDWordField (Arg3, 0, CDW1)
Or (CDW1, 4, CDW1) Or (CDW1, 4, CDW1)
Return (Arg3) Return (Arg3)
}
} }

View File

@ -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)
}
}

View File

@ -27,6 +27,7 @@
#define PCH_EHCI1_TEMP_BAR0 0xe8000000 #define PCH_EHCI1_TEMP_BAR0 0xe8000000
#define PCH_EHCI2_TEMP_BAR0 0xe8000400 #define PCH_EHCI2_TEMP_BAR0 0xe8000400
#define PCH_XHCI_TEMP_BAR0 0xe8001000
/* /*
* Setup USB controller MMIO BAR to prevent the * 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 usb0 = PCH_EHCI1_DEV;
device_t usb1 = PCH_EHCI2_DEV; device_t usb1 = PCH_EHCI2_DEV;
device_t usb3 = PCH_XHCI_DEV;
u32 cmd; u32 cmd;
/* USB Controller 1 */ /* USB Controller 1 */
@ -54,4 +56,11 @@ void enable_usb_bar(void)
cmd = pci_read_config32(usb1, PCI_COMMAND); cmd = pci_read_config32(usb1, PCI_COMMAND);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_write_config32(usb1, PCI_COMMAND, cmd); 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);
} }

View File

@ -113,7 +113,9 @@ typedef struct {
u8 gtf2[7]; u8 gtf2[7];
u8 idem; u8 idem;
u8 idet; u8 idet;
u8 rsvd11[7]; u8 rsvd11[6];
/* XHCI */
u8 xhci;
/* IGD OpRegion (not implemented yet) */ /* IGD OpRegion (not implemented yet) */
u32 aslb; /* 0xb4 - IGD OpRegion Base Address */ u32 aslb; /* 0xb4 - IGD OpRegion Base Address */
u8 ibtt; /* 0xb8 - IGD boot type */ u8 ibtt; /* 0xb8 - IGD boot type */

View File

@ -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_EHCI1_DEV PCI_DEV(0, 0x1d, 0)
#define PCH_EHCI2_DEV PCI_DEV(0, 0x1a, 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_ME_DEV PCI_DEV(0, 0x16, 0)
#define PCH_PCIE_DEV_SLOT 28 #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_IDERIP 8 /* IDE-R Pin */
#define D22IP_MEI2IP 4 /* MEI #2 Pin */ #define D22IP_MEI2IP 4 /* MEI #2 Pin */
#define D22IP_MEI1IP 0 /* MEI #1 Pin */ #define D22IP_MEI1IP 0 /* MEI #1 Pin */
#define D20IP 0x3128 /* 32bit */
#define D20IP_XHCIIP 0
#define D31IR 0x3140 /* 16bit */ #define D31IR 0x3140 /* 16bit */
#define D30IR 0x3142 /* 16bit */ #define D30IR 0x3142 /* 16bit */
#define D29IR 0x3144 /* 16bit */ #define D29IR 0x3144 /* 16bit */
@ -373,6 +376,7 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer);
#define D26IR 0x314c /* 16bit */ #define D26IR 0x314c /* 16bit */
#define D25IR 0x3150 /* 16bit */ #define D25IR 0x3150 /* 16bit */
#define D22IR 0x315c /* 16bit */ #define D22IR 0x315c /* 16bit */
#define D20IR 0x3160 /* 16bit */
#define OIC 0x31fe /* 16bit */ #define OIC 0x31fe /* 16bit */
#define SOFT_RESET_CTRL 0x38f4 #define SOFT_RESET_CTRL 0x38f4
#define SOFT_RESET_DATA 0x38f8 #define SOFT_RESET_DATA 0x38f8
@ -392,7 +396,7 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer);
#define CG 0x341c /* 32bit */ #define CG 0x341c /* 32bit */
/* Function Disable 1 RCBA 0x3418 */ /* 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_P2P (1 << 1)
#define PCH_DISABLE_SATA1 (1 << 2) #define PCH_DISABLE_SATA1 (1 << 2)
#define PCH_DISABLE_SMBUS (1 << 3) #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_PCIE(x) (1 << (16 + x))
#define PCH_DISABLE_THERMAL (1 << 24) #define PCH_DISABLE_THERMAL (1 << 24)
#define PCH_DISABLE_SATA2 (1 << 25) #define PCH_DISABLE_SATA2 (1 << 25)
#define PCH_DISABLE_XHCI (1 << 27)
/* Function Disable 2 RCBA 0x3428 */ /* Function Disable 2 RCBA 0x3428 */
#define PCH_DISABLE_KT (1 << 4) #define PCH_DISABLE_KT (1 << 4)

View File

@ -326,6 +326,17 @@ static void southbridge_gate_memory_reset(void)
outl(reg32, gpiobase + GP_LVL2); 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) static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save)
{ {
u8 reg8; 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); printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
slp_typ = (reg32 >> 10) & 7; slp_typ = (reg32 >> 10) & 7;
if (smm_get_gnvs()->xhci)
xhci_sleep(slp_typ);
/* Do any mainboard sleep handling */ /* Do any mainboard sleep handling */
tseg_relocate((void **)&mainboard_sleep); tseg_relocate((void **)&mainboard_sleep);
if (mainboard_sleep) if (mainboard_sleep)