ASoC: Intel: avs: Read HW capabilities when possible
authorCezary Rojewski <cezary.rojewski@intel.com>
Mon, 7 Apr 2025 11:23:45 +0000 (13:23 +0200)
committerMark Brown <broonie@kernel.org>
Mon, 7 Apr 2025 13:39:57 +0000 (14:39 +0100)
Starting with LunarLake (LNL) and onward, some hardware capabilities are
visible to the sound driver directly. At the same time, these may no
longer be visible to the AudioDSP firmware. Update resource allocation
function to rely on the registers when possible.

Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Link: https://patch.msgid.link/20250407112352.3720779-4-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/hdaudio_ext.h
sound/hda/ext/hdac_ext_controller.c
sound/soc/intel/avs/avs.h
sound/soc/intel/avs/loader.c

index 60ec12e3b72f8d3b1db6df3b68880a12bae101a9..7de390022ac26889bb5473dc8c6ff7165b631d72 100644 (file)
@@ -99,6 +99,7 @@ struct hdac_ext_link {
        u32 lcaps;   /* link capablities */
        u16 lsdiid;  /* link sdi identifier */
        u32 id;
+       u8 slcount;
 
        int ref_count;
 
index 2ec1531d1c1b511e892020b8314decc5d88d3f5e..c84754434d1627af3a0e2977ee7b03a8a7234492 100644 (file)
@@ -98,6 +98,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus)
                                        (AZX_ML_INTERVAL * idx);
                hlink->lcaps  = readl(hlink->ml_addr + AZX_REG_ML_LCAP);
                hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID);
+               hlink->slcount = FIELD_GET(AZX_ML_HDA_LCAP_SLCOUNT, hlink->lcaps) + 1;
 
                if (hdac_ext_link_alt(hlink)) {
                        leptr = readl(hlink->ml_addr + AZX_REG_ML_LEPTR);
index 91872d1df97a5c2408d74cac802e7f64aa9dd3c9..201897c5bdc04146240be7c77bfd55569ca93731 100644 (file)
@@ -73,6 +73,7 @@ extern const struct avs_dsp_ops avs_tgl_dsp_ops;
 #define AVS_PLATATTR_CLDMA             BIT_ULL(0)
 #define AVS_PLATATTR_IMR               BIT_ULL(1)
 #define AVS_PLATATTR_ACE               BIT_ULL(2)
+#define AVS_PLATATTR_ALTHDA            BIT_ULL(3)
 
 #define avs_platattr_test(adev, attr) \
        ((adev)->spec->attributes & AVS_PLATATTR_##attr)
index 0b29941feb0ef0c4433c2f578bf149211feb3d03..ecf050c2c0c7f4ef4f13c88212a40268a331eaf3 100644 (file)
@@ -683,6 +683,7 @@ int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge)
 
 static int avs_dsp_alloc_resources(struct avs_dev *adev)
 {
+       struct hdac_ext_link *link;
        int ret, i;
 
        ret = avs_ipc_get_hw_config(adev, &adev->hw_cfg);
@@ -693,6 +694,14 @@ static int avs_dsp_alloc_resources(struct avs_dev *adev)
        if (ret)
                return AVS_IPC_RET(ret);
 
+       /* If hw allows, read capabilities directly from it. */
+       if (avs_platattr_test(adev, ALTHDA)) {
+               link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core,
+                                                       AZX_REG_ML_LEPTR_ID_INTEL_SSP);
+               if (link)
+                       adev->hw_cfg.i2s_caps.ctrl_count = link->slcount;
+       }
+
        adev->core_refs = devm_kcalloc(adev->dev, adev->hw_cfg.dsp_cores,
                                       sizeof(*adev->core_refs), GFP_KERNEL);
        adev->lib_names = devm_kcalloc(adev->dev, adev->fw_cfg.max_libs_count,