baytrail: Add support for LPSS and SCC devices in ACPI mode

This adds the option to put LPSS and SCC devices into ACPI mode
by saving their BAR0 and BAR1 base addresses in a new device
NVS structure that is placed at offset 0x1000 within the global
NVS table.

The Chrome NVS strcture is padded out to 0xf00 bytes so there
is a clean offset to work with as it will need to be used by
depthcharge to know what addresses devices live at.

A few ACPI Mode IRQs are fixed up, DMA1 and DMA2 are swapped and
the EMMC 4.5 IRQ is changed to 44.

New ACPI code is provided to instantiate the LPSS and SCC devices
with the magic HID values from Intel so the kernel drivers can
locate and use them.

The default is still for devices to be in PCI mode so this does
not have any real effect without it being enabled in the mainboard
devicetree.

Note: this needs the updated IASL compiler which is in the CQ now
because it uses the FixedDMA() ACPI operator.

BUG=chrome-os-partner:23505,chrome-os-partner:24380
CQ-DEPEND=CL:179459,CL:179364
BRANCH=none
TEST=manual tests on rambi device:

1) build and boot with devices still in PCI mode and ensure that
nothing is changed

2) enable lpss_acpi_mode and see I2C devices detected by the kernel
in ACPI mode.  Note that by itself this breaks trackpad probing so
that will need to be implemented before it is enabled.

3) enable scc_acpi_mode and see EMMC and SDCard devices detected by
the kernel in ACPI mode.  Note that this breaks depthcharge use of
the EMMC because it is not longer discoverable as a PCI device.

Change-Id: I2a007f3c4e0b06ace5172a15c696a8eaad41ed73
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/179481
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/5004
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
This commit is contained in:
Duncan Laurie 2013-12-10 14:37:42 -08:00 committed by Kyösti Mälkki
parent 0e6be39f8b
commit 430bf0d8a9
15 changed files with 1152 additions and 38 deletions

View File

@ -0,0 +1,87 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 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 Enabled in ACPI Mode */
S0EN, 8, // SDMA Enable
S1EN, 8, // I2C1 Enable
S2EN, 8, // I2C2 Enable
S3EN, 8, // I2C3 Enable
S4EN, 8, // I2C4 Enable
S5EN, 8, // I2C5 Enable
S6EN, 8, // I2C6 Enable
S7EN, 8, // I2C7 Enable
S8EN, 8, // SDMA2 Enable
S9EN, 8, // SPI Enable
SAEN, 8, // PWM1 Enable
SBEN, 8, // PWM2 Enable
SCEN, 8, // UART2 Enable
SDEN, 8, // UART2 Enable
C0EN, 8, // MMC Enable
C1EN, 8, // SDIO Enable
C2EN, 8, // SD Card Enable
LPEN, 8, // LPE Enable
/* BAR 0 */
S0B0, 32, // SDMA BAR0
S1B0, 32, // I2C1 BAR0
S2B0, 32, // I2C2 BAR0
S3B0, 32, // I2C3 BAR0
S4B0, 32, // I2C4 BAR0
S5B0, 32, // I2C5 BAR0
S6B0, 32, // I2C6 BAR0
S7B0, 32, // I2C7 BAR0
S8B0, 32, // SDMA2 BAR0
S9B0, 32, // SPI BAR0
SAB0, 32, // PWM1 BAR0
SBB0, 32, // PWM2 BAR0
SCB0, 32, // UART1 BAR0
SDB0, 32, // UART2 BAR0
C0B0, 32, // MMC BAR0
C1B0, 32, // SDIO BAR0
C2B0, 32, // SD Card BAR0
LPB0, 32, // LPE BAR0
/* BAR 1 */
S0B1, 32, // SDMA BAR1
S1B1, 32, // I2C1 BAR1
S2B1, 32, // I2C2 BAR1
S3B1, 32, // I2C3 BAR1
S4B1, 32, // I2C4 BAR1
S5B1, 32, // I2C5 BAR1
S6B1, 32, // I2C6 BAR1
S7B1, 32, // I2C7 BAR1
S8B1, 32, // SDMA2 BAR1
S9B1, 32, // SPI BAR1
SAB1, 32, // PWM1 BAR1
SBB1, 32, // PWM2 BAR1
SCB1, 32, // UART1 BAR1
SDB1, 32, // UART2 BAR1
C0B1, 32, // MMC BAR1
C1B1, 32, // SDIO BAR1
C2B1, 32, // SD Card BAR1
LPB1, 32, // LPE BAR1
/* Extra */
LPFW, 32, // LPE BAR2 Firmware

