From 61680274c1ded5ea095b15b689f83d5d670d2aae Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Mon, 5 May 2014 12:42:35 -0500 Subject: broadwell: ACPI, romstage, and other updates broadwell: Add romstage usbdebug support Reviewed-on: https://chromium-review.googlesource.com/199412 (cherry picked from commit 1050e7d3be6ec1e4fe5aa2df408f4bb6d33a42b5) broadwell: Add romstage code to configure PCH UART for console Reviewed-on: https://chromium-review.googlesource.com/199807 (cherry picked from commit ecebda4eb5d6fe58473d25c2898ba1a2eac0f39a) broadwell: Expand the PCI device convenience macros Reviewed-on: https://chromium-review.googlesource.com/199891 (cherry picked from commit f8c54c70f136cd2cb8f977bc25661974d7e529ad) broadwell: Add ramstage driver for ADSP Reviewed-on: https://chromium-review.googlesource.com/199892 (cherry picked from commit e8e986b0ba52bbfc9923d71009fbd31e749ca43f) broadwell: Update ACPI devices Reviewed-on: https://chromium-review.googlesource.com/201080 (cherry picked from commit 2446b35578eb36e0009415bec340059135751549) broadwell: Reserve DPR region Reviewed-on: https://chromium-review.googlesource.com/201081 (cherry picked from commit 8ecd9d2096db2bded6f27ef6ee9a9b39ce2dfec6) broadwell: Remove old pei_data and add cpu function for romstage Reviewed-on: https://chromium-review.googlesource.com/201690 (cherry picked from commit d206c9cdd69519d502a90bb0595f0e3a7cb50274) broadwell: Fixes for graphics without executing VBIOS Reviewed-on: https://chromium-review.googlesource.com/202356 (cherry picked from commit 0c031df1ce92c875e95ddfd3f026f649c342c7fa) broadwell: Fix compilation failure when loglevel is lowered Reviewed-on: https://chromium-review.googlesource.com/202357 (cherry picked from commit 708ce78b2bfae5664b1238e17b086c88cac55bdc) broadwell: Disable GPIO controller interrupt Reviewed-on: https://chromium-review.googlesource.com/203645 (cherry picked from commit 2d17e98eded5958258ba5c0abf600284d8d03af9) broadwell: Add support for E0 stepping Reviewed-on: https://chromium-review.googlesource.com/205160 (cherry picked from commit 802e9d371418cc7a7fc7af131d7e5dda0ae5b273) broadwell: misc updates for CPU driver Reviewed-on: https://chromium-review.googlesource.com/205161 (cherry picked from commit ea1d403817ee193648f2c119fd45894e32e57e97) broadwell: Read power state earlier and store in romstage params Reviewed-on: https://chromium-review.googlesource.com/208151 (cherry picked from commit b2198d71084ad3c1360a0bfedc46c8dd3825bd0e) broadwell: Add parameters to pei_data structure Reviewed-on: https://chromium-review.googlesource.com/208153 (cherry picked from commit 423fbf67e497a907fbc8e12caf2929d4951858af) broadwell: Move platform report output after power state is read Reviewed-on: https://chromium-review.googlesource.com/208213 (cherry picked from commit acedf4146bf9377133433046dae1fa9c8bc69d78) Squashed 15 commits for broadwell support. Change-Id: I87e320d3d5376b84dd9c146b0b833e5ce53244aa Signed-off-by: Isaac Christensen Reviewed-on: http://review.coreboot.org/6982 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones --- src/soc/intel/broadwell/Kconfig | 18 ++ src/soc/intel/broadwell/Makefile.inc | 7 + src/soc/intel/broadwell/acpi.c | 5 - src/soc/intel/broadwell/acpi/adsp.asl | 63 +++++++ src/soc/intel/broadwell/acpi/device_nvs.asl | 3 + src/soc/intel/broadwell/acpi/gpio.asl | 17 +- src/soc/intel/broadwell/acpi/lpc.asl | 4 +- src/soc/intel/broadwell/acpi/pch.asl | 18 ++ src/soc/intel/broadwell/acpi/serialio.asl | 209 ++++++++++++++++++--- src/soc/intel/broadwell/adsp.c | 152 +++++++++++++++ src/soc/intel/broadwell/broadwell/adsp.h | 56 ++++++ src/soc/intel/broadwell/broadwell/cpu.h | 1 + src/soc/intel/broadwell/broadwell/device_nvs.h | 7 +- src/soc/intel/broadwell/broadwell/pci_devs.h | 92 ++++++--- src/soc/intel/broadwell/broadwell/pei_data.h | 7 +- src/soc/intel/broadwell/broadwell/romstage.h | 4 + src/soc/intel/broadwell/broadwell/systemagent.h | 4 + src/soc/intel/broadwell/cpu.c | 4 +- src/soc/intel/broadwell/ehci.c | 10 + src/soc/intel/broadwell/hda.c | 25 +++ src/soc/intel/broadwell/igd.c | 13 ++ src/soc/intel/broadwell/me_status.c | 3 + src/soc/intel/broadwell/memmap.c | 15 +- src/soc/intel/broadwell/pch.c | 71 +++---- src/soc/intel/broadwell/pei_data.h | 115 ------------ src/soc/intel/broadwell/romstage/Makefile.inc | 1 + src/soc/intel/broadwell/romstage/cpu.c | 6 + src/soc/intel/broadwell/romstage/raminit.c | 14 ++ src/soc/intel/broadwell/romstage/report_platform.c | 1 + src/soc/intel/broadwell/romstage/romstage.c | 15 +- src/soc/intel/broadwell/romstage/uart.c | 85 +++++++++ src/soc/intel/broadwell/serialio.c | 52 +++-- src/soc/intel/broadwell/systemagent.c | 22 ++- src/soc/intel/broadwell/usbdebug.c | 51 +++++ 34 files changed, 930 insertions(+), 240 deletions(-) create mode 100644 src/soc/intel/broadwell/acpi/adsp.asl create mode 100644 src/soc/intel/broadwell/adsp.c create mode 100644 src/soc/intel/broadwell/broadwell/adsp.h delete mode 100644 src/soc/intel/broadwell/pei_data.h create mode 100644 src/soc/intel/broadwell/romstage/uart.c create mode 100644 src/soc/intel/broadwell/usbdebug.c (limited to 'src/soc') 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 #define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_ ## slot, 0) @@ -27,43 +30,90 @@ #else #include #include -#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 -#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 #include #include +#include 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 #include #include +#include #include #include @@ -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 #include +#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 #include #include #include @@ -24,6 +25,11 @@ #include #include +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 #include #include +#include #include #if CONFIG_EC_GOOGLE_CHROMEEC #include @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +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 #include #include +#include #include #include #include @@ -34,11 +35,24 @@ #include /* 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 #include #include +#include #include #include @@ -278,11 +279,25 @@ 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 @@ -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 +#include +#include +#include +#include +#include +#include + +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); +} -- cgit v1.2.3