From e984f3ef3d2ac4a1896f7a3845b7c89c27841cbe Mon Sep 17 00:00:00 2001 From: Fred Oh Date: Fri, 27 Nov 2020 18:40:18 +0200 Subject: ASoC: SOF: ops: add parse_platform_ext_manifest() op Add parse_platform_ext_manifest() op to parse platform-specific config data in the extended manifest. Signed-off-by: Fred Oh Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20201127164022.2498406-2-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- include/sound/sof/ext_manifest.h | 1 + sound/soc/sof/loader.c | 3 +++ sound/soc/sof/ops.h | 10 ++++++++++ sound/soc/sof/sof-priv.h | 5 +++++ 4 files changed, 19 insertions(+) diff --git a/include/sound/sof/ext_manifest.h b/include/sound/sof/ext_manifest.h index e05cb21023e5..7abc4f0bd3ad 100644 --- a/include/sound/sof/ext_manifest.h +++ b/include/sound/sof/ext_manifest.h @@ -62,6 +62,7 @@ enum sof_ext_man_elem_type { SOF_EXT_MAN_ELEM_CC_VERSION = SOF_IPC_EXT_CC_INFO, SOF_EXT_MAN_ELEM_DBG_ABI = SOF_IPC_EXT_USER_ABI_INFO, SOF_EXT_MAN_ELEM_CONFIG_DATA = 5, /**< ABI3.17 */ + SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA = 6, }; /* extended manifest element header */ diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index 2a8c9bff9963..cbce484b6469 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c @@ -330,6 +330,9 @@ static int snd_sof_fw_ext_man_parse(struct snd_sof_dev *sdev, case SOF_EXT_MAN_ELEM_CONFIG_DATA: ret = ext_man_get_config_data(sdev, elem_hdr); break; + case SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA: + ret = snd_sof_dsp_parse_platform_ext_manifest(sdev, elem_hdr); + break; default: dev_info(sdev->dev, "unknown sof_ext_man header type %d size 0x%X\n", elem_hdr->type, elem_hdr->size); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index b21632f5511a..77a6ac157d37 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -100,6 +100,16 @@ static inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev) return 0; } +/* parse platform specific extended manifest */ +static inline int snd_sof_dsp_parse_platform_ext_manifest(struct snd_sof_dev *sdev, + const struct sof_ext_man_elem_header *hdr) +{ + if (sof_ops(sdev)->parse_platform_ext_manifest) + return sof_ops(sdev)->parse_platform_ext_manifest(sdev, hdr); + + return 0; +} + /* misc */ /** diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index d8bc0178dc89..32d6ceb41fdd 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -18,6 +18,7 @@ #include #include #include +#include /* debug flags */ #define SOF_DBG_ENABLE_TRACE BIT(0) @@ -208,6 +209,10 @@ struct snd_sof_dsp_ops { int (*pre_fw_run)(struct snd_sof_dev *sof_dev); /* optional */ int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */ + /* parse platform specific extended manifest, optional */ + int (*parse_platform_ext_manifest)(struct snd_sof_dev *sof_dev, + const struct sof_ext_man_elem_header *hdr); + /* DSP PM */ int (*suspend)(struct snd_sof_dev *sof_dev, u32 target_state); /* optional */ -- cgit v1.2.3 From edbaaada5c9b57e243a98bf5b442f3a7a43ed14d Mon Sep 17 00:00:00 2001 From: Fred Oh Date: Fri, 27 Nov 2020 18:40:19 +0200 Subject: ASoC: SOF: Intel: hda: define parse_platform_ext_manifest op Define the parse_platform_ext_manifest() op for HDA platforms to parse the SOF_EXT_MAN_CAVS_CONFIG_CAVS_LPRO config item to determine if the FW is configured for LPRO. The default clock configuration is assumed to be HPRO in the absence of this item in the extended manifest. New member clk_config_lpro is added to struct sof_intel_hda_dev to store the FW clock config information and that this will be used later to perform platform-specific operations in the post_fw_run op. Signed-off-by: Fred Oh Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20201127164022.2498406-3-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/apl.c | 3 +++ sound/soc/sof/intel/cnl.c | 3 +++ sound/soc/sof/intel/ext_manifest.h | 33 +++++++++++++++++++++++++++++++++ sound/soc/sof/intel/hda-loader.c | 35 +++++++++++++++++++++++++++++++++++ sound/soc/sof/intel/hda.h | 7 +++++++ sound/soc/sof/intel/tgl.c | 3 +++ 6 files changed, 84 insertions(+) create mode 100644 sound/soc/sof/intel/ext_manifest.h diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 4eeade2e77f7..fc29b91b8932 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -92,6 +92,9 @@ const struct snd_sof_dsp_ops sof_apl_ops = { .pre_fw_run = hda_dsp_pre_fw_run, .post_fw_run = hda_dsp_post_fw_run, + /* parse platform specific extended manifest */ + .parse_platform_ext_manifest = hda_dsp_ext_man_get_cavs_config_data, + /* dsp core power up/down */ .core_power_up = hda_dsp_enable_core, .core_power_down = hda_dsp_core_reset_power_down, diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index a5d3258104c0..158c38743731 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -294,6 +294,9 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .pre_fw_run = hda_dsp_pre_fw_run, .post_fw_run = hda_dsp_post_fw_run, + /* parse platform specific extended manifest */ + .parse_platform_ext_manifest = hda_dsp_ext_man_get_cavs_config_data, + /* dsp core power up/down */ .core_power_up = hda_dsp_enable_core, .core_power_down = hda_dsp_core_reset_power_down, diff --git a/sound/soc/sof/intel/ext_manifest.h b/sound/soc/sof/intel/ext_manifest.h new file mode 100644 index 000000000000..a30e25b4e655 --- /dev/null +++ b/sound/soc/sof/intel/ext_manifest.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) 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) 2020 Intel Corporation. All rights reserved. + */ + +/* + * Intel extended manifest is a extra place to store Intel cavs specific + * metadata about firmware, for example LPRO/HPRO configuration is + * Intel cavs specific. This part of output binary is not signed. + */ + +#ifndef __INTEL_CAVS_EXT_MANIFEST_H__ +#define __INTEL_CAVS_EXT_MANIFEST_H__ + +#include + +/* EXT_MAN_ELEM_PLATFORM_CONFIG_DATA elements identificators */ +enum sof_cavs_config_elem_type { + SOF_EXT_MAN_CAVS_CONFIG_EMPTY = 0, + SOF_EXT_MAN_CAVS_CONFIG_CAVS_LPRO = 1, +}; + +/* EXT_MAN_ELEM_PLATFORM_CONFIG_DATA elements */ +struct sof_ext_man_cavs_config_data { + struct sof_ext_man_elem_header hdr; + + struct sof_config_elem elems[]; +} __packed; + +#endif /* __INTEL_CAVS_EXT_MANIFEST_H__ */ diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 2707a16c6a4d..73806223abd1 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -19,6 +19,7 @@ #include #include #include +#include "ext_manifest.h" #include "../ops.h" #include "hda.h" @@ -470,3 +471,37 @@ int hda_dsp_post_fw_run(struct snd_sof_dev *sdev) /* re-enable clock gating and power gating */ return hda_dsp_ctrl_clock_power_gating(sdev, true); } + +int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev, + const struct sof_ext_man_elem_header *hdr) +{ + const struct sof_ext_man_cavs_config_data *config_data = + container_of(hdr, struct sof_ext_man_cavs_config_data, hdr); + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + int i, elem_num; + + /* calculate total number of config data elements */ + elem_num = (hdr->size - sizeof(struct sof_ext_man_elem_header)) + / sizeof(struct sof_config_elem); + if (elem_num <= 0) { + dev_err(sdev->dev, "cavs config data is inconsistent: %d\n", elem_num); + return -EINVAL; + } + + for (i = 0; i < elem_num; i++) + switch (config_data->elems[i].token) { + case SOF_EXT_MAN_CAVS_CONFIG_EMPTY: + /* skip empty token */ + break; + case SOF_EXT_MAN_CAVS_CONFIG_CAVS_LPRO: + hda->clk_config_lpro = config_data->elems[i].value; + dev_dbg(sdev->dev, "FW clock config: %s\n", + hda->clk_config_lpro ? "LPRO" : "HPRO"); + break; + default: + dev_warn(sdev->dev, "unsupported token type: %d\n", + config_data->elems[i].token); + } + + return 0; +} diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 75954e642c5e..d1df579e52aa 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -447,6 +447,9 @@ struct sof_intel_hda_dev { /* sdw context allocated by SoundWire driver */ struct sdw_intel_ctx *sdw; + + /* FW clock config, 0:HPRO, 1:LPRO */ + bool clk_config_lpro; }; static inline struct hdac_bus *sof_to_bus(struct snd_sof_dev *s) @@ -618,6 +621,10 @@ int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev); int hda_dsp_pre_fw_run(struct snd_sof_dev *sdev); int hda_dsp_post_fw_run(struct snd_sof_dev *sdev); +/* parse platform specific ext manifest ops */ +int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev, + const struct sof_ext_man_elem_header *hdr); + /* * HDA Controller Operations. */ diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index bdcc66d0df78..2252ca38ff4b 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -84,6 +84,9 @@ const struct snd_sof_dsp_ops sof_tgl_ops = { .pre_fw_run = hda_dsp_pre_fw_run, .post_fw_run = hda_dsp_post_fw_run, + /* parse platform specific extended manifest */ + .parse_platform_ext_manifest = hda_dsp_ext_man_get_cavs_config_data, + /* dsp core power up/down */ .core_power_up = hda_dsp_enable_core, .core_power_down = hda_dsp_core_reset_power_down, -- cgit v1.2.3 From e3a85dbe30cf4c6904640da10e7dbd18c4ee7be7 Mon Sep 17 00:00:00 2001 From: Fred Oh Date: Fri, 27 Nov 2020 18:40:20 +0200 Subject: ASoC: SOF: ext_manifest: parse cavs extra config data elem OUTBOX_SIZE, INBOX_SIZE are defined but not being used yet. Handle these elements to avoid warning about unknown token type. Signed-off-by: Fred Oh Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20201127164022.2498406-4-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/ext_manifest.h | 2 ++ sound/soc/sof/intel/hda-loader.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/ext_manifest.h b/sound/soc/sof/intel/ext_manifest.h index a30e25b4e655..2dfae9285d3c 100644 --- a/sound/soc/sof/intel/ext_manifest.h +++ b/sound/soc/sof/intel/ext_manifest.h @@ -21,6 +21,8 @@ enum sof_cavs_config_elem_type { SOF_EXT_MAN_CAVS_CONFIG_EMPTY = 0, SOF_EXT_MAN_CAVS_CONFIG_CAVS_LPRO = 1, + SOF_EXT_MAN_CAVS_CONFIG_OUTBOX_SIZE = 2, + SOF_EXT_MAN_CAVS_CONFIG_INBOX_SIZE = 3, }; /* EXT_MAN_ELEM_PLATFORM_CONFIG_DATA elements */ diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 73806223abd1..52101b1a3dac 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -498,8 +498,12 @@ int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev, dev_dbg(sdev->dev, "FW clock config: %s\n", hda->clk_config_lpro ? "LPRO" : "HPRO"); break; + case SOF_EXT_MAN_CAVS_CONFIG_OUTBOX_SIZE: + case SOF_EXT_MAN_CAVS_CONFIG_INBOX_SIZE: + /* These elements are defined but not being used yet. No warn is required */ + break; default: - dev_warn(sdev->dev, "unsupported token type: %d\n", + dev_info(sdev->dev, "unsupported token type: %d\n", config_data->elems[i].token); } -- cgit v1.2.3 From a70eb70827b4160ada657649c74647f8bb7768ae Mon Sep 17 00:00:00 2001 From: Fred Oh Date: Fri, 27 Nov 2020 18:40:21 +0200 Subject: ASoC: SOF: ops: modify the signature of stall op Modify the signature of stall op to specify core_mask to stall cores. Signed-off-by: Fred Oh Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20201127164022.2498406-5-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ops.h | 4 ++-- sound/soc/sof/sof-priv.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 77a6ac157d37..95e748b36903 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -48,10 +48,10 @@ static inline int snd_sof_dsp_run(struct snd_sof_dev *sdev) return sof_ops(sdev)->run(sdev); } -static inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev) +static inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev, unsigned int core_mask) { if (sof_ops(sdev)->stall) - return sof_ops(sdev)->stall(sdev); + return sof_ops(sdev)->stall(sdev, core_mask); return 0; } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 32d6ceb41fdd..9ba3e3ceed01 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -101,7 +101,7 @@ struct snd_sof_dsp_ops { /* DSP core boot / reset */ int (*run)(struct snd_sof_dev *sof_dev); /* mandatory */ - int (*stall)(struct snd_sof_dev *sof_dev); /* optional */ + int (*stall)(struct snd_sof_dev *sof_dev, unsigned int core_mask); /* optional */ int (*reset)(struct snd_sof_dev *sof_dev); /* optional */ int (*core_power_up)(struct snd_sof_dev *sof_dev, unsigned int core_mask); /* optional */ -- cgit v1.2.3 From 0cde3e9f029c25b671402425a01e029952a38c8e Mon Sep 17 00:00:00 2001 From: Fred Oh Date: Fri, 27 Nov 2020 18:40:22 +0200 Subject: ASoC: SOF: Intel: hda: add sof_icl_ops for ICL platforms Separate the dsp ops for ICL ops to specify the use of ICCMAX FW boot sequence in the run op. All other ops are identical with TGL except post_fw_run. The recommended HW programming sequence for ICL is to power up core 3 and keep it in stall if HPRO is enabled. Signed-off-by: Fred Oh Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20201127164022.2498406-6-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/Makefile | 2 +- sound/soc/sof/intel/cnl.c | 16 ----- sound/soc/sof/intel/hda-loader.c | 61 ++++++++++++++++ sound/soc/sof/intel/hda.h | 4 ++ sound/soc/sof/intel/icl.c | 145 +++++++++++++++++++++++++++++++++++++++ sound/soc/sof/sof-pci-dev.c | 2 +- 6 files changed, 212 insertions(+), 18 deletions(-) create mode 100644 sound/soc/sof/intel/icl.c diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index 72d85b25df7d..2589111c2fae 100644 --- a/sound/soc/sof/intel/Makefile +++ b/sound/soc/sof/intel/Makefile @@ -8,7 +8,7 @@ snd-sof-intel-ipc-objs := intel-ipc.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-dai.o hda-bus.o \ - apl.o cnl.o tgl.o + apl.o cnl.o tgl.o icl.o snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-compress.o snd-sof-intel-hda-objs := hda-codec.o diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 158c38743731..e38db519f38d 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -349,22 +349,6 @@ const struct sof_intel_dsp_desc cnl_chip_info = { }; EXPORT_SYMBOL_NS(cnl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); -const struct sof_intel_dsp_desc icl_chip_info = { - /* Icelake */ - .cores_num = 4, - .init_core_mask = 1, - .host_managed_cores_mask = GENMASK(3, 0), - .ipc_req = CNL_DSP_REG_HIPCIDR, - .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY, - .ipc_ack = CNL_DSP_REG_HIPCIDA, - .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE, - .ipc_ctl = CNL_DSP_REG_HIPCCTL, - .rom_init_timeout = 300, - .ssp_count = ICL_SSP_COUNT, - .ssp_base_offset = CNL_SSP_BASE_OFFSET, -}; -EXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); - const struct sof_intel_dsp_desc ehl_chip_info = { /* Elkhartlake */ .cores_num = 4, diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 52101b1a3dac..02c3ff897274 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -472,6 +472,46 @@ int hda_dsp_post_fw_run(struct snd_sof_dev *sdev) return hda_dsp_ctrl_clock_power_gating(sdev, true); } +/* + * post fw run operations for ICL, + * Core 3 will be powered up and in stall when HPRO is enabled + */ +int hda_dsp_post_fw_run_icl(struct snd_sof_dev *sdev) +{ + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + int ret; + + if (sdev->first_boot) { + ret = hda_sdw_startup(sdev); + if (ret < 0) { + dev_err(sdev->dev, + "error: could not startup SoundWire links\n"); + return ret; + } + } + + hda_sdw_int_enable(sdev, true); + + /* + * The recommended HW programming sequence for ICL is to + * power up core 3 and keep it in stall if HPRO is enabled. + * Major difference between ICL and TGL, on ICL core 3 is managed by + * the host whereas on TGL it is handled by the firmware. + */ + if (!hda->clk_config_lpro) { + ret = snd_sof_dsp_core_power_up(sdev, BIT(3)); + if (ret < 0) { + dev_err(sdev->dev, "error: dsp core power up failed on core 3\n"); + return ret; + } + + snd_sof_dsp_stall(sdev, BIT(3)); + } + + /* re-enable clock gating and power gating */ + return hda_dsp_ctrl_clock_power_gating(sdev, true); +} + int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev, const struct sof_ext_man_elem_header *hdr) { @@ -509,3 +549,24 @@ int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev, return 0; } + +int hda_dsp_core_stall_icl(struct snd_sof_dev *sdev, unsigned int core_mask) +{ + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; + + /* make sure core_mask in host managed cores */ + core_mask &= chip->host_managed_cores_mask; + if (!core_mask) { + dev_err(sdev->dev, "error: core_mask is not in host managed cores\n"); + return -EINVAL; + } + + /* stall core */ + snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR, + HDA_DSP_REG_ADSPCS, + HDA_DSP_ADSPCS_CSTALL_MASK(core_mask), + HDA_DSP_ADSPCS_CSTALL_MASK(core_mask)); + + return 0; +} diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index d1df579e52aa..9ec8ae0fd649 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -615,11 +615,14 @@ int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev, int dir); */ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev); int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev); +int hda_dsp_cl_boot_firmware_iccmax_icl(struct snd_sof_dev *sdev); int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev); /* pre and post fw run ops */ int hda_dsp_pre_fw_run(struct snd_sof_dev *sdev); int hda_dsp_post_fw_run(struct snd_sof_dev *sdev); +int hda_dsp_post_fw_run_icl(struct snd_sof_dev *sdev); +int hda_dsp_core_stall_icl(struct snd_sof_dev *sdev, unsigned int core_mask); /* parse platform specific ext manifest ops */ int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev, @@ -740,6 +743,7 @@ extern struct snd_soc_dai_driver skl_dai[]; extern const struct snd_sof_dsp_ops sof_apl_ops; extern const struct snd_sof_dsp_ops sof_cnl_ops; extern const struct snd_sof_dsp_ops sof_tgl_ops; +extern const struct snd_sof_dsp_ops sof_icl_ops; extern const struct sof_intel_dsp_desc apl_chip_info; extern const struct sof_intel_dsp_desc cnl_chip_info; diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c new file mode 100644 index 000000000000..e9d5a0a58504 --- /dev/null +++ b/sound/soc/sof/intel/icl.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Fred Oh +// + +/* + * Hardware interface for audio DSP on IceLake. + */ + +#include +#include +#include +#include +#include "../ops.h" +#include "hda.h" +#include "hda-ipc.h" +#include "../sof-audio.h" + +static const struct snd_sof_debugfs_map icl_dsp_debugfs[] = { + {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS}, + {"pp", HDA_DSP_PP_BAR, 0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS}, + {"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS}, +}; + +/* Icelake ops */ +const struct snd_sof_dsp_ops sof_icl_ops = { + /* probe and remove */ + .probe = hda_dsp_probe, + .remove = hda_dsp_remove, + + /* Register IO */ + .write = sof_io_write, + .read = sof_io_read, + .write64 = sof_io_write64, + .read64 = sof_io_read64, + + /* Block IO */ + .block_read = sof_block_read, + .block_write = sof_block_write, + + /* doorbell */ + .irq_thread = cnl_ipc_irq_thread, + + /* ipc */ + .send_msg = cnl_ipc_send_msg, + .fw_ready = sof_fw_ready, + .get_mailbox_offset = hda_dsp_ipc_get_mailbox_offset, + .get_window_offset = hda_dsp_ipc_get_window_offset, + + .ipc_msg_data = hda_ipc_msg_data, + .ipc_pcm_params = hda_ipc_pcm_params, + + /* machine driver */ + .machine_select = hda_machine_select, + .machine_register = sof_machine_register, + .machine_unregister = sof_machine_unregister, + .set_mach_params = hda_set_mach_params, + + /* debug */ + .debug_map = icl_dsp_debugfs, + .debug_map_count = ARRAY_SIZE(icl_dsp_debugfs), + .dbg_dump = hda_dsp_dump, + .ipc_dump = cnl_ipc_dump, + + /* stream callbacks */ + .pcm_open = hda_dsp_pcm_open, + .pcm_close = hda_dsp_pcm_close, + .pcm_hw_params = hda_dsp_pcm_hw_params, + .pcm_hw_free = hda_dsp_stream_hw_free, + .pcm_trigger = hda_dsp_pcm_trigger, + .pcm_pointer = hda_dsp_pcm_pointer, + +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) + /* probe callbacks */ + .probe_assign = hda_probe_compr_assign, + .probe_free = hda_probe_compr_free, + .probe_set_params = hda_probe_compr_set_params, + .probe_trigger = hda_probe_compr_trigger, + .probe_pointer = hda_probe_compr_pointer, +#endif + + /* firmware loading */ + .load_firmware = snd_sof_load_firmware_raw, + + /* pre/post fw run */ + .pre_fw_run = hda_dsp_pre_fw_run, + .post_fw_run = hda_dsp_post_fw_run_icl, + + /* parse platform specific extended manifest */ + .parse_platform_ext_manifest = hda_dsp_ext_man_get_cavs_config_data, + + /* dsp core power up/down */ + .core_power_up = hda_dsp_enable_core, + .core_power_down = hda_dsp_core_reset_power_down, + + /* firmware run */ + .run = hda_dsp_cl_boot_firmware_iccmax, + .stall = hda_dsp_core_stall_icl, + + /* trace callback */ + .trace_init = hda_dsp_trace_init, + .trace_release = hda_dsp_trace_release, + .trace_trigger = hda_dsp_trace_trigger, + + /* DAI drivers */ + .drv = skl_dai, + .num_drv = SOF_SKL_NUM_DAIS, + + /* PM */ + .suspend = hda_dsp_suspend, + .resume = hda_dsp_resume, + .runtime_suspend = hda_dsp_runtime_suspend, + .runtime_resume = hda_dsp_runtime_resume, + .runtime_idle = hda_dsp_runtime_idle, + .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume, + .set_power_state = hda_dsp_set_power_state, + + /* ALSA HW info flags */ + .hw_info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, + + .arch_ops = &sof_xtensa_arch_ops, +}; +EXPORT_SYMBOL_NS(sof_icl_ops, SND_SOC_SOF_INTEL_HDA_COMMON); + +const struct sof_intel_dsp_desc icl_chip_info = { + /* Icelake */ + .cores_num = 4, + .init_core_mask = 1, + .host_managed_cores_mask = GENMASK(3, 0), + .ipc_req = CNL_DSP_REG_HIPCIDR, + .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY, + .ipc_ack = CNL_DSP_REG_HIPCIDA, + .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE, + .ipc_ctl = CNL_DSP_REG_HIPCCTL, + .rom_init_timeout = 300, + .ssp_count = ICL_SSP_COUNT, + .ssp_base_offset = CNL_SSP_BASE_OFFSET, +}; +EXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index f2a107481336..153d66d5c948 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -209,7 +209,7 @@ static const struct sof_dev_desc icl_desc = { .default_tplg_path = "intel/sof-tplg", .default_fw_filename = "sof-icl.ri", .nocodec_tplg_filename = "sof-icl-nocodec.tplg", - .ops = &sof_cnl_ops, + .ops = &sof_icl_ops, }; #endif -- cgit v1.2.3