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

Merge series "SOF fixes and updates" from Ranjani Sridharan <ranjani.sridharan@linux.intel.com>:

This series includes fixes for error reporting, topology parsing and
runtime PM issues along with updates for DMIC support and IMX platforms.

Iulian Olaru (2):
ASoC: SOF: imx: Replace sdev->private with sdev->pdata->hw_pdata
ASoC: SOF: sof-of-dev: Add .arch_ops field

Jaska Uimonen (1):
ASoC: SOF: intel: hda: support also devices with 1 and 3 dmics

Keyon Jie (1):
ASoC: SOF: topology: fix the ipc_size calculation for process
component

Rander Wang (1):
ASoC: SOF: fix a runtime pm issue in SOF when HDMI codec doesn't work

Ranjani Sridharan (2):
ASoC: SOF: Intel: hda: report error only for the last ROM init
iteration
ASoC: SOF: Intel: hda: add extended rom status dump to error log

sound/soc/sof/imx/Kconfig | 2 ++
sound/soc/sof/imx/imx8.c | 17 +++++++++----
sound/soc/sof/imx/imx8m.c | 10 +++++---
sound/soc/sof/intel/hda-codec.c | 4 +--
sound/soc/sof/intel/hda-loader.c | 42 +++++++++++++++++++-------------
sound/soc/sof/intel/hda.c | 26 +++++++++++++++++++-
sound/soc/sof/topology.c | 4 +--
7 files changed, 74 insertions(+), 31 deletions(-)

--
2.25.1

