X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=drivers%2Fdma%2Fapbh_dma.c;h=0c1cd831e01df689ef1c4a7ac421b55f5a299fa4;hp=e85f5fe6d215b891cca7ed13e9a3269334b53ddb;hb=e5f5c4a977c411c0cd3899a4f9487eea77a0e150;hpb=c786f54b9ace5d7b20a0404a7deb1bae683cd4e8 diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c index e85f5fe6d2..0c1cd831e0 100644 --- a/drivers/dma/apbh_dma.c +++ b/drivers/dma/apbh_dma.c @@ -76,8 +76,8 @@ static unsigned int mxs_dma_cmd_address(struct mxs_dma_desc *desc) */ static int mxs_dma_read_semaphore(int channel) { - struct mx28_apbh_regs *apbh_regs = - (struct mx28_apbh_regs *)MXS_APBH_BASE; + struct mxs_apbh_regs *apbh_regs = + (struct mxs_apbh_regs *)MXS_APBH_BASE; uint32_t tmp; int ret; @@ -93,6 +93,21 @@ static int mxs_dma_read_semaphore(int channel) return tmp; } +#ifndef CONFIG_SYS_DCACHE_OFF +void mxs_dma_flush_desc(struct mxs_dma_desc *desc) +{ + uint32_t addr; + uint32_t size; + + addr = (uint32_t)desc; + size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT); + + flush_dcache_range(addr, addr + size); +} +#else +inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc) {} +#endif + /* * Enable a DMA channel. * @@ -104,8 +119,8 @@ static int mxs_dma_read_semaphore(int channel) */ static int mxs_dma_enable(int channel) { - struct mx28_apbh_regs *apbh_regs = - (struct mx28_apbh_regs *)MXS_APBH_BASE; + struct mxs_apbh_regs *apbh_regs = + (struct mxs_apbh_regs *)MXS_APBH_BASE; unsigned int sem; struct mxs_dma_chan *pchan; struct mxs_dma_desc *pdesc; @@ -176,8 +191,8 @@ static int mxs_dma_enable(int channel) static int mxs_dma_disable(int channel) { struct mxs_dma_chan *pchan; - struct mx28_apbh_regs *apbh_regs = - (struct mx28_apbh_regs *)MXS_APBH_BASE; + struct mxs_apbh_regs *apbh_regs = + (struct mxs_apbh_regs *)MXS_APBH_BASE; int ret; ret = mxs_dma_validate_chan(channel); @@ -205,16 +220,22 @@ static int mxs_dma_disable(int channel) */ static int mxs_dma_reset(int channel) { - struct mx28_apbh_regs *apbh_regs = - (struct mx28_apbh_regs *)MXS_APBH_BASE; + struct mxs_apbh_regs *apbh_regs = + (struct mxs_apbh_regs *)MXS_APBH_BASE; int ret; +#if defined(CONFIG_MX23) + uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set); + uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET; +#elif defined(CONFIG_MX28) + uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_channel_ctrl_set); + uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET; +#endif ret = mxs_dma_validate_chan(channel); if (ret) return ret; - writel(1 << (channel + APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET), - &apbh_regs->hw_apbh_channel_ctrl_set); + writel(1 << (channel + offset), setreg); return 0; } @@ -226,8 +247,8 @@ static int mxs_dma_reset(int channel) */ static int mxs_dma_enable_irq(int channel, int enable) { - struct mx28_apbh_regs *apbh_regs = - (struct mx28_apbh_regs *)MXS_APBH_BASE; + struct mxs_apbh_regs *apbh_regs = + (struct mxs_apbh_regs *)MXS_APBH_BASE; int ret; ret = mxs_dma_validate_chan(channel); @@ -252,8 +273,8 @@ static int mxs_dma_enable_irq(int channel, int enable) */ static int mxs_dma_ack_irq(int channel) { - struct mx28_apbh_regs *apbh_regs = - (struct mx28_apbh_regs *)MXS_APBH_BASE; + struct mxs_apbh_regs *apbh_regs = + (struct mxs_apbh_regs *)MXS_APBH_BASE; int ret; ret = mxs_dma_validate_chan(channel); @@ -301,7 +322,7 @@ static int mxs_dma_request(int channel) * The channel will NOT be released if it's marked "busy" (see * mxs_dma_enable()). */ -static int mxs_dma_release(int channel) +int mxs_dma_release(int channel) { struct mxs_dma_chan *pchan; int ret; @@ -329,8 +350,10 @@ static int mxs_dma_release(int channel) struct mxs_dma_desc *mxs_dma_desc_alloc(void) { struct mxs_dma_desc *pdesc; + uint32_t size; - pdesc = memalign(MXS_DMA_ALIGNMENT, sizeof(struct mxs_dma_desc)); + size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT); + pdesc = memalign(MXS_DMA_ALIGNMENT, size); if (pdesc == NULL) return NULL; @@ -415,12 +438,16 @@ int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc) last->cmd.next = mxs_dma_cmd_address(pdesc); last->cmd.data |= MXS_DMA_DESC_CHAIN; + + mxs_dma_flush_desc(last); } pdesc->flags |= MXS_DMA_DESC_READY; if (pdesc->flags & MXS_DMA_DESC_FIRST) pchan->pending_num++; list_add_tail(&pdesc->node, &pchan->active); + mxs_dma_flush_desc(pdesc); + return ret; } @@ -483,15 +510,15 @@ static int mxs_dma_finish(int channel, struct list_head *head) */ static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan) { - struct mx28_apbh_regs *apbh_regs = - (struct mx28_apbh_regs *)MXS_APBH_BASE; + struct mxs_apbh_regs *apbh_regs = + (struct mxs_apbh_regs *)MXS_APBH_BASE; int ret; ret = mxs_dma_validate_chan(chan); if (ret) return ret; - if (mx28_wait_mask_set(&apbh_regs->hw_apbh_ctrl1_reg, + if (mxs_wait_mask_set(&apbh_regs->hw_apbh_ctrl1_reg, 1 << chan, timeout)) { ret = -ETIMEDOUT; mxs_dma_reset(chan); @@ -505,7 +532,7 @@ static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan) */ int mxs_dma_go(int chan) { - uint32_t timeout = 10000; + uint32_t timeout = 10000000; int ret; LIST_HEAD(tmp_desc_list); @@ -531,14 +558,12 @@ int mxs_dma_go(int chan) /* * Initialize the DMA hardware */ -int mxs_dma_init(void) +void mxs_dma_init(void) { - struct mx28_apbh_regs *apbh_regs = - (struct mx28_apbh_regs *)MXS_APBH_BASE; - struct mxs_dma_chan *pchan; - int ret, channel; + struct mxs_apbh_regs *apbh_regs = + (struct mxs_apbh_regs *)MXS_APBH_BASE; - mx28_reset_block(&apbh_regs->hw_apbh_ctrl0_reg); + mxs_reset_block(&apbh_regs->hw_apbh_ctrl0_reg); #ifdef CONFIG_APBH_DMA_BURST8 writel(APBH_CTRL0_AHB_BURST8_EN, @@ -555,28 +580,26 @@ int mxs_dma_init(void) writel(APBH_CTRL0_APB_BURST_EN, &apbh_regs->hw_apbh_ctrl0_clr); #endif +} - for (channel = 0; channel < MXS_MAX_DMA_CHANNELS; channel++) { - pchan = mxs_dma_channels + channel; - pchan->flags = MXS_DMA_FLAGS_VALID; +int mxs_dma_init_channel(int channel) +{ + struct mxs_dma_chan *pchan; + int ret; - ret = mxs_dma_request(channel); + pchan = mxs_dma_channels + channel; + pchan->flags = MXS_DMA_FLAGS_VALID; - if (ret) { - printf("MXS DMA: Can't acquire DMA channel %i\n", - channel); + ret = mxs_dma_request(channel); - goto err; - } - - mxs_dma_reset(channel); - mxs_dma_ack_irq(channel); + if (ret) { + printf("MXS DMA: Can't acquire DMA channel %i\n", + channel); + return ret; } - return 0; + mxs_dma_reset(channel); + mxs_dma_ack_irq(channel); -err: - while (--channel >= 0) - mxs_dma_release(channel); - return ret; + return 0; }