aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorRussell King - ARM Linux <linux@arm.linux.org.uk>2011-01-03 17:38:52 -0500
committerDan Williams <dan.j.williams@intel.com>2011-01-04 22:16:12 -0500
commitc885bee4f10323a1ff3f19e1aa2aa6f4e7f89dd8 (patch)
treeb087498b048c7f69367123579e20ee872b7fb680 /drivers/dma
parentdb9f136a60c8727c8e1c9c4f2494821caebf5a7b (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.c98
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 */
190static void pl08x_set_cregs(struct pl08x_driver_data *pl08x, 191static 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
214static 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 */
250static 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,
1278static void pl08x_issue_pending(struct dma_chan *chan) 1264static 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