OSDN Git Service

ASoC: SOF: Intel: hda: add callback to check SoundWire lcount information
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Fri, 11 Nov 2022 04:26:50 +0000 (12:26 +0800)
committerMark Brown <broonie@kernel.org>
Wed, 23 Nov 2022 15:32:05 +0000 (15:32 +0000)
The number of links is stored in different registers depending on the
IP version, add sdw_check_lcount() callback. This callback only checks
that the number of links supported in hardware is compatible with the
number of links exposed in ACPI _DSD properties.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20221111042653.45520-6-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
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/shim.h
sound/soc/sof/intel/tgl.c

index cbb6474..6b075bb 100644 (file)
@@ -457,6 +457,7 @@ const struct sof_intel_dsp_desc cnl_chip_info = {
        .sdw_shim_base = SDW_SHIM_BASE,
        .sdw_alh_base = SDW_ALH_BASE,
        .d0i3_offset = SOF_HDA_VS_D0I3C,
+       .read_sdw_lcount =  hda_sdw_check_lcount_common,
        .enable_sdw_irq = hda_common_enable_sdw_irq,
        .check_sdw_irq  = hda_common_check_sdw_irq,
        .check_ipc_irq  = hda_dsp_check_ipc_irq,
@@ -491,6 +492,7 @@ const struct sof_intel_dsp_desc jsl_chip_info = {
        .sdw_shim_base = SDW_SHIM_BASE,
        .sdw_alh_base = SDW_ALH_BASE,
        .d0i3_offset = SOF_HDA_VS_D0I3C,
+       .read_sdw_lcount =  hda_sdw_check_lcount_common,
        .enable_sdw_irq = hda_common_enable_sdw_irq,
        .check_sdw_irq  = hda_common_check_sdw_irq,
        .check_ipc_irq  = hda_dsp_check_ipc_irq,
index 2dc8288..2f9d69e 100644 (file)
@@ -238,10 +238,45 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev)
        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;
 
@@ -251,6 +286,10 @@ int hda_sdw_startup(struct snd_sof_dev *sdev)
        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);
 }
 
index 79fccd7..022ce80 100644 (file)
@@ -795,6 +795,7 @@ int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd);
  */
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
 
+int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev);
 int hda_sdw_startup(struct snd_sof_dev *sdev);
 void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable);
 void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable);
@@ -803,6 +804,11 @@ bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev);
 
 #else
 
+static inline int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev)
+{
+       return 0;
+}
+
 static inline int hda_sdw_startup(struct snd_sof_dev *sdev)
 {
        return 0;
index f3aff23..435941a 100644 (file)
@@ -181,6 +181,7 @@ const struct sof_intel_dsp_desc icl_chip_info = {
        .sdw_shim_base = SDW_SHIM_BASE,
        .sdw_alh_base = SDW_ALH_BASE,
        .d0i3_offset = SOF_HDA_VS_D0I3C,
+       .read_sdw_lcount =  hda_sdw_check_lcount_common,
        .enable_sdw_irq = hda_common_enable_sdw_irq,
        .check_sdw_irq  = hda_common_check_sdw_irq,
        .check_ipc_irq  = hda_dsp_check_ipc_irq,
index a083980..904ae42 100644 (file)
@@ -654,6 +654,7 @@ const struct sof_intel_dsp_desc mtl_chip_info = {
        .sdw_shim_base = SDW_SHIM_BASE_ACE,
        .sdw_alh_base = SDW_ALH_BASE_ACE,
        .d0i3_offset = MTL_HDA_VS_D0I3C,
+       .read_sdw_lcount =  hda_sdw_check_lcount_common,
        .enable_sdw_irq = mtl_enable_sdw_irq,
        .check_sdw_irq = mtl_dsp_check_sdw_irq,
        .check_ipc_irq = mtl_dsp_check_ipc_irq,
index 2e78f27..48428cc 100644 (file)
@@ -185,6 +185,7 @@ struct sof_intel_dsp_desc {
        u32 d0i3_offset;
        u32 quirks;
        enum sof_intel_hw_ip_version hw_ip_version;
+       int (*read_sdw_lcount)(struct snd_sof_dev *sdev);
        void (*enable_sdw_irq)(struct snd_sof_dev *sdev, bool enable);
        bool (*check_sdw_irq)(struct snd_sof_dev *sdev);
        bool (*check_ipc_irq)(struct snd_sof_dev *sdev);
index dda89c8..30f2f49 100644 (file)
@@ -136,6 +136,7 @@ const struct sof_intel_dsp_desc tgl_chip_info = {
        .sdw_shim_base = SDW_SHIM_BASE,
        .sdw_alh_base = SDW_ALH_BASE,
        .d0i3_offset = SOF_HDA_VS_D0I3C,
+       .read_sdw_lcount =  hda_sdw_check_lcount_common,
        .enable_sdw_irq = hda_common_enable_sdw_irq,
        .check_sdw_irq  = hda_common_check_sdw_irq,
        .check_ipc_irq  = hda_dsp_check_ipc_irq,
@@ -163,6 +164,7 @@ const struct sof_intel_dsp_desc tglh_chip_info = {
        .sdw_shim_base = SDW_SHIM_BASE,
        .sdw_alh_base = SDW_ALH_BASE,
        .d0i3_offset = SOF_HDA_VS_D0I3C,
+       .read_sdw_lcount =  hda_sdw_check_lcount_common,
        .enable_sdw_irq = hda_common_enable_sdw_irq,
        .check_sdw_irq  = hda_common_check_sdw_irq,
        .check_ipc_irq  = hda_dsp_check_ipc_irq,
@@ -190,6 +192,7 @@ const struct sof_intel_dsp_desc ehl_chip_info = {
        .sdw_shim_base = SDW_SHIM_BASE,
        .sdw_alh_base = SDW_ALH_BASE,
        .d0i3_offset = SOF_HDA_VS_D0I3C,
+       .read_sdw_lcount =  hda_sdw_check_lcount_common,
        .enable_sdw_irq = hda_common_enable_sdw_irq,
        .check_sdw_irq  = hda_common_check_sdw_irq,
        .check_ipc_irq  = hda_dsp_check_ipc_irq,
@@ -217,6 +220,7 @@ const struct sof_intel_dsp_desc adls_chip_info = {
        .sdw_shim_base = SDW_SHIM_BASE,
        .sdw_alh_base = SDW_ALH_BASE,
        .d0i3_offset = SOF_HDA_VS_D0I3C,
+       .read_sdw_lcount =  hda_sdw_check_lcount_common,
        .enable_sdw_irq = hda_common_enable_sdw_irq,
        .check_sdw_irq  = hda_common_check_sdw_irq,
        .check_ipc_irq  = hda_dsp_check_ipc_irq,