diff options
author | Ramesh Babu K V <ramesh.babu@intel.com> | 2012-06-11 22:14:12 +0530 |
---|---|---|
committer | buildbot <buildbot@intel.com> | 2012-06-15 06:17:09 -0700 |
commit | d01710116e80233c38167c404ab533549fba444c (patch) | |
tree | 1dd3324690ce9f9e7c99f29431af0af76604310e /sound | |
parent | 1fa1794ac26ef42eba81d54c97d35f3f4581cc10 (diff) | |
download | kernel-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.c | 80 |
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) |