ASoC: SOF: ipc4/Intel: Improve and enable IPC error dump
authorMark Brown <broonie@kernel.org>
Fri, 23 Sep 2022 19:46:25 +0000 (20:46 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 23 Sep 2022 19:46:25 +0000 (20:46 +0100)
Merge series from Peter Ujfalusi <peter.ujfalusi@linux.intel.com>:

On Intel platforms the registers for DSP communications are used differently,
the IPC dump information is not correct since important registers are not
printed and existing ones are used a bit differently for IPC4.

As a last step, enable the IPC timeout 'handling' and allow the printout of
the now usefull IPC dump.

1  2 
sound/soc/sof/intel/apl.c
sound/soc/sof/intel/cnl.c
sound/soc/sof/intel/hda.c
sound/soc/sof/intel/hda.h
sound/soc/sof/intel/icl.c
sound/soc/sof/intel/mtl.c
sound/soc/sof/intel/skl.c
sound/soc/sof/intel/tgl.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -571,30 -552,167 +571,29 @@@ static int mtl_dsp_ipc_get_window_offse
        return MTL_SRAM_WINDOW_OFFSET(id);
  }
  
 -static int mtl_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
 -{
 -      struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 -      const struct sof_intel_dsp_desc *chip = hda->desc;
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      struct hdac_bus *bus = sof_to_bus(sdev);
 -#endif
 -      u32 dsphfdsscs;
 -      u32 cpa;
 -      int ret;
 -      int i;
 -
 -      mtl_disable_ipc_interrupts(sdev);
 -      ret = mtl_disable_interrupts(sdev);
 -      if (ret)
 -              return ret;
 -
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      hda_codec_jack_wake_enable(sdev, runtime_suspend);
 -      /* power down all hda link */
 -      snd_hdac_ext_bus_link_power_down_all(bus);
 -#endif
 -      snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL,
 -                              MTL_HFPWRCTL_WPDSPHPXPG, 0);
 -
 -      /* Set the DSP subsystem power down */
 -      snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFDSSCS,
 -                              MTL_HFDSSCS_SPA_MASK, 0);
 -
 -      /* Wait for unstable CPA read (1 then 0 then 1) just after setting SPA bit */
 -      usleep_range(1000, 1010);
 -
 -      /* poll with timeout to check if operation successful */
 -      cpa = MTL_HFDSSCS_CPA_MASK;
 -      dsphfdsscs = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFDSSCS);
 -      ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFDSSCS, dsphfdsscs,
 -                                          (dsphfdsscs & cpa) == 0, HDA_DSP_REG_POLL_INTERVAL_US,
 -                                      HDA_DSP_RESET_TIMEOUT_US);
 -      if (ret < 0)
 -              dev_err(sdev->dev, "failed to disable DSP subsystem\n");
 -
 -      /* reset ref counts for all cores */
 -      for (i = 0; i < chip->cores_num; i++)
 -              sdev->dsp_core_ref_count[i] = 0;
 -
 -      /* TODO: need to reset controller? */
 -
 -      /* display codec can be powered off after link reset */
 -      hda_codec_i915_display_power(sdev, false);
 -
 -      return 0;
 -}
 -
 -static int mtl_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
 -{
 -      const struct sof_dsp_power_state target_dsp_state = {
 -              .state = target_state,
 -              .substate = target_state == SOF_DSP_PM_D0 ?
 -                              SOF_HDA_DSP_PM_D0I3 : 0,
 -      };
 -      int ret;
 -
 -      ret = mtl_suspend(sdev, false);
 -      if (ret < 0)
 -              return ret;
 -
 -      return snd_sof_dsp_set_power_state(sdev, &target_dsp_state);
 -}
 -
 -static int mtl_dsp_runtime_suspend(struct snd_sof_dev *sdev)
 -{
 -      const struct sof_dsp_power_state target_state = {
 -              .state = SOF_DSP_PM_D3,
 -      };
 -      int ret;
 -
 -      ret = mtl_suspend(sdev, true);
 -      if (ret < 0)
 -              return ret;
 -
 -      return snd_sof_dsp_set_power_state(sdev, &target_state);
 -}
 -
 -static int mtl_resume(struct snd_sof_dev *sdev, bool runtime_resume)
 -{
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      struct hdac_bus *bus = sof_to_bus(sdev);
 -      struct hdac_ext_link *hlink = NULL;
 -#endif
 -
 -      /* display codec must be powered before link reset */
 -      hda_codec_i915_display_power(sdev, true);
 -
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      /* check jack status */
 -      if (runtime_resume) {
 -              hda_codec_jack_wake_enable(sdev, false);
 -              if (sdev->system_suspend_target == SOF_SUSPEND_NONE)
 -                      hda_codec_jack_check(sdev);
 -      }
 -
 -      /* turn off the links that were off before suspend */
 -      list_for_each_entry(hlink, &bus->hlink_list, list) {
 -              if (!hlink->ref_count)
 -                      snd_hdac_ext_bus_link_power_down(hlink);
 -      }
 -
 -      /* check dma status and clean up CORB/RIRB buffers */
 -      if (!bus->cmd_dma_state)
 -              snd_hdac_bus_stop_cmd_io(bus);
 -#endif
 -
 -      return 0;
 -}
 -
 -static int mtl_dsp_resume(struct snd_sof_dev *sdev)
 -{
 -      const struct sof_dsp_power_state target_state = {
 -              .state = SOF_DSP_PM_D0,
 -              .substate = SOF_HDA_DSP_PM_D0I0,
 -      };
 -      int ret;
 -
 -      ret = mtl_resume(sdev, false);
 -      if (ret < 0)
 -              return ret;
 -
 -      return snd_sof_dsp_set_power_state(sdev, &target_state);
 -}
 -
 -static int mtl_dsp_runtime_resume(struct snd_sof_dev *sdev)
 -{
 -      const struct sof_dsp_power_state target_state = {
 -              .state = SOF_DSP_PM_D0,
 -      };
 -      int ret;
 -
 -      ret = mtl_resume(sdev, true);
 -      if (ret < 0)
 -              return ret;
 -
 -      return snd_sof_dsp_set_power_state(sdev, &target_state);
 -}
 -
  static void mtl_ipc_dump(struct snd_sof_dev *sdev)
  {
-       u32 hipcctl;
-       u32 hipcida;
-       u32 hipctdr;
+       u32 hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl;
  
-       /* read IPC status */
+       hipcidr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDR);
+       hipcidd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDDY);
        hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA);
-       hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL);
        hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR);
+       hipctdd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDDY);
+       hipctda = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDA);
+       hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL);
  
-       /* dump the IPC regs */
-       /* TODO: parse the raw msg */
        dev_err(sdev->dev,
-               "error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n",
-               hipcida, hipctdr, hipcctl);
+               "Host IPC initiator: %#x|%#x|%#x, target: %#x|%#x|%#x, ctl: %#x\n",
+               hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl);
  }
  
 +static int mtl_dsp_disable_interrupts(struct snd_sof_dev *sdev)
 +{
 +      mtl_disable_ipc_interrupts(sdev);
 +      return mtl_disable_interrupts(sdev);
 +}
 +
  /* Meteorlake ops */
  struct snd_sof_dsp_ops sof_mtl_ops;
  EXPORT_SYMBOL_NS(sof_mtl_ops, SND_SOC_SOF_INTEL_HDA_COMMON);
Simple merge
Simple merge