Aaron Durbin (adurbin@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4926
-gerrit
commit a1850b032b69b609c565022953ac4ab15012d404 Author: Aaron Durbin adurbin@chromium.org Date: Wed Oct 30 17:07:46 2013 -0500
baytrail: HDA function disable workaround
Parts of the audio path are common between the HDA and LPE. However, those parts are power-controlled by the D-state of the HDA device. Therefore, one cannot put the HDA into D3Hot because those audio paths will be shutdown.
BUG=chrome-os-partner:22871 BRANCH=None TEST=Built and booted through depthcharge. Disabling HDA still causes a shutdown when performing warm reset, however I was able to verify the magic sequence was being performed.
Change-Id: I3b01356d85a4b7b902bd896b8eb9e7bc509fcc42 Signed-off-by: Aaron Durbin adurbin@chromium.org Reviewed-on: https://chromium-review.googlesource.com/175491 Reviewed-by: Duncan Laurie dlaurie@chromium.org --- src/soc/intel/baytrail/baytrail/iomap.h | 1 + src/soc/intel/baytrail/southcluster.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+)
diff --git a/src/soc/intel/baytrail/baytrail/iomap.h b/src/soc/intel/baytrail/baytrail/iomap.h index fa34105..d46a0fe 100644 --- a/src/soc/intel/baytrail/baytrail/iomap.h +++ b/src/soc/intel/baytrail/baytrail/iomap.h @@ -31,6 +31,7 @@ #define PUNIT_BASE_ADDRESS 0xfed05000 #define RCBA_BASE_ADDRESS 0xfed1c000 #define HPET_BASE_ADDRESS 0xfed00000 +#define TEMP_BASE_ADDRESS 0xfd000000
/* IO Port base */ #define ACPI_BASE_ADDRESS 0x0400 diff --git a/src/soc/intel/baytrail/southcluster.c b/src/soc/intel/baytrail/southcluster.c index 40d135b..ece99bf 100644 --- a/src/soc/intel/baytrail/southcluster.c +++ b/src/soc/intel/baytrail/southcluster.c @@ -217,10 +217,37 @@ static inline void set_d3hot_bits(device_t dev, int offset) pci_write_config8(dev, offset + 4, reg8); }
+/* Parts of the audio subsystem are powered by the HDA device. Therefore, one + * cannot put HDA into D3Hot. Instead perform this workaround to make some of + * the audio paths work for LPE audio. */ +static void hda_work_around(device_t dev) +{ + unsigned long gctl = TEMP_BASE_ADDRESS + 0x8; + + /* Need to set magic register 0x43 to 0xd7 in config space. */ + pci_write_config8(dev, 0x43, 0xd7); + + /* Need to set bit 0 of GCTL to take the device out of reset. However, + * that requires setting up the 64-bit BAR. */ + pci_write_config32(dev, PCI_BASE_ADDRESS_0, TEMP_BASE_ADDRESS); + pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0); + pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY); + write32(gctl, read32(gctl) | 0x1); + pci_write_config8(dev, PCI_COMMAND, 0); + pci_write_config32(dev, PCI_BASE_ADDRESS_0, 0); +} + static int place_device_in_d3hot(device_t dev) { unsigned offset;
+ /* Parts of the HDA block are used for LPE audio as well. + * Therefore assume the HDA will never be put into D3Hot. */ + if (dev->path.pci.devfn == PCI_DEVFN(HDA_DEV, HDA_FUNC)) { + hda_work_around(dev); + return 0; + } + offset = pci_find_capability(dev, PCI_CAP_ID_PM);
if (offset != 0) {