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:
parent
4733c647bc
commit
e7ae96f488
|
@ -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".
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 */
|
||||
/* 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")))
|
||||
{
|
||||
/* Let OS control everything */
|
||||
Return (Arg3)
|
||||
}
|
||||
Else
|
||||
{
|
||||
/* Unrecognized UUID */
|
||||
CreateDWordField (Arg3, 0, CDW1)
|
||||
Or (CDW1, 4, CDW1)
|
||||
Return (Arg3)
|
||||
}
|
||||
|
||||
/* Else Return Unrecognized UUID */
|
||||
CreateDWordField (Arg3, 0, CDW1)
|
||||
Or (CDW1, 4, CDW1)
|
||||
Return (Arg3)
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue