Commit f7aadbb2 authored by Mark Brown's avatar Mark Brown

ASoC: SOF: Add SKL/KBL support for IPC4 CI tests

Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:

This patchset was submitted earlier in April 2022 as part of the
"ASoC: SOF: add INTEL_IPC4 plumbing" series. As requested the SKL/KBL
support is moved to a different series.

This update adds minor style fixes and the ops that were missing at
the time. SKL and KBL daily tests have been running for several months
and helped identify missing sequences in the SOF driver for HDaudio
links, or platform differences that the driver did not account for
(number of pipelines, etc).

Note that this capability is not recommended for any distribution, it
is ONLY for SOF IPC4 CI tests on HDaudio devices, we will not extend
this SKL/KBL support for I2S devices based on ES8336 or Chromebooks
which are ONLY supported by the AVS driver.
parents 1dc53232 52d7939d
...@@ -95,6 +95,31 @@ config SND_SOC_SOF_MERRIFIELD ...@@ -95,6 +95,31 @@ config SND_SOC_SOF_MERRIFIELD
Say Y if you have such a device. Say Y if you have such a device.
If unsure select "N". If unsure select "N".
config SND_SOC_SOF_INTEL_SKL
tristate
select SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_INTEL_IPC4
config SND_SOC_SOF_SKYLAKE
tristate "SOF support for SkyLake"
default SND_SOC_SOF_PCI
select SND_SOC_SOF_INTEL_SKL
help
This adds support for the Intel(R) platforms using the SkyLake processors.
Say Y if you have such a device.
If unsure select "N".
This is intended only for developers and not a recommend option for distros.
config SND_SOC_SOF_KABYLAKE
tristate "SOF support for KabyLake"
default SND_SOC_SOF_PCI
select SND_SOC_SOF_INTEL_SKL
help
This adds support for the Intel(R) platforms using the KabyLake processors.
Say Y if you have such a device.
If unsure select "N".
This is intended only for developers and not a recommend option for distros.
config SND_SOC_SOF_INTEL_APL config SND_SOC_SOF_INTEL_APL
tristate tristate
select SND_SOC_SOF_HDA_COMMON select SND_SOC_SOF_HDA_COMMON
......
...@@ -6,7 +6,9 @@ snd-sof-acpi-intel-bdw-objs := bdw.o ...@@ -6,7 +6,9 @@ snd-sof-acpi-intel-bdw-objs := bdw.o
snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \ snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \
hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \ hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \
hda-dai.o hda-bus.o \ hda-dai.o hda-bus.o \
skl.o hda-loader-skl.o \
apl.o cnl.o tgl.o icl.o mtl.o hda-common-ops.o apl.o cnl.o tgl.o icl.o mtl.o hda-common-ops.o
snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-probes.o snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-probes.o
snd-sof-intel-hda-objs := hda-codec.o snd-sof-intel-hda-objs := hda-codec.o
...@@ -20,6 +22,7 @@ obj-$(CONFIG_SND_SOC_SOF_HDA_COMMON) += snd-sof-intel-hda-common.o ...@@ -20,6 +22,7 @@ obj-$(CONFIG_SND_SOC_SOF_HDA_COMMON) += snd-sof-intel-hda-common.o
obj-$(CONFIG_SND_SOC_SOF_HDA) += snd-sof-intel-hda.o obj-$(CONFIG_SND_SOC_SOF_HDA) += snd-sof-intel-hda.o
snd-sof-pci-intel-tng-objs := pci-tng.o snd-sof-pci-intel-tng-objs := pci-tng.o
snd-sof-pci-intel-skl-objs := pci-skl.o
snd-sof-pci-intel-apl-objs := pci-apl.o snd-sof-pci-intel-apl-objs := pci-apl.o
snd-sof-pci-intel-cnl-objs := pci-cnl.o snd-sof-pci-intel-cnl-objs := pci-cnl.o
snd-sof-pci-intel-icl-objs := pci-icl.o snd-sof-pci-intel-icl-objs := pci-icl.o
...@@ -27,6 +30,7 @@ snd-sof-pci-intel-tgl-objs := pci-tgl.o ...@@ -27,6 +30,7 @@ snd-sof-pci-intel-tgl-objs := pci-tgl.o
snd-sof-pci-intel-mtl-objs := pci-mtl.o snd-sof-pci-intel-mtl-objs := pci-mtl.o
obj-$(CONFIG_SND_SOC_SOF_MERRIFIELD) += snd-sof-pci-intel-tng.o obj-$(CONFIG_SND_SOC_SOF_MERRIFIELD) += snd-sof-pci-intel-tng.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_SKL) += snd-sof-pci-intel-skl.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_APL) += snd-sof-pci-intel-apl.o obj-$(CONFIG_SND_SOC_SOF_INTEL_APL) += snd-sof-pci-intel-apl.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_CNL) += snd-sof-pci-intel-cnl.o obj-$(CONFIG_SND_SOC_SOF_INTEL_CNL) += snd-sof-pci-intel-cnl.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_ICL) += snd-sof-pci-intel-icl.o obj-$(CONFIG_SND_SOC_SOF_INTEL_ICL) += snd-sof-pci-intel-icl.o
......
...@@ -114,7 +114,7 @@ static int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_ ...@@ -114,7 +114,7 @@ static int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_
return ret; return ret;
} }
static int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask) int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask)
{ {
/* stall core */ /* stall core */
snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR, snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
...@@ -126,7 +126,7 @@ static int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_ ...@@ -126,7 +126,7 @@ static int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_
return hda_dsp_core_reset_enter(sdev, core_mask); return hda_dsp_core_reset_enter(sdev, core_mask);
} }
static bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, unsigned int core_mask) bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, unsigned int core_mask)
{ {
int val; int val;
bool is_enable; bool is_enable;
......
...@@ -304,6 +304,7 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context) ...@@ -304,6 +304,7 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context)
/* Check if an IPC IRQ occurred */ /* Check if an IPC IRQ occurred */
bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev) bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev)
{ {
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
bool ret = false; bool ret = false;
u32 irq_status; u32 irq_status;
...@@ -319,6 +320,13 @@ bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev) ...@@ -319,6 +320,13 @@ bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev)
if (irq_status & HDA_DSP_ADSPIS_IPC) if (irq_status & HDA_DSP_ADSPIS_IPC)
ret = true; ret = true;
/* CLDMA message ? */
if (irq_status & HDA_DSP_ADSPIS_CL_DMA) {
hda->code_loading = 0;
wake_up(&hda->waitq);
ret = false;
}
out: out:
return ret; return ret;
} }
......
This diff is collapsed.
...@@ -1136,6 +1136,8 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) ...@@ -1136,6 +1136,8 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
INIT_DELAYED_WORK(&hdev->d0i3_work, hda_dsp_d0i3_work); INIT_DELAYED_WORK(&hdev->d0i3_work, hda_dsp_d0i3_work);
init_waitqueue_head(&hdev->waitq);
hdev->nhlt = intel_nhlt_init(sdev->dev); hdev->nhlt = intel_nhlt_init(sdev->dev);
return 0; return 0;
......
...@@ -229,6 +229,7 @@ ...@@ -229,6 +229,7 @@
#define FSR_STATE_ROM_GET_LOAD_OFFSET 0x7 #define FSR_STATE_ROM_GET_LOAD_OFFSET 0x7
#define FSR_STATE_ROM_FETCH_ROM_EXT 0x8 #define FSR_STATE_ROM_FETCH_ROM_EXT 0x8
#define FSR_STATE_ROM_FETCH_ROM_EXT_DONE 0x9 #define FSR_STATE_ROM_FETCH_ROM_EXT_DONE 0x9
#define FSR_STATE_ROM_BASEFW_ENTERED 0xf /* SKL */
/* (ROM) CSE states */ /* (ROM) CSE states */
#define FSR_STATE_ROM_CSE_IMR_REQUEST 0x10 #define FSR_STATE_ROM_CSE_IMR_REQUEST 0x10
...@@ -418,6 +419,7 @@ ...@@ -418,6 +419,7 @@
#endif #endif
/* Intel HD Audio SRAM Window 0*/ /* Intel HD Audio SRAM Window 0*/
#define HDA_DSP_SRAM_REG_ROM_STATUS_SKL 0x8000
#define HDA_ADSP_SRAM0_BASE_SKL 0x8000 #define HDA_ADSP_SRAM0_BASE_SKL 0x8000
/* Firmware status window */ /* Firmware status window */
...@@ -514,6 +516,9 @@ struct sof_intel_hda_dev { ...@@ -514,6 +516,9 @@ struct sof_intel_hda_dev {
/* FW clock config, 0:HPRO, 1:LPRO */ /* FW clock config, 0:HPRO, 1:LPRO */
bool clk_config_lpro; bool clk_config_lpro;
wait_queue_head_t waitq;
bool code_loading;
/* Intel NHLT information */ /* Intel NHLT information */
struct nhlt_acpi_table *nhlt; struct nhlt_acpi_table *nhlt;
}; };
...@@ -565,6 +570,7 @@ int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev, ...@@ -565,6 +570,7 @@ int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev,
int hda_dsp_core_get(struct snd_sof_dev *sdev, int core); int hda_dsp_core_get(struct snd_sof_dev *sdev, int core);
void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev); void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev);
void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev); void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev);
bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, unsigned int core_mask);
int hda_dsp_set_power_state(struct snd_sof_dev *sdev, int hda_dsp_set_power_state(struct snd_sof_dev *sdev,
const struct sof_dsp_power_state *target_state); const struct sof_dsp_power_state *target_state);
...@@ -769,6 +775,8 @@ int hda_dsp_dais_suspend(struct snd_sof_dev *sdev); ...@@ -769,6 +775,8 @@ int hda_dsp_dais_suspend(struct snd_sof_dev *sdev);
*/ */
extern struct snd_sof_dsp_ops sof_hda_common_ops; extern struct snd_sof_dsp_ops sof_hda_common_ops;
extern struct snd_sof_dsp_ops sof_skl_ops;
int sof_skl_ops_init(struct snd_sof_dev *sdev);
extern struct snd_sof_dsp_ops sof_apl_ops; extern struct snd_sof_dsp_ops sof_apl_ops;
int sof_apl_ops_init(struct snd_sof_dev *sdev); int sof_apl_ops_init(struct snd_sof_dev *sdev);
extern struct snd_sof_dsp_ops sof_cnl_ops; extern struct snd_sof_dsp_ops sof_cnl_ops;
...@@ -780,6 +788,7 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev); ...@@ -780,6 +788,7 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev);
extern struct snd_sof_dsp_ops sof_mtl_ops; extern struct snd_sof_dsp_ops sof_mtl_ops;
int sof_mtl_ops_init(struct snd_sof_dev *sdev); int sof_mtl_ops_init(struct snd_sof_dev *sdev);
extern const struct sof_intel_dsp_desc skl_chip_info;
extern const struct sof_intel_dsp_desc apl_chip_info; extern const struct sof_intel_dsp_desc apl_chip_info;
extern const struct sof_intel_dsp_desc cnl_chip_info; extern const struct sof_intel_dsp_desc cnl_chip_info;
extern const struct sof_intel_dsp_desc icl_chip_info; extern const struct sof_intel_dsp_desc icl_chip_info;
...@@ -833,6 +842,10 @@ extern int sof_hda_position_quirk; ...@@ -833,6 +842,10 @@ extern int sof_hda_position_quirk;
void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops); void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops);
void hda_ops_free(struct snd_sof_dev *sdev); void hda_ops_free(struct snd_sof_dev *sdev);
/* SKL/KBL */
int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev);
int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask);
/* IPC4 */ /* IPC4 */
irqreturn_t cnl_ipc4_irq_thread(int irq, void *context); irqreturn_t cnl_ipc4_irq_thread(int irq, void *context);
int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg); int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg);
......
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license. When using or
// redistributing this file, you may do so under either license.
//
// Copyright(c) 2018-2022 Intel Corporation. All rights reserved.
//
#include <linux/module.h>
#include <linux/pci.h>
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
#include <sound/sof.h>
#include "../ops.h"
#include "../sof-pci-dev.h"
/* platform specific devices */
#include "hda.h"
static struct sof_dev_desc skl_desc = {
.machines = snd_soc_acpi_intel_skl_machines,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = -1,
.resindex_imr_base = -1,
.chip_info = &skl_chip_info,
.irqindex_host_ipc = -1,
.ipc_supported_mask = BIT(SOF_INTEL_IPC4),
.ipc_default = SOF_INTEL_IPC4,
.default_fw_path = {
[SOF_INTEL_IPC4] = "intel/avs/skl",
},
.default_tplg_path = {
[SOF_INTEL_IPC4] = "intel/avs-tplg",
},
.default_fw_filename = {
[SOF_INTEL_IPC4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-skl-nocodec.tplg",
.ops = &sof_skl_ops,
.ops_init = sof_skl_ops_init,
};
static struct sof_dev_desc kbl_desc = {
.machines = snd_soc_acpi_intel_kbl_machines,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = -1,
.resindex_imr_base = -1,
.chip_info = &skl_chip_info,
.irqindex_host_ipc = -1,
.ipc_supported_mask = BIT(SOF_INTEL_IPC4),
.ipc_default = SOF_INTEL_IPC4,
.default_fw_path = {
[SOF_INTEL_IPC4] = "intel/avs/kbl",
},
.default_tplg_path = {
[SOF_INTEL_IPC4] = "intel/avs-tplg",
},
.default_fw_filename = {
[SOF_INTEL_IPC4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-kbl-nocodec.tplg",
.ops = &sof_skl_ops,
.ops_init = sof_skl_ops_init,
};
/* PCI IDs */
static const struct pci_device_id sof_pci_ids[] = {
/* Sunrise Point-LP */
{ PCI_DEVICE(0x8086, 0x9d70), .driver_data = (unsigned long)&skl_desc},
/* KBL */
{ PCI_DEVICE(0x8086, 0x9d71), .driver_data = (unsigned long)&kbl_desc},
{ 0, }
};
MODULE_DEVICE_TABLE(pci, sof_pci_ids);
/* pci_driver definition */
static struct pci_driver snd_sof_pci_intel_skl_driver = {
.name = "sof-audio-pci-intel-skl",
.id_table = sof_pci_ids,
.probe = hda_pci_intel_probe,
.remove = sof_pci_remove,
.shutdown = sof_pci_shutdown,
.driver = {
.pm = &sof_pci_pm,
},
};
module_pci_driver(snd_sof_pci_intel_skl_driver);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON);
MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV);
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license. When using or
// redistributing this file, you may do so under either license.
//
// Copyright(c) 2018-2022 Intel Corporation. All rights reserved.
//
/*
* Hardware interface for audio DSP on Skylake and Kabylake.
*/
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <sound/hdaudio_ext.h>
#include <sound/pcm_params.h>
#include <sound/sof.h>
#include <sound/sof/ext_manifest4.h>
#include "../sof-priv.h"
#include "../ipc4-priv.h"
#include "../ops.h"
#include "hda.h"
#include "../sof-audio.h"
#define SRAM_MEMORY_WINDOW_BASE 0x8000
static const __maybe_unused struct snd_sof_debugfs_map skl_dsp_debugfs[] = {
{"hda", HDA_DSP_HDA_BAR, 0, 0x4000},
{"pp", HDA_DSP_PP_BAR, 0, 0x1000},
{"dsp", HDA_DSP_BAR, 0, 0x10000},
};
static int skl_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id)
{
return SRAM_MEMORY_WINDOW_BASE + (0x2000 * id);
}
static int skl_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev)
{
return SRAM_MEMORY_WINDOW_BASE + 0x1000;
}
/* skylake ops */
struct snd_sof_dsp_ops sof_skl_ops;
EXPORT_SYMBOL_NS(sof_skl_ops, SND_SOC_SOF_INTEL_HDA_COMMON);
int sof_skl_ops_init(struct snd_sof_dev *sdev)
{
struct sof_ipc4_fw_data *ipc4_data;
/* common defaults */
memcpy(&sof_skl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));
/* probe/remove/shutdown */
sof_skl_ops.shutdown = hda_dsp_shutdown;
sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
if (!sdev->private)
return -ENOMEM;
ipc4_data = sdev->private;
ipc4_data->manifest_fw_hdr_offset = SOF_MAN4_FW_HDR_OFFSET_CAVS_1_5;
ipc4_data->mtrace_type = SOF_IPC4_MTRACE_INTEL_CAVS_1_5;
sof_skl_ops.get_window_offset = skl_dsp_ipc_get_window_offset;
sof_skl_ops.get_mailbox_offset = skl_dsp_ipc_get_mailbox_offset;
/* doorbell */
sof_skl_ops.irq_thread = hda_dsp_ipc4_irq_thread;
/* ipc */
sof_skl_ops.send_msg = hda_dsp_ipc4_send_msg;
/* set DAI driver ops */
hda_set_dai_drv_ops(sdev, &sof_skl_ops);
/* debug */
sof_skl_ops.debug_map = skl_dsp_debugfs;
sof_skl_ops.debug_map_count = ARRAY_SIZE(skl_dsp_debugfs);
sof_skl_ops.ipc_dump = hda_ipc_dump;
/* firmware run */
sof_skl_ops.run = hda_dsp_cl_boot_firmware_skl;
/* pre/post fw run */
sof_skl_ops.post_fw_run = hda_dsp_post_fw_run;
return 0;
};
EXPORT_SYMBOL_NS(sof_skl_ops_init, SND_SOC_SOF_INTEL_HDA_COMMON);
const struct sof_intel_dsp_desc skl_chip_info = {
.cores_num = 2,
.init_core_mask = 1,
.host_managed_cores_mask = GENMASK(1, 0),
.ipc_req = HDA_DSP_REG_HIPCI,
.ipc_req_mask = HDA_DSP_REG_HIPCI_BUSY,
.ipc_ack = HDA_DSP_REG_HIPCIE,
.ipc_ack_mask = HDA_DSP_REG_HIPCIE_DONE,
.ipc_ctl = HDA_DSP_REG_HIPCCTL,
.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS_SKL,
.rom_init_timeout = 300,
.check_ipc_irq = hda_dsp_check_ipc_irq,
.hw_ip_version = SOF_INTEL_CAVS_1_5,
};
EXPORT_SYMBOL_NS(skl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment