Merge tag 'soundwire-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 19 Dec 2022 14:47:33 +0000 (08:47 -0600)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 19 Dec 2022 14:47:33 +0000 (08:47 -0600)
Pull soundwire updates from Vinod Koul:
 "This include bunch of Intel driver code reorganization and support for
  qcom v1.7.0 controller:

   - intel: reorganization of hw_ops callbacks, splitting files etc

   - qcom: support for v1.7.0 qcom controllers"

* tag 'soundwire-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
  soundwire: intel: split auxdevice to different file
  soundwire: intel: add in-band wake callbacks in hw_ops
  soundwire: intel: add link power management callbacks in hw_ops
  soundwire: intel: add bus management callbacks in hw_ops
  soundwire: intel: add register_dai callback in hw_ops
  soundwire: intel: add debugfs callbacks in hw_ops
  soundwire: intel: start using hw_ops
  dt-bindings: soundwire: Convert text bindings to DT Schema
  soundwire: cadence: use dai_runtime_array instead of dma_data
  soundwire: cadence: rename sdw_cdns_dai_dma_data as sdw_cdns_dai_runtime
  soundwire: qcom: add support for v1.7 Soundwire Controller
  dt-bindings: soundwire: qcom: add v1.7.0 support
  soundwire: qcom: make reset optional for v1.6 controller
  soundwire: qcom: remove unused SWRM_SPECIAL_CMD_ID
  soundwire: dmi-quirks: add quirk variant for LAPBC710 NUC15

1  2 
drivers/soundwire/intel_init.c
include/linux/soundwire/sdw_intel.h
sound/soc/sof/intel/hda.c

@@@ -17,6 -17,7 +17,7 @@@
  #include <linux/soundwire/sdw_intel.h>
  #include "cadence_master.h"
  #include "intel.h"
+ #include "intel_auxdevice.h"
  
  static void intel_link_dev_release(struct device *dev)
  {
@@@ -60,6 -61,7 +61,7 @@@ static struct sdw_intel_link_dev *intel
  
        /* Add link information used in the driver probe */
        link = &ldev->link_res;
+       link->hw_ops = res->hw_ops;
        link->mmio_base = res->mmio_base;
        link->registers = res->mmio_base + SDW_LINK_BASE
                + (SDW_LINK_SIZE * link_id);
@@@ -125,6 -127,30 +127,6 @@@ static int sdw_intel_cleanup(struct sdw
        return 0;
  }
  
 -#define HDA_DSP_REG_ADSPIC2             (0x10)
 -#define HDA_DSP_REG_ADSPIS2             (0x14)
 -#define HDA_DSP_REG_ADSPIC2_SNDW        BIT(5)
 -
 -/**
 - * sdw_intel_enable_irq() - enable/disable Intel SoundWire IRQ
 - * @mmio_base: The mmio base of the control register
 - * @enable: true if enable
 - */
 -void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable)
 -{
 -      u32 val;
 -
 -      val = readl(mmio_base + HDA_DSP_REG_ADSPIC2);
 -
 -      if (enable)
 -              val |= HDA_DSP_REG_ADSPIC2_SNDW;
 -      else
 -              val &= ~HDA_DSP_REG_ADSPIC2_SNDW;
 -
 -      writel(val, mmio_base + HDA_DSP_REG_ADSPIC2);
 -}
 -EXPORT_SYMBOL_NS(sdw_intel_enable_irq, SOUNDWIRE_INTEL_INIT);
 -
  irqreturn_t sdw_intel_thread(int irq, void *dev_id)
  {
        struct sdw_intel_ctx *ctx = dev_id;
        list_for_each_entry(link, &ctx->link_list, list)
                sdw_cdns_irq(irq, link->cdns);
  
 -      sdw_intel_enable_irq(ctx->mmio_base, true);
        return IRQ_HANDLED;
  }
  EXPORT_SYMBOL_NS(sdw_intel_thread, SOUNDWIRE_INTEL_INIT);