View File

@ -30,7 +30,7 @@ Name(\PICM, 0) // IOAPIC/8259
*/ */
OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0xf00) OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0x2000)
Field (GNVS, ByteAcc, NoLock, Preserve) Field (GNVS, ByteAcc, NoLock, Preserve)
{ {
/* Miscellaneous */ /* Miscellaneous */
@ -70,28 +70,12 @@ Field (GNVS, ByteAcc, NoLock, Preserve)
TOLM, 32, // 0x34 - Top of Low Memory TOLM, 32, // 0x34 - Top of Low Memory
CBMC, 32, // 0x38 - coreboot mem console pointer CBMC, 32, // 0x38 - coreboot mem console pointer
/* Serial IO device BARs */
Offset (0x60),
S0B0, 32, // 0x60 - D21:F0 Serial IO SDMA BAR0
S1B0, 32, // 0x64 - D21:F1 Serial IO I2C0 BAR0
S2B0, 32, // 0x68 - D21:F2 Serial IO I2C1 BAR0
S3B0, 32, // 0x6c - D21:F3 Serial IO SPI0 BAR0
S4B0, 32, // 0x70 - D21:F4 Serial IO SPI1 BAR0
S5B0, 32, // 0x74 - D21:F5 Serial IO UAR0 BAR0
S6B0, 32, // 0x78 - D21:F6 Serial IO UAR1 BAR0
S7B0, 32, // 0x7c - D23:F0 Serial IO SDIO BAR0
S0B1, 32, // 0x80 - D21:F0 Serial IO SDMA BAR1
S1B1, 32, // 0x84 - D21:F1 Serial IO I2C0 BAR1
S2B1, 32, // 0x88 - D21:F2 Serial IO I2C1 BAR1
S3B1, 32, // 0x8c - D21:F3 Serial IO SPI0 BAR1
S4B1, 32, // 0x90 - D21:F4 Serial IO SPI1 BAR1
S5B1, 32, // 0x94 - D21:F5 Serial IO UAR0 BAR1
S6B1, 32, // 0x98 - D21:F6 Serial IO UAR1 BAR1
S7B1, 32, // 0x9c - D23:F0 Serial IO SDIO BAR1
/* ChromeOS specific */ /* ChromeOS specific */
Offset (0x100), Offset (0x100),
#include <vendorcode/google/chromeos/acpi/gnvs.asl> #include <vendorcode/google/chromeos/acpi/gnvs.asl>
Offset (0x1000),
#include <soc/intel/baytrail/acpi/device_nvs.asl>
} }
/* Set flag to enable USB charging in S3 */ /* Set flag to enable USB charging in S3 */

View File

