Skip to content
37 changes: 0 additions & 37 deletions drivers/soundwire/intel_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,30 +125,6 @@ static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
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;
Expand All @@ -157,7 +133,6 @@ irqreturn_t sdw_intel_thread(int irq, void *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);
Expand Down Expand Up @@ -297,24 +272,12 @@ sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
{
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;

Expand Down
2 changes: 0 additions & 2 deletions include/linux/soundwire/sdw_intel.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,6 @@ int sdw_intel_startup(struct sdw_intel_ctx *ctx);

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)
Expand Down
4 changes: 4 additions & 0 deletions sound/soc/sof/intel/cnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,8 @@ 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,
.cl_init = cl_dsp_init,
Expand Down Expand Up @@ -490,6 +492,8 @@ 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,
.cl_init = cl_dsp_init,
Expand Down
63 changes: 60 additions & 3 deletions sound/soc/sof/intel/hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -220,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;

Expand All @@ -233,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);
}

Expand Down Expand Up @@ -887,6 +944,8 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
return ret;
}

hda_bus_ml_get_capabilities(bus);

/* scan SoundWire capabilities exposed by DSDT */
ret = hda_sdw_acpi_scan(sdev);
if (ret < 0) {
Expand Down Expand Up @@ -915,8 +974,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev)

skip_soundwire:

hda_bus_ml_get_capabilities(bus);

/* create codec instances */
hda_codec_probe_bus(sdev);

Expand Down
12 changes: 12 additions & 0 deletions sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@
#define HDA_DSP_REG_ADSPIC2 (HDA_DSP_GEN_BASE + 0x10)
#define HDA_DSP_REG_ADSPIS2 (HDA_DSP_GEN_BASE + 0x14)

#define HDA_DSP_REG_ADSPIC2_SNDW BIT(5)
#define HDA_DSP_REG_ADSPIS2_SNDW BIT(5)

/* Intel HD Audio Inter-Processor Communication Registers */
Expand Down Expand Up @@ -794,18 +795,29 @@ 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);
void hda_sdw_process_wakeen(struct snd_sof_dev *sdev);
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;
}

static inline void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable)
{
}

static inline void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable)
{
}
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/sof/intel/icl.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ 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,
.cl_init = cl_dsp_init,
Expand Down
Loading