Commit 46234fbe authored by Mark Brown's avatar Mark Brown

ASoC: Intel: avs: Fixes and new boards support

Merge series from Cezary Rojewski <cezary.rojewski@intel.com>:

Two fixes are leading the way - one addresses the incorrect DMA mask
assignment (typo) at driver probe. The other, fixes a potential buffer
overflow when copying data received from firmware to kernel buffer.
However unlikely, the fix should still be there.

Then a range of patches providing the support for:
- AML with rt286 (machine board)
- KBL-R for rt298 (codec)
- KBL-R with rt298 (machine board)
- APL/KBL with da7219 (machine board)
- Addition of all the missing SKL-based PCI ids to core.c

Of the remaining changes, only one stands out - special case is provided
for "unsupported" IPCs. The driver supports a range of platforms,
however, on some generations given IPC may not be supported. Such call
shall not be treated as "invalid" - those are two different scenarios.

Everything else in the patchset is mostly a readability improvement:
spelling fixes and log messages issues, code simplification.
parents a2ddd19f 62d0cee4
...@@ -213,7 +213,7 @@ static int hda_codec_probe(struct snd_soc_component *component) ...@@ -213,7 +213,7 @@ static int hda_codec_probe(struct snd_soc_component *component)
patch = (hda_codec_patch_t)codec->preset->driver_data; patch = (hda_codec_patch_t)codec->preset->driver_data;
if (!patch) { if (!patch) {
dev_err(&hdev->dev, "no patch specified?\n"); dev_err(&hdev->dev, "no patch specified\n");
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
} }
......
...@@ -1166,6 +1166,13 @@ static const struct dmi_system_id force_combo_jack_table[] = { ...@@ -1166,6 +1166,13 @@ static const struct dmi_system_id force_combo_jack_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake") DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake")
} }
}, },
{
.ident = "Intel Kabylake R RVP",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform")
}
},
{ } { }
}; };
......
...@@ -133,12 +133,14 @@ static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) ...@@ -133,12 +133,14 @@ static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg)
buf = apl_log_payload_addr(addr); buf = apl_log_payload_addr(addr);
memcpy_fromio(&layout, addr, sizeof(layout)); memcpy_fromio(&layout, addr, sizeof(layout));
if (!apl_is_entry_stackdump(buf + layout.read_ptr)) { if (!apl_is_entry_stackdump(buf + layout.read_ptr)) {
union avs_notify_msg lbs_msg = AVS_NOTIFICATION(LOG_BUFFER_STATUS);
/* /*
* DSP awaits the remaining logs to be * DSP awaits the remaining logs to be
* gathered before dumping stack * gathered before dumping stack
*/ */
msg->log.core = msg->ext.coredump.core_id; lbs_msg.log.core = msg->ext.coredump.core_id;
avs_dsp_op(adev, log_buffer_status, msg); avs_dsp_op(adev, log_buffer_status, &lbs_msg);
} }
pos = dump + AVS_FW_REGS_SIZE; pos = dump + AVS_FW_REGS_SIZE;
......
...@@ -220,8 +220,10 @@ static inline void avs_ipc_err(struct avs_dev *adev, struct avs_ipc_msg *tx, ...@@ -220,8 +220,10 @@ static inline void avs_ipc_err(struct avs_dev *adev, struct avs_ipc_msg *tx,
/* /*
* If IPC channel is blocked e.g.: due to ongoing recovery, * If IPC channel is blocked e.g.: due to ongoing recovery,
* -EPERM error code is expected and thus it's not an actual error. * -EPERM error code is expected and thus it's not an actual error.
*
* Unsupported IPCs are of no harm either.
*/ */
if (error == -EPERM) if (error == -EPERM || error == AVS_IPC_NOT_SUPPORTED)
dev_dbg(adev->dev, "%s 0x%08x 0x%08x failed: %d\n", name, dev_dbg(adev->dev, "%s 0x%08x 0x%08x failed: %d\n", name,
tx->glb.primary, tx->glb.ext.val, error); tx->glb.primary, tx->glb.ext.val, error);
else else
......
...@@ -29,6 +29,12 @@ static const struct dmi_system_id kbl_dmi_table[] = { ...@@ -29,6 +29,12 @@ static const struct dmi_system_id kbl_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "Skylake Y LPDDR3 RVP3"), DMI_MATCH(DMI_BOARD_NAME, "Skylake Y LPDDR3 RVP3"),
}, },
}, },
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_BOARD_NAME, "AmberLake Y"),
},
},
{} {}
}; };
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
// //
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_data/x86/soc.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <sound/jack.h> #include <sound/jack.h>
#include <sound/pcm.h> #include <sound/pcm.h>
...@@ -80,7 +81,10 @@ static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime) ...@@ -80,7 +81,10 @@ static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime)
int ret; int ret;
jack = snd_soc_card_get_drvdata(card); jack = snd_soc_card_get_drvdata(card);
clk_freq = 19200000; if (soc_intel_is_apl())
clk_freq = 19200000;
else /* kbl */
clk_freq = 24576000;
ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq, SND_SOC_CLOCK_IN); ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq, SND_SOC_CLOCK_IN);
if (ret) { if (ret) {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> // Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
// //
#include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <sound/hda_codec.h> #include <sound/hda_codec.h>
#include <sound/hda_i915.h> #include <sound/hda_i915.h>
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> // Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
// //
#include <linux/dmi.h>
#include <linux/module.h> #include <linux/module.h>
#include <sound/jack.h> #include <sound/jack.h>
#include <sound/pcm.h> #include <sound/pcm.h>
...@@ -14,6 +15,16 @@ ...@@ -14,6 +15,16 @@
#include <sound/soc-acpi.h> #include <sound/soc-acpi.h>
#include "../../../codecs/rt298.h" #include "../../../codecs/rt298.h"
static const struct dmi_system_id kblr_dmi_table[] = {
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_BOARD_NAME, "Kabylake R DDR4 RVP"),
},
},
{}
};
static const struct snd_kcontrol_new card_controls[] = { static const struct snd_kcontrol_new card_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headphone Jack"),
SOC_DAPM_PIN_SWITCH("Mic Jack"), SOC_DAPM_PIN_SWITCH("Mic Jack"),
...@@ -96,9 +107,15 @@ avs_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_param ...@@ -96,9 +107,15 @@ avs_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_param
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
unsigned int clk_freq;
int ret; int ret;
ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, 19200000, SND_SOC_CLOCK_IN); if (dmi_first_match(kblr_dmi_table))
clk_freq = 24000000;
else
clk_freq = 19200000;
ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, clk_freq, SND_SOC_CLOCK_IN);
if (ret < 0) if (ret < 0)
dev_err(rtd->dev, "Set codec sysclk failed: %d\n", ret); dev_err(rtd->dev, "Set codec sysclk failed: %d\n", ret);
...@@ -139,7 +156,10 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in ...@@ -139,7 +156,10 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->platforms = platform; dl->platforms = platform;
dl->num_platforms = 1; dl->num_platforms = 1;
dl->id = 0; dl->id = 0;
dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; if (dmi_first_match(kblr_dmi_table))
dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
else
dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
dl->init = avs_rt298_codec_init; dl->init = avs_rt298_codec_init;
dl->be_hw_params_fixup = avs_rt298_be_fixup; dl->be_hw_params_fixup = avs_rt298_be_fixup;
dl->ops = &avs_rt298_ops; dl->ops = &avs_rt298_ops;
......
...@@ -440,7 +440,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) ...@@ -440,7 +440,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
if (bus->mlcap) if (bus->mlcap)
snd_hdac_ext_bus_get_ml_capabilities(bus); snd_hdac_ext_bus_get_ml_capabilities(bus);
if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
dma_set_max_seg_size(dev, UINT_MAX); dma_set_max_seg_size(dev, UINT_MAX);
...@@ -667,7 +667,11 @@ static const struct avs_spec apl_desc = { ...@@ -667,7 +667,11 @@ static const struct avs_spec apl_desc = {
static const struct pci_device_id avs_ids[] = { static const struct pci_device_id avs_ids[] = {
{ PCI_VDEVICE(INTEL, 0x9d70), (unsigned long)&skl_desc }, /* SKL */ { PCI_VDEVICE(INTEL, 0x9d70), (unsigned long)&skl_desc }, /* SKL */
{ PCI_VDEVICE(INTEL, 0xa170), (unsigned long)&skl_desc }, /* SKL-H */
{ PCI_VDEVICE(INTEL, 0x9d71), (unsigned long)&skl_desc }, /* KBL */ { PCI_VDEVICE(INTEL, 0x9d71), (unsigned long)&skl_desc }, /* KBL */
{ PCI_VDEVICE(INTEL, 0xa171), (unsigned long)&skl_desc }, /* KBL-H */
{ PCI_VDEVICE(INTEL, 0xa2f0), (unsigned long)&skl_desc }, /* KBL-S */
{ PCI_VDEVICE(INTEL, 0xa3f0), (unsigned long)&skl_desc }, /* CML-V */
{ PCI_VDEVICE(INTEL, 0x5a98), (unsigned long)&apl_desc }, /* APL */ { PCI_VDEVICE(INTEL, 0x5a98), (unsigned long)&apl_desc }, /* APL */
{ PCI_VDEVICE(INTEL, 0x3198), (unsigned long)&apl_desc }, /* GML */ { PCI_VDEVICE(INTEL, 0x3198), (unsigned long)&apl_desc }, /* GML */
{ 0 } { 0 }
......
...@@ -74,7 +74,7 @@ int avs_dsp_disable_d0ix(struct avs_dev *adev) ...@@ -74,7 +74,7 @@ int avs_dsp_disable_d0ix(struct avs_dev *adev)
struct avs_ipc *ipc = adev->ipc; struct avs_ipc *ipc = adev->ipc;
/* Prevent PG only on the first disable. */ /* Prevent PG only on the first disable. */
if (atomic_add_return(1, &ipc->d0ix_disable_depth) == 1) { if (atomic_inc_return(&ipc->d0ix_disable_depth) == 1) {
cancel_delayed_work_sync(&ipc->d0ix_work); cancel_delayed_work_sync(&ipc->d0ix_work);
return avs_dsp_set_d0ix(adev, false); return avs_dsp_set_d0ix(adev, false);
} }
...@@ -192,7 +192,8 @@ static void avs_dsp_receive_rx(struct avs_dev *adev, u64 header) ...@@ -192,7 +192,8 @@ static void avs_dsp_receive_rx(struct avs_dev *adev, u64 header)
/* update size in case of LARGE_CONFIG_GET */ /* update size in case of LARGE_CONFIG_GET */
if (msg.msg_target == AVS_MOD_MSG && if (msg.msg_target == AVS_MOD_MSG &&
msg.global_msg_type == AVS_MOD_LARGE_CONFIG_GET) msg.global_msg_type == AVS_MOD_LARGE_CONFIG_GET)
ipc->rx.size = msg.ext.large_config.data_off_size; ipc->rx.size = min_t(u32, AVS_MAILBOX_SIZE,
msg.ext.large_config.data_off_size);
memcpy_fromio(ipc->rx.data, avs_uplink_addr(adev), ipc->rx.size); memcpy_fromio(ipc->rx.data, avs_uplink_addr(adev), ipc->rx.size);
trace_avs_msg_payload(ipc->rx.data, ipc->rx.size); trace_avs_msg_payload(ipc->rx.data, ipc->rx.size);
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
/* Occasionally, engineering (release candidate) firmware is provided for testing. */ /* Occasionally, engineering (release candidate) firmware is provided for testing. */
static bool debug_ignore_fw_version; static bool debug_ignore_fw_version;
module_param_named(ignore_fw_version, debug_ignore_fw_version, bool, 0444); module_param_named(ignore_fw_version, debug_ignore_fw_version, bool, 0444);
MODULE_PARM_DESC(ignore_fw_version, "Verify FW version 0=yes (default), 1=no"); MODULE_PARM_DESC(ignore_fw_version, "Ignore firmware version check 0=no (default), 1=yes");
#define AVS_LIB_NAME_SIZE 8 #define AVS_LIB_NAME_SIZE 8
......
...@@ -687,20 +687,13 @@ int avs_ipc_get_modules_info(struct avs_dev *adev, struct avs_mods_info **info) ...@@ -687,20 +687,13 @@ int avs_ipc_get_modules_info(struct avs_dev *adev, struct avs_mods_info **info)
int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size) int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size)
{ {
int ret; return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
AVS_BASEFW_ENABLE_LOGS, log_info, size);
ret = avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
AVS_BASEFW_ENABLE_LOGS, log_info, size);
if (ret)
dev_err(adev->dev, "enable logs failed: %d\n", ret);
return ret;
} }
int avs_ipc_set_system_time(struct avs_dev *adev) int avs_ipc_set_system_time(struct avs_dev *adev)
{ {
struct avs_sys_time sys_time; struct avs_sys_time sys_time;
int ret;
u64 us; u64 us;
/* firmware expects UTC time in micro seconds */ /* firmware expects UTC time in micro seconds */
...@@ -708,12 +701,8 @@ int avs_ipc_set_system_time(struct avs_dev *adev) ...@@ -708,12 +701,8 @@ int avs_ipc_set_system_time(struct avs_dev *adev)
sys_time.val_l = us & UINT_MAX; sys_time.val_l = us & UINT_MAX;
sys_time.val_u = us >> 32; sys_time.val_u = us >> 32;
ret = avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time)); AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time));
if (ret)
dev_err(adev->dev, "set system time failed: %d\n", ret);
return ret;
} }
int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id, int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
......
...@@ -150,6 +150,8 @@ union avs_module_msg { ...@@ -150,6 +150,8 @@ union avs_module_msg {
}; };
} __packed; } __packed;
#define AVS_IPC_NOT_SUPPORTED 15
union avs_reply_msg { union avs_reply_msg {
u64 val; u64 val;
struct { struct {
......
...@@ -28,12 +28,12 @@ static int skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 ...@@ -28,12 +28,12 @@ static int skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32
info->core_mask = resource_mask; info->core_mask = resource_mask;
if (enable) if (enable)
for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0)) { for_each_set_bit(i, &resource_mask, num_cores) {
info->logs_core[i].enable = enable; info->logs_core[i].enable = enable;
info->logs_core[i].min_priority = *priorities++; info->logs_core[i].min_priority = *priorities++;
} }
else else
for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0)) for_each_set_bit(i, &resource_mask, num_cores)
info->logs_core[i].enable = enable; info->logs_core[i].enable = enable;
ret = avs_ipc_set_enable_logs(adev, (u8 *)info, size); ret = avs_ipc_set_enable_logs(adev, (u8 *)info, size);
......
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