aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/dma/snps-dma.txt70
-rw-r--r--drivers/dma/dw_dmac.c145
-rw-r--r--drivers/dma/dw_dmac_regs.h7
-rw-r--r--include/linux/dw_dmac.h5
4 files changed, 111 insertions, 116 deletions
diff --git a/Documentation/devicetree/bindings/dma/snps-dma.txt b/Documentation/devicetree/bindings/dma/snps-dma.txt
index 5bb3dfb6f1d8..d58675ea1abf 100644
--- a/Documentation/devicetree/bindings/dma/snps-dma.txt
+++ b/Documentation/devicetree/bindings/dma/snps-dma.txt
@@ -3,59 +3,61 @@
3Required properties: 3Required properties:
4- compatible: "snps,dma-spear1340" 4- compatible: "snps,dma-spear1340"
5- reg: Address range of the DMAC registers 5- reg: Address range of the DMAC registers
6- interrupt-parent: Should be the phandle for the interrupt controller
7 that services interrupts for this device
8- interrupt: Should contain the DMAC interrupt number 6- interrupt: Should contain the DMAC interrupt number
9- nr_channels: Number of channels supported by hardware 7- dma-channels: Number of channels supported by hardware
10- is_private: The device channels should be marked as private and not for by the 8- dma-requests: Number of DMA request lines supported, up to 16
11 general purpose DMA channel allocator. False if not passed. 9- dma-masters: Number of AHB masters supported by the controller
10- #dma-cells: must be <3>
12- chan_allocation_order: order of allocation of channel, 0 (default): ascending, 11- chan_allocation_order: order of allocation of channel, 0 (default): ascending,
13 1: descending 12 1: descending
14- chan_priority: priority of channels. 0 (default): increase from chan 0->n, 1: 13- chan_priority: priority of channels. 0 (default): increase from chan 0->n, 1:
15 increase from chan n->0 14 increase from chan n->0
16- block_size: Maximum block size supported by the controller 15- block_size: Maximum block size supported by the controller
17- nr_masters: Number of AHB masters supported by the controller
18- data_width: Maximum data width supported by hardware per AHB master 16- data_width: Maximum data width supported by hardware per AHB master
19 (0 - 8bits, 1 - 16bits, ..., 5 - 256bits) 17 (0 - 8bits, 1 - 16bits, ..., 5 - 256bits)
20- slave_info: 18
21 - bus_id: name of this device channel, not just a device name since 19
22 devices may have more than one channel e.g. "foo_tx". For using the 20Optional properties:
23 dw_generic_filter(), slave drivers must pass exactly this string as 21- interrupt-parent: Should be the phandle for the interrupt controller
24 param to filter function. 22 that services interrupts for this device
25 - cfg_hi: Platform-specific initializer for the CFG_HI register 23- is_private: The device channels should be marked as private and not for by the
26 - cfg_lo: Platform-specific initializer for the CFG_LO register 24 general purpose DMA channel allocator. False if not passed.
27 - src_master: src master for transfers on allocated channel.
28 - dst_master: dest master for transfers on allocated channel.
29 25
30Example: 26Example:
31 27
32 dma@fc000000 { 28 dmahost: dma@fc000000 {
33 compatible = "snps,dma-spear1340"; 29 compatible = "snps,dma-spear1340";
34 reg = <0xfc000000 0x1000>; 30 reg = <0xfc000000 0x1000>;
35 interrupt-parent = <&vic1>; 31 interrupt-parent = <&vic1>;
36 interrupts = <12>; 32 interrupts = <12>;
37 33
38 nr_channels = <8>; 34 dma-channels = <8>;
35 dma-requests = <16>;
36 dma-masters = <2>;
37 #dma-cells = <3>;
39 chan_allocation_order = <1>; 38 chan_allocation_order = <1>;
40 chan_priority = <1>; 39 chan_priority = <1>;
41 block_size = <0xfff>; 40 block_size = <0xfff>;
42 nr_masters = <2>;
43 data_width = <3 3 0 0>; 41 data_width = <3 3 0 0>;
42 };
44 43
45 slave_info { 44DMA clients connected to the Designware DMA controller must use the format
46 uart0-tx { 45described in the dma.txt file, using a four-cell specifier for each channel.
47 bus_id = "uart0-tx"; 46The four cells in order are:
48 cfg_hi = <0x4000>; /* 0x8 << 11 */ 47
49 cfg_lo = <0>; 481. A phandle pointing to the DMA controller
50 src_master = <0>; 492. The DMA request line number
51 dst_master = <1>; 503. Source master for transfers on allocated channel
52 }; 514. Destination master for transfers on allocated channel
53 spi0-tx { 52
54 bus_id = "spi0-tx"; 53Example:
55 cfg_hi = <0x2000>; /* 0x4 << 11 */ 54
56 cfg_lo = <0>; 55 serial@e0000000 {
57 src_master = <0>; 56 compatible = "arm,pl011", "arm,primecell";
58 dst_master = <0>; 57 reg = <0xe0000000 0x1000>;
59 }; 58 interrupts = <0 35 0x4>;
60 }; 59 status = "disabled";
60 dmas = <&dmahost 12 0 1>,
61 <&dmahost 13 0 1 0>;
62 dma-names = "rx", "rx";
61 }; 63 };
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 4c83f18803f1..c3159abf9ac1 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -19,6 +19,7 @@
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/of.h> 21#include <linux/of.h>
22#include <linux/of_dma.h>
22#include <linux/mm.h> 23#include <linux/mm.h>
23#include <linux/module.h> 24#include <linux/module.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
@@ -170,7 +171,13 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
170 if (dwc->initialized == true) 171 if (dwc->initialized == true)
171 return; 172 return;
172 173
173 if (dws) { 174 if (dws && dws->cfg_hi == ~0 && dws->cfg_lo == ~0) {
175 /* autoconfigure based on request line from DT */
176 if (dwc->direction == DMA_MEM_TO_DEV)
177 cfghi = DWC_CFGH_DST_PER(dwc->request_line);
178 else if (dwc->direction == DMA_DEV_TO_MEM)
179 cfghi = DWC_CFGH_SRC_PER(dwc->request_line);
180 } else if (dws) {
174 /* 181 /*
175 * We need controller-specific data to set up slave 182 * We need controller-specific data to set up slave
176 * transfers. 183 * transfers.
@@ -1225,49 +1232,64 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
1225 dev_vdbg(chan2dev(chan), "%s: done\n", __func__); 1232 dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
1226} 1233}
1227 1234
1228bool dw_dma_generic_filter(struct dma_chan *chan, void *param) 1235struct dw_dma_filter_args {
1236 struct dw_dma *dw;
1237 unsigned int req;
1238 unsigned int src;
1239 unsigned int dst;
1240};
1241
1242static bool dw_dma_generic_filter(struct dma_chan *chan, void *param)
1229{ 1243{
1244 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
1230 struct dw_dma *dw = to_dw_dma(chan->device); 1245 struct dw_dma *dw = to_dw_dma(chan->device);
1231 static struct dw_dma *last_dw; 1246 struct dw_dma_filter_args *fargs = param;
1232 static char *last_bus_id; 1247 struct dw_dma_slave *dws = &dwc->slave;
1233 int i = -1;
1234 1248
1235 /* 1249 /* ensure the device matches our channel */
1236 * dmaengine framework calls this routine for all channels of all dma 1250 if (chan->device != &fargs->dw->dma)
1237 * controller, until true is returned. If 'param' bus_id is not 1251 return false;
1238 * registered with a dma controller (dw), then there is no need of
1239 * running below function for all channels of dw.
1240 *
1241 * This block of code does this by saving the parameters of last
1242 * failure. If dw and param are same, i.e. trying on same dw with
1243 * different channel, return false.
1244 */
1245 if ((last_dw == dw) && (last_bus_id == param))
1246 return false;
1247 /*
1248 * Return true:
1249 * - If dw_dma's platform data is not filled with slave info, then all
1250 * dma controllers are fine for transfer.
1251 * - Or if param is NULL
1252 */
1253 if (!dw->sd || !param)
1254 return true;
1255 1252
1256 while (++i < dw->sd_count) { 1253 dws->dma_dev = dw->dma.dev;
1257 if (!strcmp(dw->sd[i].bus_id, param)) { 1254 dws->cfg_hi = ~0;
1258 chan->private = &dw->sd[i]; 1255 dws->cfg_lo = ~0;
1259 last_dw = NULL; 1256 dws->src_master = fargs->src;
1260 last_bus_id = NULL; 1257 dws->dst_master = fargs->dst;
1261 1258
1262 return true; 1259 dwc->request_line = fargs->req;
1263 }
1264 }
1265 1260
1266 last_dw = dw; 1261 chan->private = dws;
1267 last_bus_id = param; 1262
1268 return false; 1263 return true;
1264}
1265
1266static struct dma_chan *dw_dma_xlate(struct of_phandle_args *dma_spec,
1267 struct of_dma *ofdma)
1268{
1269 struct dw_dma *dw = ofdma->of_dma_data;
1270 struct dw_dma_filter_args fargs = {
1271 .dw = dw,
1272 };
1273 dma_cap_mask_t cap;
1274
1275 if (dma_spec->args_count != 3)
1276 return NULL;
1277
1278 fargs.req = be32_to_cpup(dma_spec->args+0);
1279 fargs.src = be32_to_cpup(dma_spec->args+1);
1280 fargs.dst = be32_to_cpup(dma_spec->args+2);
1281
1282 if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
1283 fargs.src >= dw->nr_masters ||
1284 fargs.dst >= dw->nr_masters))
1285 return NULL;
1286
1287 dma_cap_zero(cap);
1288 dma_cap_set(DMA_SLAVE, cap);
1289
1290 /* TODO: there should be a simpler way to do this */
1291 return dma_request_channel(cap, dw_dma_generic_filter, &fargs);
1269} 1292}
1270EXPORT_SYMBOL(dw_dma_generic_filter);
1271 1293
1272/* --------------------- Cyclic DMA API extensions -------------------- */ 1294/* --------------------- Cyclic DMA API extensions -------------------- */
1273 1295
@@ -1553,9 +1575,8 @@ static void dw_dma_off(struct dw_dma *dw)
1553static struct dw_dma_platform_data * 1575static struct dw_dma_platform_data *
1554dw_dma_parse_dt(struct platform_device *pdev) 1576dw_dma_parse_dt(struct platform_device *pdev)
1555{ 1577{
1556 struct device_node *sn, *cn, *np = pdev->dev.of_node; 1578 struct device_node *np = pdev->dev.of_node;
1557 struct dw_dma_platform_data *pdata; 1579 struct dw_dma_platform_data *pdata;
1558 struct dw_dma_slave *sd;
1559 u32 tmp, arr[4]; 1580 u32 tmp, arr[4];
1560 1581
1561 if (!np) { 1582 if (!np) {
@@ -1567,7 +1588,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
1567 if (!pdata) 1588 if (!pdata)
1568 return NULL; 1589 return NULL;
1569 1590
1570 if (of_property_read_u32(np, "nr_channels", &pdata->nr_channels)) 1591 if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
1571 return NULL; 1592 return NULL;
1572 1593
1573 if (of_property_read_bool(np, "is_private")) 1594 if (of_property_read_bool(np, "is_private"))
@@ -1582,7 +1603,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
1582 if (!of_property_read_u32(np, "block_size", &tmp)) 1603 if (!of_property_read_u32(np, "block_size", &tmp))
1583 pdata->block_size = tmp; 1604 pdata->block_size = tmp;
1584 1605
1585 if (!of_property_read_u32(np, "nr_masters", &tmp)) { 1606 if (!of_property_read_u32(np, "dma-masters", &tmp)) {
1586 if (tmp > 4) 1607 if (tmp > 4)
1587 return NULL; 1608 return NULL;
1588 1609
@@ -1594,36 +1615,6 @@ dw_dma_parse_dt(struct platform_device *pdev)
1594 for (tmp = 0; tmp < pdata->nr_masters; tmp++) 1615 for (tmp = 0; tmp < pdata->nr_masters; tmp++)
1595 pdata->data_width[tmp] = arr[tmp]; 1616 pdata->data_width[tmp] = arr[tmp];
1596 1617
1597 /* parse slave data */
1598 sn = of_find_node_by_name(np, "slave_info");
1599 if (!sn)
1600 return pdata;
1601
1602 /* calculate number of slaves */
1603 tmp = of_get_child_count(sn);
1604 if (!tmp)
1605 return NULL;
1606
1607 sd = devm_kzalloc(&pdev->dev, sizeof(*sd) * tmp, GFP_KERNEL);
1608 if (!sd)
1609 return NULL;
1610
1611 pdata->sd = sd;
1612 pdata->sd_count = tmp;
1613
1614 for_each_child_of_node(sn, cn) {
1615 sd->dma_dev = &pdev->dev;
1616 of_property_read_string(cn, "bus_id", &sd->bus_id);
1617 of_property_read_u32(cn, "cfg_hi", &sd->cfg_hi);
1618 of_property_read_u32(cn, "cfg_lo", &sd->cfg_lo);
1619 if (!of_property_read_u32(cn, "src_master", &tmp))
1620 sd->src_master = tmp;
1621
1622 if (!of_property_read_u32(cn, "dst_master", &tmp))
1623 sd->dst_master = tmp;
1624 sd++;
1625 }
1626
1627 return pdata; 1618 return pdata;
1628} 1619}
1629#else 1620#else
@@ -1704,8 +1695,6 @@ static int dw_probe(struct platform_device *pdev)
1704 clk_prepare_enable(dw->clk); 1695 clk_prepare_enable(dw->clk);
1705 1696
1706 dw->regs = regs; 1697 dw->regs = regs;
1707 dw->sd = pdata->sd;
1708 dw->sd_count = pdata->sd_count;
1709 1698
1710 /* get hardware configuration parameters */ 1699 /* get hardware configuration parameters */
1711 if (autocfg) { 1700 if (autocfg) {
@@ -1836,6 +1825,14 @@ static int dw_probe(struct platform_device *pdev)
1836 1825
1837 dma_async_device_register(&dw->dma); 1826 dma_async_device_register(&dw->dma);
1838 1827
1828 if (pdev->dev.of_node) {
1829 err = of_dma_controller_register(pdev->dev.of_node,
1830 dw_dma_xlate, dw);
1831 if (err && err != -ENODEV)
1832 dev_err(&pdev->dev,
1833 "could not register of_dma_controller\n");
1834 }
1835
1839 return 0; 1836 return 0;
1840} 1837}
1841 1838
@@ -1844,6 +1841,8 @@ static int __devexit dw_remove(struct platform_device *pdev)
1844 struct dw_dma *dw = platform_get_drvdata(pdev); 1841 struct dw_dma *dw = platform_get_drvdata(pdev);
1845 struct dw_dma_chan *dwc, *_dwc; 1842 struct dw_dma_chan *dwc, *_dwc;
1846 1843
1844 if (pdev->dev.of_node)
1845 of_dma_controller_free(pdev->dev.of_node);
1847 dw_dma_off(dw); 1846 dw_dma_off(dw);
1848 dma_async_device_unregister(&dw->dma); 1847 dma_async_device_unregister(&dw->dma);
1849 1848
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 */
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h
index 41766de66e33..481ab2345d6b 100644
--- a/include/linux/dw_dmac.h
+++ b/include/linux/dw_dmac.h
@@ -27,7 +27,6 @@
27 */ 27 */
28struct dw_dma_slave { 28struct dw_dma_slave {
29 struct device *dma_dev; 29 struct device *dma_dev;
30 const char *bus_id;
31 u32 cfg_hi; 30 u32 cfg_hi;
32 u32 cfg_lo; 31 u32 cfg_lo;
33 u8 src_master; 32 u8 src_master;
@@ -60,9 +59,6 @@ struct dw_dma_platform_data {
60 unsigned short block_size; 59 unsigned short block_size;
61 unsigned char nr_masters; 60 unsigned char nr_masters;
62 unsigned char data_width[4]; 61 unsigned char data_width[4];
63
64 struct dw_dma_slave *sd;
65 unsigned int sd_count;
66}; 62};
67 63
68/* bursts size */ 64/* bursts size */
@@ -114,6 +110,5 @@ void dw_dma_cyclic_stop(struct dma_chan *chan);
114dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan); 110dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan);
115 111
116dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan); 112dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan);
117bool dw_dma_generic_filter(struct dma_chan *chan, void *param);
118 113
119#endif /* DW_DMAC_H */ 114#endif /* DW_DMAC_H */