@@@ -272,12 -299,24 +274,12 @@@ sdw_intel_startup_controller(struct sdw
  {
        struct acpi_device *adev = acpi_fetch_acpi_dev(ctx->handle);
        struct sdw_intel_link_dev *ldev;
 -      u32 caps;
        u32 link_mask;
        int i;
  
        if (!adev)
                return -EINVAL;
  
 -      /* Check SNDWLCAP.LCOUNT */
 -      caps = ioread32(ctx->mmio_base + ctx->shim_base + SDW_SHIM_LCAP);
 -      caps &= SDW_SHIM_LCAP_LCOUNT_MASK;
 -
 -      /* Check HW supported vs property value */
 -      if (caps < ctx->count) {
 -              dev_err(&adev->dev,
 -                      "BIOS master count is larger than hardware capabilities\n");
 -              return -EINVAL;
 -      }
 -
        if (!ctx->ldev)
                return -EINVAL;
  
@@@ -233,6 -233,7 +233,7 @@@ struct sdw_intel_ctx 
   * struct sdw_intel_res - Soundwire Intel global resource structure,
   * typically populated by the DSP driver
   *
+  * @hw_ops: abstraction for platform ops
   * @count: link count
   * @mmio_base: mmio base of SoundWire registers
   * @irq: interrupt number
   * @alh_base: sdw alh base.
   */
  struct sdw_intel_res {
+       const struct sdw_intel_hw_ops *hw_ops;
        int count;
        void __iomem *mmio_base;
        int irq;
@@@ -286,8 -288,52 +288,50 @@@ int sdw_intel_startup(struct sdw_intel_
  
  void sdw_intel_exit(struct sdw_intel_ctx *ctx);
  
 -void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable);
 -
  irqreturn_t sdw_intel_thread(int irq, void *dev_id);
  
  #define SDW_INTEL_QUIRK_MASK_BUS_DISABLE      BIT(1)
  
+ struct sdw_intel;
+ /* struct intel_sdw_hw_ops - SoundWire ops for Intel platforms.
+  * @debugfs_init: initialize all debugfs capabilities
+  * @debugfs_exit: close and cleanup debugfs capabilities
+  * @register_dai: read all PDI information and register DAIs
+  * @check_clock_stop: throw error message if clock is not stopped.
+  * @start_bus: normal start
+  * @start_bus_after_reset: start after reset
+  * @start_bus_after_clock_stop: start after mode0 clock stop
+  * @stop_bus: stop all bus
+  * @link_power_up: power-up using chip-specific helpers
+  * @link_power_down: power-down with chip-specific helpers
+  * @shim_check_wake: check if a wake was received
+  * @shim_wake: enable/disable in-band wake management
+  * @pre_bank_switch: helper for bus management
+  * @post_bank_switch: helper for bus management
+  */
+ struct sdw_intel_hw_ops {
+       void (*debugfs_init)(struct sdw_intel *sdw);
+       void (*debugfs_exit)(struct sdw_intel *sdw);
+       int (*register_dai)(struct sdw_intel *sdw);
+       void (*check_clock_stop)(struct sdw_intel *sdw);
+       int (*start_bus)(struct sdw_intel *sdw);
+       int (*start_bus_after_reset)(struct sdw_intel *sdw);
+       int (*start_bus_after_clock_stop)(struct sdw_intel *sdw);
+       int (*stop_bus)(struct sdw_intel *sdw, bool clock_stop);
+       int (*link_power_up)(struct sdw_intel *sdw);
+       int (*link_power_down)(struct sdw_intel *sdw);
+       int  (*shim_check_wake)(struct sdw_intel *sdw);
+       void (*shim_wake)(struct sdw_intel *sdw, bool wake_enable);
+       int (*pre_bank_switch)(struct sdw_intel *sdw);
+       int (*post_bank_switch)(struct sdw_intel *sdw);
+ };
+ extern const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops;
  #endif
@@@ -155,27 -155,9 +155,27 @@@ struct sdw_intel_ops sdw_callback = 
        .free_stream = sdw_free_stream,
  };
  
 +void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable)
 +{
 +      struct sof_intel_hda_dev *hdev;
 +
 +      hdev = sdev->pdata->hw_pdata;
 +
 +      if (!hdev->sdw)
 +              return;
 +
 +      snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC2,
 +                              HDA_DSP_REG_ADSPIC2_SNDW,
 +                              enable ? HDA_DSP_REG_ADSPIC2_SNDW : 0);
 +}
 +
  void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable)
  {
 -      sdw_intel_enable_irq(sdev->bar[HDA_DSP_BAR], enable);
 +      const struct sof_intel_dsp_desc *chip;
 +
 +      chip = get_chip_info(sdev->pdata);
 +      if (chip && chip->enable_sdw_irq)
 +              chip->enable_sdw_irq(sdev, enable);
  }
  
  static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev)
