diff options
author | Russell King - ARM Linux <linux@arm.linux.org.uk> | 2011-01-03 17:38:52 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-01-04 22:16:12 -0500 |
commit | c885bee4f10323a1ff3f19e1aa2aa6f4e7f89dd8 (patch) | |
tree | b087498b048c7f69367123579e20ee872b7fb680 /drivers/dma | |
parent | db9f136a60c8727c8e1c9c4f2494821caebf5a7b (diff) |
ARM: PL08x: combine functions to start DMA into one function
There is no need for pl08x_config_phychan_for_txd(), pl08x_set_cregs()
and pl08x_enable_phy_chan() to be separate - they are always called in
sequence. Combine them into one function.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/amba-pl08x.c | 98 |
1 files changed, 38 insertions, 60 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 202c9e2d2e9e..c025a4b4bae4 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c | |||
@@ -185,37 +185,17 @@ static int pl08x_phy_channel_busy(struct pl08x_phy_chan *ch) | |||
185 | /* | 185 | /* |
186 | * Set the initial DMA register values i.e. those for the first LLI | 186 | * Set the initial DMA register values i.e. those for the first LLI |
187 | * The next LLI pointer and the configuration interrupt bit have | 187 | * The next LLI pointer and the configuration interrupt bit have |
188 | * been set when the LLIs were constructed | 188 | * been set when the LLIs were constructed. Poke them into the hardware |
189 | * and start the transfer. | ||
189 | */ | 190 | */ |
190 | static void pl08x_set_cregs(struct pl08x_driver_data *pl08x, | 191 | static void pl08x_start_txd(struct pl08x_dma_chan *plchan, |
191 | struct pl08x_phy_chan *ch) | 192 | struct pl08x_txd *txd) |
192 | { | 193 | { |
193 | /* Wait for channel inactive */ | 194 | struct pl08x_driver_data *pl08x = plchan->host; |
194 | while (pl08x_phy_channel_busy(ch)) | ||
195 | cpu_relax(); | ||
196 | |||
197 | dev_vdbg(&pl08x->adev->dev, | ||
198 | "WRITE channel %d: csrc=0x%08x, cdst=0x%08x, " | ||
199 | "cctl=0x%08x, clli=0x%08x, ccfg=0x%08x\n", | ||
200 | ch->id, | ||
201 | ch->csrc, | ||
202 | ch->cdst, | ||
203 | ch->cctl, | ||
204 | ch->clli, | ||
205 | ch->ccfg); | ||
206 | |||
207 | writel(ch->csrc, ch->base + PL080_CH_SRC_ADDR); | ||
208 | writel(ch->cdst, ch->base + PL080_CH_DST_ADDR); | ||
209 | writel(ch->clli, ch->base + PL080_CH_LLI); | ||
210 | writel(ch->cctl, ch->base + PL080_CH_CONTROL); | ||
211 | writel(ch->ccfg, ch->base + PL080_CH_CONFIG); | ||
212 | } | ||
213 | |||
214 | static inline void pl08x_config_phychan_for_txd(struct pl08x_dma_chan *plchan) | ||
215 | { | ||
216 | struct pl08x_channel_data *cd = plchan->cd; | ||
217 | struct pl08x_phy_chan *phychan = plchan->phychan; | 195 | struct pl08x_phy_chan *phychan = plchan->phychan; |
218 | struct pl08x_txd *txd = plchan->at; | 196 | u32 val; |
197 | |||
198 | plchan->at = txd; | ||
219 | 199 | ||
220 | /* Copy the basic control register calculated at transfer config */ | 200 | /* Copy the basic control register calculated at transfer config */ |
221 | phychan->csrc = txd->csrc; | 201 | phychan->csrc = txd->csrc; |
@@ -224,7 +204,7 @@ static inline void pl08x_config_phychan_for_txd(struct pl08x_dma_chan *plchan) | |||
224 | phychan->cctl = txd->cctl; | 204 | phychan->cctl = txd->cctl; |
225 | 205 | ||
226 | /* Assign the signal to the proper control registers */ | 206 | /* Assign the signal to the proper control registers */ |
227 | phychan->ccfg = cd->ccfg; | 207 | phychan->ccfg = plchan->cd->ccfg; |
228 | phychan->ccfg &= ~PL080_CONFIG_SRC_SEL_MASK; | 208 | phychan->ccfg &= ~PL080_CONFIG_SRC_SEL_MASK; |
229 | phychan->ccfg &= ~PL080_CONFIG_DST_SEL_MASK; | 209 | phychan->ccfg &= ~PL080_CONFIG_DST_SEL_MASK; |
230 | /* If it wasn't set from AMBA, ignore it */ | 210 | /* If it wasn't set from AMBA, ignore it */ |
@@ -240,32 +220,38 @@ static inline void pl08x_config_phychan_for_txd(struct pl08x_dma_chan *plchan) | |||
240 | phychan->ccfg |= PL080_CONFIG_ERR_IRQ_MASK; | 220 | phychan->ccfg |= PL080_CONFIG_ERR_IRQ_MASK; |
241 | /* Always enable terminal interrupts */ | 221 | /* Always enable terminal interrupts */ |
242 | phychan->ccfg |= PL080_CONFIG_TC_IRQ_MASK; | 222 | phychan->ccfg |= PL080_CONFIG_TC_IRQ_MASK; |
243 | } | ||
244 | 223 | ||
245 | /* | 224 | /* Wait for channel inactive */ |
246 | * Enable the DMA channel | 225 | while (pl08x_phy_channel_busy(phychan)) |
247 | * Assumes all other configuration bits have been set | 226 | cpu_relax(); |
248 | * as desired before this code is called | ||
249 | */ | ||
250 | static void pl08x_enable_phy_chan(struct pl08x_driver_data *pl08x, | ||
251 | struct pl08x_phy_chan *ch) | ||
252 | { | ||
253 | u32 val; | ||
254 | 227 | ||
255 | /* | 228 | dev_vdbg(&pl08x->adev->dev, |
256 | * Do not access config register until channel shows as disabled | 229 | "WRITE channel %d: csrc=0x%08x, cdst=0x%08x, " |
257 | */ | 230 | "cctl=0x%08x, clli=0x%08x, ccfg=0x%08x\n", |
258 | while (readl(pl08x->base + PL080_EN_CHAN) & (1 << ch->id)) | 231 | phychan->id, |
232 | phychan->csrc, | ||
233 | phychan->cdst, | ||
234 | phychan->cctl, | ||
235 | phychan->clli, | ||
236 | phychan->ccfg); | ||
237 | |||
238 | writel(phychan->csrc, phychan->base + PL080_CH_SRC_ADDR); | ||
239 | writel(phychan->cdst, phychan->base + PL080_CH_DST_ADDR); | ||
240 | writel(phychan->clli, phychan->base + PL080_CH_LLI); | ||
241 | writel(phychan->cctl, phychan->base + PL080_CH_CONTROL); | ||
242 | writel(phychan->ccfg, phychan->base + PL080_CH_CONFIG); | ||
243 | |||
244 | /* Enable the DMA channel */ | ||
245 | /* Do not access config register until channel shows as disabled */ | ||
246 | while (readl(pl08x->base + PL080_EN_CHAN) & (1 << phychan->id)) | ||
259 | cpu_relax(); | 247 | cpu_relax(); |
260 | 248 | ||
261 | /* | 249 | /* Do not access config register until channel shows as inactive */ |
262 | * Do not access config register until channel shows as inactive | 250 | val = readl(phychan->base + PL080_CH_CONFIG); |
263 | */ | ||
264 | val = readl(ch->base + PL080_CH_CONFIG); | ||
265 | while ((val & PL080_CONFIG_ACTIVE) || (val & PL080_CONFIG_ENABLE)) | 251 | while ((val & PL080_CONFIG_ACTIVE) || (val & PL080_CONFIG_ENABLE)) |
266 | val = readl(ch->base + PL080_CH_CONFIG); | 252 | val = readl(phychan->base + PL080_CH_CONFIG); |
267 | 253 | ||
268 | writel(val | PL080_CONFIG_ENABLE, ch->base + PL080_CH_CONFIG); | 254 | writel(val | PL080_CONFIG_ENABLE, phychan->base + PL080_CH_CONFIG); |
269 | } | 255 | } |
270 | 256 | ||
271 | /* | 257 | /* |
@@ -1278,7 +1264,6 @@ static void dma_set_runtime_config(struct dma_chan *chan, | |||
1278 | static void pl08x_issue_pending(struct dma_chan *chan) | 1264 | static void pl08x_issue_pending(struct dma_chan *chan) |
1279 | { | 1265 | { |
1280 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); | 1266 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); |
1281 | struct pl08x_driver_data *pl08x = plchan->host; | ||
1282 | unsigned long flags; | 1267 | unsigned long flags; |
1283 | 1268 | ||
1284 | spin_lock_irqsave(&plchan->lock, flags); | 1269 | spin_lock_irqsave(&plchan->lock, flags); |
@@ -1296,13 +1281,9 @@ static void pl08x_issue_pending(struct dma_chan *chan) | |||
1296 | struct pl08x_txd, | 1281 | struct pl08x_txd, |
1297 | node); | 1282 | node); |
1298 | list_del(&next->node); | 1283 | list_del(&next->node); |
1299 | plchan->at = next; | ||
1300 | plchan->state = PL08X_CHAN_RUNNING; | 1284 | plchan->state = PL08X_CHAN_RUNNING; |
1301 | 1285 | ||
1302 | /* Configure the physical channel for the active txd */ | 1286 | pl08x_start_txd(plchan, next); |
1303 | pl08x_config_phychan_for_txd(plchan); | ||
1304 | pl08x_set_cregs(pl08x, plchan->phychan); | ||
1305 | pl08x_enable_phy_chan(pl08x, plchan->phychan); | ||
1306 | } | 1287 | } |
1307 | 1288 | ||
1308 | spin_unlock_irqrestore(&plchan->lock, flags); | 1289 | spin_unlock_irqrestore(&plchan->lock, flags); |
@@ -1630,11 +1611,8 @@ static void pl08x_tasklet(unsigned long data) | |||
1630 | struct pl08x_txd, | 1611 | struct pl08x_txd, |
1631 | node); | 1612 | node); |
1632 | list_del(&next->node); | 1613 | list_del(&next->node); |
1633 | plchan->at = next; | 1614 | |
1634 | /* Configure the physical channel for the next txd */ | 1615 | pl08x_start_txd(plchan, next); |
1635 | pl08x_config_phychan_for_txd(plchan); | ||
1636 | pl08x_set_cregs(pl08x, plchan->phychan); | ||
1637 | pl08x_enable_phy_chan(pl08x, plchan->phychan); | ||
1638 | } else { | 1616 | } else { |
1639 | struct pl08x_dma_chan *waiting = NULL; | 1617 | struct pl08x_dma_chan *waiting = NULL; |
1640 | 1618 | ||