aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/baytrail/hda_verb.c
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2014-01-16 17:52:21 -0800
committerIsaac Christensen <isaac.christensen@se-eng.com>2014-09-18 01:23:14 +0200
commit51d787a5cf8b65aff0800743437443e416845655 (patch)
tree01bdc4c1864e4de68d87b487459aaf8d76e9cb90 /src/soc/intel/baytrail/hda_verb.c
parent1f279b68b6fe312b99b8969c659c87c57760c450 (diff)
rambi/baytrail: ACPI, GPIO, audio, misc updates
rambi: Change RAM_ID GPIOs to GPIO_INPUT Reviewed-on: https://chromium-review.googlesource.com/182934 (cherry picked from commit 8afd981a091a3711ff3b55520fe73f57f7258cc0) baytrail: initialize rtc device Reviewed-on: https://chromium-review.googlesource.com/183051 (cherry picked from commit 1b80d71e4942310bd7e83c5565c6a06c30811821) baytrail: Set SOC power budget values for SdpProfile 2&3 Reviewed-on: https://chromium-review.googlesource.com/183101 (cherry picked from commit 87d49323cac4492c23f910bd7d43b83b3c8a9b55) baytrail: Set PMC PTPS register correctly Reviewed-on: https://chromium-review.googlesource.com/183280 (cherry picked from commit 1b520b577f2bf1b124db301f57421665b637f9ad) baytrail: update to version 809 microcode for c0 Reviewed-on: https://chromium-review.googlesource.com/183256 (cherry picked from commit 8ed0ef4c3bed1196256c691be5b80563b81baa5e) baytrail: Add a shared GNVS init function Reviewed-on: https://chromium-review.googlesource.com/183332 (cherry picked from commit 969dffda1d3d0adaee58d604b6eeea13a41a408c) baytrail: Add basic support for ACPI System Wake Source Reviewed-on: https://chromium-review.googlesource.com/183333 (cherry picked from commit a6b85ad950fb3a51d12cb91c869420b72b433619) baytrail: allow configuration of io hole size Reviewed-on: https://chromium-review.googlesource.com/183269 (cherry picked from commit 95a79aff57ec7bf4bcbf0207a017c9dab10c1919) baytrail: add in C0 stepping idenitification support. Reviewed-on: https://chromium-review.googlesource.com/183594 (cherry picked from commit 8ad02684b25f2870cdea334fbd081f0ef4467cd4) baytrail: add option for enabling PS2 mode Reviewed-on: https://chromium-review.googlesource.com/183595 (cherry picked from commit c92db75de5edc2ff745c1d40155e8b654ad3d49f) rambi: enable PS2 mode for VNN and VCC Reviewed-on: https://chromium-review.googlesource.com/183596 (cherry picked from commit 821ce0e72c93adb60404a4dc4ff8c0f6285cbdf9) baytrail: add config option for disabling slp_x stretching Reviewed-on: https://chromium-review.googlesource.com/183587 (cherry picked from commit f99804c2649bef436644dd300be2a595659ceece) rambi: disable slp_x stretching after sus fail Reviewed-on: https://chromium-review.googlesource.com/183588 (cherry picked from commit 753fadb6b9e90fc8d1c5092d50b20a2826d8d880) baytrail: ACPI_ENABLE_WAKE_SUS_GPIO macro for ACPI Reviewed-on: https://chromium-review.googlesource.com/183597 (cherry picked from commit 78775098a87f46b3bb66ade124753a195a5fa906) rambi: fix trackpad and touchscreen wake sources Reviewed-on: https://chromium-review.googlesource.com/183598 (cherry picked from commit 3022c82b020f4cafeb5be7978eef6045d1408cd5) baytrail: Add support for LPE device in ACPI mode Reviewed-on: https://chromium-review.googlesource.com/184006 (cherry picked from commit 398387ed75a63ce5a6033239ac24b5e1d77c8c9f) rambi: Add LPE GPIOs for Jack/Mic detect Reviewed-on: https://chromium-review.googlesource.com/184007 (cherry picked from commit edde584bb23bae1e703481e0f33a1f036373a578) rambi: Set TSRx passive threshold to 60C Reviewed-on: https://chromium-review.googlesource.com/184008 (cherry picked from commit 1d6aeb85fd1af64d5f7c564c6709a1cf6daad5ee) baytrail: DPTF: Add PPCC object for power limit information Reviewed-on: https://chromium-review.googlesource.com/184158 (cherry picked from commit e9c002c393d8b4904f9d57c5c8e7cf1dfce5049b) baytrail: DPTF: Add _CRT/_PSV objects for the CPU participant Reviewed-on: https://chromium-review.googlesource.com/184442 (cherry picked from commit e04c20962aede1aa9e6899bd3072daa82e8613bd) rambi: Move the CPU passive/critical threshold config to DPTF Reviewed-on: https://chromium-review.googlesource.com/184443 (cherry picked from commit dda468793143a6d288981b6d7e1cd5ef4514c2ac) baytrail: Fix XHCI controller reset on resume Reviewed-on: https://chromium-review.googlesource.com/184500 (cherry picked from commit 0457b5dce1860709fcce1407e42ae83023b463cd) baytrail: update lpe audio firmware location Reviewed-on: https://chromium-review.googlesource.com/184481 (cherry picked from commit 0472e6bd45cb069fbe4939c6de499e03c3707ba6) rambi: Put LPSS devices in ACPI mode Reviewed-on: https://chromium-review.googlesource.com/184530 (cherry picked from commit 52bec109860b95e2d6260d5433f33d0923a05ce1) baytrail: initialize HDA device and HDMI codec Reviewed-on: https://chromium-review.googlesource.com/184710 (cherry picked from commit 393198705034aa9c6935615dda6eba8b6bd5c961) baytrail: provide GPIO_ACPI_WAKE configuration Reviewed-on: https://chromium-review.googlesource.com/184718 (cherry picked from commit 44558c3346f5b96cf7b3dcb25a23b4e99855497b) rambi: configure wake pins as just wake sources Reviewed-on: https://chromium-review.googlesource.com/184719 (cherry picked from commit ee4620a90a131dce49f96b2da7f0a3bb70b13115) baytrail: I2C: Add config data to ACPI Device Reviewed-on: https://chromium-review.googlesource.com/184922 (cherry picked from commit ffb73af007e77faf497fbc3321c8163d18c24ec8) Squashed 28 commits for rambi and baytrail. Change-Id: If6060681bb5dc9432a54e6f3c6af9d8080debad8 Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com> Reviewed-on: http://review.coreboot.org/6916 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@google.com>
Diffstat (limited to 'src/soc/intel/baytrail/hda_verb.c')
-rw-r--r--src/soc/intel/baytrail/hda_verb.c253
1 files changed, 253 insertions, 0 deletions
diff --git a/src/soc/intel/baytrail/hda_verb.c b/src/soc/intel/baytrail/hda_verb.c
new file mode 100644
index 0000000000..ae71b89770
--- /dev/null
+++ b/src/soc/intel/baytrail/hda_verb.c
@@ -0,0 +1,253 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2011 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 <console/console.h>
+#include <arch/io.h>
+#include <delay.h>
+#include <baytrail/hda_verb.h>
+
+/**
+ * Set bits in a register and wait for status
+ */
+static int set_bits(u32 port, u32 mask, u32 val)
+{
+ u32 reg32;
+ int count;
+
+ /* Write (val & mask) to port */
+ val &= mask;
+ reg32 = read32(port);
+ reg32 &= ~mask;
+ reg32 |= val;
+ write32(port, reg32);
+
+ /* Wait for readback of register to
+ * match what was just written to it
+ */
+ count = 50;
+ do {
+ /* Wait 1ms based on BKDG wait time */
+ mdelay(1);
+ reg32 = read32(port);
+ reg32 &= mask;
+ } while ((reg32 != val) && --count);
+
+ /* Timeout occurred */
+ if (!count)
+ return -1;
+ return 0;
+}
+
+/**
+ * Probe for supported codecs
+ */
+int hda_codec_detect(u32 base)
+{
+ u8 reg8;
+
+ /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
+ if (set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, HDA_GCTL_CRST) < 0)
+ goto no_codec;
+
+ /* Write back the value once reset bit is set. */
+ write16(base + HDA_GCAP_REG, read16(base + HDA_GCAP_REG));
+
+ /* Read in Codec location (BAR + 0xe)[2..0]*/
+ reg8 = read8(base + HDA_STATESTS_REG);
+ reg8 &= 0x0f;
+ if (!reg8)
+ goto no_codec;
+
+ return reg8;
+
+no_codec:
+ /* Codec Not found */
+ /* Put HDA back in reset (BAR + 0x8) [0] */
+ set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, 0);
+ printk(BIOS_DEBUG, "HDA: No codec!\n");
+ return 0;
+}
+
+/**
+ * Wait 50usec for the codec to indicate it is ready
+ * no response would imply that the codec is non-operative
+ */
+static int hda_wait_for_ready(u32 base)
+{
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+
+ while(timeout--) {
+ u32 reg32 = read32(base + HDA_ICII_REG);
+ if (!(reg32 & HDA_ICII_BUSY))
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+/**
+ * Wait 50usec for the codec to indicate that it accepted
+ * the previous command. No response would imply that the code
+ * is non-operative
+ */
+static int hda_wait_for_valid(u32 base)
+{
+ u32 reg32;
+
+ /* Send the verb to the codec */
+ reg32 = read32(base + HDA_ICII_REG);
+ reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
+ write32(base + HDA_ICII_REG, reg32);
+
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+ while(timeout--) {
+ reg32 = read32(base + HDA_ICII_REG);
+ if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
+ HDA_ICII_VALID)
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+/**
+ * Find a specific entry within a verb table
+ *
+ * @verb_table_bytes: verb table size in bytes
+ * @verb_table_data: verb table data
+ * @viddid: vendor/device to search for
+ * @verb_out: pointer to entry within table
+ *
+ * Returns size of the entry within the verb table,
+ * Returns 0 if the entry is not found
+ *
+ * The HDA verb table is composed of dwords. A set of 4 dwords is
+ * grouped together to form a "jack" descriptor.
+ * Bits 31:28 - Codec Address
+ * Bits 27:20 - NID
+ * Bits 19:8 - Verb ID
+ * Bits 7:0 - Payload
+ *
+ * coreboot groups different codec verb tables into a single table
+ * and prefixes each with a specific header consisting of 3
+ * dword entries:
+ * 1 - Codec Vendor/Device ID
+ * 2 - Subsystem ID
+ * 3 - Number of jacks (groups of 4 dwords) for this codec
+ */
+static u32 hda_find_verb(u32 verb_table_bytes,
+ const u32 *verb_table_data,
+ u32 viddid, const u32 ** verb)
+{
+ int idx=0;
+
+ while (idx < (verb_table_bytes / sizeof(u32))) {
+ u32 verb_size = 4 * verb_table_data[idx+2]; // in u32
+ if (verb_table_data[idx] != viddid) {
+ idx += verb_size + 3; // skip verb + header
+ continue;
+ }
+ *verb = &verb_table_data[idx+3];
+ return verb_size;
+ }
+
+ /* Not all codecs need to load another verb */
+ return 0;
+}
+
+/**
+ * Write a supplied verb table
+ */
+int hda_codec_write(u32 base, u32 size, const u32 *data)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (hda_wait_for_ready(base) < 0)
+ return -1;
+
+ write32(base + HDA_IC_REG, data[i]);
+
+ if (hda_wait_for_valid(base) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Initialize codec, then find the verb table and write it
+ */
+int hda_codec_init(u32 base, int addr, int verb_size, const u32 *verb_data)
+{
+ const u32 *verb;
+ u32 reg32, size;
+ int rc;
+
+ printk(BIOS_DEBUG, "HDA: Initializing codec #%d\n", addr);
+
+ if (!verb_size || !verb_data) {
+ printk(BIOS_DEBUG, "HDA: No verb list!\n");
+ return -1;
+ }
+
+ /* 1 */
+ if (hda_wait_for_ready(base) < 0) {
+ printk(BIOS_DEBUG, " codec not ready.\n");
+ return -1;
+ }
+
+ reg32 = (addr << 28) | 0x000f0000;
+ write32(base + HDA_IC_REG, reg32);
+
+ if (hda_wait_for_valid(base) < 0) {
+ printk(BIOS_DEBUG, " codec not valid.\n");
+ return -1;
+ }
+
+ /* 2 */
+ reg32 = read32(base + HDA_IR_REG);
+ printk(BIOS_DEBUG, "HDA: codec viddid: %08x\n", reg32);
+
+ size = hda_find_verb(verb_size, verb_data, reg32, &verb);
+ if (!size) {
+ printk(BIOS_DEBUG, "HDA: No verb table entry found\n");
+ return -1;
+ }
+
+ /* 3 */
+ rc = hda_codec_write(base, size, verb);
+
+ if (rc < 0)
+ printk(BIOS_DEBUG, "HDA: verb not loaded\n");
+ else
+ printk(BIOS_DEBUG, "HDA: verb loaded.\n");
+
+ return rc;
+}