Lines Matching +full:ahb +full:- +full:addr +full:- +full:masks
3 * Copyright (c) 2010 ST-Ericsson SA
39 * - CH_CONFIG register at different offset,
40 * - separate CH_CONTROL2 register for transfer size,
41 * - bigger maximum transfer size,
42 * - 8-word aligned LLI, instead of 4-word, due to extra CCTL2 word,
43 * - no support for peripheral flow control.
57 * (Bursts are irrelevant for mem to mem transfers - there are no burst
58 * signals, the DMA controller will simply facilitate its AHB master.)
63 * - DMAC flow control: the transfer size defines the number of transfers
70 * - Peripheral flow control: the transfer size is ignored (and should be
82 #include <linux/dma-mapping.h>
95 #include "virt-dma.h"
109 * struct vendor_data - vendor-specific config parameters for PL08x derivatives
113 * @dualmaster: whether this version supports dual AHB masters or not.
135 * struct pl08x_bus_data - information of source or destination
137 * @addr: current address
142 dma_addr_t addr; member
147 #define IS_BUS_ALIGNED(bus) IS_ALIGNED((bus)->addr, (bus)->buswidth)
150 * struct pl08x_phy_chan - holder for the physical channels
158 * @reg_busy: if the variant has a special per-channel busy register,
185 * struct pl08x_sg - structure containing data per sg
199 * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
227 * enum pl08x_dma_chan_state - holds the PL08x specific virtual channel
245 * struct pl08x_dma_chan - this structure wraps a DMA ENGINE channel
273 * struct pl08x_driver_data - the local state holder for the PL08x
283 * @lli_buses: bitmask to or in to LLI pointer selecting AHB port for LLI
345 const struct pl08x_platform_data *pd = plchan->host->pd; in pl08x_request_mux()
348 if (plchan->mux_use++ == 0 && pd->get_xfer_signal) { in pl08x_request_mux()
349 ret = pd->get_xfer_signal(plchan->cd); in pl08x_request_mux()
351 plchan->mux_use = 0; in pl08x_request_mux()
355 plchan->signal = ret; in pl08x_request_mux()
362 const struct pl08x_platform_data *pd = plchan->host->pd; in pl08x_release_mux()
364 if (plchan->signal >= 0) { in pl08x_release_mux()
365 WARN_ON(plchan->mux_use == 0); in pl08x_release_mux()
367 if (--plchan->mux_use == 0 && pd->put_xfer_signal) { in pl08x_release_mux()
368 pd->put_xfer_signal(plchan->cd, plchan->signal); in pl08x_release_mux()
369 plchan->signal = -1; in pl08x_release_mux()
384 if (ch->reg_busy) { in pl08x_phy_channel_busy()
385 val = readl(ch->reg_busy); in pl08x_phy_channel_busy()
386 return !!(val & BIT(ch->id)); in pl08x_phy_channel_busy()
388 val = readl(ch->reg_config); in pl08x_phy_channel_busy()
393 * pl08x_write_lli() - Write an LLI into the DMA controller.
404 if (pl08x->vd->pl080s) in pl08x_write_lli()
405 dev_vdbg(&pl08x->adev->dev, in pl08x_write_lli()
408 phychan->id, lli[PL080_LLI_SRC], lli[PL080_LLI_DST], in pl08x_write_lli()
412 dev_vdbg(&pl08x->adev->dev, in pl08x_write_lli()
415 phychan->id, lli[PL080_LLI_SRC], lli[PL080_LLI_DST], in pl08x_write_lli()
418 writel_relaxed(lli[PL080_LLI_SRC], phychan->reg_src); in pl08x_write_lli()
419 writel_relaxed(lli[PL080_LLI_DST], phychan->reg_dst); in pl08x_write_lli()
420 writel_relaxed(lli[PL080_LLI_LLI], phychan->reg_lli); in pl08x_write_lli()
428 if (phychan->ftdmac020) { in pl08x_write_lli()
434 phychan->base + FTDMAC020_CH_SIZE); in pl08x_write_lli()
439 * Bit 28: TC_MSK - mask on all except last LLI in pl08x_write_lli()
450 (FTDMAC020_LLI_SRC_WIDTH_SHIFT - in pl08x_write_lli()
453 (FTDMAC020_LLI_DST_WIDTH_SHIFT - in pl08x_write_lli()
456 (FTDMAC020_LLI_SRCAD_CTL_SHIFT - in pl08x_write_lli()
459 (FTDMAC020_LLI_DSTAD_CTL_SHIFT - in pl08x_write_lli()
473 switch (pl08x->pd->memcpy_burst_size) { in pl08x_write_lli()
510 if (pl08x->pd->memcpy_prot_buff) in pl08x_write_lli()
512 if (pl08x->pd->memcpy_prot_cache) in pl08x_write_lli()
517 writel_relaxed(val, phychan->reg_control); in pl08x_write_lli()
520 writel_relaxed(lli[PL080_LLI_CCTL], phychan->reg_control); in pl08x_write_lli()
524 if (pl08x->vd->pl080s) in pl08x_write_lli()
526 phychan->base + PL080S_CH_CONTROL2); in pl08x_write_lli()
528 writel(ccfg, phychan->reg_config); in pl08x_write_lli()
539 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_start_next_txd()
540 struct pl08x_phy_chan *phychan = plchan->phychan; in pl08x_start_next_txd()
541 struct virt_dma_desc *vd = vchan_next_desc(&plchan->vc); in pl08x_start_next_txd()
542 struct pl08x_txd *txd = to_pl08x_txd(&vd->tx); in pl08x_start_next_txd()
545 list_del(&txd->vd.node); in pl08x_start_next_txd()
547 plchan->at = txd; in pl08x_start_next_txd()
553 pl08x_write_lli(pl08x, phychan, &txd->llis_va[0], txd->ccfg); in pl08x_start_next_txd()
557 while (readl(pl08x->base + PL080_EN_CHAN) & BIT(phychan->id)) in pl08x_start_next_txd()
561 if (phychan->ftdmac020) { in pl08x_start_next_txd()
562 val = readl(phychan->reg_config); in pl08x_start_next_txd()
564 val = readl(phychan->reg_config); in pl08x_start_next_txd()
566 val = readl(phychan->reg_control); in pl08x_start_next_txd()
568 val = readl(phychan->reg_control); in pl08x_start_next_txd()
571 phychan->reg_control); in pl08x_start_next_txd()
573 val = readl(phychan->reg_config); in pl08x_start_next_txd()
576 val = readl(phychan->reg_config); in pl08x_start_next_txd()
578 writel(val | PL080_CONFIG_ENABLE, phychan->reg_config); in pl08x_start_next_txd()
585 * For M->P transfers, pause the DMAC first and then stop the peripheral -
589 * For P->M transfers, disable the peripheral first to stop it filling
597 if (ch->ftdmac020) { in pl08x_pause_phy_chan()
599 val = readl(ch->reg_control); in pl08x_pause_phy_chan()
601 writel(val, ch->reg_control); in pl08x_pause_phy_chan()
606 val = readl(ch->reg_config); in pl08x_pause_phy_chan()
608 writel(val, ch->reg_config); in pl08x_pause_phy_chan()
611 for (timeout = 1000; timeout; timeout--) { in pl08x_pause_phy_chan()
617 pr_err("pl08x: channel%u timeout waiting for pause\n", ch->id); in pl08x_pause_phy_chan()
625 if (ch->ftdmac020) { in pl08x_resume_phy_chan()
626 val = readl(ch->reg_control); in pl08x_resume_phy_chan()
628 writel(val, ch->reg_control); in pl08x_resume_phy_chan()
633 val = readl(ch->reg_config); in pl08x_resume_phy_chan()
635 writel(val, ch->reg_config); in pl08x_resume_phy_chan()
641 * an on-going transfer, but as a method of shutting down a channel
650 if (ch->ftdmac020) { in pl08x_terminate_phy_chan()
652 val = readl(ch->reg_config); in pl08x_terminate_phy_chan()
656 writel(val, ch->reg_config); in pl08x_terminate_phy_chan()
659 val = readl(ch->reg_control); in pl08x_terminate_phy_chan()
662 writel(val, ch->reg_control); in pl08x_terminate_phy_chan()
665 writel(BIT(ch->id) | BIT(ch->id + 16), in pl08x_terminate_phy_chan()
666 pl08x->base + PL080_ERR_CLEAR); in pl08x_terminate_phy_chan()
667 writel(BIT(ch->id), pl08x->base + PL080_TC_CLEAR); in pl08x_terminate_phy_chan()
672 val = readl(ch->reg_config); in pl08x_terminate_phy_chan()
675 writel(val, ch->reg_config); in pl08x_terminate_phy_chan()
677 writel(BIT(ch->id), pl08x->base + PL080_ERR_CLEAR); in pl08x_terminate_phy_chan()
678 writel(BIT(ch->id), pl08x->base + PL080_TC_CLEAR); in pl08x_terminate_phy_chan()
686 if (ch->ftdmac020) { in get_bytes_in_phy_channel()
687 bytes = readl(ch->base + FTDMAC020_CH_SIZE); in get_bytes_in_phy_channel()
689 val = readl(ch->reg_control); in get_bytes_in_phy_channel()
692 } else if (ch->pl080s) { in get_bytes_in_phy_channel()
693 val = readl(ch->base + PL080S_CH_CONTROL2); in get_bytes_in_phy_channel()
696 val = readl(ch->reg_control); in get_bytes_in_phy_channel()
701 val = readl(ch->reg_control); in get_bytes_in_phy_channel()
726 if (ch->ftdmac020) { in get_bytes_in_lli()
733 } else if (ch->pl080s) { in get_bytes_in_lli()
765 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_getbytes_chan()
774 ch = plchan->phychan; in pl08x_getbytes_chan()
775 txd = plchan->at; in pl08x_getbytes_chan()
784 clli = readl(ch->reg_lli) & ~PL080_LLI_LM_AHB2; in pl08x_getbytes_chan()
792 llis_va = txd->llis_va; in pl08x_getbytes_chan()
793 llis_bus = txd->llis_bus; in pl08x_getbytes_chan()
795 llis_max_words = pl08x->lli_words * MAX_NUM_TSFR_LLIS; in pl08x_getbytes_chan()
800 * Locate the next LLI - as this is an array, in pl08x_getbytes_chan()
803 llis_va += (clli - llis_bus) / sizeof(u32); in pl08x_getbytes_chan()
807 for (; llis_va < llis_va_limit; llis_va += pl08x->lli_words) { in pl08x_getbytes_chan()
835 for (i = 0; i < pl08x->vd->channels; i++) { in pl08x_get_phy_channel()
836 ch = &pl08x->phy_chans[i]; in pl08x_get_phy_channel()
838 spin_lock_irqsave(&ch->lock, flags); in pl08x_get_phy_channel()
840 if (!ch->locked && !ch->serving) { in pl08x_get_phy_channel()
841 ch->serving = virt_chan; in pl08x_get_phy_channel()
842 spin_unlock_irqrestore(&ch->lock, flags); in pl08x_get_phy_channel()
846 spin_unlock_irqrestore(&ch->lock, flags); in pl08x_get_phy_channel()
849 if (i == pl08x->vd->channels) { in pl08x_get_phy_channel()
861 ch->serving = NULL; in pl08x_put_phy_channel()
871 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_phy_alloc_and_start()
876 dev_dbg(&pl08x->adev->dev, "no physical channel available for xfer on %s\n", plchan->name); in pl08x_phy_alloc_and_start()
877 plchan->state = PL08X_CHAN_WAITING; in pl08x_phy_alloc_and_start()
881 dev_dbg(&pl08x->adev->dev, "allocated physical channel %d for xfer on %s\n", in pl08x_phy_alloc_and_start()
882 ch->id, plchan->name); in pl08x_phy_alloc_and_start()
884 plchan->phychan = ch; in pl08x_phy_alloc_and_start()
885 plchan->state = PL08X_CHAN_RUNNING; in pl08x_phy_alloc_and_start()
892 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_phy_reassign_start()
894 dev_dbg(&pl08x->adev->dev, "reassigned physical channel %d for xfer on %s\n", in pl08x_phy_reassign_start()
895 ch->id, plchan->name); in pl08x_phy_reassign_start()
900 * that this will only be called when it _already_ is non-NULL. in pl08x_phy_reassign_start()
902 ch->serving = plchan; in pl08x_phy_reassign_start()
903 plchan->phychan = ch; in pl08x_phy_reassign_start()
904 plchan->state = PL08X_CHAN_RUNNING; in pl08x_phy_reassign_start()
914 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_phy_free()
921 list_for_each_entry(p, &pl08x->memcpy.channels, vc.chan.device_node) in pl08x_phy_free()
922 if (p->state == PL08X_CHAN_WAITING) { in pl08x_phy_free()
927 if (!next && pl08x->has_slave) { in pl08x_phy_free()
928 list_for_each_entry(p, &pl08x->slave.channels, vc.chan.device_node) in pl08x_phy_free()
929 if (p->state == PL08X_CHAN_WAITING) { in pl08x_phy_free()
936 pl08x_terminate_phy_chan(pl08x, plchan->phychan); in pl08x_phy_free()
945 spin_lock(&next->vc.lock); in pl08x_phy_free()
946 /* Re-check the state now that we have the lock */ in pl08x_phy_free()
947 success = next->state == PL08X_CHAN_WAITING; in pl08x_phy_free()
949 pl08x_phy_reassign_start(plchan->phychan, next); in pl08x_phy_free()
950 spin_unlock(&next->vc.lock); in pl08x_phy_free()
957 pl08x_put_phy_channel(pl08x, plchan->phychan); in pl08x_phy_free()
960 plchan->phychan = NULL; in pl08x_phy_free()
961 plchan->state = PL08X_CHAN_IDLE; in pl08x_phy_free()
975 if (pl08x->vd->ftdmac020) { in pl08x_get_bytes_for_lli()
1017 if (pl08x->vd->ftdmac020) { in pl08x_lli_control_bits()
1122 * - prefers the destination bus if both available
1123 * - prefers bus with fixed address (i.e. peripheral)
1135 * The FTDMAC020 only supports memory-to-memory transfer, so in pl08x_choose_master_bus()
1138 if (pl08x->vd->ftdmac020) { in pl08x_choose_master_bus()
1151 *mbus = &bd->dstbus; in pl08x_choose_master_bus()
1152 *sbus = &bd->srcbus; in pl08x_choose_master_bus()
1154 *mbus = &bd->srcbus; in pl08x_choose_master_bus()
1155 *sbus = &bd->dstbus; in pl08x_choose_master_bus()
1157 if (bd->dstbus.buswidth >= bd->srcbus.buswidth) { in pl08x_choose_master_bus()
1158 *mbus = &bd->dstbus; in pl08x_choose_master_bus()
1159 *sbus = &bd->srcbus; in pl08x_choose_master_bus()
1161 *mbus = &bd->srcbus; in pl08x_choose_master_bus()
1162 *sbus = &bd->dstbus; in pl08x_choose_master_bus()
1174 u32 offset = num_llis * pl08x->lli_words; in pl08x_fill_lli_for_desc()
1175 u32 *llis_va = bd->txd->llis_va + offset; in pl08x_fill_lli_for_desc()
1176 dma_addr_t llis_bus = bd->txd->llis_bus; in pl08x_fill_lli_for_desc()
1181 offset += pl08x->lli_words; in pl08x_fill_lli_for_desc()
1183 llis_va[PL080_LLI_SRC] = bd->srcbus.addr; in pl08x_fill_lli_for_desc()
1184 llis_va[PL080_LLI_DST] = bd->dstbus.addr; in pl08x_fill_lli_for_desc()
1186 llis_va[PL080_LLI_LLI] |= bd->lli_bus; in pl08x_fill_lli_for_desc()
1188 if (pl08x->vd->pl080s) in pl08x_fill_lli_for_desc()
1191 if (pl08x->vd->ftdmac020) { in pl08x_fill_lli_for_desc()
1193 bd->srcbus.addr += len; in pl08x_fill_lli_for_desc()
1194 bd->dstbus.addr += len; in pl08x_fill_lli_for_desc()
1197 bd->srcbus.addr += len; in pl08x_fill_lli_for_desc()
1199 bd->dstbus.addr += len; in pl08x_fill_lli_for_desc()
1202 BUG_ON(bd->remainder < len); in pl08x_fill_lli_for_desc()
1204 bd->remainder -= len; in pl08x_fill_lli_for_desc()
1222 if (pl08x->vd->pl080s) { in pl08x_dump_lli()
1223 dev_vdbg(&pl08x->adev->dev, in pl08x_dump_lli()
1224 "%-3s %-9s %-10s %-10s %-10s %-10s %s\n", in pl08x_dump_lli()
1227 dev_vdbg(&pl08x->adev->dev, in pl08x_dump_lli()
1233 llis_va += pl08x->lli_words; in pl08x_dump_lli()
1236 dev_vdbg(&pl08x->adev->dev, in pl08x_dump_lli()
1237 "%-3s %-9s %-10s %-10s %-10s %s\n", in pl08x_dump_lli()
1240 dev_vdbg(&pl08x->adev->dev, in pl08x_dump_lli()
1245 llis_va += pl08x->lli_words; in pl08x_dump_lli()
1270 txd->llis_va = dma_pool_alloc(pl08x->pool, GFP_NOWAIT, &txd->llis_bus); in pl08x_fill_llis_for_desc()
1271 if (!txd->llis_va) { in pl08x_fill_llis_for_desc()
1272 dev_err(&pl08x->adev->dev, "%s no memory for llis\n", __func__); in pl08x_fill_llis_for_desc()
1277 bd.lli_bus = (pl08x->lli_buses & PL08X_AHB2) ? PL080_LLI_LM_AHB2 : 0; in pl08x_fill_llis_for_desc()
1278 cctl = txd->cctl; in pl08x_fill_llis_for_desc()
1286 list_for_each_entry(dsg, &txd->dsg_list, node) { in pl08x_fill_llis_for_desc()
1288 cctl = txd->cctl; in pl08x_fill_llis_for_desc()
1290 bd.srcbus.addr = dsg->src_addr; in pl08x_fill_llis_for_desc()
1291 bd.dstbus.addr = dsg->dst_addr; in pl08x_fill_llis_for_desc()
1292 bd.remainder = dsg->len; in pl08x_fill_llis_for_desc()
1298 dev_vdbg(&pl08x->adev->dev, in pl08x_fill_llis_for_desc()
1300 (u64)bd.srcbus.addr, in pl08x_fill_llis_for_desc()
1303 (u64)bd.dstbus.addr, in pl08x_fill_llis_for_desc()
1307 dev_vdbg(&pl08x->adev->dev, "mbus=%s sbus=%s\n", in pl08x_fill_llis_for_desc()
1314 * - flow controller is peripheral. in pl08x_fill_llis_for_desc()
1315 * - src.addr is aligned to src.width in pl08x_fill_llis_for_desc()
1316 * - dst.addr is aligned to dst.width in pl08x_fill_llis_for_desc()
1320 * - Memory addresses are contiguous and are not scattered. in pl08x_fill_llis_for_desc()
1326 * - Memory addresses are scattered and are not contiguous. in pl08x_fill_llis_for_desc()
1335 /* FTDMAC020 only does memory-to-memory */ in pl08x_fill_llis_for_desc()
1336 if (pl08x->vd->ftdmac020) in pl08x_fill_llis_for_desc()
1339 fc = (txd->ccfg & PL080_CONFIG_FLOW_CONTROL_MASK) >> in pl08x_fill_llis_for_desc()
1343 dev_err(&pl08x->adev->dev, "%s sg len can't be zero", in pl08x_fill_llis_for_desc()
1350 dev_err(&pl08x->adev->dev, in pl08x_fill_llis_for_desc()
1367 * - Less than a bus width available in pl08x_fill_llis_for_desc()
1368 * - until master bus is aligned in pl08x_fill_llis_for_desc()
1370 if (bd.remainder < mbus->buswidth) in pl08x_fill_llis_for_desc()
1373 early_bytes = mbus->buswidth - in pl08x_fill_llis_for_desc()
1374 (mbus->addr & (mbus->buswidth - 1)); in pl08x_fill_llis_for_desc()
1375 if ((bd.remainder - early_bytes) < mbus->buswidth) in pl08x_fill_llis_for_desc()
1380 dev_vdbg(&pl08x->adev->dev, in pl08x_fill_llis_for_desc()
1390 * - if slave is not then we must set its width down in pl08x_fill_llis_for_desc()
1393 dev_dbg(&pl08x->adev->dev, in pl08x_fill_llis_for_desc()
1397 sbus->buswidth = 1; in pl08x_fill_llis_for_desc()
1405 pl08x->vd->max_transfer_size; in pl08x_fill_llis_for_desc()
1406 dev_vdbg(&pl08x->adev->dev, in pl08x_fill_llis_for_desc()
1414 while (bd.remainder > (mbus->buswidth - 1)) { in pl08x_fill_llis_for_desc()
1427 * highest bus width - 1 in pl08x_fill_llis_for_desc()
1429 width = max(mbus->buswidth, sbus->buswidth); in pl08x_fill_llis_for_desc()
1433 dev_vdbg(&pl08x->adev->dev, in pl08x_fill_llis_for_desc()
1450 dev_vdbg(&pl08x->adev->dev, in pl08x_fill_llis_for_desc()
1458 if (total_bytes != dsg->len) { in pl08x_fill_llis_for_desc()
1459 dev_err(&pl08x->adev->dev, in pl08x_fill_llis_for_desc()
1461 __func__, total_bytes, dsg->len); in pl08x_fill_llis_for_desc()
1466 dev_err(&pl08x->adev->dev, in pl08x_fill_llis_for_desc()
1473 llis_va = txd->llis_va; in pl08x_fill_llis_for_desc()
1474 last_lli = llis_va + (num_llis - 1) * pl08x->lli_words; in pl08x_fill_llis_for_desc()
1476 if (txd->cyclic) { in pl08x_fill_llis_for_desc()
1478 last_lli[PL080_LLI_LLI] = txd->llis_bus | bd.lli_bus; in pl08x_fill_llis_for_desc()
1483 if (pl08x->vd->ftdmac020) in pl08x_fill_llis_for_desc()
1499 if (txd->llis_va) in pl08x_free_txd()
1500 dma_pool_free(pl08x->pool, txd->llis_va, txd->llis_bus); in pl08x_free_txd()
1502 list_for_each_entry_safe(dsg, _dsg, &txd->dsg_list, node) { in pl08x_free_txd()
1503 list_del(&dsg->node); in pl08x_free_txd()
1512 struct pl08x_txd *txd = to_pl08x_txd(&vd->tx); in pl08x_desc_free()
1513 struct pl08x_dma_chan *plchan = to_pl08x_chan(vd->tx.chan); in pl08x_desc_free()
1515 dma_descriptor_unmap(&vd->tx); in pl08x_desc_free()
1516 if (!txd->done) in pl08x_desc_free()
1519 pl08x_free_txd(plchan->host, txd); in pl08x_desc_free()
1527 vchan_get_all_descriptors(&plchan->vc, &head); in pl08x_free_txd_list()
1528 vchan_dma_desc_free_list(&plchan->vc, &head); in pl08x_free_txd_list()
1571 if (plchan->state == PL08X_CHAN_PAUSED) in pl08x_dma_tx_status()
1576 spin_lock_irqsave(&plchan->vc.lock, flags); in pl08x_dma_tx_status()
1579 vd = vchan_find_desc(&plchan->vc, cookie); in pl08x_dma_tx_status()
1582 struct pl08x_txd *txd = to_pl08x_txd(&vd->tx); in pl08x_dma_tx_status()
1585 list_for_each_entry(dsg, &txd->dsg_list, node) in pl08x_dma_tx_status()
1586 bytes += dsg->len; in pl08x_dma_tx_status()
1591 spin_unlock_irqrestore(&plchan->vc.lock, flags); in pl08x_dma_tx_status()
1599 if (plchan->state == PL08X_CHAN_PAUSED && ret == DMA_IN_PROGRESS) in pl08x_dma_tx_status()
1648 * Given the source and destination available bus masks, select which
1681 /* Access the cell in privileged mode, non-bufferable, non-cacheable */ in pl08x_cctl()
1727 if (plchan->cd->single) in pl08x_get_cctl()
1746 spin_lock_irqsave(&plchan->vc.lock, flags); in pl08x_issue_pending()
1747 if (vchan_issue_pending(&plchan->vc)) { in pl08x_issue_pending()
1748 if (!plchan->phychan && plchan->state != PL08X_CHAN_WAITING) in pl08x_issue_pending()
1751 spin_unlock_irqrestore(&plchan->vc.lock, flags); in pl08x_issue_pending()
1759 INIT_LIST_HEAD(&txd->dsg_list); in pl08x_get_txd()
1768 switch (pl08x->pd->memcpy_burst_size) { in pl08x_memcpy_cctl()
1770 dev_err(&pl08x->adev->dev, in pl08x_memcpy_cctl()
1807 switch (pl08x->pd->memcpy_bus_width) { in pl08x_memcpy_cctl()
1809 dev_err(&pl08x->adev->dev, in pl08x_memcpy_cctl()
1827 if (pl08x->pd->memcpy_prot_buff) in pl08x_memcpy_cctl()
1829 if (pl08x->pd->memcpy_prot_cache) in pl08x_memcpy_cctl()
1838 if (pl08x->vd->dualmaster) in pl08x_memcpy_cctl()
1840 pl08x->mem_buses, in pl08x_memcpy_cctl()
1841 pl08x->mem_buses); in pl08x_memcpy_cctl()
1851 switch (pl08x->pd->memcpy_bus_width) { in pl08x_ftdmac020_memcpy_cctl()
1853 dev_err(&pl08x->adev->dev, in pl08x_ftdmac020_memcpy_cctl()
1880 if (pl08x->vd->dualmaster) in pl08x_ftdmac020_memcpy_cctl()
1882 pl08x->mem_buses, in pl08x_ftdmac020_memcpy_cctl()
1883 pl08x->mem_buses); in pl08x_ftdmac020_memcpy_cctl()
1896 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_prep_dma_memcpy()
1903 dev_err(&pl08x->adev->dev, in pl08x_prep_dma_memcpy()
1913 list_add_tail(&dsg->node, &txd->dsg_list); in pl08x_prep_dma_memcpy()
1915 dsg->src_addr = src; in pl08x_prep_dma_memcpy()
1916 dsg->dst_addr = dest; in pl08x_prep_dma_memcpy()
1917 dsg->len = len; in pl08x_prep_dma_memcpy()
1918 if (pl08x->vd->ftdmac020) { in pl08x_prep_dma_memcpy()
1920 txd->ccfg = 0; in pl08x_prep_dma_memcpy()
1921 txd->cctl = pl08x_ftdmac020_memcpy_cctl(pl08x); in pl08x_prep_dma_memcpy()
1923 txd->ccfg = PL080_CONFIG_ERR_IRQ_MASK | in pl08x_prep_dma_memcpy()
1926 txd->cctl = pl08x_memcpy_cctl(pl08x); in pl08x_prep_dma_memcpy()
1929 ret = pl08x_fill_llis_for_desc(plchan->host, txd); in pl08x_prep_dma_memcpy()
1935 return vchan_tx_prep(&plchan->vc, &txd->vd, flags); in pl08x_prep_dma_memcpy()
1944 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_init_txd()
1953 dev_err(&pl08x->adev->dev, "%s no txd\n", __func__); in pl08x_init_txd()
1964 *slave_addr = plchan->cfg.dst_addr; in pl08x_init_txd()
1965 addr_width = plchan->cfg.dst_addr_width; in pl08x_init_txd()
1966 maxburst = plchan->cfg.dst_maxburst; in pl08x_init_txd()
1967 src_buses = pl08x->mem_buses; in pl08x_init_txd()
1968 dst_buses = plchan->cd->periph_buses; in pl08x_init_txd()
1971 *slave_addr = plchan->cfg.src_addr; in pl08x_init_txd()
1972 addr_width = plchan->cfg.src_addr_width; in pl08x_init_txd()
1973 maxburst = plchan->cfg.src_maxburst; in pl08x_init_txd()
1974 src_buses = plchan->cd->periph_buses; in pl08x_init_txd()
1975 dst_buses = pl08x->mem_buses; in pl08x_init_txd()
1978 dev_err(&pl08x->adev->dev, in pl08x_init_txd()
1986 dev_err(&pl08x->adev->dev, in pl08x_init_txd()
1991 txd->cctl = cctl | pl08x_select_bus(false, src_buses, dst_buses); in pl08x_init_txd()
1993 if (plchan->cfg.device_fc) in pl08x_init_txd()
2000 txd->ccfg = PL080_CONFIG_ERR_IRQ_MASK | in pl08x_init_txd()
2007 dev_dbg(&pl08x->adev->dev, in pl08x_init_txd()
2009 plchan->name); in pl08x_init_txd()
2013 dev_dbg(&pl08x->adev->dev, "allocated DMA request signal %d for xfer on %s\n", in pl08x_init_txd()
2014 plchan->signal, plchan->name); in pl08x_init_txd()
2018 txd->ccfg |= plchan->signal << PL080_CONFIG_DST_SEL_SHIFT; in pl08x_init_txd()
2020 txd->ccfg |= plchan->signal << PL080_CONFIG_SRC_SEL_SHIFT; in pl08x_init_txd()
2035 return -ENOMEM; in pl08x_tx_add_sg()
2037 list_add_tail(&dsg->node, &txd->dsg_list); in pl08x_tx_add_sg()
2039 dsg->len = len; in pl08x_tx_add_sg()
2041 dsg->src_addr = buf_addr; in pl08x_tx_add_sg()
2042 dsg->dst_addr = slave_addr; in pl08x_tx_add_sg()
2044 dsg->src_addr = slave_addr; in pl08x_tx_add_sg()
2045 dsg->dst_addr = buf_addr; in pl08x_tx_add_sg()
2057 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_prep_slave_sg()
2063 dev_dbg(&pl08x->adev->dev, "%s prepare transaction of %d bytes from %s\n", in pl08x_prep_slave_sg()
2064 __func__, sg_dma_len(sgl), plchan->name); in pl08x_prep_slave_sg()
2077 dev_err(&pl08x->adev->dev, "%s no mem for pl080 sg\n", in pl08x_prep_slave_sg()
2083 ret = pl08x_fill_llis_for_desc(plchan->host, txd); in pl08x_prep_slave_sg()
2090 return vchan_tx_prep(&plchan->vc, &txd->vd, flags); in pl08x_prep_slave_sg()
2099 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_prep_dma_cyclic()
2104 dev_dbg(&pl08x->adev->dev, in pl08x_prep_dma_cyclic()
2108 plchan->name); in pl08x_prep_dma_cyclic()
2114 txd->cyclic = true; in pl08x_prep_dma_cyclic()
2115 txd->cctl |= PL080_CONTROL_TC_IRQ_EN; in pl08x_prep_dma_cyclic()
2126 ret = pl08x_fill_llis_for_desc(plchan->host, txd); in pl08x_prep_dma_cyclic()
2133 return vchan_tx_prep(&plchan->vc, &txd->vd, flags); in pl08x_prep_dma_cyclic()
2140 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_config()
2142 if (!plchan->slave) in pl08x_config()
2143 return -EINVAL; in pl08x_config()
2146 if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES || in pl08x_config()
2147 config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES) in pl08x_config()
2148 return -EINVAL; in pl08x_config()
2150 if (config->device_fc && pl08x->vd->pl080s) { in pl08x_config()
2151 dev_err(&pl08x->adev->dev, in pl08x_config()
2154 return -EINVAL; in pl08x_config()
2157 plchan->cfg = *config; in pl08x_config()
2165 struct pl08x_driver_data *pl08x = plchan->host; in pl08x_terminate_all()
2168 spin_lock_irqsave(&plchan->vc.lock, flags); in pl08x_terminate_all()
2169 if (!plchan->phychan && !plchan->at) { in pl08x_terminate_all()
2170 spin_unlock_irqrestore(&plchan->vc.lock, flags); in pl08x_terminate_all()
2174 plchan->state = PL08X_CHAN_IDLE; in pl08x_terminate_all()
2176 if (plchan->phychan) { in pl08x_terminate_all()
2184 if (plchan->at) { in pl08x_terminate_all()
2185 vchan_terminate_vdesc(&plchan->at->vd); in pl08x_terminate_all()
2186 plchan->at = NULL; in pl08x_terminate_all()
2191 spin_unlock_irqrestore(&plchan->vc.lock, flags); in pl08x_terminate_all()
2200 vchan_synchronize(&plchan->vc); in pl08x_synchronize()
2212 spin_lock_irqsave(&plchan->vc.lock, flags); in pl08x_pause()
2213 if (!plchan->phychan && !plchan->at) { in pl08x_pause()
2214 spin_unlock_irqrestore(&plchan->vc.lock, flags); in pl08x_pause()
2218 pl08x_pause_phy_chan(plchan->phychan); in pl08x_pause()
2219 plchan->state = PL08X_CHAN_PAUSED; in pl08x_pause()
2221 spin_unlock_irqrestore(&plchan->vc.lock, flags); in pl08x_pause()
2235 spin_lock_irqsave(&plchan->vc.lock, flags); in pl08x_resume()
2236 if (!plchan->phychan && !plchan->at) { in pl08x_resume()
2237 spin_unlock_irqrestore(&plchan->vc.lock, flags); in pl08x_resume()
2241 pl08x_resume_phy_chan(plchan->phychan); in pl08x_resume()
2242 plchan->state = PL08X_CHAN_RUNNING; in pl08x_resume()
2244 spin_unlock_irqrestore(&plchan->vc.lock, flags); in pl08x_resume()
2255 if (chan->device->dev->driver != &pl08x_amba_driver.drv) in pl08x_filter_id()
2261 if (!strcmp(plchan->name, name)) in pl08x_filter_id()
2272 return plchan->cd == chan_id; in pl08x_filter_fn()
2284 if (pl08x->vd->nomadik) in pl08x_ensure_on()
2287 if (pl08x->vd->ftdmac020) { in pl08x_ensure_on()
2288 writel(PL080_CONFIG_ENABLE, pl08x->base + FTDMAC020_CSR); in pl08x_ensure_on()
2291 writel(PL080_CONFIG_ENABLE, pl08x->base + PL080_CONFIG); in pl08x_ensure_on()
2299 /* check & clear - ERR & TC interrupts */ in pl08x_irq()
2300 err = readl(pl08x->base + PL080_ERR_STATUS); in pl08x_irq()
2302 dev_err(&pl08x->adev->dev, "%s error interrupt, register value 0x%08x\n", in pl08x_irq()
2304 writel(err, pl08x->base + PL080_ERR_CLEAR); in pl08x_irq()
2306 tc = readl(pl08x->base + PL080_TC_STATUS); in pl08x_irq()
2308 writel(tc, pl08x->base + PL080_TC_CLEAR); in pl08x_irq()
2313 for (i = 0; i < pl08x->vd->channels; i++) { in pl08x_irq()
2316 struct pl08x_phy_chan *phychan = &pl08x->phy_chans[i]; in pl08x_irq()
2317 struct pl08x_dma_chan *plchan = phychan->serving; in pl08x_irq()
2321 dev_err(&pl08x->adev->dev, in pl08x_irq()
2327 spin_lock(&plchan->vc.lock); in pl08x_irq()
2328 tx = plchan->at; in pl08x_irq()
2329 if (tx && tx->cyclic) { in pl08x_irq()
2330 vchan_cyclic_callback(&tx->vd); in pl08x_irq()
2332 plchan->at = NULL; in pl08x_irq()
2338 tx->done = true; in pl08x_irq()
2339 vchan_cookie_complete(&tx->vd); in pl08x_irq()
2345 if (vchan_next_desc(&plchan->vc)) in pl08x_irq()
2350 spin_unlock(&plchan->vc.lock); in pl08x_irq()
2361 chan->slave = true; in pl08x_dma_slave_init()
2362 chan->name = chan->cd->bus_id; in pl08x_dma_slave_init()
2363 chan->cfg.src_addr = chan->cd->addr; in pl08x_dma_slave_init()
2364 chan->cfg.dst_addr = chan->cd->addr; in pl08x_dma_slave_init()
2377 INIT_LIST_HEAD(&dmadev->channels); in pl08x_dma_init_virtual_channels()
2387 return -ENOMEM; in pl08x_dma_init_virtual_channels()
2389 chan->host = pl08x; in pl08x_dma_init_virtual_channels()
2390 chan->state = PL08X_CHAN_IDLE; in pl08x_dma_init_virtual_channels()
2391 chan->signal = -1; in pl08x_dma_init_virtual_channels()
2394 chan->cd = &pl08x->pd->slave_channels[i]; in pl08x_dma_init_virtual_channels()
2400 chan->signal = i; in pl08x_dma_init_virtual_channels()
2403 chan->cd = kzalloc(sizeof(*chan->cd), GFP_KERNEL); in pl08x_dma_init_virtual_channels()
2404 if (!chan->cd) { in pl08x_dma_init_virtual_channels()
2406 return -ENOMEM; in pl08x_dma_init_virtual_channels()
2408 chan->cd->bus_id = "memcpy"; in pl08x_dma_init_virtual_channels()
2409 chan->cd->periph_buses = pl08x->pd->mem_buses; in pl08x_dma_init_virtual_channels()
2410 chan->name = kasprintf(GFP_KERNEL, "memcpy%d", i); in pl08x_dma_init_virtual_channels()
2411 if (!chan->name) { in pl08x_dma_init_virtual_channels()
2412 kfree(chan->cd); in pl08x_dma_init_virtual_channels()
2414 return -ENOMEM; in pl08x_dma_init_virtual_channels()
2417 dev_dbg(&pl08x->adev->dev, in pl08x_dma_init_virtual_channels()
2419 chan->name); in pl08x_dma_init_virtual_channels()
2421 chan->vc.desc_free = pl08x_desc_free; in pl08x_dma_init_virtual_channels()
2422 vchan_init(&chan->vc, dmadev); in pl08x_dma_init_virtual_channels()
2424 dev_info(&pl08x->adev->dev, "initialized %d virtual %s channels\n", in pl08x_dma_init_virtual_channels()
2435 next, &dmadev->channels, vc.chan.device_node) { in pl08x_free_virtual_channels()
2436 list_del(&chan->vc.chan.device_node); in pl08x_free_virtual_channels()
2461 struct pl08x_driver_data *pl08x = s->private; in pl08x_debugfs_show()
2469 seq_printf(s, "--------\t-----\n"); in pl08x_debugfs_show()
2470 for (i = 0; i < pl08x->vd->channels; i++) { in pl08x_debugfs_show()
2473 ch = &pl08x->phy_chans[i]; in pl08x_debugfs_show()
2475 spin_lock_irqsave(&ch->lock, flags); in pl08x_debugfs_show()
2476 virt_chan = ch->serving; in pl08x_debugfs_show()
2479 ch->id, in pl08x_debugfs_show()
2480 virt_chan ? virt_chan->name : "(none)", in pl08x_debugfs_show()
2481 ch->locked ? " LOCKED" : ""); in pl08x_debugfs_show()
2483 spin_unlock_irqrestore(&ch->lock, flags); in pl08x_debugfs_show()
2488 seq_printf(s, "--------\t------\n"); in pl08x_debugfs_show()
2489 list_for_each_entry(chan, &pl08x->memcpy.channels, vc.chan.device_node) { in pl08x_debugfs_show()
2490 seq_printf(s, "%s\t\t%s\n", chan->name, in pl08x_debugfs_show()
2491 pl08x_state_str(chan->state)); in pl08x_debugfs_show()
2494 if (pl08x->has_slave) { in pl08x_debugfs_show()
2497 seq_printf(s, "--------\t------\n"); in pl08x_debugfs_show()
2498 list_for_each_entry(chan, &pl08x->slave.channels, in pl08x_debugfs_show()
2500 seq_printf(s, "%s\t\t%s\n", chan->name, in pl08x_debugfs_show()
2501 pl08x_state_str(chan->state)); in pl08x_debugfs_show()
2510 return single_open(file, pl08x_debugfs_show, inode->i_private); in pl08x_debugfs_open()
2523 (void) debugfs_create_file(dev_name(&pl08x->adev->dev), in init_pl08x_debugfs()
2541 if (!pl08x->has_slave) in pl08x_find_chan_id()
2544 list_for_each_entry(chan, &pl08x->slave.channels, vc.chan.device_node) { in pl08x_find_chan_id()
2545 if (chan->signal == id) in pl08x_find_chan_id()
2546 return &chan->vc.chan; in pl08x_find_chan_id()
2555 struct pl08x_driver_data *pl08x = ofdma->of_dma_data; in pl08x_of_xlate()
2562 if (dma_spec->args_count != 2) { in pl08x_of_xlate()
2563 dev_err(&pl08x->adev->dev, in pl08x_of_xlate()
2568 dma_chan = pl08x_find_chan_id(pl08x, dma_spec->args[0]); in pl08x_of_xlate()
2570 dev_err(&pl08x->adev->dev, in pl08x_of_xlate()
2576 dev_dbg(&pl08x->adev->dev, in pl08x_of_xlate()
2578 dma_spec->args[0]); in pl08x_of_xlate()
2580 /* Augment channel data for applicable AHB buses */ in pl08x_of_xlate()
2581 plchan->cd->periph_buses = dma_spec->args[1]; in pl08x_of_xlate()
2595 pd = devm_kzalloc(&adev->dev, sizeof(*pd), GFP_KERNEL); in pl08x_of_probe()
2597 return -ENOMEM; in pl08x_of_probe()
2600 if (of_property_read_bool(np, "lli-bus-interface-ahb1")) in pl08x_of_probe()
2601 pd->lli_buses |= PL08X_AHB1; in pl08x_of_probe()
2602 if (of_property_read_bool(np, "lli-bus-interface-ahb2")) in pl08x_of_probe()
2603 pd->lli_buses |= PL08X_AHB2; in pl08x_of_probe()
2604 if (!pd->lli_buses) { in pl08x_of_probe()
2605 dev_info(&adev->dev, "no bus masters for LLIs stated, assume all\n"); in pl08x_of_probe()
2606 pd->lli_buses |= PL08X_AHB1 | PL08X_AHB2; in pl08x_of_probe()
2610 if (of_property_read_bool(np, "mem-bus-interface-ahb1")) in pl08x_of_probe()
2611 pd->mem_buses |= PL08X_AHB1; in pl08x_of_probe()
2612 if (of_property_read_bool(np, "mem-bus-interface-ahb2")) in pl08x_of_probe()
2613 pd->mem_buses |= PL08X_AHB2; in pl08x_of_probe()
2614 if (!pd->mem_buses) { in pl08x_of_probe()
2615 dev_info(&adev->dev, "no bus masters for memory stated, assume all\n"); in pl08x_of_probe()
2616 pd->mem_buses |= PL08X_AHB1 | PL08X_AHB2; in pl08x_of_probe()
2620 ret = of_property_read_u32(np, "memcpy-burst-size", &val); in pl08x_of_probe()
2622 dev_info(&adev->dev, "no memcpy burst size specified, using 1 byte\n"); in pl08x_of_probe()
2627 dev_err(&adev->dev, "illegal burst size for memcpy, set to 1\n"); in pl08x_of_probe()
2630 pd->memcpy_burst_size = PL08X_BURST_SZ_1; in pl08x_of_probe()
2633 pd->memcpy_burst_size = PL08X_BURST_SZ_4; in pl08x_of_probe()
2636 pd->memcpy_burst_size = PL08X_BURST_SZ_8; in pl08x_of_probe()
2639 pd->memcpy_burst_size = PL08X_BURST_SZ_16; in pl08x_of_probe()
2642 pd->memcpy_burst_size = PL08X_BURST_SZ_32; in pl08x_of_probe()
2645 pd->memcpy_burst_size = PL08X_BURST_SZ_64; in pl08x_of_probe()
2648 pd->memcpy_burst_size = PL08X_BURST_SZ_128; in pl08x_of_probe()
2651 pd->memcpy_burst_size = PL08X_BURST_SZ_256; in pl08x_of_probe()
2655 ret = of_property_read_u32(np, "memcpy-bus-width", &val); in pl08x_of_probe()
2657 dev_info(&adev->dev, "no memcpy bus width specified, using 8 bits\n"); in pl08x_of_probe()
2662 dev_err(&adev->dev, "illegal bus width for memcpy, set to 8 bits\n"); in pl08x_of_probe()
2665 pd->memcpy_bus_width = PL08X_BUS_WIDTH_8_BITS; in pl08x_of_probe()
2668 pd->memcpy_bus_width = PL08X_BUS_WIDTH_16_BITS; in pl08x_of_probe()
2671 pd->memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS; in pl08x_of_probe()
2678 * for a device and have it's AHB interfaces set up at in pl08x_of_probe()
2681 if (pl08x->vd->signals) { in pl08x_of_probe()
2682 chanp = devm_kcalloc(&adev->dev, in pl08x_of_probe()
2683 pl08x->vd->signals, in pl08x_of_probe()
2687 return -ENOMEM; in pl08x_of_probe()
2689 pd->slave_channels = chanp; in pl08x_of_probe()
2690 for (i = 0; i < pl08x->vd->signals; i++) { in pl08x_of_probe()
2692 * chanp->periph_buses will be assigned at translation in pl08x_of_probe()
2694 chanp->bus_id = kasprintf(GFP_KERNEL, "slave%d", i); in pl08x_of_probe()
2697 pd->num_slave_channels = pl08x->vd->signals; in pl08x_of_probe()
2700 pl08x->pd = pd; in pl08x_of_probe()
2702 return of_dma_controller_register(adev->dev.of_node, pl08x_of_xlate, in pl08x_of_probe()
2710 return -EINVAL; in pl08x_of_probe()
2717 struct vendor_data *vd = id->data; in pl08x_probe()
2718 struct device_node *np = adev->dev.of_node; in pl08x_probe()
2728 ret = dma_set_mask_and_coherent(&adev->dev, DMA_BIT_MASK(32)); in pl08x_probe()
2735 ret = -ENOMEM; in pl08x_probe()
2740 pl08x->adev = adev; in pl08x_probe()
2741 pl08x->vd = vd; in pl08x_probe()
2743 pl08x->base = ioremap(adev->res.start, resource_size(&adev->res)); in pl08x_probe()
2744 if (!pl08x->base) { in pl08x_probe()
2745 ret = -ENOMEM; in pl08x_probe()
2749 if (vd->ftdmac020) { in pl08x_probe()
2752 val = readl(pl08x->base + FTDMAC020_REVISION); in pl08x_probe()
2753 dev_info(&pl08x->adev->dev, "FTDMAC020 %d.%d rel %d\n", in pl08x_probe()
2755 val = readl(pl08x->base + FTDMAC020_FEATURE); in pl08x_probe()
2756 dev_info(&pl08x->adev->dev, "FTDMAC020 %d channels, " in pl08x_probe()
2757 "%s built-in bridge, %s, %s linked lists\n", in pl08x_probe()
2765 dev_warn(&pl08x->adev->dev, in pl08x_probe()
2767 vd->channels = (val >> 12) & 0x0f; in pl08x_probe()
2768 vd->dualmaster = !!(val & BIT(9)); in pl08x_probe()
2772 dma_cap_set(DMA_MEMCPY, pl08x->memcpy.cap_mask); in pl08x_probe()
2773 pl08x->memcpy.dev = &adev->dev; in pl08x_probe()
2774 pl08x->memcpy.device_free_chan_resources = pl08x_free_chan_resources; in pl08x_probe()
2775 pl08x->memcpy.device_prep_dma_memcpy = pl08x_prep_dma_memcpy; in pl08x_probe()
2776 pl08x->memcpy.device_prep_dma_interrupt = pl08x_prep_dma_interrupt; in pl08x_probe()
2777 pl08x->memcpy.device_tx_status = pl08x_dma_tx_status; in pl08x_probe()
2778 pl08x->memcpy.device_issue_pending = pl08x_issue_pending; in pl08x_probe()
2779 pl08x->memcpy.device_config = pl08x_config; in pl08x_probe()
2780 pl08x->memcpy.device_pause = pl08x_pause; in pl08x_probe()
2781 pl08x->memcpy.device_resume = pl08x_resume; in pl08x_probe()
2782 pl08x->memcpy.device_terminate_all = pl08x_terminate_all; in pl08x_probe()
2783 pl08x->memcpy.device_synchronize = pl08x_synchronize; in pl08x_probe()
2784 pl08x->memcpy.src_addr_widths = PL80X_DMA_BUSWIDTHS; in pl08x_probe()
2785 pl08x->memcpy.dst_addr_widths = PL80X_DMA_BUSWIDTHS; in pl08x_probe()
2786 pl08x->memcpy.directions = BIT(DMA_MEM_TO_MEM); in pl08x_probe()
2787 pl08x->memcpy.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; in pl08x_probe()
2788 if (vd->ftdmac020) in pl08x_probe()
2789 pl08x->memcpy.copy_align = DMAENGINE_ALIGN_4_BYTES; in pl08x_probe()
2796 if (vd->signals) { in pl08x_probe()
2797 pl08x->has_slave = true; in pl08x_probe()
2798 dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask); in pl08x_probe()
2799 dma_cap_set(DMA_CYCLIC, pl08x->slave.cap_mask); in pl08x_probe()
2800 pl08x->slave.dev = &adev->dev; in pl08x_probe()
2801 pl08x->slave.device_free_chan_resources = in pl08x_probe()
2803 pl08x->slave.device_prep_dma_interrupt = in pl08x_probe()
2805 pl08x->slave.device_tx_status = pl08x_dma_tx_status; in pl08x_probe()
2806 pl08x->slave.device_issue_pending = pl08x_issue_pending; in pl08x_probe()
2807 pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg; in pl08x_probe()
2808 pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic; in pl08x_probe()
2809 pl08x->slave.device_config = pl08x_config; in pl08x_probe()
2810 pl08x->slave.device_pause = pl08x_pause; in pl08x_probe()
2811 pl08x->slave.device_resume = pl08x_resume; in pl08x_probe()
2812 pl08x->slave.device_terminate_all = pl08x_terminate_all; in pl08x_probe()
2813 pl08x->slave.device_synchronize = pl08x_synchronize; in pl08x_probe()
2814 pl08x->slave.src_addr_widths = PL80X_DMA_BUSWIDTHS; in pl08x_probe()
2815 pl08x->slave.dst_addr_widths = PL80X_DMA_BUSWIDTHS; in pl08x_probe()
2816 pl08x->slave.directions = in pl08x_probe()
2818 pl08x->slave.residue_granularity = in pl08x_probe()
2823 pl08x->pd = dev_get_platdata(&adev->dev); in pl08x_probe()
2824 if (!pl08x->pd) { in pl08x_probe()
2830 dev_err(&adev->dev, "no platform data supplied\n"); in pl08x_probe()
2831 ret = -EINVAL; in pl08x_probe()
2835 pl08x->slave.filter.map = pl08x->pd->slave_map; in pl08x_probe()
2836 pl08x->slave.filter.mapcnt = pl08x->pd->slave_map_len; in pl08x_probe()
2837 pl08x->slave.filter.fn = pl08x_filter_fn; in pl08x_probe()
2841 pl08x->lli_buses = PL08X_AHB1; in pl08x_probe()
2842 pl08x->mem_buses = PL08X_AHB1; in pl08x_probe()
2843 if (pl08x->vd->dualmaster) { in pl08x_probe()
2844 pl08x->lli_buses = pl08x->pd->lli_buses; in pl08x_probe()
2845 pl08x->mem_buses = pl08x->pd->mem_buses; in pl08x_probe()
2848 if (vd->pl080s) in pl08x_probe()
2849 pl08x->lli_words = PL080S_LLI_WORDS; in pl08x_probe()
2851 pl08x->lli_words = PL080_LLI_WORDS; in pl08x_probe()
2852 tsfr_size = MAX_NUM_TSFR_LLIS * pl08x->lli_words * sizeof(u32); in pl08x_probe()
2854 /* A DMA memory pool for LLIs, align on 1-byte boundary */ in pl08x_probe()
2855 pl08x->pool = dma_pool_create(DRIVER_NAME, &pl08x->adev->dev, in pl08x_probe()
2857 if (!pl08x->pool) { in pl08x_probe()
2858 ret = -ENOMEM; in pl08x_probe()
2866 if (vd->ftdmac020) in pl08x_probe()
2867 /* This variant has error IRQs in bits 16-19 */ in pl08x_probe()
2868 writel(0x0000FFFF, pl08x->base + PL080_ERR_CLEAR); in pl08x_probe()
2870 writel(0x000000FF, pl08x->base + PL080_ERR_CLEAR); in pl08x_probe()
2871 writel(0x000000FF, pl08x->base + PL080_TC_CLEAR); in pl08x_probe()
2874 ret = request_irq(adev->irq[0], pl08x_irq, 0, DRIVER_NAME, pl08x); in pl08x_probe()
2876 dev_err(&adev->dev, "%s failed to request interrupt %d\n", in pl08x_probe()
2877 __func__, adev->irq[0]); in pl08x_probe()
2882 pl08x->phy_chans = kzalloc((vd->channels * sizeof(*pl08x->phy_chans)), in pl08x_probe()
2884 if (!pl08x->phy_chans) { in pl08x_probe()
2885 ret = -ENOMEM; in pl08x_probe()
2889 for (i = 0; i < vd->channels; i++) { in pl08x_probe()
2890 struct pl08x_phy_chan *ch = &pl08x->phy_chans[i]; in pl08x_probe()
2892 ch->id = i; in pl08x_probe()
2893 ch->base = pl08x->base + PL080_Cx_BASE(i); in pl08x_probe()
2894 if (vd->ftdmac020) { in pl08x_probe()
2896 ch->reg_busy = ch->base + FTDMAC020_CH_BUSY; in pl08x_probe()
2897 ch->reg_config = ch->base + FTDMAC020_CH_CFG; in pl08x_probe()
2898 ch->reg_control = ch->base + FTDMAC020_CH_CSR; in pl08x_probe()
2899 ch->reg_src = ch->base + FTDMAC020_CH_SRC_ADDR; in pl08x_probe()
2900 ch->reg_dst = ch->base + FTDMAC020_CH_DST_ADDR; in pl08x_probe()
2901 ch->reg_lli = ch->base + FTDMAC020_CH_LLP; in pl08x_probe()
2902 ch->ftdmac020 = true; in pl08x_probe()
2904 ch->reg_config = ch->base + vd->config_offset; in pl08x_probe()
2905 ch->reg_control = ch->base + PL080_CH_CONTROL; in pl08x_probe()
2906 ch->reg_src = ch->base + PL080_CH_SRC_ADDR; in pl08x_probe()
2907 ch->reg_dst = ch->base + PL080_CH_DST_ADDR; in pl08x_probe()
2908 ch->reg_lli = ch->base + PL080_CH_LLI; in pl08x_probe()
2910 if (vd->pl080s) in pl08x_probe()
2911 ch->pl080s = true; in pl08x_probe()
2913 spin_lock_init(&ch->lock); in pl08x_probe()
2920 if (vd->nomadik) { in pl08x_probe()
2923 val = readl(ch->reg_config); in pl08x_probe()
2925 dev_info(&adev->dev, "physical channel %d reserved for secure access only\n", i); in pl08x_probe()
2926 ch->locked = true; in pl08x_probe()
2930 dev_dbg(&adev->dev, "physical channel %d is %s\n", in pl08x_probe()
2935 ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->memcpy, in pl08x_probe()
2936 pl08x->vd->channels, false); in pl08x_probe()
2938 dev_warn(&pl08x->adev->dev, in pl08x_probe()
2939 "%s failed to enumerate memcpy channels - %d\n", in pl08x_probe()
2945 if (pl08x->has_slave) { in pl08x_probe()
2946 ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->slave, in pl08x_probe()
2947 pl08x->pd->num_slave_channels, true); in pl08x_probe()
2949 dev_warn(&pl08x->adev->dev, in pl08x_probe()
2950 "%s failed to enumerate slave channels - %d\n", in pl08x_probe()
2956 ret = dma_async_device_register(&pl08x->memcpy); in pl08x_probe()
2958 dev_warn(&pl08x->adev->dev, in pl08x_probe()
2959 "%s failed to register memcpy as an async device - %d\n", in pl08x_probe()
2964 if (pl08x->has_slave) { in pl08x_probe()
2965 ret = dma_async_device_register(&pl08x->slave); in pl08x_probe()
2967 dev_warn(&pl08x->adev->dev, in pl08x_probe()
2968 "%s failed to register slave as an async device - %d\n", in pl08x_probe()
2976 dev_info(&pl08x->adev->dev, "DMA: PL%03x%s rev%u at 0x%08llx irq %d\n", in pl08x_probe()
2977 amba_part(adev), pl08x->vd->pl080s ? "s" : "", amba_rev(adev), in pl08x_probe()
2978 (unsigned long long)adev->res.start, adev->irq[0]); in pl08x_probe()
2983 dma_async_device_unregister(&pl08x->memcpy); in pl08x_probe()
2985 if (pl08x->has_slave) in pl08x_probe()
2986 pl08x_free_virtual_channels(&pl08x->slave); in pl08x_probe()
2988 pl08x_free_virtual_channels(&pl08x->memcpy); in pl08x_probe()
2990 kfree(pl08x->phy_chans); in pl08x_probe()
2992 free_irq(adev->irq[0], pl08x); in pl08x_probe()
2994 dma_pool_destroy(pl08x->pool); in pl08x_probe()
2997 iounmap(pl08x->base); in pl08x_probe()