Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions sound/soc/sof/intel/hda-ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,70 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)

return ret;
}

void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_stream *stream;
int sd_offset;

if (!bus->chip_init)
return;

/* disable interrupts in stream descriptor */
list_for_each_entry(stream, &bus->stream_list, list) {
sd_offset = SOF_STREAM_SD_OFFSET(stream);
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
sd_offset +
SOF_HDA_ADSP_REG_CL_SD_CTL,
SOF_HDA_CL_DMA_SD_INT_MASK,
0);
}

/* disable SIE for all streams */
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
SOF_HDA_INT_ALL_STREAM, 0);

/* disable controller CIE and GIE */
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
0);

/* clear stream status */
list_for_each_entry(stream, &bus->stream_list, list) {
sd_offset = SOF_STREAM_SD_OFFSET(stream);
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
sd_offset +
SOF_HDA_ADSP_REG_CL_SD_STS,
SOF_HDA_CL_DMA_SD_INT_MASK,
SOF_HDA_CL_DMA_SD_INT_MASK);
}

/* clear WAKESTS */
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS,
SOF_HDA_WAKESTS_INT_MASK,
SOF_HDA_WAKESTS_INT_MASK);

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* clear rirb status */
snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
#endif

/* clear interrupt status register */
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS,
SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_ALL_STREAM);

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* disable CORB/RIRB */
snd_hdac_bus_stop_cmd_io(bus);
#endif
/* disable position buffer */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this really dependent on SOF_HDA? This is the position buffer that we can use even for NOCODEC for DPIB.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart OK, thanks for confirm, I will still follow a PR with change the same in hda_dsp_ctrl_init_chip.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a question, have you confirmed if yes/no this code is needed for NOCODEC?
And if yes, then the fix is incorrect since you are using snd_hdac_chip_writel() so introduced a dependency on hdac.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart Yes, I am confirm that this is needed for NOCODEC. for position buffer is according to HDA stream. What ever codec is using, the position buffer need to be set at beginning and reset at end. It is only that NOCODEC will not cause a issue if not set.
I will update the snd_hdac_chip_writel with SOF functions, thanks!

if (bus->posbuf.addr) {
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
SOF_HDA_ADSP_DPLBASE, 0);
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
SOF_HDA_ADSP_DPUBASE, 0);
}

bus->chip_init = false;
}
21 changes: 3 additions & 18 deletions sound/soc/sof/intel/hda-dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,23 +307,12 @@ static int hda_suspend(struct snd_sof_dev *sdev, int state)
return ret;
}

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* disable ppcap interrupt */
snd_hdac_ext_bus_ppcap_int_enable(bus, false);
snd_hdac_ext_bus_ppcap_enable(bus, false);

/* disable hda bus irq and i/o */
snd_hdac_bus_stop_chip(bus);
#else
/* disable ppcap interrupt */
hda_dsp_ctrl_ppcap_enable(sdev, false);
hda_dsp_ctrl_ppcap_int_enable(sdev, false);

/* disable hda bus irq */
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
0);
#endif
/* disable hda bus irq and streams */
hda_dsp_ctrl_stop_chip(sdev);

/* disable LP retention mode */
snd_sof_pci_update_bits(sdev, PCI_PGCTL,
Expand Down Expand Up @@ -370,10 +359,6 @@ static int hda_resume(struct snd_sof_dev *sdev)
bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);

hda_dsp_ctrl_misc_clock_gating(sdev, true);

/* enable ppcap interrupt */
snd_hdac_ext_bus_ppcap_enable(bus, true);
snd_hdac_ext_bus_ppcap_int_enable(bus, true);
#else

hda_dsp_ctrl_misc_clock_gating(sdev, false);
Expand All @@ -400,11 +385,11 @@ static int hda_resume(struct snd_sof_dev *sdev)
SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN);

hda_dsp_ctrl_misc_clock_gating(sdev, true);
#endif

/* enable ppcap interrupt */
hda_dsp_ctrl_ppcap_enable(sdev, true);
hda_dsp_ctrl_ppcap_int_enable(sdev, true);
#endif

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* turn off the links that were off before suspend */
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ int hda_dsp_ctrl_link_reset(struct snd_sof_dev *sdev, bool reset);
void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable);
int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable);
int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset);

void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev);
/*
* HDA bus operations.
*/
Expand Down