summaryrefslogtreecommitdiff
path: root/src/soc/intel/broadwell
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/broadwell')
-rw-r--r--src/soc/intel/broadwell/Kconfig18
-rw-r--r--src/soc/intel/broadwell/Makefile.inc7
-rw-r--r--src/soc/intel/broadwell/acpi.c5
-rw-r--r--src/soc/intel/broadwell/acpi/adsp.asl63
-rw-r--r--src/soc/intel/broadwell/acpi/device_nvs.asl3
-rw-r--r--src/soc/intel/broadwell/acpi/gpio.asl17
-rw-r--r--src/soc/intel/broadwell/acpi/lpc.asl4
-rw-r--r--src/soc/intel/broadwell/acpi/pch.asl18
-rw-r--r--src/soc/intel/broadwell/acpi/serialio.asl209
-rw-r--r--src/soc/intel/broadwell/adsp.c152
-rw-r--r--src/soc/intel/broadwell/broadwell/adsp.h56
-rw-r--r--src/soc/intel/broadwell/broadwell/cpu.h1
-rw-r--r--src/soc/intel/broadwell/broadwell/device_nvs.h7
-rw-r--r--src/soc/intel/broadwell/broadwell/pci_devs.h92
-rw-r--r--src/soc/intel/broadwell/broadwell/pei_data.h7
-rw-r--r--src/soc/intel/broadwell/broadwell/romstage.h4
-rw-r--r--src/soc/intel/broadwell/broadwell/systemagent.h4
-rw-r--r--src/soc/intel/broadwell/cpu.c4
-rw-r--r--src/soc/intel/broadwell/ehci.c10
-rw-r--r--src/soc/intel/broadwell/hda.c25
-rw-r--r--src/soc/intel/broadwell/igd.c13
-rw-r--r--src/soc/intel/broadwell/me_status.c3
-rw-r--r--src/soc/intel/broadwell/memmap.c15
-rw-r--r--src/soc/intel/broadwell/pch.c71
-rw-r--r--src/soc/intel/broadwell/pei_data.h115
-rw-r--r--src/soc/intel/broadwell/romstage/Makefile.inc1
-rw-r--r--src/soc/intel/broadwell/romstage/cpu.c6
-rw-r--r--src/soc/intel/broadwell/romstage/raminit.c14
-rw-r--r--src/soc/intel/broadwell/romstage/report_platform.c1
-rw-r--r--src/soc/intel/broadwell/romstage/romstage.c15
-rw-r--r--src/soc/intel/broadwell/romstage/uart.c85
-rw-r--r--src/soc/intel/broadwell/serialio.c52
-rw-r--r--src/soc/intel/broadwell/systemagent.c22
-rw-r--r--src/soc/intel/broadwell/usbdebug.c51
34 files changed, 930 insertions, 240 deletions
diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig
index 47b3116be6..e482ead8c6 100644
--- a/src/soc/intel/broadwell/Kconfig
+++ b/src/soc/intel/broadwell/Kconfig
@@ -11,6 +11,7 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ALT_CBFS_LOAD_PAYLOAD
+ select ALWAYS_LOAD_OPROM
select BACKUP_DEFAULT_SMM_REGION
select CACHE_MRC_BIN
select CACHE_MRC_SETTINGS
@@ -175,6 +176,23 @@ config MONOTONIC_TIMER_MSR
help
Provide a monotonic timer using the 24MHz MSR counter.
+config INTEL_PCH_UART_CONSOLE
+ bool "Use Serial IO UART for console"
+ default n
+ select HAVE_UART_MEMORY_MAPPED
+ select CONSOLE_SERIAL8250MEM
+ depends on !CONFIG_DRIVERS_OXFORD_OXPCIE
+
+config INTEL_PCH_UART_CONSOLE_NUMBER
+ hex "Serial IO UART number to use for console"
+ default "0x0"
+ depends on INTEL_PCH_UART_CONSOLE
+
+config TTYS0_BASE
+ hex
+ default 0xd6000000
+ depends on INTEL_PCH_UART_CONSOLE
+
config EHCI_BAR
hex
default 0xd8000000
diff --git a/src/soc/intel/broadwell/Makefile.inc b/src/soc/intel/broadwell/Makefile.inc
index 9d7ab1e8c3..072ab1ff07 100644
--- a/src/soc/intel/broadwell/Makefile.inc
+++ b/src/soc/intel/broadwell/Makefile.inc
@@ -10,6 +10,7 @@ subdirs-y += ../../../cpu/intel/microcode
subdirs-y += ../../../cpu/intel/turbo
ramstage-y += acpi.c
+ramstage-y += adsp.c
ramstage-y += chip.c
ramstage-y += cpu.c
ramstage-y += elog.c
@@ -62,6 +63,12 @@ ramstage-y += ehci.c
ramstage-y += xhci.c
smm-y += xhci.c
+ifeq ($(CONFIG_USBDEBUG),y)
+ramstage-y += usbdebug.c
+romstage-y += usbdebug.c
+smm-y += usbdebug.c
+endif
+
INCLUDES += -Isrc/soc/intel/broadwell/
# Run an intermediate step when producing coreboot.rom
diff --git a/src/soc/intel/broadwell/acpi.c b/src/soc/intel/broadwell/acpi.c
index 782503ec0e..f4cac7bcba 100644
--- a/src/soc/intel/broadwell/acpi.c
+++ b/src/soc/intel/broadwell/acpi.c
@@ -604,10 +604,5 @@ unsigned long acpi_madt_irq_overrides(unsigned long current)
irqovr = (void *)current;
current += acpi_create_madt_irqoverride(irqovr, 0, sci, sci, flags);
- /* GPIO Controller */
- irqovr = (void *)current;
- flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH;
- current += acpi_create_madt_irqoverride(irqovr, 0, 14, 14, flags);
-
return current;
}
diff --git a/src/soc/intel/broadwell/acpi/adsp.asl b/src/soc/intel/broadwell/acpi/adsp.asl
new file mode 100644
index 0000000000..d50dce6fcd
--- /dev/null
+++ b/src/soc/intel/broadwell/acpi/adsp.asl
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+Device (ADSP)
+{
+ Method (_HID, 0, Serialized)
+ {
+ If (\ISWP ()) {
+ // WildcatPoint
+ Return ("INT3438")
+ }
+
+ // LynxPoint-LP
+ Return ("INT33C8")
+ }
+ Name (_UID, 1)
+ Name (_DDN, "Intel Smart Sound Technology")
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00100000, BAR0)
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR1)
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) {3}
+ })
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ // Update BAR0 address and length if set in NVS
+ If (LNotEqual (\S8B0, Zero)) {
+ CreateDwordField (^RBUF, ^BAR0._BAS, B8A0)
+ CreateDwordField (^RBUF, ^BAR1._BAS, B8A1)
+ Store (\S8B0, B8A0)
+ Store (\S8B1, B8A1)
+ }
+
+ Return (RBUF)
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LEqual (\S8EN, 0)) {
+ Return (0x0)
+ } Else {
+ Return (0xF)
+ }
+ }
+}
diff --git a/src/soc/intel/broadwell/acpi/device_nvs.asl b/src/soc/intel/broadwell/acpi/device_nvs.asl
index d5af2e8cc9..1d2aa78edb 100644
--- a/src/soc/intel/broadwell/acpi/device_nvs.asl
+++ b/src/soc/intel/broadwell/acpi/device_nvs.asl
@@ -27,6 +27,7 @@ S4EN, 8, // SPI1 Enable
S5EN, 8, // UART0 Enable
S6EN, 8, // UART1 Enable
S7EN, 8, // SDIO Enable
+S8EN, 8, // ADSP Enable
/* BAR 0 */
@@ -38,6 +39,7 @@ S4B0, 32, // SPI1 BAR0
S5B0, 32, // UART0 BAR0
S6B0, 32, // UART1 BAR0
S7B0, 32, // SDIO BAR0
+S8B0, 32, // ADSP BAR0
/* BAR 1 */
@@ -49,3 +51,4 @@ S4B1, 32, // SPI1 BAR1
S5B1, 32, // UART0 BAR1
S6B1, 32, // UART1 BAR1
S7B1, 32, // SDIO BAR1
+S8B1, 32, // ADSP BAR1
diff --git a/src/soc/intel/broadwell/acpi/gpio.asl b/src/soc/intel/broadwell/acpi/gpio.asl
index 5df512e0e3..c6d8753975 100644
--- a/src/soc/intel/broadwell/acpi/gpio.asl
+++ b/src/soc/intel/broadwell/acpi/gpio.asl
@@ -20,8 +20,16 @@
Device (GPIO)
{
// GPIO Controller
- Name (_HID, "INT33C7")
- Name (_CID, "INT33C7")
+ Method (_HID)
+ {
+ If (\ISWP ()) {
+ // WildcatPoint
+ Return ("INT3437")
+ }
+
+ // LynxPoint-LP
+ Return ("INT33C7")
+ }
Name (_UID, 1)
Name (RBUF, ResourceTemplate()
@@ -39,8 +47,9 @@ Device (GPIO)
, // ResourceSourceIndex
, // ResourceSource
BAR0)
- Interrupt (ResourceConsumer,
- Level, ActiveHigh, Shared, , , ) {14}
+ // Disabled due to IRQ storm: http://crosbug.com/p/29548
+ //Interrupt (ResourceConsumer,
+ // Level, ActiveHigh, Shared, , , ) {14}
})
Method (_CRS, 0, NotSerialized)
diff --git a/src/soc/intel/broadwell/acpi/lpc.asl b/src/soc/intel/broadwell/acpi/lpc.asl
index 2f27d9b252..ae634a3fd6 100644
--- a/src/soc/intel/broadwell/acpi/lpc.asl
+++ b/src/soc/intel/broadwell/acpi/lpc.asl
@@ -27,10 +27,12 @@ Device (LPCB)
OperationRegion(LPC0, PCI_Config, 0x00, 0x100)
Field (LPC0, AnyAcc, NoLock, Preserve)
{
+ Offset (0x02),
+ PDID, 16, // Device ID
Offset (0x40),
PMBS, 16, // PMBASE
Offset (0x48),
- GPBS, 16, // GPIOBASE
+ GPBS, 16, // GPIOBASE
Offset (0x60), // Interrupt Routing Registers
PRTA, 8,
PRTB, 8,
diff --git a/src/soc/intel/broadwell/acpi/pch.asl b/src/soc/intel/broadwell/acpi/pch.asl
index c48449363e..e40c04269a 100644
--- a/src/soc/intel/broadwell/acpi/pch.asl
+++ b/src/soc/intel/broadwell/acpi/pch.asl
@@ -39,11 +39,29 @@ Scope (\)
, 5,
HPTE, 1, // Address Enable
}
+
+ /*
+ * Check PCH type
+ * Return 1 if PCH is WildcatPoint
+ * Return 0 if PCH is LynxPoint
+ */
+ Method (ISWP)
+ {
+ And (\_SB.PCI0.LPCB.PDID, 0xfff0, Local0)
+ If (LEqual (Local0, 0x9cc0)) {
+ Return (1)
+ } Else {
+ Return (0)
+ }
+ }
}
// High Definition Audio (Azalia) 0:1b.0
#include "hda.asl"
+// ADSP/SST 0:13.0
+#include "adsp.asl"
+
// PCI Express Ports 0:1c.x
#include "pcie.asl"
diff --git a/src/soc/intel/broadwell/acpi/serialio.asl b/src/soc/intel/broadwell/acpi/serialio.asl
index 532eb50764..6b42d54024 100644
--- a/src/soc/intel/broadwell/acpi/serialio.asl
+++ b/src/soc/intel/broadwell/acpi/serialio.asl
@@ -22,6 +22,46 @@
// Serial IO Device BAR0 and BAR1 is 4KB
#define SIO_BAR_LEN 0x1000
+// Put SerialIO device in D0 state
+// Arg0 - BAR1 of device
+// Arg1 - Set if device is in ACPI mode
+Method (LPD0, 2, Serialized)
+{
+ // PCI mode devices will be handled by OS PCI bus driver
+ If (LEqual (Arg1, 0)) {
+ Return
+ }
+
+ OperationRegion (SPRT, SystemMemory, Add (Arg0, 0x84), 4)
+ Field (SPRT, DWordAcc, NoLock, Preserve)
+ {
+ SPCS, 32
+ }
+
+ And (SPCS, 0xFFFFFFFC, SPCS)
+ Store (SPCS, Local0) // Read back after writing
+}
+
+// Put SerialIO device in D3 state
+// Arg0 - BAR1 of device
+// Arg1 - Set if device is in ACPI mode
+Method (LPD3, 2, Serialized)
+{
+ // PCI mode devices will be handled by OS PCI bus driver
+ If (LEqual (Arg1, 0)) {
+ Return
+ }
+
+ OperationRegion (SPRT, SystemMemory, Add (Arg0, 0x84), 4)
+ Field (SPRT, DWordAcc, NoLock, Preserve)
+ {
+ SPCS, 32
+ }
+
+ Or (SPCS, 0x3, SPCS)
+ Store (SPCS, Local0) // Read back after writing
+}
+
// Serial IO Resource Consumption for BAR1
Device (SIOR)
{
@@ -152,11 +192,22 @@ Device (SDMA)
Device (I2C0)
{
// Serial IO I2C0 Controller
- Name (_HID, "INT33C2")
- Name (_CID, "INT33C2")
+ Method (_HID)
+ {
+ If (\ISWP ()) {
+ // WildcatPoint
+ Return ("INT3432")
+ }
+
+ // LynxPoint-LP
+ Return ("INT33C2")
+ }
Name (_UID, 1)
Name (_ADR, 0x00150001)
+ Name (SSCN, Package () { 432, 507, 9 })
+ Name (FMCN, Package () { 72, 160, 9 })
+
// BAR0 is assigned during PCI enumeration and saved into NVS
Name (RBUF, ResourceTemplate ()
{
@@ -167,9 +218,8 @@ Device (I2C0)
// DMA channels are only used if Serial IO DMA controller is enabled
Name (DBUF, ResourceTemplate ()
{
- // TODO: Need to update IASL to support FixedDMA
- //FixedDMA (0x18, 4, Width32Bit, DMA1) // Tx
- //FixedDMA (0x19, 5, Width32Bit, DMA2) // Rx
+ FixedDMA (0x18, 4, Width32Bit, DMA1) // Tx
+ FixedDMA (0x19, 5, Width32Bit, DMA2) // Rx
})
Method (_CRS, 0, NotSerialized)
@@ -198,16 +248,37 @@ Device (I2C0)
Return (0xF)
}
}
+
+ Method (_PS0, 0, Serialized)
+ {
+ ^^LPD0 (\S1B1, \S1EN)
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+ ^^LPD3 (\S1B1, \S1EN)
+ }
}
Device (I2C1)
{
// Serial IO I2C1 Controller
- Name (_HID, "INT33C3")
- Name (_CID, "INT33C3")
+ Method (_HID)
+ {
+ If (\ISWP ()) {
+ // WildcatPoint
+ Return ("INT3433")
+ }
+
+ // LynxPoint-LP
+ Return ("INT33C3")
+ }
Name (_UID, 1)
Name (_ADR, 0x00150002)
+ Name (SSCN, Package () { 432, 507, 9 })
+ Name (FMCN, Package () { 72, 160, 9 })
+
// BAR0 is assigned during PCI enumeration and saved into NVS
Name (RBUF, ResourceTemplate ()
{
@@ -218,9 +289,8 @@ Device (I2C1)
// DMA channels are only used if Serial IO DMA controller is enabled
Name (DBUF, ResourceTemplate ()
{
- // TODO: Need to update IASL to support FixedDMA
- //FixedDMA (0x1A, 6, Width32Bit, DMA1) // Tx
- //FixedDMA (0x1B, 7, Width32Bit, DMA2) // Rx
+ FixedDMA (0x1A, 6, Width32Bit, DMA1) // Tx
+ FixedDMA (0x1B, 7, Width32Bit, DMA2) // Rx
})
Method (_CRS, 0, NotSerialized)
@@ -249,13 +319,31 @@ Device (I2C1)
Return (0xF)
}
}
+
+ Method (_PS0, 0, Serialized)
+ {
+ ^^LPD0 (\S2B1, \S2EN)
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+ ^^LPD3 (\S2B1, \S2EN)
+ }
}
Device (SPI0)
{
// Serial IO SPI0 Controller
- Name (_HID, "INT33C0")
- Name (_CID, "INT33C0")
+ Method (_HID)
+ {
+ If (\ISWP ()) {
+ // WildcatPoint
+ Return ("INT3430")
+ }
+
+ // LynxPoint-LP
+ Return ("INT33C0")
+ }
Name (_UID, 1)
Name (_ADR, 0x00150003)
@@ -287,13 +375,31 @@ Device (SPI0)
Return (0xF)
}
}
+
+ Method (_PS0, 0, Serialized)
+ {
+ ^^LPD0 (\S3B1, \S3EN)
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+ ^^LPD3 (\S3B1, \S3EN)
+ }
}
Device (SPI1)
{
// Serial IO SPI1 Controller
- Name (_HID, "INT33C1")
- Name (_CID, "INT33C1")
+ Method (_HID)
+ {
+ If (\ISWP ()) {
+ // WildcatPoint
+ Return ("INT3431")
+ }
+
+ // LynxPoint-LP
+ Return ("INT33C1")
+ }
Name (_UID, 1)
Name (_ADR, 0x00150004)
@@ -307,9 +413,8 @@ Device (SPI1)
// DMA channels are only used if Serial IO DMA controller is enabled
Name (DBUF, ResourceTemplate ()
{
- // TODO: Need to update IASL to support FixedDMA
- //FixedDMA (0x10, 0, Width32Bit, DMA1) // Tx
- //FixedDMA (0x11, 1, Width32Bit, DMA2) // Rx
+ FixedDMA (0x10, 0, Width32Bit, DMA1) // Tx
+ FixedDMA (0x11, 1, Width32Bit, DMA2) // Rx
})
Method (_CRS, 0, NotSerialized)
@@ -338,13 +443,31 @@ Device (SPI1)
Return (0xF)
}
}
+
+ Method (_PS0, 0, Serialized)
+ {
+ ^^LPD0 (\S4B1, \S4EN)
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+ ^^LPD3 (\S4B1, \S4EN)
+ }
}
Device (UAR0)
{
// Serial IO UART0 Controller
- Name (_HID, "INT33C4")
- Name (_CID, "INT33C4")
+ Method (_HID)
+ {
+ If (\ISWP ()) {
+ // WildcatPoint
+ Return ("INT3434")
+ }
+
+ // LynxPoint-LP
+ Return ("INT33C4")
+ }
Name (_UID, 1)
Name (_ADR, 0x00150005)
@@ -358,9 +481,8 @@ Device (UAR0)
// DMA channels are only used if Serial IO DMA controller is enabled
Name (DBUF, ResourceTemplate ()
{
- // TODO: Need to update IASL to support FixedDMA
- //FixedDMA (0x16, 2, Width32Bit, DMA1) // Tx
- //FixedDMA (0x17, 3, Width32Bit, DMA2) // Rx
+ FixedDMA (0x16, 2, Width32Bit, DMA1) // Tx
+ FixedDMA (0x17, 3, Width32Bit, DMA2) // Rx
})
Method (_CRS, 0, NotSerialized)
@@ -389,13 +511,31 @@ Device (UAR0)
Return (0xF)
}
}
+
+ Method (_PS0, 0, Serialized)
+ {
+ ^^LPD0 (\S5B1, \S5EN)
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+ ^^LPD3 (\S5B1, \S5EN)
+ }
}
Device (UAR1)
{
// Serial IO UART1 Controller
- Name (_HID, "INT33C5")
- Name (_CID, "INT33C5")
+ Method (_HID)
+ {
+ If (\ISWP ()) {
+ // WildcatPoint
+ Return ("INT3435")
+ }
+
+ // LynxPoint-LP
+ Return ("INT33C5")
+ }
Name (_UID, 1)
Name (_ADR, 0x00150006)
@@ -427,12 +567,31 @@ Device (UAR1)
Return (0xF)
}
}
+
+ Method (_PS0, 0, Serialized)
+ {
+ ^^LPD0 (\S6B1, \S6EN)
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+ ^^LPD3 (\S6B1, \S6EN)
+ }
}
Device (SDIO)
{
// Serial IO SDIO Controller
- Name (_HID, "INT33C6")
+ Method (_HID)
+ {
+ If (\ISWP ()) {
+ // WildcatPoint
+ Return ("INT3436")
+ }
+
+ // LynxPoint-LP
+ Return ("INT33C6")
+ }
Name (_CID, "PNP0D40")
Name (_UID, 1)
Name (_ADR, 0x00170000)
diff --git a/src/soc/intel/broadwell/adsp.c b/src/soc/intel/broadwell/adsp.c
new file mode 100644
index 0000000000..2a6dc1744a
--- /dev/null
+++ b/src/soc/intel/broadwell/adsp.c
@@ -0,0 +1,152 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <cbmem.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include <broadwell/adsp.h>
+#include <broadwell/device_nvs.h>
+#include <broadwell/iobp.h>
+#include <broadwell/nvs.h>
+#include <broadwell/pch.h>
+#include <broadwell/ramstage.h>
+#include <broadwell/rcba.h>
+#include <chip.h>
+
+static void adsp_init(struct device *dev)
+{
+ config_t *config = dev->chip_info;
+ struct resource *bar0, *bar1;
+ u32 tmp32;
+
+ /* Ensure memory and bus master are enabled */
+ tmp32 = pci_read_config32(dev, PCI_COMMAND);
+ tmp32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config32(dev, PCI_COMMAND, tmp32);
+
+ /* Find BAR0 and BAR1 */
+ bar0 = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (!bar0)
+ return;
+ bar1 = find_resource(dev, PCI_BASE_ADDRESS_1);
+ if (!bar1)
+ return;
+
+ /*
+ * Set LTR value in DSP shim LTR control register to 3ms
+ * SNOOP_REQ[13]=1b SNOOP_SCALE[12:10]=100b (1ms) SNOOP_VAL[9:0]=3h
+ */
+ tmp32 = pch_is_wpt() ? ADSP_SHIM_BASE_WPT : ADSP_SHIM_BASE_LPT;
+ write32(bar0->base + tmp32 + ADSP_SHIM_LTRC, ADSP_SHIM_LTRC_VALUE);
+
+ /* Program VDRTCTL2 D19:F0:A8[31:0] = 0x00000fff */
+ pci_write_config32(dev, ADSP_PCI_VDRTCTL2, ADSP_VDRTCTL2_VALUE);
+
+ /* Program ADSP IOBP VDLDAT1 to 0x040100 */
+ pch_iobp_write(ADSP_IOBP_VDLDAT1, ADSP_VDLDAT1_VALUE);
+
+ /* Set D3 Power Gating Enable in D19:F0:A0 based on PCH type */
+ tmp32 = pci_read_config32(dev, ADSP_PCI_VDRTCTL0);
+ if (pch_is_wpt()) {
+ tmp32 &= ~ADSP_VDRTCTL0_D3PGD_WPT;
+ tmp32 &= ~ADSP_VDRTCTL0_D3SRAMPGD_WPT;
+ } else {
+ tmp32 &= ~ADSP_VDRTCTL0_D3PGD_LPT;
+ tmp32 &= ~ADSP_VDRTCTL0_D3SRAMPGD_LPT;
+ }
+ pci_write_config32(dev, ADSP_PCI_VDRTCTL0, tmp32);
+
+ /* Set PSF Snoop to SA, RCBA+0x3350[10]=1b */
+ RCBA32_OR(0x3350, (1 << 10));
+
+ /* Set DSP IOBP PMCTL 0x1e0=0x3f */
+ pch_iobp_write(ADSP_IOBP_PMCTL, ADSP_PMCTL_VALUE);
+
+ if (config->sio_acpi_mode) {
+ /* Configure for ACPI mode */
+ global_nvs_t *gnvs;
+
+ printk(BIOS_INFO, "ADSP: Enable ACPI Mode IRQ3\n");
+
+ /* Find ACPI NVS to update BARs */
+ gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
+ if (!gnvs) {
+ printk(BIOS_ERR, "Unable to locate Global NVS\n");
+ return;
+ }
+
+ /* Save BAR0 and BAR1 to ACPI NVS */
+ gnvs->dev.bar0[SIO_NVS_ADSP] = (u32)bar0->base;
+ gnvs->dev.bar1[SIO_NVS_ADSP] = (u32)bar1->base;
+ gnvs->dev.enable[SIO_NVS_ADSP] = 1;
+
+ /* Set PCI Config Disable Bit */
+ pch_iobp_update(ADSP_IOBP_PCICFGCTL, ~0, ADSP_PCICFGCTL_PCICD);
+
+ /* Set interrupt de-assert/assert opcode override to IRQ3 */
+ pch_iobp_write(ADSP_IOBP_VDLDAT2, ADSP_IOBP_ACPI_IRQ3);
+
+ /* Enable IRQ3 in RCBA */
+ RCBA32_OR(ACPIIRQEN, ADSP_ACPI_IRQEN);
+
+ /* Set ACPI Interrupt Enable Bit */
+ pch_iobp_update(ADSP_IOBP_PCICFGCTL, ~ADSP_PCICFGCTL_SPCBAD,
+ ADSP_PCICFGCTL_ACPIIE);
+
+ /* Put ADSP in D3hot */
+ tmp32 = read32(bar1->base + PCH_PCS);
+ tmp32 |= PCH_PCS_PS_D3HOT;
+ write32(bar1->base + PCH_PCS, tmp32);
+ } else {
+ printk(BIOS_INFO, "ADSP: Enable PCI Mode IRQ23\n");
+
+ /* Configure for PCI mode */
+ pci_write_config32(dev, PCI_INTERRUPT_LINE, ADSP_PCI_IRQ);
+
+ /* Clear ACPI Interrupt Enable Bit */
+ pch_iobp_update(ADSP_IOBP_PCICFGCTL,
+ ~(ADSP_PCICFGCTL_SPCBAD | ADSP_PCICFGCTL_ACPIIE), 0);
+ }
+}
+
+static struct device_operations adsp_ops = {
+ .read_resources = &pci_dev_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .init = &adsp_init,
+ .ops_pci = &broadwell_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+ 0x9c36, /* LynxPoint */
+ 0x9cb6, /* WildcatPoint */
+ 0
+};
+
+static const struct pci_driver pch_adsp __pci_driver = {
+ .ops = &adsp_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
+
diff --git a/src/soc/intel/broadwell/broadwell/adsp.h b/src/soc/intel/broadwell/broadwell/adsp.h
new file mode 100644
index 0000000000..747a123579
--- /dev/null
+++ b/src/soc/intel/broadwell/broadwell/adsp.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _BROADWELL_ADSP_H_
+#define _BROADWELL_ADSP_H_
+
+#define ADSP_PCI_IRQ 23
+#define ADSP_ACPI_IRQ 3
+#define ADSP_ACPI_IRQEN (1 << 3)
+
+#define ADSP_SHIM_BASE_LPT 0xe7000
+#define ADSP_SHIM_BASE_WPT 0xfb000
+#define ADSP_SHIM_LTRC 0xe0
+#define ADSP_SHIM_LTRC_VALUE 0x3003
+#define ADSP_SHIM_IMC 0x28
+#define ADSP_SHIM_IPCD 0x40
+
+#define ADSP_PCI_VDRTCTL0 0xa0
+#define ADSP_VDRTCTL0_D3PGD_LPT (1 << 1)
+#define ADSP_VDRTCTL0_D3PGD_WPT (1 << 0)
+#define ADSP_VDRTCTL0_D3SRAMPGD_LPT (1 << 2)
+#define ADSP_VDRTCTL0_D3SRAMPGD_WPT (1 << 1)
+#define ADSP_PCI_VDRTCTL1 0xa4
+#define ADSP_PCI_VDRTCTL2 0xa8
+#define ADSP_VDRTCTL2_VALUE 0x00000fff
+
+#define ADSP_IOBP_VDLDAT1 0xd7000624
+#define ADSP_VDLDAT1_VALUE 0x00040100
+#define ADSP_IOBP_VDLDAT2 0xd7000628
+#define ADSP_IOBP_ACPI_IRQ3 0xd9d8
+#define ADSP_IOBP_ACPI_IRQ3I 0xd8d9
+#define ADSP_IOBP_ACPI_IRQ4 0xdbda
+#define ADSP_IOBP_PMCTL 0xd70001e0
+#define ADSP_PMCTL_VALUE 0x3f
+#define ADSP_IOBP_PCICFGCTL 0xd7000500
+#define ADSP_PCICFGCTL_PCICD (1 << 0)
+#define ADSP_PCICFGCTL_ACPIIE (1 << 1)
+#define ADSP_PCICFGCTL_SPCBAD (1 << 7)
+
+#endif
diff --git a/src/soc/intel/broadwell/broadwell/cpu.h b/src/soc/intel/broadwell/broadwell/cpu.h
index 0f6f593736..312532d68a 100644
--- a/src/soc/intel/broadwell/broadwell/cpu.h
+++ b/src/soc/intel/broadwell/broadwell/cpu.h
@@ -36,6 +36,7 @@
#define CPUID_HASWELL_HALO 0x40661
#define CPUID_BROADWELL_C0 0x306d2
#define CPUID_BROADWELL_D0 0x306d3
+#define CPUID_BROADWELL_E0 0x306d4
/* CPU bus clock is fixed at 100MHz */
#define CPU_BCLK 100
diff --git a/src/soc/intel/broadwell/broadwell/device_nvs.h b/src/soc/intel/broadwell/broadwell/device_nvs.h
index f10f28d35e..7dab40da6a 100644
--- a/src/soc/intel/broadwell/broadwell/device_nvs.h
+++ b/src/soc/intel/broadwell/broadwell/device_nvs.h
@@ -33,11 +33,12 @@
#define SIO_NVS_UART0 5
#define SIO_NVS_UART1 6
#define SIO_NVS_SDIO 7
+#define SIO_NVS_ADSP 8
typedef struct {
- u8 enable[8];
- u32 bar0[8];
- u32 bar1[8];
+ u8 enable[9];
+ u32 bar0[9];
+ u32 bar1[9];
} __attribute__((packed)) device_nvs_t;
#endif
diff --git a/src/soc/intel/broadwell/broadwell/pci_devs.h b/src/soc/intel/broadwell/broadwell/pci_devs.h
index 9c3dd06640..76e3a688ed 100644
--- a/src/soc/intel/broadwell/broadwell/pci_devs.h
+++ b/src/soc/intel/broadwell/broadwell/pci_devs.h
@@ -20,6 +20,9 @@
#ifndef _BROADWELL_PCI_DEVS_H_
#define _BROADWELL_PCI_DEVS_H_
+#define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0)
+#define _PCH_DEVFN(slot,func) PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func)
+
#if defined(__PRE_RAM__) || defined(__SMM__) || defined(__ROMCC__)
#include <arch/io.h>
#define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_ ## slot, 0)
@@ -27,43 +30,90 @@
#else
#include <device/device.h>
#include <device/pci_def.h>
-#define _SA_DEV(slot) dev_find_slot(0, \
- PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0))
-#define _PCH_DEV(slot,func) dev_find_slot(0, \
- PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func))
+#define _SA_DEV(slot) dev_find_slot(0, _SA_DEVFN(slot))
+#define _PCH_DEV(slot,func) dev_find_slot(0, _PCH_DEVFN(slot, func))
#endif
/* System Agent Devices */
#define SA_DEV_SLOT_ROOT 0x00
+#define SA_DEVFN_ROOT _SA_DEVFN(ROOT)
+#define SA_DEV_ROOT _SA_DEV(ROOT)
+
#define SA_DEV_SLOT_IGD 0x02
-#define SA_DEV_SLOT_MINIHD 0x03
+#define SA_DEVFN_IGD _SA_DEVFN(IGD)
+#define SA_DEV_IGD _SA_DEV(IGD)
-#define SA_DEV_ROOT _SA_DEV(ROOT)
-#define SA_DEV_IGD _SA_DEV(IGD)
-#define SA_DEV_MINIHD _SA_DEV(MINIHD)
+#define SA_DEV_SLOT_MINIHD 0x03
+#define SA_DEVFN_MINIHD _SA_DEVFN(MINIHD)
+#define SA_DEV_MINIHD _SA_DEV(MINIHD)
/* PCH Devices */
+#define PCH_DEV_SLOT_ADSP 0x13
+#define PCH_DEVFN_ADSP _PCH_DEVFN(ADSP, 0)
+#define PCH_DEV_ADSP _PCH_DEV(ADSP, 0)
+
#define PCH_DEV_SLOT_XHCI 0x14
+#define PCH_DEVFN_XHCI _PCH_DEVFN(XHCI, 0)
+#define PCH_DEV_XHCI _PCH_DEV(XHCI, 0)
+
#define PCH_DEV_SLOT_SIO 0x15
+#define PCH_DEV_SDMA _PCH_DEV(SIO, 0)
+#define PCH_DEV_I2C0 _PCH_DEV(SIO, 1)
+#define PCH_DEV_I2C1 _PCH_DEV(SIO, 2)
+#define PCH_DEV_SPI0 _PCH_DEV(SIO, 3)
+#define PCH_DEV_SPI1 _PCH_DEV(SIO, 4)
+#define PCH_DEV_UART0 _PCH_DEV(SIO, 5)
+#define PCH_DEV_UART1 _PCH_DEV(SIO, 6)
+#define PCH_DEVFN_SDMA _PCH_DEVFN(SIO, 0)
+#define PCH_DEVFN_I2C0 _PCH_DEVFN(SIO, 1)
+#define PCH_DEVFN_I2C1 _PCH_DEVFN(SIO, 2)
+#define PCH_DEVFN_SPI0 _PCH_DEVFN(SIO, 3)
+#define PCH_DEVFN_SPI1 _PCH_DEVFN(SIO, 4)
+#define PCH_DEVFN_UART0 _PCH_DEVFN(SIO, 5)
+#define PCH_DEVFN_UART1 _PCH_DEVFN(SIO, 6)
+
#define PCH_DEV_SLOT_ME 0x16
+#define PCH_DEVFN_ME _PCH_DEVFN(ME, 0)
+#define PCH_DEVFN_ME_2 _PCH_DEVFN(ME, 1)
+#define PCH_DEVFN_ME_IDER _PCH_DEVFN(ME, 2)
+#define PCH_DEVFN_ME_KT _PCH_DEVFN(ME, 3)
+#define PCH_DEV_ME _PCH_DEV(ME, 0)
+#define PCH_DEV_ME_2 _PCH_DEV(ME, 1)
+#define PCH_DEV_ME_IDER _PCH_DEV(ME, 2)
+#define PCH_DEV_ME_KT _PCH_DEV(ME, 3)
+
+#define PCH_DEV_SLOT_SDIO 0x17
+#define PCH_DEVFN_SDIO _PCH_DEVFN(SDIO, 0)
+#define PCH_DEV_SDIO _PCH_DEV(SDIO, 0)
+
+#define PCH_DEV_SLOT_GBE 0x19
+#define PCH_DEVFN_GBE _PCH_DEVFN(GBE, 0)
+#define PCH_DEV_GBE _PCH_DEV(GBE, 0)
+
#define PCH_DEV_SLOT_HDA 0x1b
+#define PCH_DEVFN_HDA _PCH_DEVFN(HDA, 0)
+#define PCH_DEV_HDA _PCH_DEV(HDA, 0)
+
#define PCH_DEV_SLOT_PCIE 0x1c
+
#define PCH_DEV_SLOT_EHCI 0x1d
-#define PCH_DEV_SLOT_LPC 0x1f
+#define PCH_DEVFN_EHCI _PCH_DEVFN(EHCI, 0)
+#define PCH_DEV_EHCI _PCH_DEV(EHCI, 0)
-#define PCH_DEV_XHCI _PCH_DEV(XHCI, 0)
-#define PCH_DEV_UART0 _PCH_DEV(UART0, 0)
-#define PCH_DEV_UART1 _PCH_DEV(UART1, 0)
-#define PCH_DEV_ME _PCH_DEV(ME, 0)
-#define PCH_DEV_HDA _PCH_DEV(HDA, 0)
-#define PCH_DEV_EHCI _PCH_DEV(EHCI, 0)
-#define PCH_DEV_LPC _PCH_DEV(LPC, 0)
-#define PCH_DEV_IDE _PCH_DEV(LPC, 1)
-#define PCH_DEV_SATA _PCH_DEV(LPC, 2)
-#define PCH_DEV_SMBUS _PCH_DEV(LPC, 3)
-#define PCH_DEV_SATA2 _PCH_DEV(LPC, 5)
-#define PCH_DEV_THERMAL _PCH_DEV(LPC, 6)
+#define PCH_DEV_SLOT_LPC 0x1f
+#define PCH_DEVFN_LPC _PCH_DEVFN(LPC, 0)
+#define PCH_DEVFN_IDE _PCH_DEVFN(LPC, 1)
+#define PCH_DEVFN_SATA _PCH_DEVFN(LPC, 2)
+#define PCH_DEVFN_SMBUS _PCH_DEVFN(LPC, 3)
+#define PCH_DEVFN_SATA2 _PCH_DEVFN(LPC, 5)
+#define PCH_DEVFN_THERMAL _PCH_DEVFN(LPC, 6)
+#define PCH_DEV_LPC _PCH_DEV(LPC, 0)
+#define PCH_DEV_IDE _PCH_DEV(LPC, 1)
+#define PCH_DEV_SATA _PCH_DEV(LPC, 2)
+#define PCH_DEV_SMBUS _PCH_DEV(LPC, 3)
+#define PCH_DEV_SATA2 _PCH_DEV(LPC, 5)
+#define PCH_DEV_THERMAL _PCH_DEV(LPC, 6)
#endif
diff --git a/src/soc/intel/broadwell/broadwell/pei_data.h b/src/soc/intel/broadwell/broadwell/pei_data.h
index f8e63069b3..07b04d24d4 100644
--- a/src/soc/intel/broadwell/broadwell/pei_data.h
+++ b/src/soc/intel/broadwell/broadwell/pei_data.h
@@ -31,7 +31,7 @@
#include <types.h>
-#define PEI_VERSION 20
+#define PEI_VERSION 21
#define ABI_X86 __attribute__((regparm(0)))
@@ -122,6 +122,8 @@ struct pei_data
int dq_pins_interleaved;
/* Limit DDR3 frequency */
int max_ddr3_freq;
+ /* Disable self refresh */
+ int disable_self_refresh;
/* USB port configuration */
struct usb2_port_setting usb2_ports[MAX_USB2_PORTS];
@@ -167,6 +169,9 @@ struct pei_data
const void *saved_data;
int saved_data_size;
+ /* Disable use of saved data (can be set by mainboard) */
+ int disable_saved_data;
+
/* Data from MRC that should be saved to flash */
void *data_to_save;
int data_to_save_size;
diff --git a/src/soc/intel/broadwell/broadwell/romstage.h b/src/soc/intel/broadwell/broadwell/romstage.h
index d48ec13106..d3702c7490 100644
--- a/src/soc/intel/broadwell/broadwell/romstage.h
+++ b/src/soc/intel/broadwell/broadwell/romstage.h
@@ -29,9 +29,12 @@ struct romstage_timestamps {
int count;
};
+struct chipset_power_state;
+struct pei_data;
struct romstage_params {
struct romstage_timestamps ts;
unsigned long bist;
+ struct chipset_power_state *power_state;
struct pei_data *pei_data;
};
@@ -52,6 +55,7 @@ void set_max_freq(void);
void systemagent_early_init(void);
void pch_early_init(void);
+void pch_uart_init(void);
void intel_early_me_status(void);
void enable_smbus(void);
diff --git a/src/soc/intel/broadwell/broadwell/systemagent.h b/src/soc/intel/broadwell/broadwell/systemagent.h
index 27c06f7608..f95370b2b5 100644
--- a/src/soc/intel/broadwell/broadwell/systemagent.h
+++ b/src/soc/intel/broadwell/broadwell/systemagent.h
@@ -52,6 +52,10 @@
#define DEVEN_D1F1EN (1 << 2)
#define DEVEN_D1F2EN (1 << 1)
#define DEVEN_D0EN (1 << 0)
+#define DPR 0x5c
+#define DPR_EPM (1 << 2)
+#define DPR_PRS (1 << 1)
+#define DPR_SIZE_MASK 0xff0
#define PAM0 0x80
#define PAM1 0x81
diff --git a/src/soc/intel/broadwell/cpu.c b/src/soc/intel/broadwell/cpu.c
index 3676865efb..58f81fc79d 100644
--- a/src/soc/intel/broadwell/cpu.c
+++ b/src/soc/intel/broadwell/cpu.c
@@ -218,7 +218,7 @@ static void initialize_vr_config(void)
msr.hi &= 0xc0000000;
msr.hi |= (0x01 << (52 - 32)); /* PSI3 threshold - 1A. */
msr.hi |= (0x05 << (42 - 32)); /* PSI2 threshold - 5A. */
- msr.hi |= (0x0f << (32 - 32)); /* PSI1 threshold - 15A. */
+ msr.hi |= (0x14 << (32 - 32)); /* PSI1 threshold - 20A. */
msr.hi |= (1 << (62 - 32)); /* Enable PSI4 */
/* Leave the max instantaneous current limit (12:0) to default. */
wrmsr(MSR_VR_CURRENT_CONFIG, msr);
@@ -387,6 +387,7 @@ static void configure_c_states(void)
msr_t msr;
msr = rdmsr(MSR_PMG_CST_CONFIG_CONTROL);
+ msr.lo |= (1 << 31); // Timed MWAIT Enable
msr.lo |= (1 << 30); // Package c-state Undemotion Enable
msr.lo |= (1 << 29); // Package c-state Demotion Enable
msr.lo |= (1 << 28); // C1 Auto Undemotion Enable
@@ -661,6 +662,7 @@ static struct cpu_device_id cpu_table[] = {
{ X86_VENDOR_INTEL, CPUID_HASWELL_ULT },
{ X86_VENDOR_INTEL, CPUID_BROADWELL_C0 },
{ X86_VENDOR_INTEL, CPUID_BROADWELL_D0 },
+ { X86_VENDOR_INTEL, CPUID_BROADWELL_E0 },
{ 0, 0 },
};
diff --git a/src/soc/intel/broadwell/ehci.c b/src/soc/intel/broadwell/ehci.c
index e27c8e59c9..a59d3c8190 100644
--- a/src/soc/intel/broadwell/ehci.c
+++ b/src/soc/intel/broadwell/ehci.c
@@ -26,6 +26,7 @@
#include <usbdebug.h>
#include <arch/io.h>
#include <broadwell/ehci.h>
+#include <broadwell/pch.h>
static void usb_ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
@@ -70,6 +71,14 @@ static void usb_ehci_set_resources(struct device *dev)
#endif
}
+static void ehci_enable(struct device *dev)
+{
+ if (CONFIG_USBDEBUG)
+ dev->enabled = 1;
+ else
+ pch_disable_devfn(dev);
+}
+
static struct pci_operations ehci_ops_pci = {
.set_subsystem = &usb_ehci_set_subsystem,
};
@@ -79,6 +88,7 @@ static struct device_operations usb_ehci_ops = {
.set_resources = &usb_ehci_set_resources,
.enable_resources = &pci_dev_enable_resources,
.ops_pci = &ehci_ops_pci,
+ .enable = &ehci_enable,
};
static const unsigned short pci_device_ids[] = {
diff --git a/src/soc/intel/broadwell/hda.c b/src/soc/intel/broadwell/hda.c
index 9a9225b479..80caa2c2eb 100644
--- a/src/soc/intel/broadwell/hda.c
+++ b/src/soc/intel/broadwell/hda.c
@@ -27,6 +27,7 @@
#include <arch/io.h>
#include <delay.h>
#include <soc/intel/common/hda_verb.h>
+#include <broadwell/pch.h>
#include <broadwell/ramstage.h>
#include <broadwell/rcba.h>
@@ -134,11 +135,35 @@ static void hda_init(struct device *dev)
}
}
+static void hda_enable(struct device *dev)
+{
+ u32 reg32;
+
+ if (!dev->enabled) {
+ /* Route I/O buffers to ADSP function */
+ reg32 = pci_read_config32(dev, 0x42);
+ reg32 |= (1 << 7) | (1 << 6);
+ pci_write_config32(dev, 0x42, reg32);
+
+ printk(BIOS_INFO, "HDA disabled, I/O buffers routed to ADSP\n");
+
+ /* Ensure memory, io, and bus master are all disabled */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 &= ~(PCI_COMMAND_MASTER |
+ PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ /* Disable this device */
+ pch_disable_devfn(dev);
+ }
+}
+
static struct device_operations hda_ops = {
.read_resources = &pci_dev_read_resources,
.set_resources = &pci_dev_set_resources,
.enable_resources = &pci_dev_enable_resources,
.init = &hda_init,
+ .enable = &hda_enable,
.ops_pci = &broadwell_pci_ops,
};
diff --git a/src/soc/intel/broadwell/igd.c b/src/soc/intel/broadwell/igd.c
index 8235b3f3df..eac9ac1ec1 100644
--- a/src/soc/intel/broadwell/igd.c
+++ b/src/soc/intel/broadwell/igd.c
@@ -472,6 +472,7 @@ static void igd_init(struct device *dev)
{
int is_broadwell = !!(cpu_family_model() == BROADWELL_FAMILY_ULT);
u32 rp1_gfx_freq;
+ extern int oprom_is_loaded;
/* IGD needs to be Bus Master */
u32 reg32 = pci_read_config32(dev, PCI_COMMAND);
@@ -510,6 +511,18 @@ static void igd_init(struct device *dev)
igd_cdclk_init_haswell(dev);
reg_script_run_on_dev(dev, haswell_late_init_script);
}
+
+ if (!oprom_is_loaded) {
+ /*
+ * Enable DDI-A if the Option ROM did not execute:
+ *
+ * bit 0: Display detected (RO)
+ * bit 4: DDI A supports 4 lanes and DDI E is not used
+ * bit 7: DDI buffer is idle
+ */
+ gtt_write(DDI_BUF_CTL_A, DDI_BUF_IS_IDLE | DDI_A_4_LANES |
+ DDI_INIT_DISPLAY_DETECTED);
+ }
}
static void igd_read_resources(struct device *dev)
diff --git a/src/soc/intel/broadwell/me_status.c b/src/soc/intel/broadwell/me_status.c
index 476268f61a..40078b97d4 100644
--- a/src/soc/intel/broadwell/me_status.c
+++ b/src/soc/intel/broadwell/me_status.c
@@ -26,6 +26,8 @@
#include <broadwell/pci_devs.h>
#include <broadwell/me.h>
+#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG)
+
/* HFS1[3:0] Current Working State Values */
static const char *me_cws_values[] = {
[ME_HFS_CWS_RESET] = "Reset",
@@ -276,3 +278,4 @@ void intel_me_status(void)
}
printk(BIOS_DEBUG, "\n");
}
+#endif
diff --git a/src/soc/intel/broadwell/memmap.c b/src/soc/intel/broadwell/memmap.c
index c960347cf2..698ff6b83c 100644
--- a/src/soc/intel/broadwell/memmap.c
+++ b/src/soc/intel/broadwell/memmap.c
@@ -26,11 +26,18 @@
static unsigned long get_top_of_ram(void)
{
/*
- * Base of TSEG is top of usable DRAM below 4GiB. The register has
- * 1 MiB alignement.
+ * Base of DPR is top of usable DRAM below 4GiB. The register has
+ * 1 MiB alignment and reports the TOP of the range, the base
+ * must be calculated from the size in MiB in bits 11:4.
*/
- u32 tom = pci_read_config32(SA_DEV_ROOT, TSEG);
- return (unsigned long) tom & ~((1 << 20) - 1);
+ u32 dpr = pci_read_config32(SA_DEV_ROOT, DPR);
+ u32 tom = dpr & ~((1 << 20) - 1);
+
+ /* Subtract DMA Protected Range size if enabled */
+ if (dpr & DPR_EPM)
+ tom -= (dpr & DPR_SIZE_MASK) << 16;
+
+ return (unsigned long)tom;
}
void *cbmem_top(void)
diff --git a/src/soc/intel/broadwell/pch.c b/src/soc/intel/broadwell/pch.c
index 9ac833110d..82390a470b 100644
--- a/src/soc/intel/broadwell/pch.c
+++ b/src/soc/intel/broadwell/pch.c
@@ -92,91 +92,88 @@ static void pch_enable_d3hot(device_t dev)
void pch_disable_devfn(device_t dev)
{
switch (dev->path.pci.devfn) {
- case PCI_DEVFN(19, 0): /* Audio DSP */
+ case PCH_DEVFN_ADSP: /* Audio DSP */
RCBA32_OR(FD, PCH_DISABLE_ADSPD);
break;
- case PCI_DEVFN(20, 0): /* XHCI */
+ case PCH_DEVFN_XHCI: /* XHCI */
RCBA32_OR(FD, PCH_DISABLE_XHCI);
break;
- case PCI_DEVFN(21, 0): /* DMA */
+ case PCH_DEVFN_SDMA: /* DMA */
pch_enable_d3hot(dev);
pch_iobp_update(SIO_IOBP_FUNCDIS0, ~0UL, SIO_IOBP_FUNCDIS_DIS);
break;
- case PCI_DEVFN(21, 1): /* I2C0 */
+ case PCH_DEVFN_I2C0: /* I2C0 */
pch_enable_d3hot(dev);
pch_iobp_update(SIO_IOBP_FUNCDIS1, ~0UL, SIO_IOBP_FUNCDIS_DIS);
break;
- case PCI_DEVFN(21, 2): /* I2C1 */
+ case PCH_DEVFN_I2C1: /* I2C1 */
pch_enable_d3hot(dev);
pch_iobp_update(SIO_IOBP_FUNCDIS2, ~0UL, SIO_IOBP_FUNCDIS_DIS);
break;
- case PCI_DEVFN(21, 3): /* SPI0 */
+ case PCH_DEVFN_SPI0: /* SPI0 */
pch_enable_d3hot(dev);
pch_iobp_update(SIO_IOBP_FUNCDIS3, ~0UL, SIO_IOBP_FUNCDIS_DIS);
break;
- case PCI_DEVFN(21, 4): /* SPI1 */
+ case PCH_DEVFN_SPI1: /* SPI1 */
pch_enable_d3hot(dev);
pch_iobp_update(SIO_IOBP_FUNCDIS4, ~0UL, SIO_IOBP_FUNCDIS_DIS);
break;
- case PCI_DEVFN(21, 5): /* UART0 */
+ case PCH_DEVFN_UART0: /* UART0 */
pch_enable_d3hot(dev);
pch_iobp_update(SIO_IOBP_FUNCDIS5, ~0UL, SIO_IOBP_FUNCDIS_DIS);
break;
- case PCI_DEVFN(21, 6): /* UART1 */
+ case PCH_DEVFN_UART1: /* UART1 */
pch_enable_d3hot(dev);
pch_iobp_update(SIO_IOBP_FUNCDIS6, ~0UL, SIO_IOBP_FUNCDIS_DIS);
break;
- case PCI_DEVFN(22, 0): /* MEI #1 */
+ case PCH_DEVFN_ME: /* MEI #1 */
RCBA32_OR(FD2, PCH_DISABLE_MEI1);
break;
- case PCI_DEVFN(22, 1): /* MEI #2 */
+ case PCH_DEVFN_ME_2: /* MEI #2 */
RCBA32_OR(FD2, PCH_DISABLE_MEI2);
break;
- case PCI_DEVFN(22, 2): /* IDE-R */
+ case PCH_DEVFN_ME_IDER: /* IDE-R */
RCBA32_OR(FD2, PCH_DISABLE_IDER);
break;
- case PCI_DEVFN(22, 3): /* KT */
+ case PCH_DEVFN_ME_KT: /* KT */
RCBA32_OR(FD2, PCH_DISABLE_KT);
break;
- case PCI_DEVFN(23, 0): /* SDIO */
+ case PCH_DEVFN_SDIO: /* SDIO */
pch_enable_d3hot(dev);
pch_iobp_update(SIO_IOBP_FUNCDIS7, ~0UL, SIO_IOBP_FUNCDIS_DIS);
break;
- case PCI_DEVFN(25, 0): /* Gigabit Ethernet */
+ case PCH_DEVFN_GBE: /* Gigabit Ethernet */
RCBA32_OR(BUC, PCH_DISABLE_GBE);
break;
- case PCI_DEVFN(26, 0): /* EHCI #2 */
- RCBA32_OR(FD, PCH_DISABLE_EHCI2);
- break;
- case PCI_DEVFN(27, 0): /* HD Audio Controller */
+ case PCH_DEVFN_HDA: /* HD Audio Controller */
RCBA32_OR(FD, PCH_DISABLE_HD_AUDIO);
break;
- case PCI_DEVFN(28, 0): /* PCI Express Root Port 1 */
- case PCI_DEVFN(28, 1): /* PCI Express Root Port 2 */
- case PCI_DEVFN(28, 2): /* PCI Express Root Port 3 */
- case PCI_DEVFN(28, 3): /* PCI Express Root Port 4 */
- case PCI_DEVFN(28, 4): /* PCI Express Root Port 5 */
- case PCI_DEVFN(28, 5): /* PCI Express Root Port 6 */
- case PCI_DEVFN(28, 6): /* PCI Express Root Port 7 */
- case PCI_DEVFN(28, 7): /* PCI Express Root Port 8 */
+ case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 0): /* PCI Express Root Port 1 */
+ case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 1): /* PCI Express Root Port 2 */
+ case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 2): /* PCI Express Root Port 3 */
+ case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 3): /* PCI Express Root Port 4 */
+ case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 4): /* PCI Express Root Port 5 */
+ case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 5): /* PCI Express Root Port 6 */
+ case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 6): /* PCI Express Root Port 7 */
+ case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 7): /* PCI Express Root Port 8 */
RCBA32_OR(FD, PCH_DISABLE_PCIE(PCI_FUNC(dev->path.pci.devfn)));
break;
- case PCI_DEVFN(29, 0): /* EHCI #1 */
+ case PCH_DEVFN_EHCI: /* EHCI #1 */
RCBA32_OR(FD, PCH_DISABLE_EHCI1);
break;
- case PCI_DEVFN(31, 0): /* LPC */
+ case PCH_DEVFN_LPC: /* LPC */
RCBA32_OR(FD, PCH_DISABLE_LPC);
break;
- case PCI_DEVFN(31, 2): /* SATA #1 */
+ case PCH_DEVFN_SATA: /* SATA #1 */
RCBA32_OR(FD, PCH_DISABLE_SATA1);
break;
- case PCI_DEVFN(31, 3): /* SMBUS */
+ case PCH_DEVFN_SMBUS: /* SMBUS */
RCBA32_OR(FD, PCH_DISABLE_SMBUS);
break;
- case PCI_DEVFN(31, 5): /* SATA #2 */
+ case PCH_DEVFN_SATA2: /* SATA #2 */
RCBA32_OR(FD, PCH_DISABLE_SATA2);
break;
- case PCI_DEVFN(31, 6): /* Thermal Subsystem */
+ case PCH_DEVFN_THERMAL: /* Thermal Subsystem */
RCBA32_OR(FD, PCH_DISABLE_THERMAL);
break;
}
@@ -186,9 +183,13 @@ void broadwell_pch_enable_dev(device_t dev)
{
u32 reg32;
- /* PCH PCIe Root Ports are handled in PCIe driver. */
- if (PCI_SLOT(dev->path.pci.devfn) == PCH_DEV_SLOT_PCIE)
+ /* These devices need special enable/disable handling */
+ switch (PCI_SLOT(dev->path.pci.devfn)) {
+ case PCH_DEV_SLOT_PCIE:
+ case PCH_DEV_SLOT_EHCI:
+ case PCH_DEV_SLOT_HDA:
return;
+ }
if (!dev->enabled) {
printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
diff --git a/src/soc/intel/broadwell/pei_data.h b/src/soc/intel/broadwell/pei_data.h
deleted file mode 100644
index f92c0a68e0..0000000000
--- a/src/soc/intel/broadwell/pei_data.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * coreboot UEFI PEI wrapper
- *
- * Copyright (c) 2011, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PEI_DATA_H
-#define PEI_DATA_H
-
-typedef void (*tx_byte_func)(unsigned char byte);
-#define PEI_VERSION 15
-
-#define MAX_USB2_PORTS 16
-#define MAX_USB3_PORTS 16
-#define USB_OC_PIN_SKIP 8
-
-enum usb2_port_location {
- USB_PORT_BACK_PANEL = 0,
- USB_PORT_FRONT_PANEL,
- USB_PORT_DOCK,
- USB_PORT_MINI_PCIE,
- USB_PORT_FLEX,
- USB_PORT_INTERNAL,
- USB_PORT_SKIP
-};
-
-/* Usb Port Length:
- * [16:4] = length in inches in octal format
- * [3:0] = decimal point
- */
-struct usb2_port_setting {
- uint16_t length;
- uint8_t enable;
- uint8_t over_current_pin;
- uint8_t location;
-} __attribute__((packed));
-
-struct usb3_port_setting {
- uint8_t enable;
- uint8_t over_current_pin;
-} __attribute__((packed));
-
-struct pei_data
-{
- uint32_t pei_version;
- uint32_t mchbar;
- uint32_t dmibar;
- uint32_t epbar;
- uint32_t pciexbar;
- uint16_t smbusbar;
- uint32_t wdbbar;
- uint32_t wdbsize;
- uint32_t hpet_address;
- uint32_t rcba;
- uint32_t pmbase;
- uint32_t gpiobase;
- uint32_t temp_mmio_base;
- uint32_t system_type; // 0 Mobile, 1 Desktop/Server
- uint32_t tseg_size;
- uint8_t spd_addresses[4];
- int boot_mode;
- int ec_present;
- int gbe_enable;
- // 0 = leave channel enabled
- // 1 = disable dimm 0 on channel
- // 2 = disable dimm 1 on channel
- // 3 = disable dimm 0+1 on channel
- int dimm_channel0_disabled;
- int dimm_channel1_disabled;
- /* Enable 2x Refresh Mode */
- int ddr_refresh_2x;
- int dq_pins_interleaved;
- /* Data read from flash and passed into MRC */
- unsigned char *mrc_input;
- unsigned int mrc_input_len;
- /* Data from MRC that should be saved to flash */
- unsigned char *mrc_output;
- unsigned int mrc_output_len;
- /*
- * Max frequency DDR3 could be ran at. Could be one of four values: 800,
- * 1067, 1333, 1600
- */
- uint32_t max_ddr3_freq;
- /* Route all USB ports to XHCI controller in resume path */
- int usb_xhci_on_resume;
- struct usb2_port_setting usb2_ports[MAX_USB2_PORTS];
- struct usb3_port_setting usb3_ports[MAX_USB3_PORTS];
- uint8_t spd_data[4][256];
- tx_byte_func tx_byte;
-} __attribute__((packed));
-
-#endif
diff --git a/src/soc/intel/broadwell/romstage/Makefile.inc b/src/soc/intel/broadwell/romstage/Makefile.inc
index 98d87a4965..f8a961795b 100644
--- a/src/soc/intel/broadwell/romstage/Makefile.inc
+++ b/src/soc/intel/broadwell/romstage/Makefile.inc
@@ -10,3 +10,4 @@ romstage-y += smbus.c
romstage-y += spi.c
romstage-y += stack.c
romstage-y += systemagent.c
+romstage-$(CONFIG_CONSOLE_SERIAL8250MEM) += uart.c
diff --git a/src/soc/intel/broadwell/romstage/cpu.c b/src/soc/intel/broadwell/romstage/cpu.c
index e7139b807d..754bc31cd6 100644
--- a/src/soc/intel/broadwell/romstage/cpu.c
+++ b/src/soc/intel/broadwell/romstage/cpu.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <arch/cpu.h>
#include <stdlib.h>
#include <console/console.h>
#include <cpu/x86/msr.h>
@@ -24,6 +25,11 @@
#include <broadwell/msr.h>
#include <broadwell/romstage.h>
+u32 cpu_family_model(void)
+{
+ return cpuid_eax(1) & 0x0fff0ff0;
+}
+
void set_max_freq(void)
{
msr_t msr, perf_ctl, platform_info;
diff --git a/src/soc/intel/broadwell/romstage/raminit.c b/src/soc/intel/broadwell/romstage/raminit.c
index 870952f79a..a5f688ea69 100644
--- a/src/soc/intel/broadwell/romstage/raminit.c
+++ b/src/soc/intel/broadwell/romstage/raminit.c
@@ -24,6 +24,7 @@
#include <cbmem.h>
#include <console/console.h>
#include <device/pci_def.h>
+#include <lib.h>
#include <string.h>
#if CONFIG_EC_GOOGLE_CHROMEEC
#include <ec/google/chromeec/ec.h>
@@ -73,6 +74,16 @@ void raminit(struct pei_data *pei_data)
#endif
}
+ /*
+ * Do not use saved pei data. Can be set by mainboard romstage
+ * to force a full train of memory on every boot.
+ */
+ if (pei_data->disable_saved_data) {
+ printk(BIOS_DEBUG, "Disabling PEI saved data by request\n");
+ pei_data->saved_data = NULL;
+ pei_data->saved_data_size = 0;
+ }
+
/* Determine if mrc.bin is in the cbfs. */
entry = (pei_wrapper_entry_t)cbfs_get_file_content(
CBFS_DEFAULT_MEDIA, "mrc.bin", 0xab);
@@ -95,6 +106,9 @@ void raminit(struct pei_data *pei_data)
report_memory_config();
+ /* Basic memory sanity test */
+ quick_ram_check();
+
if (pei_data->boot_mode != SLEEP_STATE_S3) {
cbmem_initialize_empty();
} else if (cbmem_initialize()) {
diff --git a/src/soc/intel/broadwell/romstage/report_platform.c b/src/soc/intel/broadwell/romstage/report_platform.c
index 3c4016fa1f..4e161dc442 100644
--- a/src/soc/intel/broadwell/romstage/report_platform.c
+++ b/src/soc/intel/broadwell/romstage/report_platform.c
@@ -41,6 +41,7 @@ static struct {
{ CPUID_HASWELL_HALO, "Haswell Perf Halo" },
{ CPUID_BROADWELL_C0, "Broadwell C0" },
{ CPUID_BROADWELL_D0, "Broadwell D0" },
+ { CPUID_BROADWELL_E0, "Broadwell E0" },
};
static struct {
diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c
index 84d1f11f5c..1d5ee89d54 100644
--- a/src/soc/intel/broadwell/romstage/romstage.c
+++ b/src/soc/intel/broadwell/romstage/romstage.c
@@ -73,6 +73,9 @@ void * asmlinkage romstage_main(unsigned long bist,
/* Start console drivers */
console_init();
+ /* Get power state */
+ rp.power_state = fill_power_state();
+
/* Print useful platform information */
report_platform_info();
@@ -96,19 +99,16 @@ static inline void chromeos_init(int prev_sleep_state)
/* Entry from the mainboard. */
void romstage_common(struct romstage_params *params)
{
- struct chipset_power_state *ps;
struct romstage_handoff *handoff;
post_code(0x32);
mark_ts(params, timestamp_get());
- /* Get power state */
- ps = fill_power_state();
- params->pei_data->boot_mode = ps->prev_sleep_state;
+ params->pei_data->boot_mode = params->power_state->prev_sleep_state;
#if CONFIG_ELOG_BOOT_COUNT
- if (ps->prev_sleep_state != SLEEP_STATE_S3)
+ if (params->power_state->prev_sleep_state != SLEEP_STATE_S3)
boot_count_increment();
#endif
@@ -121,11 +121,12 @@ void romstage_common(struct romstage_params *params)
handoff = romstage_handoff_find_or_add();
if (handoff != NULL)
- handoff->s3_resume = (ps->prev_sleep_state == SLEEP_STATE_S3);
+ handoff->s3_resume = (params->power_state->prev_sleep_state ==
+ SLEEP_STATE_S3);
else
printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
- chromeos_init(ps->prev_sleep_state);
+ chromeos_init(params->power_state->prev_sleep_state);
/* Save timestamp information. */
timestamp_init(params->ts.times[0]);
diff --git a/src/soc/intel/broadwell/romstage/uart.c b/src/soc/intel/broadwell/romstage/uart.c
new file mode 100644
index 0000000000..8214a8a116
--- /dev/null
+++ b/src/soc/intel/broadwell/romstage/uart.c
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/early_variables.h>
+#include <arch/io.h>
+#include <delay.h>
+#include <device/pci_def.h>
+#include <reg_script.h>
+#include <stdint.h>
+#include <uart8250.h>
+#include <broadwell/iobp.h>
+#include <broadwell/serialio.h>
+
+const struct reg_script uart_init[] = {
+ /* Set MMIO BAR */
+ REG_PCI_WRITE32(PCI_BASE_ADDRESS_0, CONFIG_TTYS0_BASE),
+ /* Enable Memory access and Bus Master */
+ REG_PCI_OR32(PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER),
+ /* Initialize LTR */
+ REG_MMIO_RMW32(CONFIG_TTYS0_BASE + SIO_REG_PPR_GEN,
+ ~SIO_REG_PPR_GEN_LTR_MODE_MASK, 0),
+ REG_MMIO_RMW32(CONFIG_TTYS0_BASE + SIO_REG_PPR_RST,
+ ~(SIO_REG_PPR_RST_ASSERT), 0),
+ /* Take UART out of reset */
+ REG_MMIO_OR32(CONFIG_TTYS0_BASE + SIO_REG_PPR_RST,
+ SIO_REG_PPR_RST_ASSERT),
+ /* Set M and N divisor inputs and enable clock */
+ REG_MMIO_WRITE32(CONFIG_TTYS0_BASE + SIO_REG_PPR_CLOCK,
+ SIO_REG_PPR_CLOCK_EN | SIO_REG_PPR_CLOCK_UPDATE |
+ (SIO_REG_PPR_CLOCK_N_DIV << 16) |
+ (SIO_REG_PPR_CLOCK_M_DIV << 1)),
+ REG_SCRIPT_END
+};
+
+void pch_uart_init(void)
+{
+ /* Program IOBP CB000154h[12,9:8,4:0] = 1001100011111b */
+ u32 gpiodf = 0x131f;
+ device_t dev;
+
+ /* Put UART in byte access mode for 16550 compatibility */
+ switch (CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER) {
+ case 0:
+ dev = PCH_DEV_UART0;
+ gpiodf |= SIO_IOBP_GPIODF_UART0_BYTE_ACCESS;
+ break;
+ case 1:
+ dev = PCH_DEV_UART1;
+ gpiodf |= SIO_IOBP_GPIODF_UART1_BYTE_ACCESS;
+ break;
+ default:
+ return;
+ }
+
+ /* Program IOBP GPIODF */
+ pch_iobp_update(SIO_IOBP_GPIODF, ~gpiodf, gpiodf);
+
+ /* Program IOBP CB000180h[5:0] = 111111b (undefined register) */
+ pch_iobp_update(0xcb000180, ~0x0000003f, 0x0000003f);
+
+ /* Initialize chipset uart interface */
+ reg_script_run_on_dev(dev, uart_init);
+
+ /*
+ * Perform standard UART initialization
+ * Divisor 1 is 115200 BAUD
+ */
+ uart8250_mem_init(CONFIG_TTYS0_BASE, 1);
+}
diff --git a/src/soc/intel/broadwell/serialio.c b/src/soc/intel/broadwell/serialio.c
index bbb018f87a..e2b17afa66 100644
--- a/src/soc/intel/broadwell/serialio.c
+++ b/src/soc/intel/broadwell/serialio.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <broadwell/iobp.h>
#include <broadwell/nvs.h>
+#include <broadwell/pci_devs.h>
#include <broadwell/pch.h>
#include <broadwell/ramstage.h>
#include <broadwell/rcba.h>
@@ -34,11 +35,24 @@
#include <chip.h>
/* Set D3Hot Power State in ACPI mode */
-static void serialio_enable_d3hot(struct device *dev)
+static void serialio_enable_d3hot(struct resource *res)
{
- u32 reg32 = pci_read_config32(dev, PCH_PCS);
+ u32 reg32 = read32(res->base + PCH_PCS);
reg32 |= PCH_PCS_PS_D3HOT;
- pci_write_config32(dev, PCH_PCS, reg32);
+ write32(res->base + PCH_PCS, reg32);
+}
+
+static int serialio_uart_is_debug(struct device *dev)
+{
+#if CONFIG_INTEL_PCH_UART_CONSOLE
+ switch (dev->path.pci.devfn) {
+ case PCH_DEVFN_UART0: /* UART0 */
+ return !!(CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 0);
+ case PCH_DEVFN_UART1: /* UART1 */
+ return !!(CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 1);
+ }
+#endif
+ return 0;
}
/* Enable clock in PCI mode */
@@ -182,55 +196,55 @@ static void serialio_init(struct device *dev)
if (!config->sio_acpi_mode)
serialio_enable_clock(bar0);
- else if (dev->path.pci.devfn != PCI_DEVFN(21, 0))
- serialio_enable_d3hot(dev); /* all but SDMA */
switch (dev->path.pci.devfn) {
- case PCI_DEVFN(21, 0): /* SDMA */
+ case PCH_DEVFN_SDMA: /* SDMA */
sio_index = SIO_ID_SDMA;
serialio_init_once(config->sio_acpi_mode);
serialio_d21_mode(sio_index, SIO_PIN_INTB,
config->sio_acpi_mode);
break;
- case PCI_DEVFN(21, 1): /* I2C0 */
+ case PCH_DEVFN_I2C0: /* I2C0 */
sio_index = SIO_ID_I2C0;
serialio_d21_ltr(bar0);
serialio_i2c_voltage_sel(bar0, config->sio_i2c0_voltage);
serialio_d21_mode(sio_index, SIO_PIN_INTC,
config->sio_acpi_mode);
break;
- case PCI_DEVFN(21, 2): /* I2C1 */
+ case PCH_DEVFN_I2C1: /* I2C1 */
sio_index = SIO_ID_I2C1;
serialio_d21_ltr(bar0);
serialio_i2c_voltage_sel(bar0, config->sio_i2c1_voltage);
serialio_d21_mode(sio_index, SIO_PIN_INTC,
config->sio_acpi_mode);
break;
- case PCI_DEVFN(21, 3): /* SPI0 */
+ case PCH_DEVFN_SPI0: /* SPI0 */
sio_index = SIO_ID_SPI0;
serialio_d21_ltr(bar0);
serialio_d21_mode(sio_index, SIO_PIN_INTC,
config->sio_acpi_mode);
break;
- case PCI_DEVFN(21, 4): /* SPI1 */
+ case PCH_DEVFN_SPI1: /* SPI1 */
sio_index = SIO_ID_SPI1;
serialio_d21_ltr(bar0);
serialio_d21_mode(sio_index, SIO_PIN_INTC,
config->sio_acpi_mode);
break;
- case PCI_DEVFN(21, 5): /* UART0 */
+ case PCH_DEVFN_UART0: /* UART0 */
sio_index = SIO_ID_UART0;
- serialio_d21_ltr(bar0);
+ if (!serialio_uart_is_debug(dev))
+ serialio_d21_ltr(bar0);
serialio_d21_mode(sio_index, SIO_PIN_INTD,
config->sio_acpi_mode);
break;
- case PCI_DEVFN(21, 6): /* UART1 */
+ case PCH_DEVFN_UART1: /* UART1 */
sio_index = SIO_ID_UART1;
- serialio_d21_ltr(bar0);
+ if (!serialio_uart_is_debug(dev))
+ serialio_d21_ltr(bar0);
serialio_d21_mode(sio_index, SIO_PIN_INTD,
config->sio_acpi_mode);
break;
- case PCI_DEVFN(23, 0): /* SDIO */
+ case PCH_DEVFN_SDIO: /* SDIO */
sio_index = SIO_ID_SDIO;
serialio_d23_ltr(bar0);
serialio_d23_mode(config->sio_acpi_mode);
@@ -252,6 +266,14 @@ static void serialio_init(struct device *dev)
/* Save BAR0 and BAR1 to ACPI NVS */
gnvs->dev.bar0[sio_index] = (u32)bar0->base;
gnvs->dev.bar1[sio_index] = (u32)bar1->base;
+
+ /* Do not enable UART if it is used as debug port */
+ if (!serialio_uart_is_debug(dev))
+ gnvs->dev.enable[sio_index] = 1;
+
+ /* Put device in D3hot state via BAR1 */
+ if (dev->path.pci.devfn != PCH_DEVFN_SDMA)
+ serialio_enable_d3hot(bar1); /* all but SDMA */
}
}
diff --git a/src/soc/intel/broadwell/systemagent.c b/src/soc/intel/broadwell/systemagent.c
index 56a44d99e5..787a62b2ee 100644
--- a/src/soc/intel/broadwell/systemagent.c
+++ b/src/soc/intel/broadwell/systemagent.c
@@ -33,6 +33,7 @@
#include <vendorcode/google/chromeos/chromeos.h>
#include <broadwell/cpu.h>
#include <broadwell/iomap.h>
+#include <broadwell/pci_devs.h>
#include <broadwell/ramstage.h>
#include <broadwell/systemagent.h>
@@ -278,12 +279,26 @@ static void mc_add_dram_resources(device_t dev)
unsigned long index;
struct resource *resource;
uint64_t mc_values[NUM_MAP_ENTRIES];
+ unsigned long dpr_size = 0;
+ u32 dpr_reg;
/* Read in the MAP registers and report their values. */
mc_read_map_entries(dev, &mc_values[0]);
mc_report_map_entries(dev, &mc_values[0]);
/*
+ * DMA Protected Range can be reserved below TSEG for PCODE patch
+ * or TXT/BootGuard related data. Rather than report a base address
+ * the DPR register reports the TOP of the region, which is the same
+ * as TSEG base. The region size is reported in MiB in bits 11:4.
+ */
+ dpr_reg = pci_read_config32(SA_DEV_ROOT, DPR);
+ if (dpr_reg & DPR_EPM) {
+ dpr_size = (dpr_reg & DPR_SIZE_MASK) << 16;
+ printk(BIOS_INFO, "DPR SIZE: 0x%lx\n", dpr_size);
+ }
+
+ /*
* These are the host memory ranges that should be added:
* - 0 -> 0xa0000: cacheable
* - 0xc0000 -> TSEG : cacheable
@@ -320,14 +335,15 @@ static void mc_add_dram_resources(device_t dev)
size_k = (0xa0000 >> 10) - base_k;
ram_resource(dev, index++, base_k, size_k);
- /* 0xc0000 -> TSEG */
+ /* 0xc0000 -> TSEG - DPR */
base_k = 0xc0000 >> 10;
size_k = (unsigned long)(mc_values[TSEG_REG] >> 10) - base_k;
+ size_k -= dpr_size >> 10;
ram_resource(dev, index++, base_k, size_k);
- /* TSEG -> BGSM */
+ /* TSEG - DPR -> BGSM */
resource = new_resource(dev, index++);
- resource->base = mc_values[TSEG_REG];
+ resource->base = mc_values[TSEG_REG] - dpr_size;
resource->size = mc_values[BGSM_REG] - resource->base;
resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
IORESOURCE_STORED | IORESOURCE_RESERVE |
diff --git a/src/soc/intel/broadwell/usbdebug.c b/src/soc/intel/broadwell/usbdebug.c
new file mode 100644
index 0000000000..d462e89f90
--- /dev/null
+++ b/src/soc/intel/broadwell/usbdebug.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <usbdebug.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <broadwell/pci_devs.h>
+
+void set_debug_port(unsigned int port)
+{
+ /* Hardcoded to physical port 1 */
+}
+
+void enable_usbdebug(unsigned int port)
+{
+ u32 tmp32;
+
+ tmp32 = pci_read_config32(PCH_DEV_EHCI, PCI_VENDOR_ID);
+ if (tmp32 == 0xffffffff || tmp32 == 0)
+ return;
+
+ /* Set the EHCI BAR address. */
+ pci_write_config32(PCH_DEV_EHCI, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+
+ /* Enable access to the EHCI memory space registers. */
+ pci_write_config8(PCH_DEV_EHCI, PCI_COMMAND, PCI_COMMAND_MEMORY);
+
+ /* Force ownership of the Debug Port to the EHCI controller. */
+ tmp32 = read32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET);
+ tmp32 |= (1 << 30);
+ write32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET, tmp32);
+}