@ -0,0 +1,670 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 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 (SDM1)
{
Name (_HID, "INTL9C60")
Name (_UID, 1)
Name (_DDN, "DMA Controller #1")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_DMA1_IRQ
}
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S0B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S0EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
}
Device (SDM2)
{
Name (_HID, "INTL9C60")
Name (_UID, 2)
Name (_DDN, "DMA Controller #2")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_DMA2_IRQ
}
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S8B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S8EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
}
Device (I2C1)
{
Name (_HID, "80860F41")
Name (_UID, 1)
Name (_DDN, "I2C Controller #1")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_I2C1_IRQ
}
FixedDMA (0x10, 0x0, Width32Bit, )
FixedDMA (0x11, 0x1, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S1B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S1EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, S1B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (I2C2)
{
Name (_HID, "80860F41")
Name (_UID, 2)
Name (_DDN, "I2C Controller #2")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_I2C2_IRQ
}
FixedDMA (0x10, 0x0, Width32Bit, )
FixedDMA (0x11, 0x1, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S2B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S2EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, S2B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (I2C3)
{
Name (_HID, "80860F41")
Name (_UID, 3)
Name (_DDN, "I2C Controller #3")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_I2C3_IRQ
}
FixedDMA (0x10, 0x0, Width32Bit, )
FixedDMA (0x11, 0x1, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S3B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S3EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, S3B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (I2C4)
{
Name (_HID, "80860F41")
Name (_UID, 4)
Name (_DDN, "I2C Controller #4")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_I2C4_IRQ
}
FixedDMA (0x10, 0x0, Width32Bit, )
FixedDMA (0x11, 0x1, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S4B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S4EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, S4B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (I2C5)
{
Name (_HID, "80860F41")
Name (_UID, 5)
Name (_DDN, "I2C Controller #5")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_I2C5_IRQ
}
FixedDMA (0x10, 0x0, Width32Bit, )
FixedDMA (0x11, 0x1, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S5B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S5EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, S5B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (I2C6)
{
Name (_HID, "80860F41")
Name (_UID, 6)
Name (_DDN, "I2C Controller #6")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_I2C6_IRQ
}
FixedDMA (0x10, 0x0, Width32Bit, )
FixedDMA (0x11, 0x1, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S6B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S6EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, S6B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (I2C7)
{
Name (_HID, "80860F41")
Name (_UID, 7)
Name (_DDN, "I2C Controller #7")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_I2C7_IRQ
}
FixedDMA (0x10, 0x0, Width32Bit, )
FixedDMA (0x11, 0x1, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S7B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S7EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, S7B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (SPI1)
{
Name (_HID, "80860F0E")
Name (_UID, 1)
Name (_DDN, "SPI Controller #2")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_SPI_IRQ
}
FixedDMA (0x0, 0x0, Width32Bit, )
FixedDMA (0x1, 0x1, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\S9B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\S9EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, S9B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (PWM1)
{
Name (_HID, "80860F09")
Name (_UID, 1)
Name (_DDN, "PWM Controller #1")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\SAB0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\SAEN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
}
Device (PWM2)
{
Name (_HID, "80860F09")
Name (_UID, 2)
Name (_DDN, "PWM Controller #2")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\SBB0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\SBEN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
}
Device (UAR1)
{
Name (_HID, "80860F0A")
Name (_UID, 1)
Name (_DDN, "HS-UART Controller #1")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_HSUART1_IRQ
}
FixedDMA (0x2, 0x2, Width32Bit, )
FixedDMA (0x3, 0x3, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\SCB0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\SCEN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, SCB1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (UAR2)
{
Name (_HID, "80860F0A")
Name (_UID, 2)
Name (_DDN, "HS-UART Controller #2")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPSS_HSUART2_IRQ
}
FixedDMA (0x4, 0x4, Width32Bit, )
FixedDMA (0x5, 0x5, Width32Bit, )
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\SDB0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\SDEN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, SDB1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}

View File

@ -0,0 +1,187 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 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 (EMMC)
{
Name (_HID, "80860F14")
Name (_CID, "PNP0D40")
Name (_UID, 1)
Name (_DDN, "eMMC Controller 4.5")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
SCC_EMMC_IRQ
}
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\C0B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\C0EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, C0B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Device (EM45)
{
/* Slot 0, Function 8 */
Name (_ADR, 0x8)
Method (_RMV, 0, NotSerialized)
{
Return (0)
}
}
}
Device (SDIO)
{
Name (_HID, "INT33BB")
Name (_CID, "PNP0D40")
Name (_UID, 2)
Name (_DDN, "SDIO Controller")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
SCC_SDIO_IRQ
}
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\C1B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\C1EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, C1B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
Device (SDCD)
{
Name (_HID, "80860F16")
Name (_CID, "PNP0D40")
Name (_UID, 3)
Name (_DDN, "SD Card Controller")
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
SCC_SD_IRQ
}
})
Method (_CRS)
{
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
Store (\C2B0, RBAS)
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\C2EN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, C2B1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
Method (_PS3)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_PS0)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}

View File

@ -20,6 +20,7 @@
*/ */
#include <soc/intel/baytrail/baytrail/iomap.h> #include <soc/intel/baytrail/baytrail/iomap.h>
#include <soc/intel/baytrail/baytrail/irq.h>
Scope(\) Scope(\)
{ {
@ -233,5 +234,14 @@ Method (_OSC, 4)
// IRQ routing for each PCI device // IRQ routing for each PCI device
#include "irqroute.asl" #include "irqroute.asl"
// GPIO Devices Scope (\_SB)
#include "gpio.asl" {
// GPIO Devices
#include "gpio.asl"
// LPSS Devices
#include "lpss.asl"
// SCC Devices
#include "scc.asl"
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 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>
#define LPSS_NVS_SIO_DMA1 0
#define LPSS_NVS_I2C1 1
#define LPSS_NVS_I2C2 2
#define LPSS_NVS_I2C3 3
#define LPSS_NVS_I2C4 4
#define LPSS_NVS_I2C5 5
#define LPSS_NVS_I2C6 6
#define LPSS_NVS_I2C7 7
#define LPSS_NVS_SIO_DMA2 8
#define LPSS_NVS_SPI 9
#define LPSS_NVS_PWM1 10
#define LPSS_NVS_PWM2 11
#define LPSS_NVS_HSUART1 12
#define LPSS_NVS_HSUART2 13
#define SCC_NVS_MMC 0
#define SCC_NVS_SDIO 1
#define SCC_NVS_SD 2
typedef struct {
/* Device Enabled in ACPI Mode */
u8 lpss_en[14];
u8 scc_en[3];
u8 lpe_en;
/* BAR 0 */
u32 lpss_bar0[14];
u32 scc_bar0[3];
u32 lpe_bar0;
/* BAR 0 */
u32 lpss_bar1[14];
u32 scc_bar1[3];
u32 lpe_bar1;
/* Extra */
u32 lpe_fw; /* LPE Firmware */
} __attribute__((packed)) device_nvs_t;

View File

@ -210,6 +210,15 @@ void iosf_scc_write(int reg, uint32_t val);
# define LPSS_CTL_NOSNOOP (1 << 19) # define LPSS_CTL_NOSNOOP (1 << 19)
# define LPSS_CTL_PM_CAP_PRSNT (1 << 1) # define LPSS_CTL_PM_CAP_PRSNT (1 << 1)
/*
* SCC Registers
*/
#define SCC_SD_CTL 0x504
#define SCC_SDIO_CTL 0x508
#define SCC_MMC_CTL 0x50c
# define SCC_CTL_PCI_CFG_DIS (1 << 0)
# define SCC_CTL_ACPI_INT_EN (1 << 1)
/* /*
* CCU Registers * CCU Registers
*/ */

View File

@ -45,9 +45,9 @@
#define LPSS_HSUART1_IRQ 39 #define LPSS_HSUART1_IRQ 39
#define LPSS_HSUART2_IRQ 40 #define LPSS_HSUART2_IRQ 40
#define LPSS_SPI_IRQ 41 #define LPSS_SPI_IRQ 41
#define LPSS_DMA2_IRQ 42 #define LPSS_DMA1_IRQ 42
#define LPSS_DMA1_IRQ 43 #define LPSS_DMA2_IRQ 43
#define SCC_EMMC_IRQ 45 #define SCC_EMMC_IRQ 44
#define SCC_SDIO_IRQ 46 #define SCC_SDIO_IRQ 46
#define SCC_SD_IRQ 47 #define SCC_SD_IRQ 47
#define GPIO_NC_IRQ 48 #define GPIO_NC_IRQ 48

View File

@ -18,7 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "vendorcode/google/chromeos/gnvs.h" #include <vendorcode/google/chromeos/gnvs.h>
#include <baytrail/device_nvs.h>
typedef struct { typedef struct {
/* Miscellaneous */ /* Miscellaneous */
u16 osys; /* 0x00 - Operating System */ u16 osys; /* 0x00 - Operating System */
@ -55,15 +57,13 @@ typedef struct {
u32 cmem; /* 0x30 - CBMEM TOC */ u32 cmem; /* 0x30 - CBMEM TOC */
u32 tolm; /* 0x34 - Top of Low Memory */ u32 tolm; /* 0x34 - Top of Low Memory */
u32 cbmc; /* 0x38 - coreboot memconsole */ u32 cbmc; /* 0x38 - coreboot memconsole */
u8 rsvd5[36]; u8 rsvd3[196];
/* Serial IO device BARs */ /* ChromeOS specific (0x100-0xfff)*/
u32 s0b[8]; /* 0x60 - 0x7f - BAR0 */
u32 s1b[8]; /* 0x80 - 0x9f - BAR1 */
u8 rsvd6[96];
/* ChromeOS specific (starts at 0x100)*/
chromeos_acpi_t chromeos; chromeos_acpi_t chromeos;
/* Baytrail LPSS (0x1000) */
device_nvs_t dev;
} __attribute__((packed)) global_nvs_t; } __attribute__((packed)) global_nvs_t;
#ifdef __SMM__ #ifdef __SMM__

View File

@ -34,6 +34,7 @@ void baytrail_run_reference_code(void);
static inline void baytrail_run_reference_code(void) {} static inline void baytrail_run_reference_code(void) {}
#endif #endif
void baytrail_init_scc(void); void baytrail_init_scc(void);
void scc_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index);
extern struct pci_operations soc_pci_ops; extern struct pci_operations soc_pci_ops;

View File

@ -56,6 +56,11 @@ struct soc_intel_baytrail_config {
uint32_t sdcard_cap_low; uint32_t sdcard_cap_low;
uint32_t sdcard_cap_high; uint32_t sdcard_cap_high;
/* Enable devices in ACPI mode */
int lpss_acpi_mode;
int scc_acpi_mode;
int lpe_acpi_mode;
/* /*
* Digital Port Hotplug Enable: * Digital Port Hotplug Enable:
* 0x04 = Enabled, 2ms short pulse * 0x04 = Enabled, 2ms short pulse

View File

@ -26,8 +26,10 @@
#include <reg_script.h> #include <reg_script.h>
#include <baytrail/iosf.h> #include <baytrail/iosf.h>
#include <baytrail/nvs.h>
#include <baytrail/pci_devs.h> #include <baytrail/pci_devs.h>
#include <baytrail/ramstage.h> #include <baytrail/ramstage.h>
#include "chip.h"
static const struct reg_script emmc_ops[] = { static const struct reg_script emmc_ops[] = {
/* Enable 2ms card stable feature. */ /* Enable 2ms card stable feature. */
@ -49,6 +51,7 @@ static const struct reg_script emmc_ops[] = {
static void emmc_init(device_t dev) static void emmc_init(device_t dev)
{ {
struct soc_intel_baytrail_config *config = dev->chip_info;
struct reg_script ops[] = { struct reg_script ops[] = {
REG_SCRIPT_SET_DEV(dev), REG_SCRIPT_SET_DEV(dev),
REG_SCRIPT_NEXT(emmc_ops), REG_SCRIPT_NEXT(emmc_ops),
@ -56,6 +59,9 @@ static void emmc_init(device_t dev)
}; };
printk(BIOS_DEBUG, "eMMC init\n"); printk(BIOS_DEBUG, "eMMC init\n");
reg_script_run(ops); reg_script_run(ops);
if (config->scc_acpi_mode)
scc_enable_acpi_mode(dev, SCC_MMC_CTL, SCC_NVS_MMC);
} }
static struct device_operations device_ops = { static struct device_operations device_ops = {

View File

@ -19,6 +19,7 @@
#include <stdint.h> #include <stdint.h>
#include <arch/io.h> #include <arch/io.h>
#include <cbmem.h>
#include <console/console.h> #include <console/console.h>
#include <device/device.h> #include <device/device.h>
#include <device/pci.h> #include <device/pci.h>
@ -26,9 +27,49 @@
#include <reg_script.h> #include <reg_script.h>
#include <baytrail/iosf.h> #include <baytrail/iosf.h>
#include <baytrail/nvs.h>
#include <baytrail/pci_devs.h> #include <baytrail/pci_devs.h>
#include <baytrail/ramstage.h> #include <baytrail/ramstage.h>
#include "chip.h"
static void dev_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index)
{
struct reg_script ops[] = {
REG_SCRIPT_SET_DEV(dev),
/* Disable PCI interrupt, enable Memory and Bus Master */
REG_PCI_OR32(PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
/* Enable ACPI mode */
REG_IOSF_OR(IOSF_PORT_LPSS, iosf_reg,
LPSS_CTL_PCI_CFG_DIS | LPSS_CTL_ACPI_INT_EN),
REG_SCRIPT_END
};
struct resource *bar;
global_nvs_t *gnvs;
/* 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 */
bar = find_resource(dev, PCI_BASE_ADDRESS_0);
if (bar)
gnvs->dev.lpss_bar0[nvs_index] = (u32)bar->base;
bar = find_resource(dev, PCI_BASE_ADDRESS_1);
if (bar)
gnvs->dev.lpss_bar1[nvs_index] = (u32)bar->base;
/* Device is enabled in ACPI mode */
gnvs->dev.lpss_en[nvs_index] = 1;
/* Put device in ACPI mode */
reg_script_run(ops);
}
static void dev_enable_snoop_and_pm(device_t dev, int iosf_reg) static void dev_enable_snoop_and_pm(device_t dev, int iosf_reg)
{ {
@ -43,12 +84,14 @@ static void dev_enable_snoop_and_pm(device_t dev, int iosf_reg)
reg_script_run(ops); reg_script_run(ops);
} }
static int dev_ctl_reg(device_t dev) static void dev_ctl_reg(device_t dev, int *iosf_reg, int *nvs_index)
{ {
int iosf_reg = -1; *iosf_reg = -1;
*nvs_index = -1;
#define SET_IOSF_REG(name_) \ #define SET_IOSF_REG(name_) \
case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC): \ case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC): \
iosf_reg = LPSS_ ## name_ ## _CTL *iosf_reg = LPSS_ ## name_ ## _CTL; \
*nvs_index = LPSS_NVS_ ## name_
switch (dev->path.pci.devfn) { switch (dev->path.pci.devfn) {
SET_IOSF_REG(SIO_DMA1); SET_IOSF_REG(SIO_DMA1);
@ -80,7 +123,6 @@ static int dev_ctl_reg(device_t dev)
SET_IOSF_REG(SPI); SET_IOSF_REG(SPI);
break; break;
} }
return iosf_reg;
} }
static void i2c_disable_resets(device_t dev) static void i2c_disable_resets(device_t dev)
@ -113,7 +155,10 @@ static void i2c_disable_resets(device_t dev)
static void lpss_init(device_t dev) static void lpss_init(device_t dev)
{ {
int iosf_reg = dev_ctl_reg(dev); struct soc_intel_baytrail_config *config = dev->chip_info;
int iosf_reg, nvs_index;
dev_ctl_reg(dev, &iosf_reg, &nvs_index);
if (iosf_reg < 0) { if (iosf_reg < 0) {
int slot = PCI_SLOT(dev->path.pci.devfn); int slot = PCI_SLOT(dev->path.pci.devfn);
@ -124,6 +169,9 @@ static void lpss_init(device_t dev)
} }
dev_enable_snoop_and_pm(dev, iosf_reg); dev_enable_snoop_and_pm(dev, iosf_reg);
if (config->lpss_acpi_mode)
dev_enable_acpi_mode(dev, iosf_reg, nvs_index);
i2c_disable_resets(dev); i2c_disable_resets(dev);
} }

View File

@ -18,10 +18,15 @@
*/ */
#include <cbmem.h>
#include <console/console.h> #include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <reg_script.h> #include <reg_script.h>
#include <baytrail/iosf.h> #include <baytrail/iosf.h>
#include <baytrail/nvs.h>
#include <baytrail/ramstage.h> #include <baytrail/ramstage.h>
static const struct reg_script scc_start_dll[] = { static const struct reg_script scc_start_dll[] = {
@ -81,3 +86,41 @@ void baytrail_init_scc(void)
reg_script_run(scc_after_dll); reg_script_run(scc_after_dll);
} }
void scc_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index)
{
struct reg_script ops[] = {
REG_SCRIPT_SET_DEV(dev),
/* Disable PCI interrupt, enable Memory and Bus Master */
REG_PCI_OR32(PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
/* Enable ACPI mode */
REG_IOSF_OR(IOSF_PORT_SCC, iosf_reg,
SCC_CTL_PCI_CFG_DIS | SCC_CTL_ACPI_INT_EN),
REG_SCRIPT_END
};
struct resource *bar;
global_nvs_t *gnvs;
/* 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 */
bar = find_resource(dev, PCI_BASE_ADDRESS_0);
if (bar)
gnvs->dev.scc_bar0[nvs_index] = (u32)bar->base;
bar = find_resource(dev, PCI_BASE_ADDRESS_1);
if (bar)
gnvs->dev.scc_bar1[nvs_index] = (u32)bar->base;
/* Device is enabled in ACPI mode */
gnvs->dev.scc_en[nvs_index] = 1;
/* Put device in ACPI mode */
reg_script_run(ops);
}

View File

@ -24,6 +24,8 @@
#include <device/pci_ids.h> #include <device/pci_ids.h>
#include <reg_script.h> #include <reg_script.h>
#include <baytrail/iosf.h>
#include <baytrail/nvs.h>
#include <baytrail/pci_devs.h> #include <baytrail/pci_devs.h>
#include <baytrail/ramstage.h> #include <baytrail/ramstage.h>
#include "chip.h" #include "chip.h"
@ -46,6 +48,9 @@ static void sd_init(device_t dev)
pci_write_config32(dev, CAP_OVERRIDE_HIGH, pci_write_config32(dev, CAP_OVERRIDE_HIGH,
config->sdcard_cap_high | USE_CAP_OVERRIDES); config->sdcard_cap_high | USE_CAP_OVERRIDES);
} }
if (config->scc_acpi_mode)
scc_enable_acpi_mode(dev, SCC_SD_CTL, SCC_NVS_SD);
} }
static const struct device_operations device_ops = { static const struct device_operations device_ops = {