Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

+66 -28
+1 -1
sound/soc/codecs/hda.c
··· 213 213 214 214 patch = (hda_codec_patch_t)codec->preset->driver_data; 215 215 if (!patch) { 216 - dev_err(&hdev->dev, "no patch specified?\n"); 216 + dev_err(&hdev->dev, "no patch specified\n"); 217 217 ret = -EINVAL; 218 218 goto err; 219 219 }
+7
sound/soc/codecs/rt298.c
··· 1166 1166 DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake") 1167 1167 } 1168 1168 }, 1169 + { 1170 + .ident = "Intel Kabylake R RVP", 1171 + .matches = { 1172 + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 1173 + DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform") 1174 + } 1175 + }, 1169 1176 { } 1170 1177 }; 1171 1178
+4 -2
sound/soc/intel/avs/apl.c
··· 133 133 buf = apl_log_payload_addr(addr); 134 134 memcpy_fromio(&layout, addr, sizeof(layout)); 135 135 if (!apl_is_entry_stackdump(buf + layout.read_ptr)) { 136 + union avs_notify_msg lbs_msg = AVS_NOTIFICATION(LOG_BUFFER_STATUS); 137 + 136 138 /* 137 139 * DSP awaits the remaining logs to be 138 140 * gathered before dumping stack 139 141 */ 140 - msg->log.core = msg->ext.coredump.core_id; 141 - avs_dsp_op(adev, log_buffer_status, msg); 142 + lbs_msg.log.core = msg->ext.coredump.core_id; 143 + avs_dsp_op(adev, log_buffer_status, &lbs_msg); 142 144 } 143 145 144 146 pos = dump + AVS_FW_REGS_SIZE;
+3 -1
sound/soc/intel/avs/avs.h
··· 220 220 /* 221 221 * If IPC channel is blocked e.g.: due to ongoing recovery, 222 222 * -EPERM error code is expected and thus it's not an actual error. 223 + * 224 + * Unsupported IPCs are of no harm either. 223 225 */ 224 - if (error == -EPERM) 226 + if (error == -EPERM || error == AVS_IPC_NOT_SUPPORTED) 225 227 dev_dbg(adev->dev, "%s 0x%08x 0x%08x failed: %d\n", name, 226 228 tx->glb.primary, tx->glb.ext.val, error); 227 229 else
+6
sound/soc/intel/avs/board_selection.c
··· 29 29 DMI_MATCH(DMI_BOARD_NAME, "Skylake Y LPDDR3 RVP3"), 30 30 }, 31 31 }, 32 + { 33 + .matches = { 34 + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 35 + DMI_MATCH(DMI_BOARD_NAME, "AmberLake Y"), 36 + }, 37 + }, 32 38 {} 33 39 }; 34 40
+5 -1
sound/soc/intel/avs/boards/da7219.c
··· 6 6 // 7 7 8 8 #include <linux/module.h> 9 + #include <linux/platform_data/x86/soc.h> 9 10 #include <linux/platform_device.h> 10 11 #include <sound/jack.h> 11 12 #include <sound/pcm.h> ··· 81 80 int ret; 82 81 83 82 jack = snd_soc_card_get_drvdata(card); 84 - clk_freq = 19200000; 83 + if (soc_intel_is_apl()) 84 + clk_freq = 19200000; 85 + else /* kbl */ 86 + clk_freq = 24576000; 85 87 86 88 ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq, SND_SOC_CLOCK_IN); 87 89 if (ret) {
+1
sound/soc/intel/avs/boards/hdaudio.c
··· 6 6 // Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> 7 7 // 8 8 9 + #include <linux/module.h> 9 10 #include <linux/platform_device.h> 10 11 #include <sound/hda_codec.h> 11 12 #include <sound/hda_i915.h>
+22 -2
sound/soc/intel/avs/boards/rt298.c
··· 6 6 // Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> 7 7 // 8 8 9 + #include <linux/dmi.h> 9 10 #include <linux/module.h> 10 11 #include <sound/jack.h> 11 12 #include <sound/pcm.h> ··· 14 13 #include <sound/soc.h> 15 14 #include <sound/soc-acpi.h> 16 15 #include "../../../codecs/rt298.h" 16 + 17 + static const struct dmi_system_id kblr_dmi_table[] = { 18 + { 19 + .matches = { 20 + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 21 + DMI_MATCH(DMI_BOARD_NAME, "Kabylake R DDR4 RVP"), 22 + }, 23 + }, 24 + {} 25 + }; 17 26 18 27 static const struct snd_kcontrol_new card_controls[] = { 19 28 SOC_DAPM_PIN_SWITCH("Headphone Jack"), ··· 107 96 { 108 97 struct snd_soc_pcm_runtime *rtd = substream->private_data; 109 98 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 99 + unsigned int clk_freq; 110 100 int ret; 111 101 112 - ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, 19200000, SND_SOC_CLOCK_IN); 102 + if (dmi_first_match(kblr_dmi_table)) 103 + clk_freq = 24000000; 104 + else 105 + clk_freq = 19200000; 106 + 107 + ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, clk_freq, SND_SOC_CLOCK_IN); 113 108 if (ret < 0) 114 109 dev_err(rtd->dev, "Set codec sysclk failed: %d\n", ret); 115 110 ··· 156 139 dl->platforms = platform; 157 140 dl->num_platforms = 1; 158 141 dl->id = 0; 159 - dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; 142 + if (dmi_first_match(kblr_dmi_table)) 143 + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; 144 + else 145 + dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; 160 146 dl->init = avs_rt298_codec_init; 161 147 dl->be_hw_params_fixup = avs_rt298_be_fixup; 162 148 dl->ops = &avs_rt298_ops;
+5 -1
sound/soc/intel/avs/core.c
··· 440 440 if (bus->mlcap) 441 441 snd_hdac_ext_bus_get_ml_capabilities(bus); 442 442 443 - if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) 443 + if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) 444 444 dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 445 445 dma_set_max_seg_size(dev, UINT_MAX); 446 446 ··· 667 667 668 668 static const struct pci_device_id avs_ids[] = { 669 669 { PCI_VDEVICE(INTEL, 0x9d70), (unsigned long)&skl_desc }, /* SKL */ 670 + { PCI_VDEVICE(INTEL, 0xa170), (unsigned long)&skl_desc }, /* SKL-H */ 670 671 { PCI_VDEVICE(INTEL, 0x9d71), (unsigned long)&skl_desc }, /* KBL */ 672 + { PCI_VDEVICE(INTEL, 0xa171), (unsigned long)&skl_desc }, /* KBL-H */ 673 + { PCI_VDEVICE(INTEL, 0xa2f0), (unsigned long)&skl_desc }, /* KBL-S */ 674 + { PCI_VDEVICE(INTEL, 0xa3f0), (unsigned long)&skl_desc }, /* CML-V */ 671 675 { PCI_VDEVICE(INTEL, 0x5a98), (unsigned long)&apl_desc }, /* APL */ 672 676 { PCI_VDEVICE(INTEL, 0x3198), (unsigned long)&apl_desc }, /* GML */ 673 677 { 0 }
+3 -2
sound/soc/intel/avs/ipc.c
··· 74 74 struct avs_ipc *ipc = adev->ipc; 75 75 76 76 /* Prevent PG only on the first disable. */ 77 - if (atomic_add_return(1, &ipc->d0ix_disable_depth) == 1) { 77 + if (atomic_inc_return(&ipc->d0ix_disable_depth) == 1) { 78 78 cancel_delayed_work_sync(&ipc->d0ix_work); 79 79 return avs_dsp_set_d0ix(adev, false); 80 80 } ··· 192 192 /* update size in case of LARGE_CONFIG_GET */ 193 193 if (msg.msg_target == AVS_MOD_MSG && 194 194 msg.global_msg_type == AVS_MOD_LARGE_CONFIG_GET) 195 - ipc->rx.size = msg.ext.large_config.data_off_size; 195 + ipc->rx.size = min_t(u32, AVS_MAILBOX_SIZE, 196 + msg.ext.large_config.data_off_size); 196 197 197 198 memcpy_fromio(ipc->rx.data, avs_uplink_addr(adev), ipc->rx.size); 198 199 trace_avs_msg_payload(ipc->rx.data, ipc->rx.size);
+1 -1
sound/soc/intel/avs/loader.c
··· 43 43 /* Occasionally, engineering (release candidate) firmware is provided for testing. */ 44 44 static bool debug_ignore_fw_version; 45 45 module_param_named(ignore_fw_version, debug_ignore_fw_version, bool, 0444); 46 - MODULE_PARM_DESC(ignore_fw_version, "Verify FW version 0=yes (default), 1=no"); 46 + MODULE_PARM_DESC(ignore_fw_version, "Ignore firmware version check 0=no (default), 1=yes"); 47 47 48 48 #define AVS_LIB_NAME_SIZE 8 49 49
+4 -15
sound/soc/intel/avs/messages.c
··· 687 687 688 688 int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size) 689 689 { 690 - int ret; 691 - 692 - ret = avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, 693 - AVS_BASEFW_ENABLE_LOGS, log_info, size); 694 - if (ret) 695 - dev_err(adev->dev, "enable logs failed: %d\n", ret); 696 - 697 - return ret; 690 + return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, 691 + AVS_BASEFW_ENABLE_LOGS, log_info, size); 698 692 } 699 693 700 694 int avs_ipc_set_system_time(struct avs_dev *adev) 701 695 { 702 696 struct avs_sys_time sys_time; 703 - int ret; 704 697 u64 us; 705 698 706 699 /* firmware expects UTC time in micro seconds */ ··· 701 708 sys_time.val_l = us & UINT_MAX; 702 709 sys_time.val_u = us >> 32; 703 710 704 - ret = avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, 705 - AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time)); 706 - if (ret) 707 - dev_err(adev->dev, "set system time failed: %d\n", ret); 708 - 709 - return ret; 711 + return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, 712 + AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time)); 710 713 } 711 714 712 715 int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
+2
sound/soc/intel/avs/messages.h
··· 150 150 }; 151 151 } __packed; 152 152 153 + #define AVS_IPC_NOT_SUPPORTED 15 154 + 153 155 union avs_reply_msg { 154 156 u64 val; 155 157 struct {
+2 -2
sound/soc/intel/avs/skl.c
··· 28 28 29 29 info->core_mask = resource_mask; 30 30 if (enable) 31 - for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0)) { 31 + for_each_set_bit(i, &resource_mask, num_cores) { 32 32 info->logs_core[i].enable = enable; 33 33 info->logs_core[i].min_priority = *priorities++; 34 34 } 35 35 else 36 - for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0)) 36 + for_each_set_bit(i, &resource_mask, num_cores) 37 37 info->logs_core[i].enable = enable; 38 38 39 39 ret = avs_ipc_set_enable_logs(adev, (u8 *)info, size);