]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ASoC: Intel: Skylake: Read HIPCT extension before clearing DONE bit
authorCezary Rojewski <cezary.rojewski@intel.com>
Thu, 13 Jun 2019 19:04:32 +0000 (21:04 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 25 Jun 2019 14:33:39 +0000 (15:33 +0100)
Host clears DONE bit to signal IPC target it has completed the
operation. Once this is done, IPC target i.e. DSP may proceed with the
next reply, filling registers with new portion of data.

Because of this, host should always read all registers prior to clearing
DONE and BUSY bits to ensure no desynchronization happens the time in
between clearing bits and reading message data (here, extension).

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/skylake/cnl-sst.c
sound/soc/intel/skylake/skl-sst-ipc.c

index 245df1067ba8902e2151cc999fd5172220f2968c..759ea59615ca2a028c40782698f70ea36a0ad6ba 100644 (file)
@@ -313,6 +313,7 @@ static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context)
 
        hipcida = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCIDA);
        hipctdr = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDR);
+       hipctdd = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDD);
 
        /* reply message from dsp */
        if (hipcida & CNL_ADSP_REG_HIPCIDA_DONE) {
@@ -332,7 +333,6 @@ static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context)
 
        /* new message from dsp */
        if (hipctdr & CNL_ADSP_REG_HIPCTDR_BUSY) {
-               hipctdd = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDD);
                header.primary = hipctdr;
                header.extension = hipctdd;
                dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x",
index 9f3ce73593aec44be387a633c23077f6168f4950..5c9206dc793288a96f949b724681680b52acfb8e 100644 (file)
@@ -511,6 +511,7 @@ irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
 
        hipcie = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCIE);
        hipct = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCT);
+       hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE);
 
        /* reply message from DSP */
        if (hipcie & SKL_ADSP_REG_HIPCIE_DONE) {
@@ -530,7 +531,6 @@ irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
 
        /* New message from DSP */
        if (hipct & SKL_ADSP_REG_HIPCT_BUSY) {
-               hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE);
                header.primary = hipct;
                header.extension = hipcte;
                dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n",