+75 -32
+2
sound/soc/sof/imx/Kconfig
··· 30 30 31 31 config SND_SOC_SOF_IMX8 32 32 tristate 33 + select SND_SOC_SOF_XTENSA 33 34 help 34 35 This option is not user-selectable but automagically handled by 35 36 'select' statements at a higher level ··· 45 44 46 45 config SND_SOC_SOF_IMX8M 47 46 tristate 47 + select SND_SOC_SOF_XTENSA 48 48 help 49 49 This option is not user-selectable but automagically handled by 50 50 'select' statements at a higher level
+12 -5
sound/soc/sof/imx/imx8.c
··· 126 126 127 127 static int imx8_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) 128 128 { 129 - struct imx8_priv *priv = (struct imx8_priv *)sdev->private; 129 + struct imx8_priv *priv = sdev->pdata->hw_pdata; 130 130 131 131 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 132 132 msg->msg_size); ··· 140 140 */ 141 141 static int imx8x_run(struct snd_sof_dev *sdev) 142 142 { 143 - struct imx8_priv *dsp_priv = (struct imx8_priv *)sdev->private; 143 + struct imx8_priv *dsp_priv = sdev->pdata->hw_pdata; 144 144 int ret; 145 145 146 146 ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP, ··· 180 180 181 181 static int imx8_run(struct snd_sof_dev *sdev) 182 182 { 183 - struct imx8_priv *dsp_priv = (struct imx8_priv *)sdev->private; 183 + struct imx8_priv *dsp_priv = sdev->pdata->hw_pdata; 184 184 int ret; 185 185 186 186 ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP, ··· 213 213 if (!priv) 214 214 return -ENOMEM; 215 215 216 - sdev->private = priv; 216 + sdev->pdata->hw_pdata = priv; 217 217 priv->dev = sdev->dev; 218 218 priv->sdev = sdev; 219 219 ··· 339 339 340 340 static int imx8_remove(struct snd_sof_dev *sdev) 341 341 { 342 - struct imx8_priv *priv = (struct imx8_priv *)sdev->private; 342 + struct imx8_priv *priv = sdev->pdata->hw_pdata; 343 343 int i; 344 344 345 345 platform_device_unregister(priv->ipc_dev); ··· 424 424 /* firmware loading */ 425 425 .load_firmware = snd_sof_load_firmware_memcpy, 426 426 427 + /* Firmware ops */ 428 + .arch_ops = &sof_xtensa_arch_ops, 429 + 427 430 /* DAI drivers */ 428 431 .drv = imx8_dai, 429 432 .num_drv = ARRAY_SIZE(imx8_dai), ··· 467 464 /* firmware loading */ 468 465 .load_firmware = snd_sof_load_firmware_memcpy, 469 466 467 + /* Firmware ops */ 468 + .arch_ops = &sof_xtensa_arch_ops, 469 + 470 470 /* DAI drivers */ 471 471 .drv = imx8_dai, 472 472 .num_drv = ARRAY_SIZE(imx8_dai), ··· 483 477 }; 484 478 EXPORT_SYMBOL(sof_imx8x_ops); 485 479 480 + MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); 486 481 MODULE_LICENSE("Dual BSD/GPL");
+7 -3
sound/soc/sof/imx/imx8m.c
··· 99 99 100 100 static int imx8m_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) 101 101 { 102 - struct imx8m_priv *priv = (struct imx8m_priv *)sdev->private; 102 + struct imx8m_priv *priv = sdev->pdata->hw_pdata; 103 103 104 104 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 105 105 msg->msg_size); ··· 133 133 if (!priv) 134 134 return -ENOMEM; 135 135 136 - sdev->private = priv; 136 + sdev->pdata->hw_pdata = priv; 137 137 priv->dev = sdev->dev; 138 138 priv->sdev = sdev; 139 139 ··· 209 209 210 210 static int imx8m_remove(struct snd_sof_dev *sdev) 211 211 { 212 - struct imx8m_priv *priv = (struct imx8m_priv *)sdev->private; 212 + struct imx8m_priv *priv = sdev->pdata->hw_pdata; 213 213 214 214 platform_device_unregister(priv->ipc_dev); 215 215 ··· 277 277 /* firmware loading */ 278 278 .load_firmware = snd_sof_load_firmware_memcpy, 279 279 280 + /* Firmware ops */ 281 + .arch_ops = &sof_xtensa_arch_ops, 282 + 280 283 /* DAI drivers */ 281 284 .drv = imx8m_dai, 282 285 .num_drv = ARRAY_SIZE(imx8m_dai), ··· 292 289 }; 293 290 EXPORT_SYMBOL(sof_imx8m_ops); 294 291 292 + MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); 295 293 MODULE_LICENSE("Dual BSD/GPL");
+2 -2
sound/soc/sof/intel/hda-codec.c
··· 151 151 if (!hdev->bus->audio_component) { 152 152 dev_dbg(sdev->dev, 153 153 "iDisp hw present but no driver\n"); 154 - return -ENOENT; 154 + goto error; 155 155 } 156 156 hda_priv->need_display_power = true; 157 157 } ··· 174 174 * other return codes without modification 175 175 */ 176 176 if (ret == 0) 177 - ret = -ENOENT; 177 + goto error; 178 178 } 179 179 180 180 return ret;
+26 -18
sound/soc/sof/intel/hda-loader.c
··· 79 79 * reset/stall and then turn it off 80 80 */ 81 81 static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata, 82 - u32 fwsize, int stream_tag) 82 + u32 fwsize, int stream_tag, int iteration) 83 83 { 84 84 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 85 85 const struct sof_intel_dsp_desc *chip = hda->desc; ··· 90 90 /* step 1: power up corex */ 91 91 ret = hda_dsp_core_power_up(sdev, chip->cores_mask); 92 92 if (ret < 0) { 93 - dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n"); 93 + if (iteration == HDA_FW_BOOT_ATTEMPTS) 94 + dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n"); 94 95 goto err; 95 96 } 96 97 ··· 113 112 /* step 3: unset core 0 reset state & unstall/run core 0 */ 114 113 ret = hda_dsp_core_run(sdev, HDA_DSP_CORE_MASK(0)); 115 114 if (ret < 0) { 116 - dev_err(sdev->dev, "error: dsp core start failed %d\n", ret); 115 + if (iteration == HDA_FW_BOOT_ATTEMPTS) 116 + dev_err(sdev->dev, 117 + "error: dsp core start failed %d\n", ret); 117 118 ret = -EIO; 118 119 goto err; 119 120 } ··· 129 126 HDA_DSP_INIT_TIMEOUT_US); 130 127 131 128 if (ret < 0) { 132 - dev_err(sdev->dev, "error: %s: timeout for HIPCIE done\n", 133 - __func__); 129 + if (iteration == HDA_FW_BOOT_ATTEMPTS) 130 + dev_err(sdev->dev, 131 + "error: %s: timeout for HIPCIE done\n", 132 + __func__); 134 133 goto err; 135 134 } 136 135 ··· 146 141 ret = hda_dsp_core_power_down(sdev, 147 142 chip->cores_mask & ~(HDA_DSP_CORE_MASK(0))); 148 143 if (ret < 0) { 149 - dev_err(sdev->dev, "error: dsp core x power down failed\n"); 144 + if (iteration == HDA_FW_BOOT_ATTEMPTS) 145 + dev_err(sdev->dev, 146 + "error: dsp core x power down failed\n"); 150 147 goto err; 151 148 } 152 149 ··· 166 159 if (!ret) 167 160 return 0; 168 161 169 - dev_err(sdev->dev, 170 - "error: %s: timeout HDA_DSP_SRAM_REG_ROM_STATUS read\n", 171 - __func__); 162 + if (iteration == HDA_FW_BOOT_ATTEMPTS) 163 + dev_err(sdev->dev, 164 + "error: %s: timeout HDA_DSP_SRAM_REG_ROM_STATUS read\n", 165 + __func__); 172 166 173 167 err: 174 168 hda_dsp_dump(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX); ··· 337 329 338 330 /* try ROM init a few times before giving up */ 339 331 for (i = 0; i < HDA_FW_BOOT_ATTEMPTS; i++) { 332 + dev_dbg(sdev->dev, 333 + "Attempting iteration %d of Core En/ROM load...\n", i); 334 + 340 335 ret = cl_dsp_init(sdev, stripped_firmware.data, 341 - stripped_firmware.size, tag); 336 + stripped_firmware.size, tag, i + 1); 342 337 343 338 /* don't retry anymore if successful */ 344 339 if (!ret) 345 340 break; 346 - 347 - dev_dbg(sdev->dev, "iteration %d of Core En/ROM load failed: %d\n", 348 - i, ret); 349 - dev_dbg(sdev->dev, "Error code=0x%x: FW status=0x%x\n", 350 - snd_sof_dsp_read(sdev, HDA_DSP_BAR, 351 - HDA_DSP_SRAM_REG_ROM_ERROR), 352 - snd_sof_dsp_read(sdev, HDA_DSP_BAR, 353 - HDA_DSP_SRAM_REG_ROM_STATUS)); 354 341 } 355 342 356 343 if (i == HDA_FW_BOOT_ATTEMPTS) { 357 344 dev_err(sdev->dev, "error: dsp init failed after %d attempts with err: %d\n", 358 345 i, ret); 346 + dev_err(sdev->dev, "ROM error=0x%x: FW status=0x%x\n", 347 + snd_sof_dsp_read(sdev, HDA_DSP_BAR, 348 + HDA_DSP_SRAM_REG_ROM_ERROR), 349 + snd_sof_dsp_read(sdev, HDA_DSP_BAR, 350 + HDA_DSP_SRAM_REG_ROM_STATUS)); 359 351 goto cleanup; 360 352 } 361 353
+25 -1
sound/soc/sof/intel/hda.c
··· 37 37 #include "shim.h" 38 38 39 39 #define EXCEPT_MAX_HDR_SIZE 0x400 40 + #define HDA_EXT_ROM_STATUS_SIZE 8 40 41 41 42 #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) 42 43 ··· 415 414 } 416 415 } 417 416 417 + /* dump the first 8 dwords representing the extended ROM status */ 418 + static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev) 419 + { 420 + char msg[128]; 421 + int len = 0; 422 + u32 value; 423 + int i; 424 + 425 + for (i = 0; i < HDA_EXT_ROM_STATUS_SIZE; i++) { 426 + value = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_ROM_STATUS + i * 0x4); 427 + len += snprintf(msg + len, sizeof(msg) - len, " 0x%x", value); 428 + } 429 + 430 + dev_err(sdev->dev, "error: extended rom status:%s", msg); 431 + } 432 + 418 433 void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) 419 434 { 420 435 struct sof_ipc_dsp_oops_xtensa xoops; ··· 454 437 } else { 455 438 dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", 456 439 status, panic); 440 + hda_dsp_dump_ext_rom_status(sdev); 457 441 hda_dsp_get_status(sdev); 458 442 } 459 443 } ··· 562 544 if (nhlt) { 563 545 dmic_num = intel_nhlt_get_dmic_geo(sdev->dev, nhlt); 564 546 intel_nhlt_free(nhlt); 565 - if (dmic_num == 2 || dmic_num == 4) 547 + if (dmic_num >= 1 && dmic_num <= 4) 566 548 return dmic_num; 567 549 } 568 550 ··· 1010 992 dmic_num = hda_dmic_num; 1011 993 1012 994 switch (dmic_num) { 995 + case 1: 996 + dmic_str = "-1ch"; 997 + break; 1013 998 case 2: 1014 999 dmic_str = "-2ch"; 1000 + break; 1001 + case 3: 1002 + dmic_str = "-3ch"; 1015 1003 break; 1016 1004 case 4: 1017 1005 dmic_str = "-4ch";
+1 -3
sound/soc/sof/topology.c
··· 2114 2114 goto out; 2115 2115 } 2116 2116 2117 - ipc_size = sizeof(struct sof_ipc_comp_process) + 2118 - le32_to_cpu(private->size) + 2119 - ipc_data_size; 2117 + ipc_size = sizeof(struct sof_ipc_comp_process) + ipc_data_size; 2120 2118 2121 2119 /* we are exceeding max ipc size, config needs to be sent separately */ 2122 2120 if (ipc_size > SOF_IPC_MSG_MAX_SIZE) {