Lines Matching refs:pl330
1381 struct pl330_dmac *pl330 = thrd->dmac; in pl330_submit_req() local
1388 if (pl330->state == DYING in pl330_submit_req()
1389 || pl330->dmac_tbd.reset_chan & (1 << thrd->id)) { in pl330_submit_req()
1397 desc->peri >= pl330->pcfg.num_peri) { in pl330_submit_req()
1404 spin_lock_irqsave(&pl330->lock, flags); in pl330_submit_req()
1429 if (ret > pl330->mcbufsz / 2) { in pl330_submit_req()
1430 dev_info(pl330->ddma.dev, "%s:%d Try increasing mcbufsz (%i/%i)\n", in pl330_submit_req()
1431 __func__, __LINE__, ret, pl330->mcbufsz / 2); in pl330_submit_req()
1444 spin_unlock_irqrestore(&pl330->lock, flags); in pl330_submit_req()
1474 struct pl330_dmac *pl330 = (struct pl330_dmac *) data; in pl330_dotask() local
1478 spin_lock_irqsave(&pl330->lock, flags); in pl330_dotask()
1481 if (pl330->dmac_tbd.reset_dmac) { in pl330_dotask()
1482 pl330->state = DYING; in pl330_dotask()
1484 pl330->dmac_tbd.reset_mngr = true; in pl330_dotask()
1486 pl330->dmac_tbd.reset_dmac = false; in pl330_dotask()
1489 if (pl330->dmac_tbd.reset_mngr) { in pl330_dotask()
1490 _stop(pl330->manager); in pl330_dotask()
1492 pl330->dmac_tbd.reset_chan = (1 << pl330->pcfg.num_chan) - 1; in pl330_dotask()
1494 pl330->dmac_tbd.reset_mngr = false; in pl330_dotask()
1497 for (i = 0; i < pl330->pcfg.num_chan; i++) { in pl330_dotask()
1499 if (pl330->dmac_tbd.reset_chan & (1 << i)) { in pl330_dotask()
1500 struct pl330_thread *thrd = &pl330->channels[i]; in pl330_dotask()
1501 void __iomem *regs = pl330->base; in pl330_dotask()
1511 spin_unlock_irqrestore(&pl330->lock, flags); in pl330_dotask()
1514 spin_lock_irqsave(&pl330->lock, flags); in pl330_dotask()
1521 pl330->dmac_tbd.reset_chan &= ~(1 << i); in pl330_dotask()
1525 spin_unlock_irqrestore(&pl330->lock, flags); in pl330_dotask()
1531 static int pl330_update(struct pl330_dmac *pl330) in pl330_update() argument
1539 regs = pl330->base; in pl330_update()
1541 spin_lock_irqsave(&pl330->lock, flags); in pl330_update()
1545 pl330->dmac_tbd.reset_mngr = true; in pl330_update()
1547 pl330->dmac_tbd.reset_mngr = false; in pl330_update()
1549 val = readl(regs + FSC) & ((1 << pl330->pcfg.num_chan) - 1); in pl330_update()
1550 pl330->dmac_tbd.reset_chan |= val; in pl330_update()
1553 while (i < pl330->pcfg.num_chan) { in pl330_update()
1555 dev_info(pl330->ddma.dev, in pl330_update()
1559 _stop(&pl330->channels[i]); in pl330_update()
1567 if (pl330->pcfg.num_events < 32 in pl330_update()
1568 && val & ~((1 << pl330->pcfg.num_events) - 1)) { in pl330_update()
1569 pl330->dmac_tbd.reset_dmac = true; in pl330_update()
1570 dev_err(pl330->ddma.dev, "%s:%d Unexpected!\n", __func__, in pl330_update()
1576 for (ev = 0; ev < pl330->pcfg.num_events; ev++) { in pl330_update()
1588 id = pl330->events[ev]; in pl330_update()
1590 thrd = &pl330->channels[id]; in pl330_update()
1606 list_add_tail(&descdone->rqd, &pl330->req_done); in pl330_update()
1611 list_for_each_entry_safe(descdone, tmp, &pl330->req_done, rqd) { in pl330_update()
1613 spin_unlock_irqrestore(&pl330->lock, flags); in pl330_update()
1615 spin_lock_irqsave(&pl330->lock, flags); in pl330_update()
1619 spin_unlock_irqrestore(&pl330->lock, flags); in pl330_update()
1621 if (pl330->dmac_tbd.reset_dmac in pl330_update()
1622 || pl330->dmac_tbd.reset_mngr in pl330_update()
1623 || pl330->dmac_tbd.reset_chan) { in pl330_update()
1625 tasklet_schedule(&pl330->tasks); in pl330_update()
1634 struct pl330_dmac *pl330 = thrd->dmac; in _alloc_event() local
1637 for (ev = 0; ev < pl330->pcfg.num_events; ev++) in _alloc_event()
1638 if (pl330->events[ev] == -1) { in _alloc_event()
1639 pl330->events[ev] = thrd->id; in _alloc_event()
1646 static bool _chan_ns(const struct pl330_dmac *pl330, int i) in _chan_ns() argument
1648 return pl330->pcfg.irq_ns & (1 << i); in _chan_ns()
1654 static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330) in pl330_request_channel() argument
1660 if (pl330->state == DYING) in pl330_request_channel()
1663 chans = pl330->pcfg.num_chan; in pl330_request_channel()
1665 spin_lock_irqsave(&pl330->lock, flags); in pl330_request_channel()
1668 thrd = &pl330->channels[i]; in pl330_request_channel()
1670 _chan_ns(pl330, i))) { in pl330_request_channel()
1684 spin_unlock_irqrestore(&pl330->lock, flags); in pl330_request_channel()
1692 struct pl330_dmac *pl330 = thrd->dmac; in _free_event() local
1695 if (ev >= 0 && ev < pl330->pcfg.num_events in _free_event()
1696 && pl330->events[ev] == thrd->id) in _free_event()
1697 pl330->events[ev] = -1; in _free_event()
1702 struct pl330_dmac *pl330; in pl330_release_channel() local
1713 pl330 = thrd->dmac; in pl330_release_channel()
1715 spin_lock_irqsave(&pl330->lock, flags); in pl330_release_channel()
1718 spin_unlock_irqrestore(&pl330->lock, flags); in pl330_release_channel()
1724 static void read_dmac_config(struct pl330_dmac *pl330) in read_dmac_config() argument
1726 void __iomem *regs = pl330->base; in read_dmac_config()
1731 pl330->pcfg.data_bus_width = 8 * (1 << val); in read_dmac_config()
1735 pl330->pcfg.data_buf_dep = val + 1; in read_dmac_config()
1740 pl330->pcfg.num_chan = val; in read_dmac_config()
1746 pl330->pcfg.num_peri = val; in read_dmac_config()
1747 pl330->pcfg.peri_ns = readl(regs + CR4); in read_dmac_config()
1749 pl330->pcfg.num_peri = 0; in read_dmac_config()
1754 pl330->pcfg.mode |= DMAC_MODE_NS; in read_dmac_config()
1756 pl330->pcfg.mode &= ~DMAC_MODE_NS; in read_dmac_config()
1761 pl330->pcfg.num_events = val; in read_dmac_config()
1763 pl330->pcfg.irq_ns = readl(regs + CR3); in read_dmac_config()
1768 struct pl330_dmac *pl330 = thrd->dmac; in _reset_thread() local
1770 thrd->req[0].mc_cpu = pl330->mcode_cpu in _reset_thread()
1771 + (thrd->id * pl330->mcbufsz); in _reset_thread()
1772 thrd->req[0].mc_bus = pl330->mcode_bus in _reset_thread()
1773 + (thrd->id * pl330->mcbufsz); in _reset_thread()
1777 + pl330->mcbufsz / 2; in _reset_thread()
1779 + pl330->mcbufsz / 2; in _reset_thread()
1785 static int dmac_alloc_threads(struct pl330_dmac *pl330) in dmac_alloc_threads() argument
1787 int chans = pl330->pcfg.num_chan; in dmac_alloc_threads()
1792 pl330->channels = kzalloc((1 + chans) * sizeof(*thrd), in dmac_alloc_threads()
1794 if (!pl330->channels) in dmac_alloc_threads()
1799 thrd = &pl330->channels[i]; in dmac_alloc_threads()
1801 thrd->dmac = pl330; in dmac_alloc_threads()
1807 thrd = &pl330->channels[chans]; in dmac_alloc_threads()
1809 thrd->dmac = pl330; in dmac_alloc_threads()
1811 pl330->manager = thrd; in dmac_alloc_threads()
1816 static int dmac_alloc_resources(struct pl330_dmac *pl330) in dmac_alloc_resources() argument
1818 int chans = pl330->pcfg.num_chan; in dmac_alloc_resources()
1825 pl330->mcode_cpu = dma_alloc_coherent(pl330->ddma.dev, in dmac_alloc_resources()
1826 chans * pl330->mcbufsz, in dmac_alloc_resources()
1827 &pl330->mcode_bus, GFP_KERNEL); in dmac_alloc_resources()
1828 if (!pl330->mcode_cpu) { in dmac_alloc_resources()
1829 dev_err(pl330->ddma.dev, "%s:%d Can't allocate memory!\n", in dmac_alloc_resources()
1834 ret = dmac_alloc_threads(pl330); in dmac_alloc_resources()
1836 dev_err(pl330->ddma.dev, "%s:%d Can't to create channels for DMAC!\n", in dmac_alloc_resources()
1838 dma_free_coherent(pl330->ddma.dev, in dmac_alloc_resources()
1839 chans * pl330->mcbufsz, in dmac_alloc_resources()
1840 pl330->mcode_cpu, pl330->mcode_bus); in dmac_alloc_resources()
1847 static int pl330_add(struct pl330_dmac *pl330) in pl330_add() argument
1852 regs = pl330->base; in pl330_add()
1855 if ((pl330->pcfg.periph_id & 0xfffff) != PERIPH_ID_VAL) { in pl330_add()
1856 dev_err(pl330->ddma.dev, "PERIPH_ID 0x%x !\n", in pl330_add()
1857 pl330->pcfg.periph_id); in pl330_add()
1862 read_dmac_config(pl330); in pl330_add()
1864 if (pl330->pcfg.num_events == 0) { in pl330_add()
1865 dev_err(pl330->ddma.dev, "%s:%d Can't work without events!\n", in pl330_add()
1870 spin_lock_init(&pl330->lock); in pl330_add()
1872 INIT_LIST_HEAD(&pl330->req_done); in pl330_add()
1875 if (!pl330->mcbufsz) in pl330_add()
1876 pl330->mcbufsz = MCODE_BUFF_PER_REQ * 2; in pl330_add()
1879 for (i = 0; i < pl330->pcfg.num_events; i++) in pl330_add()
1880 pl330->events[i] = -1; in pl330_add()
1883 ret = dmac_alloc_resources(pl330); in pl330_add()
1885 dev_err(pl330->ddma.dev, "Unable to create channels for DMAC\n"); in pl330_add()
1889 tasklet_init(&pl330->tasks, pl330_dotask, (unsigned long) pl330); in pl330_add()
1891 pl330->state = INIT; in pl330_add()
1896 static int dmac_free_threads(struct pl330_dmac *pl330) in dmac_free_threads() argument
1902 for (i = 0; i < pl330->pcfg.num_chan; i++) { in dmac_free_threads()
1903 thrd = &pl330->channels[i]; in dmac_free_threads()
1908 kfree(pl330->channels); in dmac_free_threads()
1913 static void pl330_del(struct pl330_dmac *pl330) in pl330_del() argument
1915 pl330->state = UNINIT; in pl330_del()
1917 tasklet_kill(&pl330->tasks); in pl330_del()
1920 dmac_free_threads(pl330); in pl330_del()
1922 dma_free_coherent(pl330->ddma.dev, in pl330_del()
1923 pl330->pcfg.num_chan * pl330->mcbufsz, pl330->mcode_cpu, in pl330_del()
1924 pl330->mcode_bus); in pl330_del()
2061 struct pl330_dmac *pl330 = ofdma->of_dma_data; in of_dma_pl330_xlate() local
2064 if (!pl330) in of_dma_pl330_xlate()
2071 if (chan_id >= pl330->num_peripherals) in of_dma_pl330_xlate()
2074 return dma_get_slave_channel(&pl330->peripherals[chan_id].chan); in of_dma_pl330_xlate()
2080 struct pl330_dmac *pl330 = pch->dmac; in pl330_alloc_chan_resources() local
2088 pch->thread = pl330_request_channel(pl330); in pl330_alloc_chan_resources()
2130 struct pl330_dmac *pl330 = pch->dmac; in pl330_terminate_all() local
2133 pm_runtime_get_sync(pl330->ddma.dev); in pl330_terminate_all()
2135 spin_lock(&pl330->lock); in pl330_terminate_all()
2137 spin_unlock(&pl330->lock); in pl330_terminate_all()
2154 list_splice_tail_init(&pch->submitted_list, &pl330->desc_pool); in pl330_terminate_all()
2155 list_splice_tail_init(&pch->work_list, &pl330->desc_pool); in pl330_terminate_all()
2156 list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); in pl330_terminate_all()
2158 pm_runtime_mark_last_busy(pl330->ddma.dev); in pl330_terminate_all()
2159 pm_runtime_put_autosuspend(pl330->ddma.dev); in pl330_terminate_all()
2174 struct pl330_dmac *pl330 = pch->dmac; in pl330_pause() local
2177 pm_runtime_get_sync(pl330->ddma.dev); in pl330_pause()
2180 spin_lock(&pl330->lock); in pl330_pause()
2182 spin_unlock(&pl330->lock); in pl330_pause()
2185 pm_runtime_mark_last_busy(pl330->ddma.dev); in pl330_pause()
2186 pm_runtime_put_autosuspend(pl330->ddma.dev); in pl330_pause()
2216 struct pl330_dmac *pl330 = pch->dmac; in pl330_get_current_xferred_count() local
2220 pm_runtime_get_sync(pl330->ddma.dev); in pl330_get_current_xferred_count()
2230 pm_runtime_put_autosuspend(pl330->ddma.dev); in pl330_get_current_xferred_count()
2360 static int add_desc(struct pl330_dmac *pl330, gfp_t flg, int count) in add_desc() argument
2370 spin_lock_irqsave(&pl330->pool_lock, flags); in add_desc()
2374 list_add_tail(&desc[i].node, &pl330->desc_pool); in add_desc()
2377 spin_unlock_irqrestore(&pl330->pool_lock, flags); in add_desc()
2382 static struct dma_pl330_desc *pluck_desc(struct pl330_dmac *pl330) in pluck_desc() argument
2387 spin_lock_irqsave(&pl330->pool_lock, flags); in pluck_desc()
2389 if (!list_empty(&pl330->desc_pool)) { in pluck_desc()
2390 desc = list_entry(pl330->desc_pool.next, in pluck_desc()
2399 spin_unlock_irqrestore(&pl330->pool_lock, flags); in pluck_desc()
2406 struct pl330_dmac *pl330 = pch->dmac; in pl330_get_desc() local
2411 desc = pluck_desc(pl330); in pl330_get_desc()
2415 if (!add_desc(pl330, GFP_ATOMIC, 1)) in pl330_get_desc()
2419 desc = pluck_desc(pl330); in pl330_get_desc()
2479 struct pl330_dmac *pl330 = pch->dmac; in get_burst_len() local
2482 burst_len = pl330->pcfg.data_bus_width / 8; in get_burst_len()
2483 burst_len *= pl330->pcfg.data_buf_dep / pl330->pcfg.num_chan; in get_burst_len()
2506 struct pl330_dmac *pl330 = pch->dmac; in pl330_prep_dma_cyclic() local
2529 spin_lock_irqsave(&pl330->pool_lock, flags); in pl330_prep_dma_cyclic()
2534 list_move_tail(&desc->node, &pl330->desc_pool); in pl330_prep_dma_cyclic()
2537 list_move_tail(&first->node, &pl330->desc_pool); in pl330_prep_dma_cyclic()
2539 spin_unlock_irqrestore(&pl330->pool_lock, flags); in pl330_prep_dma_cyclic()
2590 struct pl330_dmac *pl330; in pl330_prep_dma_memcpy() local
2596 pl330 = pch->dmac; in pl330_prep_dma_memcpy()
2607 burst = pl330->pcfg.data_bus_width / 8; in pl330_prep_dma_memcpy()
2625 if (desc->rqcfg.brst_size * 8 < pl330->pcfg.data_bus_width) in pl330_prep_dma_memcpy()
2636 static void __pl330_giveback_desc(struct pl330_dmac *pl330, in __pl330_giveback_desc() argument
2645 spin_lock_irqsave(&pl330->pool_lock, flags); in __pl330_giveback_desc()
2650 list_move_tail(&desc->node, &pl330->desc_pool); in __pl330_giveback_desc()
2653 list_move_tail(&first->node, &pl330->desc_pool); in __pl330_giveback_desc()
2655 spin_unlock_irqrestore(&pl330->pool_lock, flags); in __pl330_giveback_desc()
2680 struct pl330_dmac *pl330 = pch->dmac; in pl330_prep_slave_sg() local
2685 __pl330_giveback_desc(pl330, first); in pl330_prep_slave_sg()
2778 struct pl330_dmac *pl330; in pl330_probe() local
2792 pl330 = devm_kzalloc(&adev->dev, sizeof(*pl330), GFP_KERNEL); in pl330_probe()
2793 if (!pl330) { in pl330_probe()
2798 pd = &pl330->ddma; in pl330_probe()
2801 pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0; in pl330_probe()
2804 pl330->base = devm_ioremap_resource(&adev->dev, res); in pl330_probe()
2805 if (IS_ERR(pl330->base)) in pl330_probe()
2806 return PTR_ERR(pl330->base); in pl330_probe()
2808 amba_set_drvdata(adev, pl330); in pl330_probe()
2815 dev_name(&adev->dev), pl330); in pl330_probe()
2823 pcfg = &pl330->pcfg; in pl330_probe()
2826 ret = pl330_add(pl330); in pl330_probe()
2830 INIT_LIST_HEAD(&pl330->desc_pool); in pl330_probe()
2831 spin_lock_init(&pl330->pool_lock); in pl330_probe()
2834 if (!add_desc(pl330, GFP_KERNEL, NR_DEFAULT_DESC)) in pl330_probe()
2845 pl330->num_peripherals = num_chan; in pl330_probe()
2847 pl330->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); in pl330_probe()
2848 if (!pl330->peripherals) { in pl330_probe()
2855 pch = &pl330->peripherals[i]; in pl330_probe()
2867 pch->dmac = pl330; in pl330_probe()
2907 of_dma_pl330_xlate, pl330); in pl330_probe()
2914 adev->dev.dma_parms = &pl330->dma_parms; in pl330_probe()
2941 list_for_each_entry_safe(pch, _p, &pl330->ddma.channels, in pl330_probe()
2954 pl330_del(pl330); in pl330_probe()
2961 struct pl330_dmac *pl330 = amba_get_drvdata(adev); in pl330_remove() local
2964 pm_runtime_get_noresume(pl330->ddma.dev); in pl330_remove()
2969 dma_async_device_unregister(&pl330->ddma); in pl330_remove()
2972 list_for_each_entry_safe(pch, _p, &pl330->ddma.channels, in pl330_remove()
2985 pl330_del(pl330); in pl330_remove()