static ssize_t memcpy_dma_write(struct device *device, struct device_attribute *attr, const char *argv, size_t count) { int rt; struct Dma_MemToMem *DmaMemInfo = (struct Dma_MemToMem *)argv; rt = rk29_dma_devconfig(DMACH_DMAC0_MEMTOMEM, RK29_DMASRC_MEMTOMEM, DmaMemInfo->SrcAddr); rt = rk29_dma_enqueue(DMACH_DMAC0_MEMTOMEM, NULL, DmaMemInfo->DstAddr, DmaMemInfo->MenSize); rt = rk29_dma_ctrl(DMACH_DMAC0_MEMTOMEM, RK29_DMAOP_START); wait_event_interruptible_timeout(wq, wq_condition, 200); wq_condition = 0; //init_waitqueue_head(&dma_memcpy_wait); //interruptible_sleep_on(&dma_memcpy_wait); return 0; }
/* rockchip_pcm_enqueue * * place a dma buffer onto the queue for the dma system * to handle. */ static void rockchip_pcm_enqueue(struct snd_pcm_substream *substream) { struct rockchip_runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; int ret; // DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); while (prtd->dma_loaded < prtd->dma_limit) { unsigned long len = prtd->dma_period; // DBG("dma_loaded: %d\n", prtd->dma_loaded); if ((pos + len) > prtd->dma_end) { len = prtd->dma_end - pos; } if((len%(prtd->params->dma_size*16) == 0) && (prtd->params->flag == 1)) { ret = rk29_dma_config(prtd->params->channel, prtd->params->dma_size, 16); prtd->params->flag = 0; DBG("size = 16, channel = %d, flag = %d\n",prtd->params->channel,prtd->params->flag); } else if((len%(prtd->params->dma_size*16) != 0) && (prtd->params->flag == 0)) { ret = rk29_dma_config(prtd->params->channel, prtd->params->dma_size, 1); prtd->params->flag = 1; DBG("size = 1, channel = %d, flag = %d\n",prtd->params->channel,prtd->params->flag); } ret = rk29_dma_enqueue(prtd->params->channel,substream, pos, len); // if(prtd->params->channel == 2) DBG("Enter::%s, %d, ret=%d, Channel=%d, Addr=0x%X, Len=%lu\n", __FUNCTION__,__LINE__, ret, prtd->params->channel, pos, len); if (ret == 0) { prtd->dma_loaded++; pos += prtd->dma_period; if (pos >= prtd->dma_end) pos = prtd->dma_start; } else break; } prtd->dma_pos = pos; }
static int dma_start(struct rk_mmc *host) { int i, res, direction, sg_len; enum rk29_dmasrc src; struct mmc_data *data = host->data; BUG_ON(!data); host->dma_xfer_size = 0; if (data->flags & MMC_DATA_READ){ direction = DMA_FROM_DEVICE; src = RK29_DMASRC_HW; }else{ direction = DMA_TO_DEVICE; src = RK29_DMASRC_MEM; } sg_len = rk_mmc_pre_dma_transfer(host, host->data, 0); if(sg_len < 0){ host->ops->stop(host); return sg_len; } res = rk29_dma_devconfig(MMC_DMA_CHN, src, host->dma_addr); if(unlikely(res < 0)) return res; for(i = 0; i < sg_len; i++){ res = rk29_dma_enqueue(MMC_DMA_CHN, host, sg_dma_address(&data->sg[i]), sg_dma_len(&data->sg[i])); if(unlikely(res < 0)) return res; } res = rk29_dma_ctrl(MMC_DMA_CHN, RK29_DMAOP_START); if(unlikely(res < 0)) return res; return res; }
/* rockchip_pcm_enqueue * * place a dma buffer onto the queue for the dma system * to handle. */ static void rockchip_pcm_enqueue(struct snd_pcm_substream *substream) { struct rockchip_runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; unsigned int limit; int ret; DBG("Enter::%s----%d prtd->dma_period = %d prtd->dma_limit = %d\n",__FUNCTION__,__LINE__,prtd->dma_period,prtd->dma_limit); if (rk29_dma_has_circular()) limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; else limit = prtd->dma_limit; if (DMA_INFIN_LOOP()) { if(prtd->dma_period % (prtd->params->dma_size*16)){ printk("dma_period(%d) is not an integer multiple of dma_size(%d)",prtd->dma_period,prtd->params->dma_size*16); rk29_dma_config(prtd->params->channel, prtd->params->dma_size, 1); } else rk29_dma_config(prtd->params->channel, prtd->params->dma_size, 16); ret = rk29_dma_enqueue_ring(prtd->params->channel, substream, pos, prtd->dma_period, limit ,true); if (ret == 0) pos = prtd->dma_start; } else { while (prtd->dma_loaded < prtd->dma_limit) { unsigned long len = prtd->dma_period; // DBG("dma_loaded: %d\n", prtd->dma_loaded); if ((pos + len) > prtd->dma_end) { len = prtd->dma_end - pos; } if((len%(prtd->params->dma_size*16) == 0) && (prtd->params->flag == 1)) { ret = rk29_dma_config(prtd->params->channel, prtd->params->dma_size, 16); prtd->params->flag = 0; DBG("size = 16, channel = %d, flag = %d\n",prtd->params->channel,prtd->params->flag); } else if((len%(prtd->params->dma_size*16) != 0) && (prtd->params->flag == 0)) { ret = rk29_dma_config(prtd->params->channel, prtd->params->dma_size, 1); prtd->params->flag = 1; DBG("size = 1, channel = %d, flag = %d\n",prtd->params->channel,prtd->params->flag); } ret = rk29_dma_enqueue(prtd->params->channel,substream, pos, len); // if(prtd->params->channel == 2) DBG("Enter::%s, %d, ret=%d, Channel=%d, Addr=0x%X, Len=%lu\n", __FUNCTION__,__LINE__, ret, prtd->params->channel, pos, len); if (ret == 0) { prtd->dma_loaded++; pos += prtd->dma_period; if (pos >= prtd->dma_end) pos = prtd->dma_start; } else break; } } prtd->dma_pos = pos; }