baytrail: Add support for LPE device in ACPI mode

This adds an ACPI Device entry for the LPE Audio controller
and code to put the device in ACPI mode if set in devicetree.cb

The ACPI device attempts to append GPIOs that may be defined in
the mainboard-supplied ACPI code.

BUG=chrome-os-partner:24380
BRANCH=baytrail
TEST=manual: Build and boot on rambi with LPE in ACPI mode.
Without kernel support this is not very useful but it did show
that the device was no longer visible as a PCI device.

Change-Id: I44d5423f5bbea77e156012c071df6cb335fe658b
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/184006
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Commit-Queue: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Duncan Laurie 2014-01-27 15:30:35 -08:00 committed by chrome-internal-fetch
commit 398387ed75
4 changed files with 179 additions and 0 deletions

View file

@ -0,0 +1,119 @@
/*
* 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 (LPEA)
{
Name (_HID, "80860F28")
Name (_CID, "80860F28")
Name (_UID, 1)
Name (_DDN, "Low Power Audio Controller")
Name (_PR0, Package () { PLPE })
Name (RBUF, ResourceTemplate()
{
Memory32Fixed (ReadWrite, 0, 0x00200000, BAR0)
Memory32Fixed (ReadWrite, 0, 0x00001000, BAR1)
Memory32Fixed (ReadWrite, 0, 0x00100000, BAR2)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPE_DMA0_IRQ
}
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPE_DMA1_IRQ
}
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPE_SSP0_IRQ
}
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPE_SSP1_IRQ
}
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPE_SSP2_IRQ
}
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
{
LPE_IPC2HOST_IRQ
}
})
Method (_CRS)
{
/* Update BAR0 from NVS */
CreateDwordField (^RBUF, ^BAR0._BAS, BAS0)
Store (\LPB0, BAS0)
/* Update BAR1 from NVS */
CreateDwordField (^RBUF, ^BAR1._BAS, BAS1)
Store (\LPB1, BAS1)
/* Update LPE FW from NVS */
CreateDwordField (^RBUF, ^BAR2._BAS, BAS2)
Store (\LPFW, BAS2)
/* Append any Mainboard defined GPIOs */
If (CondRefOf (^GBUF, Local0)) {
ConcatenateResTemplate (^RBUF, Local0, Local1)
Return (Local1)
}
Return (^RBUF)
}
Method (_STA)
{
If (LEqual (\LPEN, 1)) {
Return (0xF)
} Else {
Return (0x0)
}
}
OperationRegion (KEYS, SystemMemory, LPB1, 0x100)
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
{
Offset (0x84),
PSAT, 32,
}
PowerResource (PLPE, 0, 0)
{
Method (_STA)
{
Return (1)
}
Method (_OFF)
{
Or (PSAT, 0x00000003, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
Method (_ON)
{
And (PSAT, 0xfffffffc, PSAT)
Or (PSAT, 0x00000000, PSAT)
}
}
}

View file

@ -268,4 +268,7 @@ Scope (\_SB)
// SCC Devices
#include "scc.asl"
// LPE Device
#include "lpe.asl"
}

View file

@ -331,4 +331,11 @@ void iosf_ssus_write(int reg, uint32_t val);
#define USHPHY_REE_DAC_CONTROL 0x80b8
#define USHPHY_CDN_U1_POWER_STATE_DEF 0x0000
/*
* LPE Registers
*/
#define LPE_PCICFGCTR1 0x0500
# define LPE_PCICFGCTR1_PCI_CFG_DIS (1 << 0)
# define LPE_PCICFGCTR1_ACPI_INT_EN (1 << 1)
#endif /* _BAYTRAIL_IOSF_H_ */

View file

@ -18,12 +18,16 @@
*/
#include <arch/io.h>
#include <cbmem.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <reg_script.h>
#include <baytrail/iomap.h>
#include <baytrail/iosf.h>
#include <baytrail/nvs.h>
#include <baytrail/pci_devs.h>
#include <baytrail/pmc.h>
#include <baytrail/ramstage.h>
@ -37,6 +41,47 @@
#define FIRMWARE_REG_BASE 0xa8
#define FIRMWARE_REG_LENGTH 0xac
static void lpe_enable_acpi_mode(device_t dev)
{
static const struct reg_script ops[] = {
/* 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_0x58, LPE_PCICFGCTR1,
LPE_PCICFGCTR1_PCI_CFG_DIS |
LPE_PCICFGCTR1_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.lpe_bar0 = (u32)bar->base;
bar = find_resource(dev, PCI_BASE_ADDRESS_1);
if (bar)
gnvs->dev.lpe_bar1 = (u32)bar->base;
/* Save reserved firmware region */
gnvs->dev.lpe_fw = (u32)FIRMWARE_REG_BASE;
/* Device is enabled in ACPI mode */
gnvs->dev.lpe_en = 1;
/* Put device in ACPI mode */
reg_script_run_on_dev(dev, ops);
}
static void setup_codec_clock(device_t dev)
{
uint32_t reg;
@ -77,7 +122,12 @@ static void setup_codec_clock(device_t dev)
static void lpe_init(device_t dev)
{
struct soc_intel_baytrail_config *config = dev->chip_info;
setup_codec_clock(dev);
if (config->lpe_acpi_mode)
lpe_enable_acpi_mode(dev);
}
static void lpe_read_resources(device_t dev)