summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorRamesh Babu K V <ramesh.babu@intel.com>2012-06-11 22:14:12 +0530
committerbuildbot <buildbot@intel.com>2012-06-15 06:17:09 -0700
commitd01710116e80233c38167c404ab533549fba444c (patch)
tree1dd3324690ce9f9e7c99f29431af0af76604310e /sound
parent1fa1794ac26ef42eba81d54c97d35f3f4581cc10 (diff)
downloadkernel-mfld-blackbay-d01710116e80233c38167c404ab533549fba444c.tar.gz
kernel-mfld-blackbay-d01710116e80233c38167c404ab533549fba444c.tar.bz2
kernel-mfld-blackbay-d01710116e80233c38167c404ab533549fba444c.zip
audio:use single block DMA transfer for firmware download
BZ: 35751 Fabric error has been noticed when we use LLI DMA along with single block transfer. LLI and single block DMAs works good independently. Fabric error have been experienced when switching from single block DMA to LLI DMA. Added single block DMA transfer support for downloading firmware. Change-Id: I5df836fea163612a56e2edf2d5d8a9ff89b8111c Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Ramesh Babu K V <ramesh.babu@intel.com> Reviewed-on: http://android.intel.com:8080/52368 Reviewed-by: R, Dharageswari <dharageswari.r@intel.com> Reviewed-by: Vinnakota, Lakshmi N <lakshmi.n.vinnakota@intel.com> Reviewed-by: Agarwal, Vaibhav <vaibhav.agarwal@intel.com> Reviewed-by: Gupta, ArvindX K <arvindx.k.gupta@intel.com> Reviewed-by: Hibare, PramodX <pramodx.hibare@intel.com> Tested-by: Hibare, PramodX <pramodx.hibare@intel.com> Reviewed-by: buildbot <buildbot@intel.com> Tested-by: buildbot <buildbot@intel.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/mid-x86/sst/intel_sst_dsp.c80
1 files changed, 62 insertions, 18 deletions
diff --git a/sound/soc/mid-x86/sst/intel_sst_dsp.c b/sound/soc/mid-x86/sst/intel_sst_dsp.c
index 017fcd49074..f3415bfca5d 100644
--- a/sound/soc/mid-x86/sst/intel_sst_dsp.c
+++ b/sound/soc/mid-x86/sst/intel_sst_dsp.c
@@ -401,41 +401,84 @@ end_release:
return retval;
}
-int sst_dma_firmware(struct sst_dma *dma, struct sst_sg_list *sg_list)
+static inline int sst_dma_wait_for_completion(struct intel_sst_drv *sst)
+{
+ /* call prep and wait */
+ sst->desc->callback = sst_dma_transfer_complete;
+ sst->desc->callback_param = sst;
+
+ sst->dma_info_blk.condition = false;
+ sst->dma_info_blk.ret_code = 0;
+ sst->dma_info_blk.on = true;
+
+ sst->desc->tx_submit(sst_drv_ctx->desc);
+ return sst_wait_timeout(sst, &sst->dma_info_blk);
+}
+
+static int sst_dma_single_blk(struct sst_dma *dma, struct sst_sg_list *sg_list)
{
- int retval = 0;
enum dma_ctrl_flags flag = DMA_CTRL_ACK;
- struct scatterlist *sg_src_list, *sg_dst_list;
- int length;
- pr_debug(" sst_dma_firmware\n");
+ struct scatterlist *sg_src_list, *sg_dst_list, *sg;
+ int length, i, retval = 0;
+ dma_addr_t src_addr, dstn_addr;
+ size_t dma_len;
+
+ pr_debug("Enter:%s\n", __func__);
sg_src_list = sg_list->src;
sg_dst_list = sg_list->dst;
length = sg_list->list_len;
+
+ for_each_sg(sg_src_list, sg, length, i) {
+ dma_len = sg->length;
+ pr_debug("memcpy for desc %d, length %d\n", i, dma_len);
+ /* get one desc */
+ src_addr = sg_phys(sg);
+ dstn_addr = sg_phys(sg_dst_list);
+ if (sg_dst_list)
+ sg_dst_list = sg_next(sg_dst_list);
+ sst_drv_ctx->desc = dma->ch->device->device_prep_dma_memcpy(
+ dma->ch, dstn_addr, src_addr, dma_len, flag);
+ if (!sst_drv_ctx->desc) {
+ pr_err("failed to get desc for mempcy %d\n", i);
+ return -EIO;
+ }
+ retval = sst_dma_wait_for_completion(sst_drv_ctx);
+ if (retval)
+ pr_err("%s..timeout! %d\n", __func__, retval);
+ }
+ return retval;
+}
+
+static int sst_dma_lli(struct sst_dma *dma, struct sst_sg_list *sg_list)
+{
+ enum dma_ctrl_flags flag = DMA_CTRL_ACK;
+ int retval = 0;
+
+ pr_debug("Enter:%s\n", __func__);
+
+
sst_drv_ctx->desc = dma->ch->device->device_prep_dma_sg(dma->ch,
- sg_dst_list, length,
- sg_src_list, length, flag);
+ sg_list->dst, sg_list->list_len,
+ sg_list->src, sg_list->list_len, flag);
if (!sst_drv_ctx->desc)
return -EFAULT;
- sst_drv_ctx->desc->callback = sst_dma_transfer_complete;
- sst_drv_ctx->desc->callback_param = sst_drv_ctx;
-
- sst_drv_ctx->dma_info_blk.condition = false;
- sst_drv_ctx->dma_info_blk.ret_code = 0;
- sst_drv_ctx->dma_info_blk.on = true;
-
- sst_drv_ctx->desc->tx_submit(sst_drv_ctx->desc);
- retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->dma_info_blk);
+ retval = sst_dma_wait_for_completion(sst_drv_ctx);
if (retval)
- pr_err("sst_dma_firmware..timeout!\n");
+ pr_err("%s..timeout! %d\n", __func__, retval);
return retval;
}
+int sst_dma_firmware(struct sst_dma *dma, struct sst_sg_list *sg_list)
+{
+ pr_debug("Enter:%s\n", __func__);
+ return sst_dma_single_blk(dma, sg_list);
+}
+
void sst_dma_free_resources(struct sst_dma *dma)
{
pr_debug("entry:%s\n", __func__);
-
dma_release_channel(dma->ch);
}
@@ -469,6 +512,7 @@ int sst_load_fw(const void *fw_in_mem, void *context)
&sst_drv_ctx->fw_sg_list);
if (ret_val)
goto free_dma;
+
sst_set_fw_state_locked(sst_drv_ctx, SST_FW_LOADED);
/* bring sst out of reset */
if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)