Commit 625339ca authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Mark Brown

ASoC: SOF: Intel: hda: add callback to check SoundWire lcount information

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: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20221111042653.45520-6-yung-chuan.liao@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent aa70a580
...@@ -457,6 +457,7 @@ const struct sof_intel_dsp_desc cnl_chip_info = { ...@@ -457,6 +457,7 @@ const struct sof_intel_dsp_desc cnl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq, .enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
...@@ -491,6 +492,7 @@ const struct sof_intel_dsp_desc jsl_chip_info = { ...@@ -491,6 +492,7 @@ const struct sof_intel_dsp_desc jsl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq, .enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
......
...@@ -238,10 +238,45 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev) ...@@ -238,10 +238,45 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev)
return 0; 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) int hda_sdw_startup(struct snd_sof_dev *sdev)
{ {
struct sof_intel_hda_dev *hdev; struct sof_intel_hda_dev *hdev;
struct snd_sof_pdata *pdata = sdev->pdata; struct snd_sof_pdata *pdata = sdev->pdata;
int ret;
hdev = sdev->pdata->hw_pdata; hdev = sdev->pdata->hw_pdata;
...@@ -251,6 +286,10 @@ int hda_sdw_startup(struct snd_sof_dev *sdev) ...@@ -251,6 +286,10 @@ int hda_sdw_startup(struct snd_sof_dev *sdev)
if (pdata->machine && !pdata->machine->mach_params.link_mask) if (pdata->machine && !pdata->machine->mach_params.link_mask)
return 0; return 0;
ret = hda_sdw_check_lcount(sdev);
if (ret < 0)
return ret;
return sdw_intel_startup(hdev->sdw); return sdw_intel_startup(hdev->sdw);
} }
......
...@@ -795,6 +795,7 @@ int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd); ...@@ -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) #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); int hda_sdw_startup(struct snd_sof_dev *sdev);
void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable); 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); 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); ...@@ -803,6 +804,11 @@ bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev);
#else #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) static inline int hda_sdw_startup(struct snd_sof_dev *sdev)
{ {
return 0; return 0;
......
...@@ -181,6 +181,7 @@ const struct sof_intel_dsp_desc icl_chip_info = { ...@@ -181,6 +181,7 @@ const struct sof_intel_dsp_desc icl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq, .enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
......
...@@ -654,6 +654,7 @@ const struct sof_intel_dsp_desc mtl_chip_info = { ...@@ -654,6 +654,7 @@ const struct sof_intel_dsp_desc mtl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE_ACE, .sdw_shim_base = SDW_SHIM_BASE_ACE,
.sdw_alh_base = SDW_ALH_BASE_ACE, .sdw_alh_base = SDW_ALH_BASE_ACE,
.d0i3_offset = MTL_HDA_VS_D0I3C, .d0i3_offset = MTL_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = mtl_enable_sdw_irq, .enable_sdw_irq = mtl_enable_sdw_irq,
.check_sdw_irq = mtl_dsp_check_sdw_irq, .check_sdw_irq = mtl_dsp_check_sdw_irq,
.check_ipc_irq = mtl_dsp_check_ipc_irq, .check_ipc_irq = mtl_dsp_check_ipc_irq,
......
...@@ -185,6 +185,7 @@ struct sof_intel_dsp_desc { ...@@ -185,6 +185,7 @@ struct sof_intel_dsp_desc {
u32 d0i3_offset; u32 d0i3_offset;
u32 quirks; u32 quirks;
enum sof_intel_hw_ip_version hw_ip_version; 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); void (*enable_sdw_irq)(struct snd_sof_dev *sdev, bool enable);
bool (*check_sdw_irq)(struct snd_sof_dev *sdev); bool (*check_sdw_irq)(struct snd_sof_dev *sdev);
bool (*check_ipc_irq)(struct snd_sof_dev *sdev); bool (*check_ipc_irq)(struct snd_sof_dev *sdev);
......
...@@ -136,6 +136,7 @@ const struct sof_intel_dsp_desc tgl_chip_info = { ...@@ -136,6 +136,7 @@ const struct sof_intel_dsp_desc tgl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq, .enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
...@@ -163,6 +164,7 @@ const struct sof_intel_dsp_desc tglh_chip_info = { ...@@ -163,6 +164,7 @@ const struct sof_intel_dsp_desc tglh_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq, .enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
...@@ -190,6 +192,7 @@ const struct sof_intel_dsp_desc ehl_chip_info = { ...@@ -190,6 +192,7 @@ const struct sof_intel_dsp_desc ehl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq, .enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
...@@ -217,6 +220,7 @@ const struct sof_intel_dsp_desc adls_chip_info = { ...@@ -217,6 +220,7 @@ const struct sof_intel_dsp_desc adls_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq, .enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment