summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/soc/intel/skylake/Kconfig31
-rw-r--r--src/soc/intel/skylake/Makefile.inc1
-rw-r--r--src/soc/intel/skylake/include/soc/nhlt.h64
-rw-r--r--src/soc/intel/skylake/nhlt/Makefile.inc43
-rw-r--r--src/soc/intel/skylake/nhlt/dmic.c99
-rw-r--r--src/soc/intel/skylake/nhlt/max98357.c48
-rw-r--r--src/soc/intel/skylake/nhlt/nau88l25.c73
-rw-r--r--src/soc/intel/skylake/nhlt/nhlt.c102
-rw-r--r--src/soc/intel/skylake/nhlt/ssm4567.c48
9 files changed, 509 insertions, 0 deletions
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index 1f7be57642..76459c9bca 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -11,6 +11,7 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_RAMSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_VERSTAGE_X86_32
+ select ACPI_NHLT
select BACKUP_DEFAULT_SMM_REGION
select CACHE_MRC_SETTINGS
select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM if RELOCATABLE_RAMSTAGE
@@ -139,4 +140,34 @@ config CHIPSET_BOOTBLOCK_INCLUDE
string
default "soc/intel/skylake/bootblock/timestamp.inc"
+config NHLT_DMIC_2CH
+ bool
+ default n
+ help
+ Include DSP firmware settings for 2 channel DMIC array.
+
+config NHLT_DMIC_4CH
+ bool
+ default n
+ help
+ Include DSP firmware settings for 4 channel DMIC array.
+
+config NHLT_NAU88L25
+ bool
+ default n
+ help
+ Include DSP firmware settings for nau88l25 headset codec.
+
+config NHLT_MAX98357
+ bool
+ default n
+ help
+ Include DSP firmware settings for max98357 amplifier.
+
+config NHLT_SSM4567
+ bool
+ default n
+ help
+ Include DSP firmware settings for ssm4567 smart amplifier.
+
endif
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index 9dd4cac8c3..d6c2212310 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -1,5 +1,6 @@
ifeq ($(CONFIG_SOC_INTEL_SKYLAKE),y)
+subdirs-y += nhlt
subdirs-y += romstage
subdirs-y += ../../../cpu/intel/microcode
subdirs-y += ../../../cpu/intel/turbo
diff --git a/src/soc/intel/skylake/include/soc/nhlt.h b/src/soc/intel/skylake/include/soc/nhlt.h
new file mode 100644
index 0000000000..3800bb978d
--- /dev/null
+++ b/src/soc/intel/skylake/include/soc/nhlt.h
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#ifndef _SOC_NHLT_H_
+#define _SOC_NHLT_H_
+
+#include <nhlt.h>
+
+/*
+ * Skylake NHLT device and hardware link types. These values are to be used
+ * with nhlt_soc_add_endpoint().
+ */
+
+enum {
+ AUDIO_LINK_SSP0,
+ AUDIO_LINK_SSP1,
+ AUDIO_LINK_SSP2, /* Only Bluetooth supported on SSP2. */
+ AUDIO_LINK_DMIC,
+};
+
+enum {
+ AUDIO_DEV_I2S,
+ AUDIO_DEV_DMIC,
+ AUDIO_DEV_BT,
+};
+
+/*
+ * Add a dmic array composed of the provided number of channels. The skylake
+ * SoC currently only supports dmic arrays on the dmic signals. Either 2
+ * or 4 channel arrays are supported. Returns 0 on success, < 0 on error.
+ */
+int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels);
+
+/*
+ * Add nau88l25 headset codec on provided SSP link. Return 0 on succes, < 0
+ * on error.
+ */
+int nhlt_soc_add_nau88l25(struct nhlt *nhlt, int hwlink);
+
+/*
+ * Add ssm4567 smart amplifiers in stereo configuration on provided SSP link.
+ * Return 0 on success, < 0 on error.
+ */
+int nhlt_soc_add_ssm4567(struct nhlt *nhlt, int hwlink);
+
+/*
+ * Add max98357a amplifier in stereo configuration on provide SSP link.
+ * Return 0 on success, < 0 on error.
+ */
+int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink);
+
+#endif
diff --git a/src/soc/intel/skylake/nhlt/Makefile.inc b/src/soc/intel/skylake/nhlt/Makefile.inc
new file mode 100644
index 0000000000..201dad5328
--- /dev/null
+++ b/src/soc/intel/skylake/nhlt/Makefile.inc
@@ -0,0 +1,43 @@
+ramstage-y += nhlt.c
+ramstage-y += dmic.c
+ramstage-y += nau88l25.c
+ramstage-y += max98357.c
+ramstage-y += ssm4567.c
+
+# DSP firmware settings files.
+NHLT_BLOB_PATH = 3rdparty/blobs/soc/intel/skylake
+DMIC_2CH_48KHZ_16B = dmic-2ch-48khz-16b.bin
+DMIC_2CH_48KHZ_32B = dmic-2ch-48khz-32b.bin
+DMIC_4CH_48KHZ_16B = dmic-4ch-48khz-16b.bin
+DMIC_4CH_48KHZ_32B = dmic-4ch-48khz-32b.bin
+NAU88L25 = nau88l25-2ch-48khz-24b.bin
+MAX98357_RENDER = max98357-render-2ch-48khz-24b.bin
+SSM4567_RENDER = ssm4567-render-2ch-48khz-24b.bin
+
+cbfs-files-$(CONFIG_NHLT_DMIC_2CH) += $(DMIC_2CH_48KHZ_16B)
+$(DMIC_2CH_48KHZ_16B)-file := $(NHLT_BLOB_PATH)/$(DMIC_2CH_48KHZ_16B)
+$(DMIC_2CH_48KHZ_16B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_DMIC_2CH) += $(DMIC_2CH_48KHZ_32B)
+$(DMIC_2CH_48KHZ_32B)-file := $(NHLT_BLOB_PATH)/$(DMIC_2CH_48KHZ_32B)
+$(DMIC_2CH_48KHZ_32B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_DMIC_4CH) += $(DMIC_4CH_48KHZ_16B)
+$(DMIC_4CH_48KHZ_16B)-file := $(NHLT_BLOB_PATH)/$(DMIC_4CH_48KHZ_16B)
+$(DMIC_4CH_48KHZ_16B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_DMIC_4CH) += $(DMIC_4CH_48KHZ_32B)
+$(DMIC_4CH_48KHZ_32B)-file := $(NHLT_BLOB_PATH)/$(DMIC_4CH_48KHZ_32B)
+$(DMIC_4CH_48KHZ_32B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_NAU88L25) += $(NAU88L25)
+$(NAU88L25)-file := $(NHLT_BLOB_PATH)/$(NAU88L25)
+$(NAU88L25)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_MAX98357) += $(MAX98357_RENDER)
+$(MAX98357_RENDER)-file := $(NHLT_BLOB_PATH)/$(MAX98357_RENDER)
+$(MAX98357_RENDER)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_SSM4567) += $(SSM4567_RENDER)
+$(SSM4567_RENDER)-file := $(NHLT_BLOB_PATH)/$(SSM4567_RENDER)
+$(SSM4567_RENDER)-type := raw
diff --git a/src/soc/intel/skylake/nhlt/dmic.c b/src/soc/intel/skylake/nhlt/dmic.c
new file mode 100644
index 0000000000..0aadbb20df
--- /dev/null
+++ b/src/soc/intel/skylake/nhlt/dmic.c
@@ -0,0 +1,99 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <soc/nhlt.h>
+#include <string.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,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "dmic-2ch-48khz-16b.bin",
+ },
+ /* 48 KHz 32-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 32,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "dmic-2ch-48khz-32b.bin",
+ },
+};
+
+static const struct nhlt_format_config dmic_4ch_cfg[] = {
+ /* 48 KHz 16-bits per sample. */
+ {
+ .num_channels = 4,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 16,
+ .valid_bits_per_sample = 16,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
+ SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
+ .settings_file = "dmic-4ch-48khz-16b.bin",
+ },
+ /* 48 KHz 32-bits per sample. */
+ {
+ .num_channels = 4,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 32,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
+ SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
+ .settings_file = "dmic-4ch-48khz-32b.bin",
+ },
+};
+
+int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels)
+{
+ struct nhlt_endpoint *endp;
+ struct nhlt_dmic_array_config mic_config;
+ const struct nhlt_format_config *formats;
+ size_t num_formats;
+
+ 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:
+ formats = dmic_2ch_cfg;
+ num_formats = ARRAY_SIZE(dmic_2ch_cfg);
+ mic_config.array_type = NHLT_MIC_ARRAY_2CH_SMALL;
+ break;
+ case 4:
+ formats = dmic_4ch_cfg;
+ num_formats = ARRAY_SIZE(dmic_4ch_cfg);
+ 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, formats, num_formats);
+}
diff --git a/src/soc/intel/skylake/nhlt/max98357.c b/src/soc/intel/skylake/nhlt/max98357.c
new file mode 100644
index 0000000000..fa14dd2f61
--- /dev/null
+++ b/src/soc/intel/skylake/nhlt/max98357.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <soc/nhlt.h>
+
+static const struct nhlt_format_config max98357_render_cfg[] = {
+ /* 48 KHz 24-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 24,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "max98357-render-2ch-48khz-24b.bin",
+ },
+};
+
+int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink)
+{
+ struct nhlt_endpoint *endp;
+
+ /* Render Endpoint */
+ endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
+ NHLT_DIR_RENDER);
+
+ if (endp == NULL)
+ return -1;
+
+ if (nhlt_endpoint_add_formats(endp, max98357_render_cfg,
+ ARRAY_SIZE(max98357_render_cfg)))
+ return -1;
+
+ nhlt_next_instance(nhlt, NHLT_LINK_SSP);
+
+ return 0;
+}
diff --git a/src/soc/intel/skylake/nhlt/nau88l25.c b/src/soc/intel/skylake/nhlt/nau88l25.c
new file mode 100644
index 0000000000..d9b9cbd849
--- /dev/null
+++ b/src/soc/intel/skylake/nhlt/nau88l25.c
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <soc/nhlt.h>
+
+/* The same DSP firmwware settings are used for both the capture and
+ * render endpoints. */
+static const struct nhlt_format_config nau88l25_cfg[] = {
+ /* 48 KHz 24-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 24,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "nau88l25-2ch-48khz-24b.bin",
+ },
+};
+
+int nhlt_soc_add_nau88l25(struct nhlt *nhlt, int hwlink)
+{
+ struct nhlt_endpoint *endp;
+ /* The nau88l25 just has headphones and a mic. Both the capture and
+ * render endpoints occupy the same virtual slot. */
+ struct nhlt_tdm_config tdm_config = {
+ .virtual_slot = 0,
+ .config_type = NHLT_TDM_BASIC,
+ };
+ const void *fmt_cfg = nau88l25_cfg;
+ size_t fmt_sz = ARRAY_SIZE(nau88l25_cfg);
+
+ /* Render Endpoint */
+ endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
+ NHLT_DIR_RENDER);
+
+ if (endp == NULL)
+ return -1;
+
+ if (nhlt_endpoint_append_config(endp, &tdm_config, sizeof(tdm_config)))
+ return -1;
+
+ if (nhlt_endpoint_add_formats(endp, fmt_cfg, fmt_sz))
+ return -1;
+
+ /* Capture Endpoint */
+ endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
+ NHLT_DIR_CAPTURE);
+
+ if (endp == NULL)
+ return -1;
+
+ if (nhlt_endpoint_append_config(endp, &tdm_config, sizeof(tdm_config)))
+ return -1;
+
+ if (nhlt_endpoint_add_formats(endp, fmt_cfg, fmt_sz))
+ return -1;
+
+ nhlt_next_instance(nhlt, NHLT_LINK_SSP);
+
+ return 0;
+}
diff --git a/src/soc/intel/skylake/nhlt/nhlt.c b/src/soc/intel/skylake/nhlt/nhlt.c
new file mode 100644
index 0000000000..56e7d39254
--- /dev/null
+++ b/src/soc/intel/skylake/nhlt/nhlt.c
@@ -0,0 +1,102 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <cbmem.h>
+#include <soc/acpi.h>
+#include <soc/nhlt.h>
+
+#define NHLT_VID 0x8086
+#define NHLT_DID_DMIC 0xae20
+#define NHLT_DID_BT 0xae30
+#define NHLT_DID_SSP 0xae34
+
+struct nhlt_endpoint *nhlt_soc_add_endpoint(struct nhlt *nhlt, int soc_hwintf,
+ int soc_devtype, int dir)
+{
+ int nhlt_link_type;
+ int nhlt_dev_type;
+ uint16_t did;
+ struct nhlt_endpoint *endp;
+
+ /* Check link type and device type. */
+ switch (soc_hwintf) {
+ case AUDIO_LINK_SSP0:
+ case AUDIO_LINK_SSP1:
+ /* Only I2S devices on SSP0 and SSP1. */
+ if (soc_devtype != AUDIO_DEV_I2S)
+ return NULL;
+ nhlt_link_type = NHLT_LINK_SSP;
+ break;
+ case AUDIO_LINK_SSP2:
+ /* Only Bluetooth devices on SSP2. */
+ if (soc_devtype != AUDIO_DEV_BT)
+ return NULL;
+ nhlt_link_type = NHLT_LINK_SSP;
+ break;
+ case AUDIO_LINK_DMIC:
+ /* Only DMIC devices on DMIC links. */
+ if (soc_devtype != AUDIO_DEV_DMIC)
+ return NULL;
+ nhlt_link_type = NHLT_LINK_PDM;
+ break;
+ default:
+ return NULL;
+ }
+
+ switch (soc_devtype) {
+ case AUDIO_DEV_I2S:
+ nhlt_dev_type = NHLT_SSP_DEV_I2S;
+ did = NHLT_DID_SSP;
+ break;
+ case AUDIO_DEV_DMIC:
+ nhlt_dev_type = NHLT_PDM_DEV;
+ did = NHLT_DID_DMIC;
+ break;
+ case AUDIO_DEV_BT:
+ nhlt_dev_type = NHLT_SSP_DEV_BT;
+ did = NHLT_DID_BT;
+ break;
+ default:
+ return NULL;
+ }
+
+ endp = nhlt_add_endpoint(nhlt, nhlt_link_type, nhlt_dev_type, dir,
+ NHLT_VID, did);
+
+ if (endp == NULL)
+ return NULL;
+
+ /* Virtual bus id of SSP links are the hardware port ids proper. */
+ if (nhlt_link_type == NHLT_LINK_SSP)
+ endp->virtual_bus_id = soc_hwintf;
+
+ return endp;
+}
+
+uintptr_t nhlt_soc_serialize(struct nhlt *nhlt, uintptr_t acpi_addr)
+{
+ global_nvs_t *gnvs;
+
+ gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+
+ if (gnvs == NULL)
+ return acpi_addr;
+
+ /* Update NHLT GNVS Data */
+ gnvs->nhla = (uintptr_t)acpi_addr;
+ gnvs->nhll = nhlt_current_size(nhlt);
+
+ return nhlt_serialize(nhlt, acpi_addr);
+}
diff --git a/src/soc/intel/skylake/nhlt/ssm4567.c b/src/soc/intel/skylake/nhlt/ssm4567.c
new file mode 100644
index 0000000000..f531e25a35
--- /dev/null
+++ b/src/soc/intel/skylake/nhlt/ssm4567.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <soc/nhlt.h>
+
+static const struct nhlt_format_config ssm4567_render_cfg[] = {
+ /* 48 KHz 24-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 24,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "ssm4567-render-2ch-48khz-24b.bin",
+ },
+};
+
+int nhlt_soc_add_ssm4567(struct nhlt *nhlt, int hwlink)
+{
+ struct nhlt_endpoint *endp;
+
+ /* Render Endpoint */
+ endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
+ NHLT_DIR_RENDER);
+
+ if (endp == NULL)
+ return -1;
+
+ if (nhlt_endpoint_add_formats(endp, ssm4567_render_cfg,
+ ARRAY_SIZE(ssm4567_render_cfg)))
+ return -1;
+
+ nhlt_next_instance(nhlt, NHLT_LINK_SSP);
+
+ return 0;
+}