static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) { struct davinci_runtime_data *prtd = substream->runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data; int tcc = TCC_ANY; int ret; if (!dma_data) return -ENODEV; prtd->params = dma_data; /* Request master DMA channel */ ret = davinci_request_dma(prtd->params->channel, prtd->params->name, davinci_pcm_dma_irq, substream, &prtd->master_lch, &tcc, EVENTQ_0); if (ret) return ret; /* Request slave DMA channel */ ret = davinci_request_dma(PARAM_ANY, "Link", NULL, NULL, &prtd->slave_lch, &tcc, EVENTQ_0); if (ret) { davinci_free_dma(prtd->master_lch); return ret; } /* Link slave DMA channel in loopback */ davinci_dma_link_lch(prtd->slave_lch, prtd->slave_lch); return 0; }
int DMA_demuxRun(DMA_DemuxPrm *pUserPrm ) { DMA_Obj *pObj; DMA_DemuxObj *pDemuxObj; DRV_DmaDemux *prm; DMA_DemuxPrm kernelPrm; int i, status; status = copy_from_user(&kernelPrm, pUserPrm, sizeof(kernelPrm)); if (status < 0) { FUNCERR( "copy_from_user()\n"); return status; } if (kernelPrm.chId >= DMA_DEV_MAX_CH) { FUNCERR( "Illegal parameter (chId = %d)\n", kernelPrm.chId ); return -1; } pObj = gDMA_dev.pObj[kernelPrm.chId]; if (pObj==NULL) { FUNCERR( "Illegal parameter (chId = %d)\n", kernelPrm.chId ); return -1; } pDemuxObj = pObj->demuxObj; if (pDemuxObj==NULL) { FUNCERR( "Illegal parameter (chId = %d)\n", kernelPrm.chId ); return -1; } prm = &pDemuxObj->demuxPrm; memcpy(prm, &kernelPrm.prm, sizeof(pDemuxObj->demuxPrm)); prm->srcPhysAddrList = pDemuxObj->srcPhysAddrList; prm->dstPhysAddrList = pDemuxObj->dstPhysAddrList; if (prm->numLines>pDemuxObj->maxLines) { FUNCERR( "Illegal parameter (chId = %d)\n", kernelPrm.chId ); return -1; } status = copy_from_user(prm->srcPhysAddrList, kernelPrm.prm.srcPhysAddrList, sizeof(unsigned long)*prm->numLines); if (status < 0) { FUNCERR( "copy_from_user() (chId = %d)\n", kernelPrm.chId ); return status; } status = copy_from_user(prm->dstPhysAddrList, kernelPrm.prm.dstPhysAddrList, sizeof(unsigned long)*prm->numLines); if (status < 0) { FUNCERR( "copy_from_user() (chId = %d)\n", kernelPrm.chId ); return status; } pDemuxObj->curLine = 0; for (i=0; i<DRV_DMA_MAX_DEMUX_PARAM; i++) { pDemuxObj->dmaParamDemux[i].a_b_cnt = (uint32_t)(1<<16)|prm->copyWidth; } for (i=0; i<DRV_DMA_MAX_DEMUX_PARAM; i+=1) { if (pDemuxObj->curLine<prm->numLines) { pDemuxObj->dmaParamDemux[i].src = (uint32_t) pDemuxObj->srcPhysAddrList[pDemuxObj->curLine]; pDemuxObj->dmaParamDemux[i].dst = (uint32_t) pDemuxObj->dstPhysAddrList[pDemuxObj->curLine]; } pDemuxObj->curLine++; } for (i=0; i<DRV_DMA_MAX_DEMUX_PARAM; i++) { davinci_set_dma_params(pDemuxObj->channelDemux[i], &pDemuxObj->dmaParamDemux[i]); } for (i=1; i<DRV_DMA_MAX_DEMUX_PARAM; i++) { davinci_dma_link_lch(pDemuxObj->channelDemux[i-1], pDemuxObj->channelDemux[i]); davinci_get_dma_params(pDemuxObj->channelDemux[i-1], &pDemuxObj->dmaParamDemux[i-1]); } #ifdef DMA_DEBUG for (i=0; i<DRV_DMA_MAX_DEMUX_PARAM; i++) { DMA_dumpPARAM("Demux", pDemuxObj->channelDemux[i]); } #endif #if 1 davinci_start_dma(pDemuxObj->channelDemux[0]); wait_for_completion_interruptible(&pDemuxObj->dma_complete); INIT_COMPLETION(pDemuxObj->dma_complete); #endif return 0; }
static int mmc_davinci_send_dma_request(struct mmc_davinci_host *host, struct mmc_request *req) { int sync_dev; unsigned char i, j; unsigned short acnt, bcnt, ccnt; unsigned int src_port, dst_port, temp_ccnt; enum address_mode mode_src, mode_dst; enum fifo_width fifo_width_src, fifo_width_dst; unsigned short src_bidx, dst_bidx; unsigned short src_cidx, dst_cidx; unsigned short bcntrld; enum sync_dimension sync_mode; edmacc_paramentry_regs temp; int edma_chan_num; struct mmc_data *data = host->data; struct scatterlist *sg = &data->sg[0]; unsigned int count; int num_frames, frame; frame = data->blksz; count = sg_dma_len(sg); if ((data->blocks == 1) && (count > data->blksz)) count = frame; if (count % 32 == 0) { acnt = 4; bcnt = 8; num_frames = count / 32; } else { acnt = count; bcnt = 1; num_frames = 1; } if (num_frames > MAX_C_CNT) { temp_ccnt = MAX_C_CNT; ccnt = temp_ccnt; } else { ccnt = num_frames; temp_ccnt = ccnt; } if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) { /*AB Sync Transfer */ sync_dev = host->dma_tx_event; src_port = (unsigned int)sg_dma_address(sg); mode_src = INCR; fifo_width_src = W8BIT; /* It's not cared as modeDsr is INCR */ src_bidx = acnt; src_cidx = acnt * bcnt; dst_port = host->phys_base + DAVINCI_MMC_REG_DXR; mode_dst = INCR; fifo_width_dst = W8BIT; /* It's not cared as modeDsr is INCR */ dst_bidx = 0; dst_cidx = 0; bcntrld = 8; sync_mode = ABSYNC; } else { sync_dev = host->dma_rx_event; src_port = host->phys_base + DAVINCI_MMC_REG_DRR; mode_src = INCR; fifo_width_src = W8BIT; src_bidx = 0; src_cidx = 0; dst_port = (unsigned int)sg_dma_address(sg); mode_dst = INCR; fifo_width_dst = W8BIT; /* It's not cared as modeDsr is INCR */ dst_bidx = acnt; dst_cidx = acnt * bcnt; bcntrld = 8; sync_mode = ABSYNC; } davinci_set_dma_src_params(sync_dev, src_port, mode_src, fifo_width_src); davinci_set_dma_dest_params(sync_dev, dst_port, mode_dst, fifo_width_dst); davinci_set_dma_src_index(sync_dev, src_bidx, src_cidx); davinci_set_dma_dest_index(sync_dev, dst_bidx, dst_cidx); davinci_set_dma_transfer_params(sync_dev, acnt, bcnt, ccnt, bcntrld, sync_mode); davinci_get_dma_params(sync_dev, &temp); if (sync_dev == host->dma_tx_event) { if (host->option_write == 0) { host->option_write = temp.opt; } else { temp.opt = host->option_write; davinci_set_dma_params(sync_dev, &temp); } } if (sync_dev == host->dma_rx_event) { if (host->option_read == 0) { host->option_read = temp.opt; } else { temp.opt = host->option_read; davinci_set_dma_params(sync_dev, &temp); } } if (host->sg_len > 1) { davinci_get_dma_params(sync_dev, &temp); temp.opt &= ~TCINTEN; davinci_set_dma_params(sync_dev, &temp); for (i = 0; i < host->sg_len - 1; i++) { sg = &data->sg[i + 1]; if (i != 0) { j = i - 1; davinci_get_dma_params(host->edma_ch_details. chanel_num[j], &temp); temp.opt &= ~TCINTEN; davinci_set_dma_params(host->edma_ch_details. chanel_num[j], &temp); } edma_chan_num = host->edma_ch_details.chanel_num[0]; frame = data->blksz; count = sg_dma_len(sg); if ((data->blocks == 1) && (count > data->blksz)) count = frame; ccnt = count / 32; if (sync_dev == host->dma_tx_event) temp.src = (unsigned int)sg_dma_address(sg); else temp.dst = (unsigned int)sg_dma_address(sg); temp.opt |= TCINTEN; temp.ccnt = (temp.ccnt & 0xFFFF0000) | (ccnt); davinci_set_dma_params(edma_chan_num, &temp); if (i != 0) { j = i - 1; davinci_dma_link_lch(host->edma_ch_details. chanel_num[j], edma_chan_num); } } davinci_dma_link_lch(sync_dev, host->edma_ch_details.chanel_num[0]); } davinci_start_dma(sync_dev); return 0; }