ASoC: Intel: Skylake: Poll CLDMA RUN bit when set
authorJeeja KP <jeeja.kp@intel.com>
Mon, 23 Nov 2015 16:56:27 +0000 (22:26 +0530)
committerMark Brown <broonie@kernel.org>
Wed, 25 Nov 2015 17:55:41 +0000 (17:55 +0000)
This patch adds polling of CLDMA stream run bit when set
to confirm the HW reports the same value.

Signed-off-by: Jeeja KP <jeeja.kp@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/skylake/skl-sst-cldma.c

index 947a08e42e8604092dee3264d53ad6cdbe2d6fa1..8c7e8576cba39f556aa1abef6a6dd830ee93de0e 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/device.h>
 #include <linux/mm.h>
 #include <linux/kthread.h>
+#include <linux/delay.h>
 #include "../common/sst-dsp.h"
 #include "../common/sst-dsp-priv.h"
 
@@ -33,6 +34,32 @@ void skl_cldma_int_disable(struct sst_dsp *ctx)
                        SKL_ADSP_REG_ADSPIC, SKL_ADSPIC_CL_DMA, 0);
 }
 
+static void skl_cldma_stream_run(struct sst_dsp  *ctx, bool enable)
+{
+       unsigned char val;
+       int timeout;
+
+       sst_dsp_shim_update_bits_unlocked(ctx,
+                       SKL_ADSP_REG_CL_SD_CTL,
+                       CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(enable));
+
+       udelay(3);
+       timeout = 300;
+       do {
+               /* waiting for hardware to report that the stream Run bit set */
+               val = sst_dsp_shim_read(ctx, SKL_ADSP_REG_CL_SD_CTL) &
+                       CL_SD_CTL_RUN_MASK;
+               if (enable && val)
+                       break;
+               else if (!enable && !val)
+                       break;
+               udelay(3);
+       } while (--timeout);
+
+       if (timeout == 0)
+               dev_err(ctx->dev, "Failed to set Run bit=%d enable=%d\n", val, enable);
+}
+
 /* Code loader helper APIs */
 static void skl_cldma_setup_bdle(struct sst_dsp *ctx,
                struct snd_dma_buffer *dmab_data,
@@ -107,18 +134,6 @@ static void skl_cldma_cleanup_spb(struct sst_dsp  *ctx)
        sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_CL_SPBFIFO_SPIB, 0);
 }
 
-static void skl_cldma_trigger(struct sst_dsp  *ctx, bool enable)
-{
-       if (enable)
-               sst_dsp_shim_update_bits_unlocked(ctx,
-                       SKL_ADSP_REG_CL_SD_CTL,
-                       CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(1));
-       else
-               sst_dsp_shim_update_bits_unlocked(ctx,
-                       SKL_ADSP_REG_CL_SD_CTL,
-                       CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(0));
-}
-
 static void skl_cldma_cleanup(struct sst_dsp  *ctx)
 {
        skl_cldma_cleanup_spb(ctx);
@@ -167,7 +182,7 @@ cleanup:
 
 static void skl_cldma_stop(struct sst_dsp *ctx)
 {
-       ctx->cl_dev.ops.cl_trigger(ctx, false);
+       skl_cldma_stream_run(ctx, false);
 }
 
 static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
@@ -309,7 +324,7 @@ int skl_cldma_prepare(struct sst_dsp *ctx)
        ctx->cl_dev.ops.cl_setup_controller = skl_cldma_setup_controller;
        ctx->cl_dev.ops.cl_setup_spb = skl_cldma_setup_spb;
        ctx->cl_dev.ops.cl_cleanup_spb = skl_cldma_cleanup_spb;
-       ctx->cl_dev.ops.cl_trigger = skl_cldma_trigger;
+       ctx->cl_dev.ops.cl_trigger = skl_cldma_stream_run;
        ctx->cl_dev.ops.cl_cleanup_controller = skl_cldma_cleanup;
        ctx->cl_dev.ops.cl_copy_to_dmabuf = skl_cldma_copy_to_buf;
        ctx->cl_dev.ops.cl_stop_dma = skl_cldma_stop;