问题自己已经解决
通过自己修改driver/edma.c,为edma的非memcpy通道也配置上mem_to_mem函数指针即可
static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode)[ struct dma_device *s_ddev = &ecc->dma_slave; struct dma_device *m_ddev = NULL; s32 *memcpy_channels = ecc->info->memcpy_channels; int i, j; dma_cap_zero(s_ddev->cap_mask); dma_cap_set(DMA_SLAVE, s_ddev->cap_mask); dma_cap_set(DMA_CYCLIC, s_ddev->cap_mask); if (ecc->legacy_mode && !memcpy_channels) [ dev_warn(ecc->dev, "Legacy memcpy is enabled, things might not workn"); dma_cap_set(DMA_MEMCPY, s_ddev->cap_mask); s_ddev->device_prep_dma_memcpy = edma_prep_dma_memcpy; s_ddev->directions = BIT(DMA_MEM_TO_MEM); ] s_ddev->device_prep_slave_sg = edma_prep_slave_sg; s_ddev->device_prep_dma_cyclic = edma_prep_dma_cyclic; s_ddev->device_alloc_chan_resources = edma_alloc_chan_resources; s_ddev->device_free_chan_resources = edma_free_chan_resources; s_ddev->device_issue_pending = edma_issue_pending; s_ddev->device_tx_status = edma_tx_status; s_ddev->device_config = edma_slave_config; s_ddev->device_pause = edma_dma_pause; s_ddev->device_resume = edma_dma_resume; s_ddev->device_terminate_all = edma_terminate_all; s_ddev->device_synchronize = edma_synchronize; s_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS; s_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS; s_ddev->directions |= (BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV)); s_ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;////////////////////////////////////////////////////// /* cet,liudachuan: try to support mem_to_mem transfer */ s_ddev->device_prep_dma_memcpy = edma_prep_dma_memcpy; s_ddev->directions |= BIT(DMA_MEM_TO_MEM); /* end of mod */////////////////////////////////////////////////////// s_ddev->dev = ecc->dev; INIT_LIST_HEAD(&s_ddev->channels); if (memcpy_channels) [ m_ddev = devm_kzalloc(ecc->dev, sizeof(*m_ddev), GFP_KERNEL); ecc->dma_memcpy = m_ddev; dma_cap_zero(m_ddev->cap_mask); dma_cap_set(DMA_MEMCPY, m_ddev->cap_mask); m_ddev->device_prep_dma_memcpy = edma_prep_dma_memcpy; m_ddev->device_alloc_chan_resources = edma_alloc_chan_resources; m_ddev->device_free_chan_resources = edma_free_chan_resources; m_ddev->device_issue_pending = edma_issue_pending; m_ddev->device_tx_status = edma_tx_status; m_ddev->device_config = edma_slave_config; m_ddev->device_pause = edma_dma_pause; m_ddev->device_resume = edma_dma_resume; m_ddev->device_terminate_all = edma_terminate_all; m_ddev->device_synchronize = edma_synchronize; m_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS; m_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS; m_ddev->directions = BIT(DMA_MEM_TO_MEM); m_ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; m_ddev->dev = ecc->dev; INIT_LIST_HEAD(&m_ddev->channels); ] else if (!ecc->legacy_mode) [ dev_info(ecc->dev, "memcpy is disabledn"); ] for (i = 0; i < ecc->num_channels; i++) [ struct edma_chan *echan = &ecc->slave_chans
; echan->ch_num = EDMA_CTLR_CHAN(ecc->id, i); echan->ecc = ecc; echan->vchan.desc_free = edma_desc_free; if (m_ddev && edma_is_memcpy_channel(i, memcpy_channels)) vchan_init(&echan->vchan, m_ddev); else vchan_init(&echan->vchan, s_ddev); INIT_LIST_HEAD(&echan->node); for (j = 0; j < EDMA_MAX_SLOTS; j++) echan->slot[j] = -1; ]]
问题自己已经解决
通过自己修改driver/edma.c,为edma的非memcpy通道也配置上mem_to_mem函数指针即可
static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode)[ struct dma_device *s_ddev = &ecc->dma_slave; struct dma_device *m_ddev = NULL; s32 *memcpy_channels = ecc->info->memcpy_channels; int i, j; dma_cap_zero(s_ddev->cap_mask); dma_cap_set(DMA_SLAVE, s_ddev->cap_mask); dma_cap_set(DMA_CYCLIC, s_ddev->cap_mask); if (ecc->legacy_mode && !memcpy_channels) [ dev_warn(ecc->dev, "Legacy memcpy is enabled, things might not workn"); dma_cap_set(DMA_MEMCPY, s_ddev->cap_mask); s_ddev->device_prep_dma_memcpy = edma_prep_dma_memcpy; s_ddev->directions = BIT(DMA_MEM_TO_MEM); ] s_ddev->device_prep_slave_sg = edma_prep_slave_sg; s_ddev->device_prep_dma_cyclic = edma_prep_dma_cyclic; s_ddev->device_alloc_chan_resources = edma_alloc_chan_resources; s_ddev->device_free_chan_resources = edma_free_chan_resources; s_ddev->device_issue_pending = edma_issue_pending; s_ddev->device_tx_status = edma_tx_status; s_ddev->device_config = edma_slave_config; s_ddev->device_pause = edma_dma_pause; s_ddev->device_resume = edma_dma_resume; s_ddev->device_terminate_all = edma_terminate_all; s_ddev->device_synchronize = edma_synchronize; s_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS; s_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS; s_ddev->directions |= (BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV)); s_ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;////////////////////////////////////////////////////// /* cet,liudachuan: try to support mem_to_mem transfer */ s_ddev->device_prep_dma_memcpy = edma_prep_dma_memcpy; s_ddev->directions |= BIT(DMA_MEM_TO_MEM); /* end of mod */////////////////////////////////////////////////////// s_ddev->dev = ecc->dev; INIT_LIST_HEAD(&s_ddev->channels); if (memcpy_channels) [ m_ddev = devm_kzalloc(ecc->dev, sizeof(*m_ddev), GFP_KERNEL); ecc->dma_memcpy = m_ddev; dma_cap_zero(m_ddev->cap_mask); dma_cap_set(DMA_MEMCPY, m_ddev->cap_mask); m_ddev->device_prep_dma_memcpy = edma_prep_dma_memcpy; m_ddev->device_alloc_chan_resources = edma_alloc_chan_resources; m_ddev->device_free_chan_resources = edma_free_chan_resources; m_ddev->device_issue_pending = edma_issue_pending; m_ddev->device_tx_status = edma_tx_status; m_ddev->device_config = edma_slave_config; m_ddev->device_pause = edma_dma_pause; m_ddev->device_resume = edma_dma_resume; m_ddev->device_terminate_all = edma_terminate_all; m_ddev->device_synchronize = edma_synchronize; m_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS; m_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS; m_ddev->directions = BIT(DMA_MEM_TO_MEM); m_ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; m_ddev->dev = ecc->dev; INIT_LIST_HEAD(&m_ddev->channels); ] else if (!ecc->legacy_mode) [ dev_info(ecc->dev, "memcpy is disabledn"); ] for (i = 0; i < ecc->num_channels; i++) [ struct edma_chan *echan = &ecc->slave_chans
; echan->ch_num = EDMA_CTLR_CHAN(ecc->id, i); echan->ecc = ecc; echan->vchan.desc_free = edma_desc_free; if (m_ddev && edma_is_memcpy_channel(i, memcpy_channels)) vchan_init(&echan->vchan, m_ddev); else vchan_init(&echan->vchan, s_ddev); INIT_LIST_HEAD(&echan->node); for (j = 0; j < EDMA_MAX_SLOTS; j++) echan->slot[j] = -1; ]]
举报