Saurabh Satija (saurabh.satija(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15484
-gerrit
commit 1200d122a62b63828003b99430aaadde63cf8329
Author: Saurabh Satija <saurabh.satija(a)intel.com>
Date: Tue Jun 28 12:32:39 2016 -0700
soc/intel/apollolake: Add NHLT blobs configuration settings
Select ACPI_NHLT and add configuration settings for NHLT audio
blobs for Intel Apollolake SoC. These configs are set in mainboard
for including NHLT audio blobs in cbfs. The following audio blobs
configs are added:
NHLT_DMIC_2CH_16B
NHLT_MAX98357
NHLT_DA7219
Change-Id: Ieebf535b584919d6551bde0f2ee691a93eb9e57e
Signed-off-by: Saurabh Satija <saurabh.satija(a)intel.com>
---
src/soc/intel/apollolake/Kconfig | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig
index d830a9f..9bc199d 100644
--- a/src/soc/intel/apollolake/Kconfig
+++ b/src/soc/intel/apollolake/Kconfig
@@ -17,6 +17,8 @@ config CPU_SPECIFIC_OPTIONS
select SMP
select SSE2
select SUPPORT_CPU_UCODE_IN_CBFS
+ # Audio options
+ select ACPI_NHLT
# Misc options
select C_ENVIRONMENT_BOOTBLOCK
select COLLECT_TIMESTAMPS
@@ -184,4 +186,25 @@ config IFWI_FILE_NAME
help
Name of file to store in the IFWI region.
+config NHLT_DMIC_2CH_16B
+ bool
+ depends on ACPI_NHLT
+ default n
+ help
+ Include DSP firmware settings for 2 channel 16B DMIC array.
+
+config NHLT_MAX98357
+ bool
+ depends on ACPI_NHLT
+ default n
+ help
+ Include DSP firmware settings for headset codec.
+
+config NHLT_DA7219
+ bool
+ depends on ACPI_NHLT
+ default n
+ help
+ Include DSP firmware settings for headset codec.
+
endif
Saurabh Satija (saurabh.satija(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15026
-gerrit
commit 2b52ee0d1e37fc75e521256504a4f33b435903f3
Author: Saurabh Satija <saurabh.satija(a)intel.com>
Date: Tue Mar 8 17:33:29 2016 -0800
apollolake: Add ACPI device for audio controller
Add the audio controller device to ACPI and define the _DSM handler
to return the address of the NHLT table, if set in NVS.
Change-Id: I619dbfb562b94255e42a3e5d5a3926c28b14db3e
Signed-off-by: Saurabh Satija <saurabh.satija(a)intel.com>
---
src/soc/intel/apollolake/acpi/pch_hda.asl | 84 +++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/src/soc/intel/apollolake/acpi/pch_hda.asl b/src/soc/intel/apollolake/acpi/pch_hda.asl
new file mode 100644
index 0000000..33cd771
--- /dev/null
+++ b/src/soc/intel/apollolake/acpi/pch_hda.asl
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corporation.
+ * Copyright (C) 2016 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.
+ *
+ */
+
+/* Audio Controller - Device 14, Function 0 */
+
+Device (HDAS)
+{
+ Name (_ADR, 0x000E0000)
+ Name (_DDN, "Audio Controller")
+ Name (UUID, ToUUID("A69F886E-6CEB-4594-A41F-7B5DCE24C553"))
+
+ /* Device is D3 wake capable */
+ Name (_S0W, 3)
+
+ /* NHLT Table Address populated from GNVS values */
+ Name (NBUF, ResourceTemplate() {
+ QWordMemory (ResourceConsumer, PosDecode, MinFixed,
+ MaxFixed, Cacheable, ReadOnly,
+ 0, 0, 0, 0, 1,,, NHLT, AddressRangeACPI)
+ }
+ )
+
+ /*
+ * Device Specific Method
+ * Arg0 - UUID
+ * Arg1 - Revision
+ * Arg2 - Function Index
+ */
+ Method (_DSM, 4) {
+ If (LEqual (Arg0, ^UUID)) {
+ /*
+ * Function 0: Function Support Query
+ * Returns a bitmask of functions supported.
+ */
+ If (LEqual (Arg2, Zero)) {
+ /*
+ * NHLT Query only supported for revision 1 and
+ * if NHLT address and length are set in NVS.
+ */
+ If (LAnd (LEqual (Arg1, One),
+ LAnd (LNotEqual (NHLA, Zero),
+ LNotEqual (NHLL, Zero)))) {
+ Return (Buffer (One) { 0x03 })
+ }
+ Else {
+ Return (Buffer (One) { 0x01 })
+ }
+ }
+
+ /*
+ * Function 1: Query NHLT memory address used by
+ * Intel Offload Engine Driver to discover any non-HDA
+ * devices that are supported by the DSP.
+ *
+ * Returns a pointer to NHLT table in memory.
+ */
+ If (LEqual (Arg2, One)) {
+ CreateQWordField (NBUF, ^NHLT._MIN, NBAS)
+ CreateQWordField (NBUF, ^NHLT._MAX, NMAS)
+ CreateQWordField (NBUF, ^NHLT._LEN, NLEN)
+ Store (NHLA, NBAS)
+ Store (NHLA, NMAS)
+ Store (NHLL, NLEN)
+ Return (NBUF)
+ }
+ }
+
+ Return (Buffer (One) { 0x00 })
+ }
+}
Saurabh Satija (saurabh.satija(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15311
-gerrit
commit 3090705e872827b2726f71dc0c954400a6267289
Author: Saurabh Satija <saurabh.satija(a)intel.com>
Date: Tue Jun 21 14:22:16 2016 -0700
soc/intel/apollolake: Add NHLT add codec APIs and device/vendor ids
nhlt_add_<codec>_on_ssp uses codec configs, tdm configs and add the
particular codec on a SSP port specified by mainboard.
get_nhlt_link_type() returns a corresponding NHLT link type based on
audio soc hardware interface passed as an argument.
Also define vendor id for NHLT and device ids for NHLT Bluetooth,
DMIC & SSPs. These ids are used to add NHLT endpoints for different
audio codecs. These ids are platform dependent.
Change-Id: Ic9bd26ebe8d6df60af23733e122fd8f3c0432e1f
Signed-off-by: Saurabh Satija <saurabh.satija(a)intel.com>
---
src/soc/intel/apollolake/Makefile.inc | 1 +
src/soc/intel/apollolake/include/soc/nhlt.h | 39 +++++++++
src/soc/intel/apollolake/nhlt.c | 130 ++++++++++++++++++++++++++++
3 files changed, 170 insertions(+)
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index 38ed07d..c335e39 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -55,6 +55,7 @@ ramstage-y += pmutil.c
ramstage-y += pmc.c
ramstage-y += smi.c
ramstage-y += reset.c
+ramstage-y += nhlt.c
postcar-y += exit_car.S
postcar-y += memmap.c
diff --git a/src/soc/intel/apollolake/include/soc/nhlt.h b/src/soc/intel/apollolake/include/soc/nhlt.h
new file mode 100644
index 0000000..cc6486b
--- /dev/null
+++ b/src/soc/intel/apollolake/include/soc/nhlt.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corp.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_APOLLOLAKE_NHLT_H_
+#define _SOC_APOLLOLAKE_NHLT_H_
+
+#define NHLT_VID 0x8086
+#define NHLT_DID_DMIC 0xae20
+#define NHLT_DID_BT 0xae30
+#define NHLT_DID_SSP 0xae34
+
+enum {
+ AUDIO_LINK_SSP0,
+ AUDIO_LINK_SSP1,
+ AUDIO_LINK_SSP2,
+ AUDIO_LINK_SSP3,
+ AUDIO_LINK_SSP4,
+ AUDIO_LINK_SSP5,
+ AUDIO_LINK_DMIC,
+};
+
+int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels);
+int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink);
+int nhlt_soc_add_da7219(struct nhlt *nhlt, int hwlink);
+
+#endif
diff --git a/src/soc/intel/apollolake/nhlt.c b/src/soc/intel/apollolake/nhlt.c
new file mode 100644
index 0000000..87fc65a
--- /dev/null
+++ b/src/soc/intel/apollolake/nhlt.c
@@ -0,0 +1,130 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corp.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <nhlt.h>
+#include <soc/nhlt.h>
+
+static const struct nhlt_format_config dmic_2ch_cfg[] = {
+ /* 48 KHz 16-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 16,
+ .valid_bits_per_sample = 16,
+ .settings_file = "dmic-2ch-48khz-16b.bin",
+ },
+};
+
+static const struct nhlt_format_config da7219_cfg[] = {
+ /* 48 KHz 24-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 24,
+ .settings_file = "dialog-2ch-48khz-24b.bin",
+ },
+};
+
+static const struct nhlt_tdm_config tdm_cfg = {
+ .virtual_slot = 0,
+ .config_type = NHLT_TDM_BASIC,
+};
+
+static const struct nhlt_format_config max98357_cfg[] = {
+ /* 48 KHz 24-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 24,
+ .settings_file = "max98357-render-2ch-48khz-24b.bin",
+ },
+};
+
+int nhlt_soc_get_link_type(int hwlink, int soc_devtype)
+{
+ int nhlt_link_type;
+
+ switch (hwlink) {
+ case AUDIO_LINK_SSP0:
+ case AUDIO_LINK_SSP1:
+ case AUDIO_LINK_SSP3:
+ case AUDIO_LINK_SSP4:
+ case AUDIO_LINK_SSP5:
+ /* Only I2S devices. */
+ if (soc_devtype != AUDIO_DEV_I2S)
+ return -1;
+ nhlt_link_type = NHLT_LINK_SSP;
+ break;
+ case AUDIO_LINK_SSP2:
+ /* Only Bluetooth devices on SSP2. */
+ if (soc_devtype != AUDIO_DEV_BT)
+ return -1;
+ nhlt_link_type = NHLT_LINK_SSP;
+ break;
+ case AUDIO_LINK_DMIC:
+ // Only DMIC devices on DMIC links.
+ if (soc_devtype != AUDIO_DEV_DMIC)
+ return -1;
+ nhlt_link_type = NHLT_LINK_PDM;
+ break;
+ default:
+ return -1;
+ }
+
+ return nhlt_link_type;
+}
+
+int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels)
+{
+ if (num_channels != 2) {
+ printk(BIOS_ERR, "APL only supports 2CH DMIC array.\n");
+ return -1;
+ }
+
+ if (nhlt_add_dmic_array(nhlt, num_channels, dmic_2ch_cfg,
+ ARRAY_SIZE(dmic_2ch_cfg))) {
+ printk(BIOS_ERR, "Couldn't add 2CH DMIC array.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink)
+{
+ if (nhlt_add_codec_on_ssp(nhlt, hwlink, max98357_cfg,
+ ARRAY_SIZE(max98357_cfg), NULL, 0, NULL, 0)) {
+ printk(BIOS_ERR, "Couldn't add Maxim_98357 codec.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int nhlt_soc_add_da7219(struct nhlt *nhlt, int hwlink)
+{
+ if (nhlt_add_codec_on_ssp(nhlt, hwlink, da7219_cfg,
+ ARRAY_SIZE(da7219_cfg), da7219_cfg, ARRAY_SIZE(da7219_cfg), &tdm_cfg,
+ sizeof(tdm_cfg))) {
+ printk(BIOS_ERR, "Couldn't add Dialog_7219 codec.\n");
+ return -1;
+ }
+
+ return 0;
+}
Saurabh Satija (saurabh.satija(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15023
-gerrit
commit 21b049a404969f9b0d00cf19d75655b043b83b25
Author: Saurabh Satija <saurabh.satija(a)intel.com>
Date: Thu Jun 23 14:46:27 2016 -0700
lib/nhlt: Add common NHLT audio for Intel platforms
The use of a NHLT table is required to make audio work
on the Intel SoCs employing the internal DSP. The table
describes the audio endpoints (render vs capture) along with
their supported formats. These formats are not only dependent
on the audio peripheral but also hardware interfaces. As such
each format has an associated blob of DSP settings to make
the peripheral work. Lastly, each of these settings are provided
by Intel and need to be generated for each device's hardware
connection plus mode/format it supports. This patch does not
include the DSP setting blobs.
Change-Id: I3c75d3537288c47d29e8949ca253ea8c5c1a387d
Signed-off-by: Saurabh Satija <saurabh.satija(a)intel.com>
---
src/include/nhlt.h | 45 +++++++++++++++++++++++++++
src/lib/nhlt.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/src/include/nhlt.h b/src/include/nhlt.h
index f0b3b6f..20d20ed 100644
--- a/src/include/nhlt.h
+++ b/src/include/nhlt.h
@@ -23,6 +23,51 @@ struct nhlt;
struct nhlt_endpoint;
struct nhlt_format;
struct nhlt_format_config;
+struct nhlt_tdm_config;
+
+/*
+ * NHLT device types. These values are used with nhlt_soc_add_endpoint().
+ */
+enum {
+ AUDIO_DEV_I2S,
+ AUDIO_DEV_DMIC,
+ AUDIO_DEV_BT,
+};
+
+/*
+ * Returns corresponding nhlt link type based on hardware link number.
+ * Hardware link number is the SSP port number on which the particular
+ * is present, which is mainboard specfic.
+ * nhlt_soc_get_link_type() is SoC specific.
+ */
+int nhlt_soc_get_link_type(int hwlink, int soc_devtype);
+
+/*
+ * Add a dmic array composed of the provided number of channels.
+ * Returns 0 on success, < 0 on error.
+ */
+int nhlt_add_dmic_array(struct nhlt *nhlt, int num_channels,
+ const struct nhlt_format_config *dmic_ch_config, int num_fmt);
+
+/*
+ * Add audio codec on provided SSP link. Return 0 on succes, < 0 on error.
+ *
+ * The same DSP firmware settings can be used for both the capture and render
+ * endpoints in some cases. Most of the smart amps use different DSP firmware
+ * settings for capture and render endpoints.
+ *
+ * render_cfg, capture_cfg: These are the audio codec configuration defined
+ * in mainboard souce code.
+ * cfg_size: This is the number of configurations defined in codec config.
+ * Each configuration is added as an endpoint.
+ * tdm_config: This is also board specific and defined in mainboard.c
+ * hwlink: This is the SSP hardware port number.
+ * direction: This can be Render only, Capture only or Bi-directional.
+ */
+int nhlt_add_codec_on_ssp(struct nhlt *nhlt, int hwlink,
+ const struct nhlt_format_config *render_cfg, int r_num_fmt,
+ const struct nhlt_format_config *capture_cfg, int c_num_fmt,
+ const struct nhlt_tdm_config *tdm_config, size_t tdm_size);
/*
* Non HD Audio ACPI support. This table is typically used for Intel Smart
diff --git a/src/lib/nhlt.c b/src/lib/nhlt.c
index d9107ee..3883b32 100644
--- a/src/lib/nhlt.c
+++ b/src/lib/nhlt.c
@@ -15,9 +15,12 @@
#include <arch/acpi.h>
#include <cbfs.h>
+#include <cbmem.h>
#include <commonlib/endian.h>
#include <console/console.h>
#include <nhlt.h>
+#include <soc/nvs.h>
+#include <soc/nhlt.h>
#include <stdlib.h>
#include <string.h>
@@ -47,8 +50,7 @@ struct nhlt *nhlt_init(void)
}
struct nhlt_endpoint *nhlt_add_endpoint(struct nhlt *nhlt, int link_type,
- int device_type, int dir,
- uint16_t vid, uint16_t did)
+ int device_type, int dir, uint16_t vid, uint16_t did)
{
struct nhlt_endpoint *endp;
@@ -503,3 +505,88 @@ uintptr_t nhlt_soc_serialize_oem_overrides(struct nhlt *nhlt,
return nhlt_serialize_oem_overrides(nhlt, acpi_addr, oem_id,
oem_table_id);
}
+
+int nhlt_add_dmic_array(struct nhlt *nhlt, int num_channels,
+ const struct nhlt_format_config *dmic_ch_cfg, int num_fmt)
+{
+ struct nhlt_endpoint *endp;
+ struct nhlt_dmic_array_config mic_config;
+
+ if (num_channels != 2 && num_channels != 4)
+ return -1;
+
+ endp = nhlt_soc_add_endpoint(nhlt, AUDIO_LINK_DMIC, AUDIO_DEV_DMIC,
+ NHLT_DIR_CAPTURE);
+
+ if (endp == NULL)
+ return -1;
+
+ memset(&mic_config, 0, sizeof(mic_config));
+ mic_config.tdm_config.config_type = NHLT_TDM_MIC_ARRAY;
+
+ switch (num_channels) {
+ case 2:
+ mic_config.array_type = NHLT_MIC_ARRAY_2CH_SMALL;
+ break;
+ case 4:
+ mic_config.array_type = NHLT_MIC_ARRAY_4CH_L_SHAPED;
+ break;
+ }
+
+ if (nhlt_endpoint_append_config(endp, &mic_config, sizeof(mic_config)))
+ return -1;
+
+ return nhlt_endpoint_add_formats(endp, dmic_ch_cfg, num_fmt);
+}
+
+int nhlt_add_codec_on_ssp(struct nhlt *nhlt, int hwlink,
+ const struct nhlt_format_config *render_cfg, int r_num_fmt,
+ const struct nhlt_format_config *capture_cfg, int c_num_fmt,
+ const struct nhlt_tdm_config *tdm_config, size_t tdm_size)
+{
+ struct nhlt_endpoint *endp;
+
+ /* For Bi-directional amplifiers, both capture and render
+ * configuratoins are needed.
+ */
+ if (render_cfg == NULL && capture_cfg == NULL)
+ return -1;
+
+ /* Render Endpoint */
+ if (render_cfg != NULL) {
+ endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
+ NHLT_DIR_RENDER);
+ if (endp == NULL)
+ return -1;
+
+ if (tdm_config != NULL) {
+ if (nhlt_endpoint_append_config(endp, tdm_config,
+ tdm_size))
+ return -1;
+ }
+
+ if (nhlt_endpoint_add_formats(endp, render_cfg, r_num_fmt))
+ return -1;
+ }
+
+ /* Capture Endpoint */
+ if (capture_cfg != NULL) {
+ endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
+ NHLT_DIR_CAPTURE);
+ if (endp == NULL)
+ return -1;
+
+ if (tdm_config != NULL) {
+ if (nhlt_endpoint_append_config(endp, tdm_config,
+ tdm_size))
+ return -1;
+ }
+
+ if (nhlt_endpoint_add_formats(endp, capture_cfg, c_num_fmt))
+ return -1;
+ }
+
+ nhlt_next_instance(nhlt, NHLT_LINK_SSP);
+
+ return 0;
+}