@@@ -206,6 -188,7 +206,7 @@@ static int hda_sdw_probe(struct snd_sof
  
        memset(&res, 0, sizeof(res));
  
+       res.hw_ops = &sdw_intel_cnl_hw_ops;
        res.mmio_base = sdev->bar[HDA_DSP_BAR];
        res.shim_base = hdev->desc->sdw_shim_base;
        res.alh_base = hdev->desc->sdw_alh_base;
        return 0;
  }
  
 +int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev)
 +{
 +      struct sof_intel_hda_dev *hdev;
 +      struct sdw_intel_ctx *ctx;
 +      u32 caps;
 +
 +      hdev = sdev->pdata->hw_pdata;
 +      ctx = hdev->sdw;
 +
 +      caps = snd_sof_dsp_read(sdev, HDA_DSP_BAR, ctx->shim_base + SDW_SHIM_LCAP);
 +      caps &= SDW_SHIM_LCAP_LCOUNT_MASK;
 +
 +      /* Check HW supported vs property value */
 +      if (caps < ctx->count) {
 +              dev_err(sdev->dev,
 +                      "BIOS master count %d is larger than hardware capabilities %d\n",
 +                      ctx->count, caps);
 +              return -EINVAL;
 +      }
 +
 +      return 0;
 +}
 +
 +static int hda_sdw_check_lcount(struct snd_sof_dev *sdev)
 +{
 +      const struct sof_intel_dsp_desc *chip;
 +
 +      chip = get_chip_info(sdev->pdata);
 +      if (chip && chip->read_sdw_lcount)
 +              return chip->read_sdw_lcount(sdev);
 +
 +      return 0;
 +}
 +
  int hda_sdw_startup(struct snd_sof_dev *sdev)
  {
        struct sof_intel_hda_dev *hdev;
        struct snd_sof_pdata *pdata = sdev->pdata;
 +      int ret;
  
        hdev = sdev->pdata->hw_pdata;
  
        if (pdata->machine && !pdata->machine->mach_params.link_mask)
                return 0;
  
 +      ret = hda_sdw_check_lcount(sdev);
 +      if (ret < 0)
 +              return ret;
 +
        return sdw_intel_startup(hdev->sdw);
  }
  
