aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/dw_dmac.c145
-rw-r--r--drivers/dma/dw_dmac_regs.h7
2 files changed, 75 insertions, 77 deletions
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 51c3ea2ed41a..c599558faeda 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -20,6 +20,7 @@
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/of_dma.h>
23#include <linux/mm.h> 24#include <linux/mm.h>
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/platform_device.h> 26#include <linux/platform_device.h>
@@ -171,7 +172,13 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
171 if (dwc->initialized == true) 172 if (dwc->initialized == true)
172 return; 173 return;
173 174
174 if (dws) { 175 if (dws && dws->cfg_hi == ~0 && dws->cfg_lo == ~0) {
176 /* autoconfigure based on request line from DT */
177 if (dwc->direction == DMA_MEM_TO_DEV)
178 cfghi = DWC_CFGH_DST_PER(dwc->request_line);
179 else if (dwc->direction == DMA_DEV_TO_MEM)
180 cfghi = DWC_CFGH_SRC_PER(dwc->request_line);
181 } else if (dws) {
175 /* 182 /*
176 * We need controller-specific data to set up slave 183 * We need controller-specific data to set up slave
177 * transfers. 184 * transfers.
@@ -1226,49 +1233,64 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
1226 dev_vdbg(chan2dev(chan), "%s: done\n", __func__); 1233 dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
1227} 1234}
1228 1235
1229bool dw_dma_generic_filter(struct dma_chan *chan, void *param) 1236struct dw_dma_filter_args {
1237 struct dw_dma *dw;
1238 unsigned int req;
1239 unsigned int src;
1240 unsigned int dst;
1241};
1242
1243static bool dw_dma_generic_filter(struct dma_chan *chan, void *param)
1230{ 1244{
1245 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
1231 struct dw_dma *dw = to_dw_dma(chan->device); 1246 struct dw_dma *dw = to_dw_dma(chan->device);
1232 static struct dw_dma *last_dw; 1247 struct dw_dma_filter_args *fargs = param;
1233 static char *last_bus_id; 1248 struct dw_dma_slave *dws = &dwc->slave;
1234 int i = -1;
1235 1249
1236 /* 1250 /* ensure the device matches our channel */
1237 * dmaengine framework calls this routine for all channels of all dma 1251 if (chan->device != &fargs->dw->dma)
1238 * controller, until true is returned. If 'param' bus_id is not 1252 return false;
1239 * registered with a dma controller (dw), then there is no need of
1240 * running below function for all channels of dw.
1241 *
1242 * This block of code does this by saving the parameters of last
1243 * failure. If dw and param are same, i.e. trying on same dw with
1244 * different channel, return false.
1245 */
1246 if ((last_dw == dw) && (last_bus_id == param))
1247 return false;
1248 /*
1249 * Return true:
1250 * - If dw_dma's platform data is not filled with slave info, then all
1251 * dma controllers are fine for transfer.
1252 * - Or if param is NULL
1253 */
1254 if (!dw->sd || !param)
1255 return true;
1256 1253
1257 while (++i < dw->sd_count) { 1254 dws->dma_dev = dw->dma.dev;
1258 if (!strcmp(dw->sd[i].bus_id, param)) { 1255 dws->cfg_hi = ~0;
1259 chan->private = &dw->sd[i]; 1256 dws->cfg_lo = ~0;
1260 last_dw = NULL; 1257 dws->src_master = fargs->src;
1261 last_bus_id = NULL; 1258 dws->dst_master = fargs->dst;
1262 1259
1263 return true; 1260 dwc->request_line = fargs->req;
1264 }
1265 }
1266 1261
1267 last_dw = dw; 1262 chan->private = dws;
1268 last_bus_id = param; 1263
1269 return false; 1264 return true;
1265}
1266
1267static struct dma_chan *dw_dma_xlate(struct of_phandle_args *dma_spec,
1268 struct of_dma *ofdma)
1269{
1270 struct dw_dma *dw = ofdma->of_dma_data;
1271 struct dw_dma_filter_args fargs = {
1272 .dw = dw,
1273 };
1274 dma_cap_mask_t cap;
1275
1276 if (dma_spec->args_count != 3)
1277 return NULL;
1278
1279 fargs.req = be32_to_cpup(dma_spec->args+0);
1280 fargs.src = be32_to_cpup(dma_spec->args+1);
1281 fargs.dst = be32_to_cpup(dma_spec->args+2);
1282
1283 if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
1284 fargs.src >= dw->nr_masters ||
1285 fargs.dst >= dw->nr_masters))
1286 return NULL;
1287
1288 dma_cap_zero(cap);
1289 dma_cap_set(DMA_SLAVE, cap);
1290
1291 /* TODO: there should be a simpler way to do this */
1292 return dma_request_channel(cap, dw_dma_generic_filter, &fargs);
1270} 1293}
1271EXPORT_SYMBOL(dw_dma_generic_filter);
1272 1294
1273/* --------------------- Cyclic DMA API extensions -------------------- */ 1295/* --------------------- Cyclic DMA API extensions -------------------- */
1274 1296
@@ -1554,9 +1576,8 @@ static void dw_dma_off(struct dw_dma *dw)
1554static struct dw_dma_platform_data * 1576static struct dw_dma_platform_data *
1555dw_dma_parse_dt(struct platform_device *pdev) 1577dw_dma_parse_dt(struct platform_device *pdev)
1556{ 1578{
1557 struct device_node *sn, *cn, *np = pdev->dev.of_node; 1579 struct device_node *np = pdev->dev.of_node;
1558 struct dw_dma_platform_data *pdata; 1580 struct dw_dma_platform_data *pdata;
1559 struct dw_dma_slave *sd;
1560 u32 tmp, arr[4]; 1581 u32 tmp, arr[4];
1561 1582
1562 if (!np) { 1583 if (!np) {
@@ -1568,7 +1589,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
1568 if (!pdata) 1589 if (!pdata)
1569 return NULL; 1590 return NULL;
1570 1591
1571 if (of_property_read_u32(np, "nr_channels", &pdata->nr_channels)) 1592 if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
1572 return NULL; 1593 return NULL;
1573 1594
1574 if (of_property_read_bool(np, "is_private")) 1595 if (of_property_read_bool(np, "is_private"))
@@ -1583,7 +1604,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
1583 if (!of_property_read_u32(np, "block_size", &tmp)) 1604 if (!of_property_read_u32(np, "block_size", &tmp))
1584 pdata->block_size = tmp; 1605 pdata->block_size = tmp;
1585 1606
1586 if (!of_property_read_u32(np, "nr_masters", &tmp)) { 1607 if (!of_property_read_u32(np, "dma-masters", &tmp)) {
1587 if (tmp > 4) 1608 if (tmp > 4)
1588 return NULL; 1609 return NULL;
1589 1610
@@ -1595,36 +1616,6 @@ dw_dma_parse_dt(struct platform_device *pdev)
1595 for (tmp = 0; tmp < pdata->nr_masters; tmp++) 1616 for (tmp = 0; tmp < pdata->nr_masters; tmp++)
1596 pdata->data_width[tmp] = arr[tmp]; 1617 pdata->data_width[tmp] = arr[tmp];
1597 1618
1598 /* parse slave data */
1599 sn = of_find_node_by_name(np, "slave_info");
1600 if (!sn)
1601 return pdata;
1602
1603 /* calculate number of slaves */
1604 tmp = of_get_child_count(sn);
1605 if (!tmp)
1606 return NULL;
1607
1608 sd = devm_kzalloc(&pdev->dev, sizeof(*sd) * tmp, GFP_KERNEL);
1609 if (!sd)
1610 return NULL;
1611
1612 pdata->sd = sd;
1613 pdata->sd_count = tmp;
1614
1615 for_each_child_of_node(sn, cn) {
1616 sd->dma_dev = &pdev->dev;
1617 of_property_read_string(cn, "bus_id", &sd->bus_id);
1618 of_property_read_u32(cn, "cfg_hi", &sd->cfg_hi);
1619 of_property_read_u32(cn, "cfg_lo", &sd->cfg_lo);
1620 if (!of_property_read_u32(cn, "src_master", &tmp))
1621 sd->src_master = tmp;
1622
1623 if (!of_property_read_u32(cn, "dst_master", &tmp))
1624 sd->dst_master = tmp;
1625 sd++;
1626 }
1627
1628 return pdata; 1619 return pdata;
1629} 1620}
1630#else 1621#else
@@ -1705,8 +1696,6 @@ static int dw_probe(struct platform_device *pdev)
1705 clk_prepare_enable(dw->clk); 1696 clk_prepare_enable(dw->clk);
1706 1697
1707 dw->regs = regs; 1698 dw->regs = regs;
1708 dw->sd = pdata->sd;
1709 dw->sd_count = pdata->sd_count;
1710 1699
1711 /* get hardware configuration parameters */ 1700 /* get hardware configuration parameters */
1712 if (autocfg) { 1701 if (autocfg) {
@@ -1837,6 +1826,14 @@ static int dw_probe(struct platform_device *pdev)
1837 1826
1838 dma_async_device_register(&dw->dma); 1827 dma_async_device_register(&dw->dma);
1839 1828
1829 if (pdev->dev.of_node) {
1830 err = of_dma_controller_register(pdev->dev.of_node,
1831 dw_dma_xlate, dw);
1832 if (err && err != -ENODEV)
1833 dev_err(&pdev->dev,
1834 "could not register of_dma_controller\n");
1835 }
1836
1840 return 0; 1837 return 0;
1841} 1838}
1842 1839
@@ -1845,6 +1842,8 @@ static int dw_remove(struct platform_device *pdev)
1845 struct dw_dma *dw = platform_get_drvdata(pdev); 1842 struct dw_dma *dw = platform_get_drvdata(pdev);
1846 struct dw_dma_chan *dwc, *_dwc; 1843 struct dw_dma_chan *dwc, *_dwc;
1847 1844
1845 if (pdev->dev.of_node)
1846 of_dma_controller_free(pdev->dev.of_node);
1848 dw_dma_off(dw); 1847 dw_dma_off(dw);
1849 dma_async_device_unregister(&dw->dma); 1848 dma_async_device_unregister(&dw->dma);
1850 1849
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index 88dd8eb31957..cf0ce5c77d60 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -13,6 +13,7 @@
13#include <linux/dw_dmac.h> 13#include <linux/dw_dmac.h>
14 14
15#define DW_DMA_MAX_NR_CHANNELS 8 15#define DW_DMA_MAX_NR_CHANNELS 8
16#define DW_DMA_MAX_NR_REQUESTS 16
16 17
17/* flow controller */ 18/* flow controller */
18enum dw_dma_fc { 19enum dw_dma_fc {
@@ -211,6 +212,8 @@ struct dw_dma_chan {
211 /* hardware configuration */ 212 /* hardware configuration */
212 unsigned int block_size; 213 unsigned int block_size;
213 bool nollp; 214 bool nollp;
215 unsigned int request_line;
216 struct dw_dma_slave slave;
214 217
215 /* configuration passed via DMA_SLAVE_CONFIG */ 218 /* configuration passed via DMA_SLAVE_CONFIG */
216 struct dma_slave_config dma_sconfig; 219 struct dma_slave_config dma_sconfig;
@@ -239,10 +242,6 @@ struct dw_dma {
239 struct tasklet_struct tasklet; 242 struct tasklet_struct tasklet;
240 struct clk *clk; 243 struct clk *clk;
241 244
242 /* slave information */
243 struct dw_dma_slave *sd;
244 unsigned int sd_count;
245
246 u8 all_chan_mask; 245 u8 all_chan_mask;
247 246
248 /* hardware configuration */ 247 /* hardware configuration */