X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fdma%2Fapbh_dma.c;h=22defcd7d9223be898b18cdc8ae1236a38272671;hb=19d829fa60fc4e6df514a046142faaaf9fc8185d;hp=c086629b0a91e967b1cd078b52af48122665de5c;hpb=bc6f6c87b685bcdcd5bef522982d15209b6b9601;p=u-boot diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c index c086629b0a..22defcd7d9 100644 --- a/drivers/dma/apbh_dma.c +++ b/drivers/dma/apbh_dma.c @@ -7,19 +7,7 @@ * Based on code from LTIB: * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -31,7 +19,8 @@ #include #include #include -#include +#include +#include static struct mxs_dma_chan mxs_dma_channels[MXS_MAX_DMA_CHANNELS]; @@ -76,8 +65,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; @@ -119,8 +108,8 @@ inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc) {} */ 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; @@ -191,8 +180,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); @@ -220,16 +209,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) || defined(CONFIG_MX6)) + 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; } @@ -241,8 +236,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); @@ -267,8 +262,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); @@ -316,7 +311,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; @@ -504,15 +499,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); @@ -526,7 +521,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); @@ -549,17 +544,37 @@ int mxs_dma_go(int chan) return ret; } +/* + * Execute a continuously running circular DMA descriptor. + * NOTE: This is not intended for general use, but rather + * for the LCD driver in Smart-LCD mode. It allows + * continuous triggering of the RUN bit there. + */ +void mxs_dma_circ_start(int chan, struct mxs_dma_desc *pdesc) +{ + struct mxs_apbh_regs *apbh_regs = + (struct mxs_apbh_regs *)MXS_APBH_BASE; + + mxs_dma_flush_desc(pdesc); + + mxs_dma_enable_irq(chan, 1); + + writel(mxs_dma_cmd_address(pdesc), + &apbh_regs->ch[chan].hw_apbh_ch_nxtcmdar); + writel(1, &apbh_regs->ch[chan].hw_apbh_ch_sema); + writel(1 << (chan + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET), + &apbh_regs->hw_apbh_ctrl0_clr); +} + /* * 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, @@ -576,28 +591,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; - - ret = mxs_dma_request(channel); +int mxs_dma_init_channel(int channel) +{ + struct mxs_dma_chan *pchan; + int ret; - if (ret) { - printf("MXS DMA: Can't acquire DMA channel %i\n", - channel); + pchan = mxs_dma_channels + channel; + pchan->flags = MXS_DMA_FLAGS_VALID; - goto err; - } + ret = mxs_dma_request(channel); - 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; }