Lines Matching refs:pl330

514 		.quirk = "arm,pl330-broken-no-flushp",
518 .quirk = "arm,pl330-periph-burst",
1185 static inline int _ldst_peripheral(struct pl330_dmac *pl330,
1196 if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
1209 static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
1215 if (pl330->quirks & PL330_QUIRK_PERIPH_BURST)
1221 off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs, cyc,
1243 static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[],
1271 off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs, 1,
1290 static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
1298 return _bursts(pl330, dry_run, buf, pxs, 1);
1316 szbrst = _bursts(pl330, 1, buf, pxs, 1);
1348 off += _bursts(pl330, dry_run, &buf[off], pxs, cyc);
1371 static inline int _setup_loops(struct pl330_dmac *pl330,
1384 off += _loop(pl330, dry_run, &buf[off], &c, pxs);
1387 off += _dregs(pl330, dry_run, &buf[off], pxs, num_dregs);
1392 static inline int _setup_xfer(struct pl330_dmac *pl330,
1405 off += _setup_loops(pl330, dry_run, &buf[off], pxs);
1414 static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run,
1427 off += _setup_xfer(pl330, dry_run, &buf[off], pxs);
1477 struct pl330_dmac *pl330 = thrd->dmac;
1498 if (pl330->state == DYING
1499 || pl330->dmac_tbd.reset_chan & (1 << thrd->id)) {
1507 desc->peri >= pl330->pcfg.num_peri) {
1514 spin_lock_irqsave(&pl330->lock, flags);
1535 ret = _setup_req(pl330, 1, thrd, idx, &xs);
1539 if (ret > pl330->mcbufsz / 2) {
1540 dev_info(pl330->ddma.dev, "%s:%d Try increasing mcbufsz (%i/%i)\n",
1541 __func__, __LINE__, ret, pl330->mcbufsz / 2);
1549 _setup_req(pl330, 0, thrd, idx, &xs);
1554 spin_unlock_irqrestore(&pl330->lock, flags);
1584 struct pl330_dmac *pl330 = from_tasklet(pl330, t, tasks);
1588 spin_lock_irqsave(&pl330->lock, flags);
1591 if (pl330->dmac_tbd.reset_dmac) {
1592 pl330->state = DYING;
1594 pl330->dmac_tbd.reset_mngr = true;
1596 pl330->dmac_tbd.reset_dmac = false;
1599 if (pl330->dmac_tbd.reset_mngr) {
1600 _stop(pl330->manager);
1602 pl330->dmac_tbd.reset_chan = (1 << pl330->pcfg.num_chan) - 1;
1604 pl330->dmac_tbd.reset_mngr = false;
1607 for (i = 0; i < pl330->pcfg.num_chan; i++) {
1609 if (pl330->dmac_tbd.reset_chan & (1 << i)) {
1610 struct pl330_thread *thrd = &pl330->channels[i];
1611 void __iomem *regs = pl330->base;
1621 spin_unlock_irqrestore(&pl330->lock, flags);
1624 spin_lock_irqsave(&pl330->lock, flags);
1631 pl330->dmac_tbd.reset_chan &= ~(1 << i);
1635 spin_unlock_irqrestore(&pl330->lock, flags);
1641 static int pl330_update(struct pl330_dmac *pl330)
1649 regs = pl330->base;
1651 spin_lock_irqsave(&pl330->lock, flags);
1655 pl330->dmac_tbd.reset_mngr = true;
1657 pl330->dmac_tbd.reset_mngr = false;
1659 val = readl(regs + FSC) & ((1 << pl330->pcfg.num_chan) - 1);
1660 pl330->dmac_tbd.reset_chan |= val;
1663 while (i < pl330->pcfg.num_chan) {
1665 dev_info(pl330->ddma.dev,
1669 _stop(&pl330->channels[i]);
1677 if (pl330->pcfg.num_events < 32
1678 && val & ~((1 << pl330->pcfg.num_events) - 1)) {
1679 pl330->dmac_tbd.reset_dmac = true;
1680 dev_err(pl330->ddma.dev, "%s:%d Unexpected!\n", __func__,
1686 for (ev = 0; ev < pl330->pcfg.num_events; ev++) {
1698 id = pl330->events[ev];
1700 thrd = &pl330->channels[id];
1716 list_add_tail(&descdone->rqd, &pl330->req_done);
1721 while (!list_empty(&pl330->req_done)) {
1722 descdone = list_first_entry(&pl330->req_done,
1725 spin_unlock_irqrestore(&pl330->lock, flags);
1727 spin_lock_irqsave(&pl330->lock, flags);
1731 spin_unlock_irqrestore(&pl330->lock, flags);
1733 if (pl330->dmac_tbd.reset_dmac
1734 || pl330->dmac_tbd.reset_mngr
1735 || pl330->dmac_tbd.reset_chan) {
1737 tasklet_schedule(&pl330->tasks);
1746 struct pl330_dmac *pl330 = thrd->dmac;
1749 for (ev = 0; ev < pl330->pcfg.num_events; ev++)
1750 if (pl330->events[ev] == -1) {
1751 pl330->events[ev] = thrd->id;
1758 static bool _chan_ns(const struct pl330_dmac *pl330, int i)
1760 return pl330->pcfg.irq_ns & (1 << i);
1766 static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330)
1771 if (pl330->state == DYING)
1774 chans = pl330->pcfg.num_chan;
1777 thrd = &pl330->channels[i];
1779 _chan_ns(pl330, i))) {
1799 struct pl330_dmac *pl330 = thrd->dmac;
1802 if (ev >= 0 && ev < pl330->pcfg.num_events
1803 && pl330->events[ev] == thrd->id)
1804 pl330->events[ev] = -1;
1824 static void read_dmac_config(struct pl330_dmac *pl330)
1826 void __iomem *regs = pl330->base;
1831 pl330->pcfg.data_bus_width = 8 * (1 << val);
1835 pl330->pcfg.data_buf_dep = val + 1;
1840 pl330->pcfg.num_chan = val;
1846 pl330->pcfg.num_peri = val;
1847 pl330->pcfg.peri_ns = readl(regs + CR4);
1849 pl330->pcfg.num_peri = 0;
1854 pl330->pcfg.mode |= DMAC_MODE_NS;
1856 pl330->pcfg.mode &= ~DMAC_MODE_NS;
1861 pl330->pcfg.num_events = val;
1863 pl330->pcfg.irq_ns = readl(regs + CR3);
1868 struct pl330_dmac *pl330 = thrd->dmac;
1870 thrd->req[0].mc_cpu = pl330->mcode_cpu
1871 + (thrd->id * pl330->mcbufsz);
1872 thrd->req[0].mc_bus = pl330->mcode_bus
1873 + (thrd->id * pl330->mcbufsz);
1877 + pl330->mcbufsz / 2;
1879 + pl330->mcbufsz / 2;
1885 static int dmac_alloc_threads(struct pl330_dmac *pl330)
1887 int chans = pl330->pcfg.num_chan;
1892 pl330->channels = kcalloc(1 + chans, sizeof(*thrd),
1894 if (!pl330->channels)
1899 thrd = &pl330->channels[i];
1901 thrd->dmac = pl330;
1907 thrd = &pl330->channels[chans];
1909 thrd->dmac = pl330;
1911 pl330->manager = thrd;
1916 static int dmac_alloc_resources(struct pl330_dmac *pl330)
1918 int chans = pl330->pcfg.num_chan;
1925 pl330->mcode_cpu = dma_alloc_attrs(pl330->ddma.dev,
1926 chans * pl330->mcbufsz,
1927 &pl330->mcode_bus, GFP_KERNEL,
1929 if (!pl330->mcode_cpu) {
1930 dev_err(pl330->ddma.dev, "%s:%d Can't allocate memory!\n",
1935 ret = dmac_alloc_threads(pl330);
1937 dev_err(pl330->ddma.dev, "%s:%d Can't to create channels for DMAC!\n",
1939 dma_free_attrs(pl330->ddma.dev,
1940 chans * pl330->mcbufsz,
1941 pl330->mcode_cpu, pl330->mcode_bus,
1949 static int pl330_add(struct pl330_dmac *pl330)
1954 if ((pl330->pcfg.periph_id & 0xfffff) != PERIPH_ID_VAL) {
1955 dev_err(pl330->ddma.dev, "PERIPH_ID 0x%x !\n",
1956 pl330->pcfg.periph_id);
1961 read_dmac_config(pl330);
1963 if (pl330->pcfg.num_events == 0) {
1964 dev_err(pl330->ddma.dev, "%s:%d Can't work without events!\n",
1969 spin_lock_init(&pl330->lock);
1971 INIT_LIST_HEAD(&pl330->req_done);
1974 if (!pl330->mcbufsz)
1975 pl330->mcbufsz = MCODE_BUFF_PER_REQ * 2;
1978 for (i = 0; i < pl330->pcfg.num_events; i++)
1979 pl330->events[i] = -1;
1982 ret = dmac_alloc_resources(pl330);
1984 dev_err(pl330->ddma.dev, "Unable to create channels for DMAC\n");
1988 tasklet_setup(&pl330->tasks, pl330_dotask);
1990 pl330->state = INIT;
1995 static int dmac_free_threads(struct pl330_dmac *pl330)
2001 for (i = 0; i < pl330->pcfg.num_chan; i++) {
2002 thrd = &pl330->channels[i];
2007 kfree(pl330->channels);
2012 static void pl330_del(struct pl330_dmac *pl330)
2014 pl330->state = UNINIT;
2016 tasklet_kill(&pl330->tasks);
2019 dmac_free_threads(pl330);
2021 dma_free_attrs(pl330->ddma.dev,
2022 pl330->pcfg.num_chan * pl330->mcbufsz, pl330->mcode_cpu,
2023 pl330->mcode_bus, DMA_ATTR_PRIVILEGED);
2148 struct pl330_dmac *pl330 = ofdma->of_dma_data;
2151 if (!pl330)
2158 if (chan_id >= pl330->num_peripherals)
2161 return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
2167 struct pl330_dmac *pl330 = pch->dmac;
2170 spin_lock_irqsave(&pl330->lock, flags);
2175 pch->thread = pl330_request_channel(pl330);
2177 spin_unlock_irqrestore(&pl330->lock, flags);
2183 spin_unlock_irqrestore(&pl330->lock, flags);
2287 struct pl330_dmac *pl330 = pch->dmac;
2290 pm_runtime_get_sync(pl330->ddma.dev);
2293 spin_lock(&pl330->lock);
2298 spin_unlock(&pl330->lock);
2314 list_splice_tail_init(&pch->submitted_list, &pl330->desc_pool);
2315 list_splice_tail_init(&pch->work_list, &pl330->desc_pool);
2316 list_splice_tail_init(&pch->completed_list, &pl330->desc_pool);
2318 pm_runtime_mark_last_busy(pl330->ddma.dev);
2320 pm_runtime_put_autosuspend(pl330->ddma.dev);
2321 pm_runtime_put_autosuspend(pl330->ddma.dev);
2336 struct pl330_dmac *pl330 = pch->dmac;
2340 pm_runtime_get_sync(pl330->ddma.dev);
2343 spin_lock(&pl330->lock);
2345 spin_unlock(&pl330->lock);
2352 pm_runtime_mark_last_busy(pl330->ddma.dev);
2353 pm_runtime_put_autosuspend(pl330->ddma.dev);
2361 struct pl330_dmac *pl330 = pch->dmac;
2367 spin_lock_irqsave(&pl330->lock, flags);
2375 spin_unlock_irqrestore(&pl330->lock, flags);
2385 struct pl330_dmac *pl330 = pch->dmac;
2389 pm_runtime_get_sync(pl330->ddma.dev);
2399 pm_runtime_put_autosuspend(pl330->ddma.dev);
2599 struct pl330_dmac *pl330 = pch->dmac;
2604 desc = pluck_desc(&pl330->desc_pool, &pl330->pool_lock);
2670 struct pl330_dmac *pl330 = pch->dmac;
2673 burst_len = pl330->pcfg.data_bus_width / 8;
2674 burst_len *= pl330->pcfg.data_buf_dep / pl330->pcfg.num_chan;
2691 struct pl330_dmac *pl330 = pch->dmac;
2721 spin_lock_irqsave(&pl330->pool_lock, iflags);
2726 list_move_tail(&desc->node, &pl330->desc_pool);
2729 list_move_tail(&first->node, &pl330->desc_pool);
2731 spin_unlock_irqrestore(&pl330->pool_lock, iflags);
2782 struct pl330_dmac *pl330;
2788 pl330 = pch->dmac;
2799 burst = pl330->pcfg.data_bus_width / 8;
2818 if (burst * 8 < pl330->pcfg.data_bus_width)
2828 static void __pl330_giveback_desc(struct pl330_dmac *pl330,
2837 spin_lock_irqsave(&pl330->pool_lock, flags);
2842 list_move_tail(&desc->node, &pl330->desc_pool);
2845 list_move_tail(&first->node, &pl330->desc_pool);
2847 spin_unlock_irqrestore(&pl330->pool_lock, flags);
2874 struct pl330_dmac *pl330 = pch->dmac;
2879 __pl330_giveback_desc(pl330, first);
2930 struct pl330_dmac *pl330 = s->private;
2933 chans = pl330->pcfg.num_chan;
2934 pchs = pl330->num_peripherals;
2940 struct pl330_thread *thrd = &pl330->channels[ch];
2944 struct dma_pl330_chan *pch = &pl330->peripherals[pr];
2964 static inline void init_pl330_debugfs(struct pl330_dmac *pl330)
2966 debugfs_create_file(dev_name(pl330->ddma.dev),
2967 S_IFREG | 0444, NULL, pl330,
2971 static inline void init_pl330_debugfs(struct pl330_dmac *pl330)
3014 struct pl330_dmac *pl330;
3027 pl330 = devm_kzalloc(&adev->dev, sizeof(*pl330), GFP_KERNEL);
3028 if (!pl330)
3031 pd = &pl330->ddma;
3034 pl330->mcbufsz = 0;
3039 pl330->quirks |= of_quirks[i].id;
3042 pl330->base = devm_ioremap_resource(&adev->dev, res);
3043 if (IS_ERR(pl330->base))
3044 return PTR_ERR(pl330->base);
3046 amba_set_drvdata(adev, pl330);
3048 pl330->rstc = devm_reset_control_get_optional(&adev->dev, "dma");
3049 if (IS_ERR(pl330->rstc)) {
3050 return dev_err_probe(&adev->dev, PTR_ERR(pl330->rstc), "Failed to get reset!\n");
3052 ret = reset_control_deassert(pl330->rstc);
3059 pl330->rstc_ocp = devm_reset_control_get_optional(&adev->dev, "dma-ocp");
3060 if (IS_ERR(pl330->rstc_ocp)) {
3061 return dev_err_probe(&adev->dev, PTR_ERR(pl330->rstc_ocp),
3064 ret = reset_control_deassert(pl330->rstc_ocp);
3076 dev_name(&adev->dev), pl330);
3084 pcfg = &pl330->pcfg;
3087 ret = pl330_add(pl330);
3091 INIT_LIST_HEAD(&pl330->desc_pool);
3092 spin_lock_init(&pl330->pool_lock);
3095 if (!add_desc(&pl330->desc_pool, &pl330->pool_lock,
3104 pl330->num_peripherals = num_chan;
3106 pl330->peripherals = kcalloc(num_chan, sizeof(*pch), GFP_KERNEL);
3107 if (!pl330->peripherals) {
3113 pch = &pl330->peripherals[i];
3122 pch->dmac = pl330;
3160 of_dma_pl330_xlate, pl330);
3176 init_pl330_debugfs(pl330);
3193 list_for_each_entry_safe(pch, _p, &pl330->ddma.channels,
3206 pl330_del(pl330);
3208 if (pl330->rstc_ocp)
3209 reset_control_assert(pl330->rstc_ocp);
3211 if (pl330->rstc)
3212 reset_control_assert(pl330->rstc);
3218 struct pl330_dmac *pl330 = amba_get_drvdata(adev);
3222 pm_runtime_get_noresume(pl330->ddma.dev);
3230 devm_free_irq(&adev->dev, irq, pl330);
3233 dma_async_device_unregister(&pl330->ddma);
3236 list_for_each_entry_safe(pch, _p, &pl330->ddma.channels,
3249 pl330_del(pl330);
3251 if (pl330->rstc_ocp)
3252 reset_control_assert(pl330->rstc_ocp);
3254 if (pl330->rstc)
3255 reset_control_assert(pl330->rstc);
3271 .name = "dma-pl330",