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

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: Intel: avs: Fixes and cleanups

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

A set of loosely connected changes, fixing few outstanding issues as
well as improving readability of the existing code.

The fixes lead the series, first five patches. The goal is to make sure
proper read() is used when accessing the registers, probe() and remove()
sequences for HDAudio streaming are synced, minimal AudioDSP firmware
version points to correct values and recent additions to the topology
are parsed properly.

The only patch that points to 'new functionality' is:
ASoC: Intel: avs: Update ASRC definition

as with the struct definition updates, one can utilize the ASRC module
in both streaming directions now (previously limited to Capture).
Everything else either improves the logging or provides comments vital
for long-term maintenance of the code.

+97 -65
+1 -1
sound/soc/intel/avs/apl.c
··· 125 125 struct avs_apl_log_buffer_layout layout; 126 126 void __iomem *addr, *buf; 127 127 size_t dump_size; 128 - u16 offset = 0; 128 + u32 offset = 0; 129 129 u8 *dump, *pos; 130 130 131 131 dump_size = AVS_FW_REGS_SIZE + msg->ext.coredump.stack_dump_size;
+17 -7
sound/soc/intel/avs/core.c
··· 829 829 .hipc = &cnl_hipc_spec, 830 830 }; 831 831 832 - #define AVS_TGL_BASED_SPEC(sname) \ 832 + #define AVS_TGL_BASED_SPEC(sname, min) \ 833 833 static const struct avs_spec sname##_desc = { \ 834 834 .name = #sname, \ 835 - .min_fw_version = { 10, 29, 0, 5646 }, \ 835 + .min_fw_version = { 10, min, 0, 5646 }, \ 836 836 .dsp_ops = &avs_tgl_dsp_ops, \ 837 837 .core_init_mask = 1, \ 838 838 .attributes = AVS_PLATATTR_IMR, \ ··· 840 840 .hipc = &cnl_hipc_spec, \ 841 841 } 842 842 843 - AVS_TGL_BASED_SPEC(lkf); 844 - AVS_TGL_BASED_SPEC(tgl); 845 - AVS_TGL_BASED_SPEC(ehl); 846 - AVS_TGL_BASED_SPEC(adl); 847 - AVS_TGL_BASED_SPEC(adl_n); 843 + AVS_TGL_BASED_SPEC(lkf, 28); 844 + AVS_TGL_BASED_SPEC(tgl, 29); 845 + AVS_TGL_BASED_SPEC(ehl, 30); 846 + AVS_TGL_BASED_SPEC(adl, 35); 847 + AVS_TGL_BASED_SPEC(adl_n, 35); 848 848 849 849 static const struct pci_device_id avs_ids[] = { 850 850 { PCI_DEVICE_DATA(INTEL, HDA_SKL_LP, &skl_desc) }, ··· 902 902 MODULE_AUTHOR("Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>"); 903 903 MODULE_DESCRIPTION("Intel cAVS sound driver"); 904 904 MODULE_LICENSE("GPL"); 905 + MODULE_FIRMWARE("intel/skl/dsp_basefw.bin"); 906 + MODULE_FIRMWARE("intel/apl/dsp_basefw.bin"); 907 + MODULE_FIRMWARE("intel/cnl/dsp_basefw.bin"); 908 + MODULE_FIRMWARE("intel/icl/dsp_basefw.bin"); 909 + MODULE_FIRMWARE("intel/jsl/dsp_basefw.bin"); 910 + MODULE_FIRMWARE("intel/lkf/dsp_basefw.bin"); 911 + MODULE_FIRMWARE("intel/tgl/dsp_basefw.bin"); 912 + MODULE_FIRMWARE("intel/ehl/dsp_basefw.bin"); 913 + MODULE_FIRMWARE("intel/adl/dsp_basefw.bin"); 914 + MODULE_FIRMWARE("intel/adl_n/dsp_basefw.bin");
+1
sound/soc/intel/avs/debugfs.c
··· 10 10 #include <linux/kfifo.h> 11 11 #include <linux/wait.h> 12 12 #include <linux/sched/signal.h> 13 + #include <linux/string_helpers.h> 13 14 #include <sound/soc.h> 14 15 #include "avs.h" 15 16 #include "messages.h"
+15 -10
sound/soc/intel/avs/ipc.c
··· 184 184 { 185 185 struct avs_ipc *ipc = adev->ipc; 186 186 union avs_reply_msg msg = AVS_MSG(header); 187 - u64 reg; 187 + u32 sts, lec; 188 188 189 - reg = readq(avs_sram_addr(adev, AVS_FW_REGS_WINDOW)); 190 - trace_avs_ipc_reply_msg(header, reg); 189 + sts = snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev)); 190 + lec = snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev)); 191 + trace_avs_ipc_reply_msg(header, sts, lec); 191 192 192 193 ipc->rx.header = header; 193 194 /* Abort copying payload if request processing was unsuccessful. */ ··· 210 209 union avs_notify_msg msg = AVS_MSG(header); 211 210 size_t data_size = 0; 212 211 void *data = NULL; 213 - u64 reg; 212 + u32 sts, lec; 214 213 215 - reg = readq(avs_sram_addr(adev, AVS_FW_REGS_WINDOW)); 216 - trace_avs_ipc_notify_msg(header, reg); 214 + sts = snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev)); 215 + lec = snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev)); 216 + trace_avs_ipc_notify_msg(header, sts, lec); 217 217 218 218 /* Ignore spurious notifications until handshake is established. */ 219 219 if (!adev->ipc->ready && msg.notify_msg_type != AVS_NOTIFY_FW_READY) { ··· 369 367 static void avs_dsp_send_tx(struct avs_dev *adev, struct avs_ipc_msg *tx, bool read_fwregs) 370 368 { 371 369 const struct avs_spec *const spec = adev->spec; 372 - u64 reg = ULONG_MAX; 370 + u32 sts = UINT_MAX; 371 + u32 lec = UINT_MAX; 373 372 374 373 tx->header |= spec->hipc->req_busy_mask; 375 - if (read_fwregs) 376 - reg = readq(avs_sram_addr(adev, AVS_FW_REGS_WINDOW)); 374 + if (read_fwregs) { 375 + sts = snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev)); 376 + lec = snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev)); 377 + } 377 378 378 - trace_avs_request(tx, reg); 379 + trace_avs_request(tx, sts, lec); 379 380 380 381 if (tx->size) 381 382 memcpy_toio(avs_downlink_addr(adev), tx->data, tx->size);
+19 -17
sound/soc/intel/avs/loader.c
··· 167 167 (reg & AVS_ROM_INIT_DONE) == AVS_ROM_INIT_DONE, 168 168 AVS_ROM_INIT_POLLING_US, SKL_ROM_INIT_TIMEOUT_US); 169 169 if (ret < 0) { 170 - dev_err(adev->dev, "rom init timeout: %d\n", ret); 170 + dev_err(adev->dev, "rom init failed: %d, status: 0x%08x, lec: 0x%08x\n", 171 + ret, reg, snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev))); 171 172 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK); 172 173 return ret; 173 174 } ··· 181 180 AVS_FW_INIT_POLLING_US, AVS_FW_INIT_TIMEOUT_US); 182 181 hda_cldma_stop(cl); 183 182 if (ret < 0) { 184 - dev_err(adev->dev, "transfer fw failed: %d\n", ret); 183 + dev_err(adev->dev, "transfer fw failed: %d, status: 0x%08x, lec: 0x%08x\n", 184 + ret, reg, snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev))); 185 185 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK); 186 186 return ret; 187 187 } ··· 310 308 } 311 309 312 310 /* await ROM init */ 313 - ret = snd_hdac_adsp_readq_poll(adev, spec->sram->rom_status_offset, reg, 311 + ret = snd_hdac_adsp_readl_poll(adev, spec->sram->rom_status_offset, reg, 314 312 (reg & 0xF) == AVS_ROM_INIT_DONE || 315 313 (reg & 0xF) == APL_ROM_FW_ENTERED, 316 314 AVS_ROM_INIT_POLLING_US, APL_ROM_INIT_TIMEOUT_US); 317 315 if (ret < 0) { 318 - dev_err(adev->dev, "rom init timeout: %d\n", ret); 316 + dev_err(adev->dev, "rom init failed: %d, status: 0x%08x, lec: 0x%08x\n", 317 + ret, reg, snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev))); 319 318 goto err; 320 319 } 321 320 ··· 340 337 341 338 /* DMA id ignored when flashing from IMR as no transfer occurs. */ 342 339 ret = avs_hda_init_rom(adev, 0, false); 343 - if (ret < 0) { 344 - dev_err(adev->dev, "rom init failed: %d\n", ret); 340 + if (ret < 0) 345 341 return ret; 346 - } 347 342 348 343 ret = wait_for_completion_timeout(&adev->fw_ready, 349 344 msecs_to_jiffies(AVS_FW_INIT_TIMEOUT_MS)); 350 345 if (!ret) { 351 - dev_err(adev->dev, "firmware ready timeout\n"); 346 + dev_err(adev->dev, "firmware ready timeout, status: 0x%08x, lec: 0x%08x\n", 347 + snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev)), 348 + snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev))); 352 349 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK); 353 350 return -ETIMEDOUT; 354 351 } ··· 395 392 ret = avs_hda_init_rom(adev, dma_id, true); 396 393 if (!ret) 397 394 break; 398 - dev_info(adev->dev, "#%d rom init fail: %d\n", i + 1, ret); 395 + dev_info(adev->dev, "#%d rom init failed: %d\n", i + 1, ret); 399 396 } 400 397 if (ret < 0) 401 398 goto cleanup_resources; ··· 407 404 AVS_FW_INIT_POLLING_US, AVS_FW_INIT_TIMEOUT_US); 408 405 snd_hdac_dsp_trigger(hstream, false); 409 406 if (ret < 0) { 410 - dev_err(adev->dev, "transfer fw failed: %d\n", ret); 407 + dev_err(adev->dev, "transfer fw failed: %d, status: 0x%08x, lec: 0x%08x\n", 408 + ret, reg, snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev))); 411 409 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK); 412 410 } 413 411 ··· 588 584 ret = wait_for_completion_timeout(&adev->fw_ready, 589 585 msecs_to_jiffies(AVS_FW_INIT_TIMEOUT_MS)); 590 586 if (!ret) { 591 - dev_err(adev->dev, "firmware ready timeout\n"); 587 + dev_err(adev->dev, "firmware ready timeout, status: 0x%08x, lec: 0x%08x\n", 588 + snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev)), 589 + snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev))); 592 590 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK); 593 591 ret = -ETIMEDOUT; 594 592 goto release_fw; ··· 681 675 } 682 676 683 677 ret = avs_ipc_get_hw_config(adev, &adev->hw_cfg); 684 - if (ret) { 685 - dev_err(adev->dev, "get hw cfg failed: %d\n", ret); 678 + if (ret) 686 679 return AVS_IPC_RET(ret); 687 - } 688 680 689 681 ret = avs_ipc_get_fw_config(adev, &adev->fw_cfg); 690 - if (ret) { 691 - dev_err(adev->dev, "get fw cfg failed: %d\n", ret); 682 + if (ret) 692 683 return AVS_IPC_RET(ret); 693 - } 694 684 695 685 adev->core_refs = devm_kcalloc(adev->dev, adev->hw_cfg.dsp_cores, 696 686 sizeof(*adev->core_refs), GFP_KERNEL);
+16 -6
sound/soc/intel/avs/messages.c
··· 400 400 AVS_BASEFW_FIRMWARE_CONFIG, NULL, 0, 401 401 &payload, &payload_size); 402 402 if (ret) 403 - return ret; 403 + goto err; 404 404 /* Non-zero payload expected for FIRMWARE_CONFIG. */ 405 - if (!payload_size) 406 - return -EREMOTEIO; 405 + if (!payload_size) { 406 + ret = -EREMOTEIO; 407 + goto err; 408 + } 407 409 408 410 while (offset < payload_size) { 409 411 tlv = (struct avs_tlv *)(payload + offset); ··· 504 502 505 503 /* No longer needed, free it as it's owned by the get_large_config() caller. */ 506 504 kfree(payload); 505 + err: 506 + if (ret) 507 + dev_err(adev->dev, "get fw cfg failed: %d\n", ret); 507 508 return ret; 508 509 } 509 510 ··· 522 517 AVS_BASEFW_HARDWARE_CONFIG, NULL, 0, 523 518 &payload, &payload_size); 524 519 if (ret) 525 - return ret; 520 + goto err; 526 521 /* Non-zero payload expected for HARDWARE_CONFIG. */ 527 - if (!payload_size) 528 - return -EREMOTEIO; 522 + if (!payload_size) { 523 + ret = -EREMOTEIO; 524 + goto err; 525 + } 529 526 530 527 while (offset < payload_size) { 531 528 tlv = (struct avs_tlv *)(payload + offset); ··· 597 590 exit: 598 591 /* No longer needed, free it as it's owned by the get_large_config() caller. */ 599 592 kfree(payload); 593 + err: 594 + if (ret) 595 + dev_err(adev->dev, "get hw cfg failed: %d\n", ret); 600 596 return ret; 601 597 } 602 598
+1 -2
sound/soc/intel/avs/messages.h
··· 859 859 struct avs_asrc_cfg { 860 860 struct avs_modcfg_base base; 861 861 u32 out_freq; 862 - u32 rsvd0:1; 863 - u32 mode:1; 862 + u32 mode:2; 864 863 u32 rsvd2:2; 865 864 u32 disable_jitter_buffer:1; 866 865 u32 rsvd3:27;
+4 -1
sound/soc/intel/avs/pcm.c
··· 161 161 struct snd_soc_dpcm *dpcm; 162 162 163 163 be = snd_soc_substream_to_rtd(substream); 164 + /* dpcm_fe_dai_open() guarantees the list is not empty at this point. */ 164 165 for_each_dpcm_fe(be, substream->stream, dpcm) { 165 166 fe = dpcm->fe; 166 167 fe_hw_params = &fe->dpcm[substream->stream].hw_params; ··· 577 576 hdac_stream(host_stream)->format_val = 0; 578 577 579 578 fe = snd_soc_substream_to_rtd(substream); 579 + /* dpcm_fe_dai_open() guarantees the list is not empty at this point. */ 580 580 for_each_dpcm_be(fe, substream->stream, dpcm) { 581 581 be = dpcm->be; 582 582 be_hw_params = &be->dpcm[substream->stream].hw_params; ··· 1566 1564 if (ret < 0) { 1567 1565 dev_err(component->dev, "create widgets failed: %d\n", 1568 1566 ret); 1567 + snd_soc_unregister_dai(dai); 1569 1568 goto exit; 1570 1569 } 1571 1570 } ··· 1581 1578 1582 1579 static void avs_component_hda_remove(struct snd_soc_component *component) 1583 1580 { 1584 - avs_component_hda_unregister_dais(component); 1585 1581 avs_component_remove(component); 1582 + avs_component_hda_unregister_dais(component); 1586 1583 } 1587 1584 1588 1585 static int avs_component_hda_open(struct snd_soc_component *component,
+1 -1
sound/soc/intel/avs/registers.h
··· 74 74 /* Constants used when accessing SRAM, space shared with firmware */ 75 75 #define AVS_FW_REG_BASE(adev) ((adev)->spec->sram->base_offset) 76 76 #define AVS_FW_REG_STATUS(adev) (AVS_FW_REG_BASE(adev) + 0x0) 77 - #define AVS_FW_REG_ERROR_CODE(adev) (AVS_FW_REG_BASE(adev) + 0x4) 77 + #define AVS_FW_REG_ERROR(adev) (AVS_FW_REG_BASE(adev) + 0x4) 78 78 79 79 #define AVS_WINDOW_CHUNK_SIZE SZ_4K 80 80 #define AVS_FW_REGS_SIZE AVS_WINDOW_CHUNK_SIZE
+2 -2
sound/soc/intel/avs/topology.c
··· 1466 1466 1467 1467 static const struct avs_tplg_token_parser mod_init_config_parsers[] = { 1468 1468 { 1469 - .token = AVS_TKN_MOD_INIT_CONFIG_ID_U32, 1469 + .token = AVS_TKN_INIT_CONFIG_ID_U32, 1470 1470 .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, 1471 1471 .offset = offsetof(struct avs_tplg_init_config, id), 1472 1472 .parse = avs_parse_word_token, ··· 1519 1519 esize = le32_to_cpu(tuples->size) + le32_to_cpu(tmp->size); 1520 1520 1521 1521 ret = parse_dictionary_entries(comp, tuples, esize, config, 1, sizeof(*config), 1522 - AVS_TKN_MOD_INIT_CONFIG_ID_U32, 1522 + AVS_TKN_INIT_CONFIG_ID_U32, 1523 1523 mod_init_config_parsers, 1524 1524 ARRAY_SIZE(mod_init_config_parsers)); 1525 1525
+20 -18
sound/soc/intel/avs/trace.h
··· 37 37 38 38 void trace_avs_msg_payload(const void *data, size_t size); 39 39 40 - #define trace_avs_request(msg, fwregs) \ 40 + #define trace_avs_request(msg, sts, lec) \ 41 41 ({ \ 42 - trace_avs_ipc_request_msg((msg)->header, fwregs); \ 42 + trace_avs_ipc_request_msg((msg)->header, sts, lec); \ 43 43 trace_avs_msg_payload((msg)->data, (msg)->size); \ 44 44 }) 45 45 46 - #define trace_avs_reply(msg, fwregs) \ 46 + #define trace_avs_reply(msg, sts, lec) \ 47 47 ({ \ 48 - trace_avs_ipc_reply_msg((msg)->header, fwregs); \ 48 + trace_avs_ipc_reply_msg((msg)->header, sts, lec); \ 49 49 trace_avs_msg_payload((msg)->data, (msg)->size); \ 50 50 }) 51 51 52 - #define trace_avs_notify(msg, fwregs) \ 52 + #define trace_avs_notify(msg, sts, lec) \ 53 53 ({ \ 54 - trace_avs_ipc_notify_msg((msg)->header, fwregs); \ 54 + trace_avs_ipc_notify_msg((msg)->header, sts, lec); \ 55 55 trace_avs_msg_payload((msg)->data, (msg)->size); \ 56 56 }) 57 57 #endif 58 58 59 59 DECLARE_EVENT_CLASS(avs_ipc_msg_hdr, 60 60 61 - TP_PROTO(u64 header, u64 fwregs), 61 + TP_PROTO(u64 header, u32 sts, u32 lec), 62 62 63 - TP_ARGS(header, fwregs), 63 + TP_ARGS(header, sts, lec), 64 64 65 65 TP_STRUCT__entry( 66 66 __field(u64, header) 67 - __field(u64, fwregs) 67 + __field(u32, sts) 68 + __field(u32, lec) 68 69 ), 69 70 70 71 TP_fast_assign( 71 72 __entry->header = header; 72 - __entry->fwregs = fwregs; 73 + __entry->sts = sts; 74 + __entry->lec = lec; 73 75 ), 74 76 75 77 TP_printk("primary: 0x%08X, extension: 0x%08X,\n" 76 - "fwstatus: 0x%08X, fwerror: 0x%08X", 78 + "status: 0x%08X, error: 0x%08X", 77 79 lower_32_bits(__entry->header), upper_32_bits(__entry->header), 78 - lower_32_bits(__entry->fwregs), upper_32_bits(__entry->fwregs)) 80 + __entry->sts, __entry->lec) 79 81 ); 80 82 81 83 DEFINE_EVENT(avs_ipc_msg_hdr, avs_ipc_request_msg, 82 - TP_PROTO(u64 header, u64 fwregs), 83 - TP_ARGS(header, fwregs) 84 + TP_PROTO(u64 header, u32 sts, u32 lec), 85 + TP_ARGS(header, sts, lec) 84 86 ); 85 87 86 88 DEFINE_EVENT(avs_ipc_msg_hdr, avs_ipc_reply_msg, 87 - TP_PROTO(u64 header, u64 fwregs), 88 - TP_ARGS(header, fwregs) 89 + TP_PROTO(u64 header, u32 sts, u32 lec), 90 + TP_ARGS(header, sts, lec) 89 91 ); 90 92 91 93 DEFINE_EVENT(avs_ipc_msg_hdr, avs_ipc_notify_msg, 92 - TP_PROTO(u64 header, u64 fwregs), 93 - TP_ARGS(header, fwregs) 94 + TP_PROTO(u64 header, u32 sts, u32 lec), 95 + TP_ARGS(header, sts, lec) 94 96 ); 95 97 96 98 TRACE_EVENT_CONDITION(avs_ipc_msg_payload,