@@@ -440,6 -384,12 +441,6 @@@ static int mclk_id_override = -1
  module_param_named(mclk_id, mclk_id_override, int, 0444);
  MODULE_PARM_DESC(mclk_id, "SOF SSP mclk_id");
  
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI);
 -module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444);
 -MODULE_PARM_DESC(use_common_hdmi, "SOF HDA use common HDMI codec driver");
 -#endif
 -
  static const struct hda_dsp_msg_code hda_dsp_rom_fw_error_texts[] = {
        {HDA_DSP_ROM_CSE_ERROR, "error: cse error"},
        {HDA_DSP_ROM_CSE_WRONG_RESPONSE, "error: cse wrong response"},
@@@ -676,6 -626,7 +677,6 @@@ static bool hda_check_ipc_irq(struct sn
  
  void hda_ipc_irq_dump(struct snd_sof_dev *sdev)
  {
 -      struct hdac_bus *bus = sof_to_bus(sdev);
        u32 adspis;
        u32 intsts;
        u32 intctl;
        intsts = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS);
        intctl = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL);
        ppsts = snd_sof_dsp_read(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPSTS);
 -      rirbsts = snd_hdac_chip_readb(bus, RIRBSTS);
 +      rirbsts = snd_sof_dsp_read8(sdev, HDA_DSP_HDA_BAR, AZX_REG_RIRBSTS);
  
        dev_err(sdev->dev, "hda irq intsts 0x%8.8x intlctl 0x%8.8x rirb %2.2x\n",
                intsts, intctl, rirbsts);
@@@ -731,17 -682,6 +732,17 @@@ void hda_ipc4_dump(struct snd_sof_dev *
                hipci, hipcie, hipct, hipcte, hipcctl);
  }
  
 +bool hda_ipc4_tx_is_busy(struct snd_sof_dev *sdev)
 +{
 +      struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 +      const struct sof_intel_dsp_desc *chip = hda->desc;
 +      u32 val;
 +
 +      val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, chip->ipc_req);
 +
 +      return !!(val & chip->ipc_req_mask);
 +}
 +
  static int hda_init(struct snd_sof_dev *sdev)
  {
        struct hda_bus *hbus;
        bus = sof_to_bus(sdev);
  
        /* HDA bus init */
 -      sof_hda_bus_init(bus, &pci->dev);
 +      sof_hda_bus_init(sdev, &pci->dev);
  
        if (sof_hda_position_quirk == SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS)
                bus->use_posbuf = 0;
@@@ -848,7 -788,7 +849,7 @@@ static int check_nhlt_ssp_mclk_mask(str
        return intel_nhlt_ssp_mclk_mask(nhlt, ssp_num);
  }
  
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
 +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
  
  static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
                                   const char *sof_tplg_filename,
@@@ -928,6 -868,9 +929,6 @@@ static int hda_init_caps(struct snd_sof
  {
        struct hdac_bus *bus = sof_to_bus(sdev);
        struct snd_sof_pdata *pdata = sdev->pdata;
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      struct hdac_ext_link *hlink;
 -#endif
        struct sof_intel_hda_dev *hdev = pdata->hw_pdata;
        u32 link_mask;
        int ret = 0;
                dev_dbg(sdev->dev, "PP capability, will probe DSP later.\n");
  
        /* Init HDA controller after i915 init */
 -      ret = hda_dsp_ctrl_init_chip(sdev, true);
 +      ret = hda_dsp_ctrl_init_chip(sdev);
        if (ret < 0) {
                dev_err(bus->dev, "error: init chip failed with ret: %d\n",
                        ret);
                return ret;
        }
  
 +      hda_bus_ml_get_capabilities(bus);
 +
        /* scan SoundWire capabilities exposed by DSDT */
        ret = hda_sdw_acpi_scan(sdev);
        if (ret < 0) {
  
  skip_soundwire:
  
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      if (bus->mlcap)
 -              snd_hdac_ext_bus_get_ml_capabilities(bus);
 -
        /* create codec instances */
 -      hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi);
 +      hda_codec_probe_bus(sdev);
  
        if (!HDA_IDISP_CODEC(bus->codec_mask))
                hda_codec_i915_display_power(sdev, false);
  
 -      /*
 -       * we are done probing so decrement link counts
 -       */
 -      list_for_each_entry(hlink, &bus->hlink_list, list)
 -              snd_hdac_ext_bus_link_put(bus, hlink);
 -#endif
 -      return 0;
 -}
 +      hda_bus_ml_put_all(bus);
  
 -static void hda_check_for_state_change(struct snd_sof_dev *sdev)
 -{
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      struct hdac_bus *bus = sof_to_bus(sdev);
 -      unsigned int codec_mask;
 -
 -      codec_mask = snd_hdac_chip_readw(bus, STATESTS);
 -      if (codec_mask) {
 -              hda_codec_jack_check(sdev);
 -              snd_hdac_chip_writew(bus, STATESTS, codec_mask);
 -      }
 -#endif
 +      return 0;
  }
  
  static irqreturn_t hda_dsp_interrupt_handler(int irq, void *context)
@@@ -1034,7 -997,7 +1035,7 @@@ static irqreturn_t hda_dsp_interrupt_th
                hda_sdw_process_wakeen(sdev);
        }
  
 -      hda_check_for_state_change(sdev);
 +      hda_codec_check_for_state_change(sdev);
  
        /* enable GIE interrupt */
        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
@@@ -1230,7 -1193,10 +1231,7 @@@ int hda_dsp_remove(struct snd_sof_dev *
        /* cancel any attempt for DSP D0I3 */
        cancel_delayed_work_sync(&hda->d0i3_work);
  
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      /* codec removal, invoke bus_device_remove */
 -      snd_hdac_ext_bus_device_remove(bus);
 -#endif
 +      hda_codec_device_remove(sdev);
  
        hda_sdw_exit(sdev);
  
                pci_free_irq_vectors(pci);
  
        hda_dsp_stream_free(sdev);
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      snd_hdac_link_free_all(bus);
 -#endif
 +
 +      hda_bus_ml_free(sof_to_bus(sdev));
  
        iounmap(sdev->bar[HDA_DSP_BAR]);
        iounmap(bus->remap_addr);
  
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 -      snd_hdac_ext_bus_exit(bus);
 -#endif
 +      sof_hda_bus_exit(sdev);
 +
        hda_codec_i915_exit(sdev);
  
        return 0;
@@@ -1279,7 -1247,7 +1280,7 @@@ int hda_power_down_dsp(struct snd_sof_d
        return hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask);
  }
  
 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
  static void hda_generic_machine_select(struct snd_sof_dev *sdev,
                                       struct snd_soc_acpi_mach **mach)
  {
        if (*mach) {
                mach_params = &(*mach)->mach_params;
                mach_params->codec_mask = bus->codec_mask;
 -              mach_params->common_hdmi_codec_drv = hda_codec_use_common_hdmi;
 +              mach_params->common_hdmi_codec_drv = true;
        }
  }
  #else
@@@ -1727,3 -1695,4 +1728,4 @@@ MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_
  MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
  MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);
  MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);
+ MODULE_IMPORT_NS(SOUNDWIRE_INTEL);