1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Platform driver for the Synopsys DesignWare DMA Controller |
4 | * |
5 | * Copyright (C) 2007-2008 Atmel Corporation |
6 | * Copyright (C) 2010-2011 ST Microelectronics |
7 | * Copyright (C) 2013 Intel Corporation |
8 | */ |
9 | |
10 | #include <linux/of.h> |
11 | #include <linux/of_dma.h> |
12 | #include <linux/platform_device.h> |
13 | |
14 | #include "internal.h" |
15 | |
16 | static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec, |
17 | struct of_dma *ofdma) |
18 | { |
19 | struct dw_dma *dw = ofdma->of_dma_data; |
20 | struct dw_dma_slave slave = { |
21 | .dma_dev = dw->dma.dev, |
22 | }; |
23 | dma_cap_mask_t cap; |
24 | |
25 | if (dma_spec->args_count < 3 || dma_spec->args_count > 4) |
26 | return NULL; |
27 | |
28 | slave.src_id = dma_spec->args[0]; |
29 | slave.dst_id = dma_spec->args[0]; |
30 | slave.m_master = dma_spec->args[1]; |
31 | slave.p_master = dma_spec->args[2]; |
32 | if (dma_spec->args_count >= 4) |
33 | slave.channels = dma_spec->args[3]; |
34 | |
35 | if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS || |
36 | slave.dst_id >= DW_DMA_MAX_NR_REQUESTS || |
37 | slave.m_master >= dw->pdata->nr_masters || |
38 | slave.p_master >= dw->pdata->nr_masters || |
39 | slave.channels >= BIT(dw->pdata->nr_channels))) |
40 | return NULL; |
41 | |
42 | dma_cap_zero(cap); |
43 | dma_cap_set(DMA_SLAVE, cap); |
44 | |
45 | /* TODO: there should be a simpler way to do this */ |
46 | return dma_request_channel(cap, dw_dma_filter, &slave); |
47 | } |
48 | |
49 | struct dw_dma_platform_data *dw_dma_parse_dt(struct platform_device *pdev) |
50 | { |
51 | struct device_node *np = pdev->dev.of_node; |
52 | struct dw_dma_platform_data *pdata; |
53 | u32 tmp, arr[DW_DMA_MAX_NR_MASTERS]; |
54 | u32 nr_masters; |
55 | u32 nr_channels; |
56 | |
57 | if (of_property_read_u32(np, propname: "dma-masters" , out_value: &nr_masters)) |
58 | return NULL; |
59 | if (nr_masters < 1 || nr_masters > DW_DMA_MAX_NR_MASTERS) |
60 | return NULL; |
61 | |
62 | if (of_property_read_u32(np, propname: "dma-channels" , out_value: &nr_channels)) |
63 | return NULL; |
64 | if (nr_channels > DW_DMA_MAX_NR_CHANNELS) |
65 | return NULL; |
66 | |
67 | pdata = devm_kzalloc(dev: &pdev->dev, size: sizeof(*pdata), GFP_KERNEL); |
68 | if (!pdata) |
69 | return NULL; |
70 | |
71 | pdata->nr_masters = nr_masters; |
72 | pdata->nr_channels = nr_channels; |
73 | |
74 | of_property_read_u32(np, propname: "chan_allocation_order" , out_value: &pdata->chan_allocation_order); |
75 | of_property_read_u32(np, propname: "chan_priority" , out_value: &pdata->chan_priority); |
76 | |
77 | of_property_read_u32(np, propname: "block_size" , out_value: &pdata->block_size); |
78 | |
79 | /* Try deprecated property first */ |
80 | if (!of_property_read_u32_array(np, propname: "data_width" , out_values: arr, sz: nr_masters)) { |
81 | for (tmp = 0; tmp < nr_masters; tmp++) |
82 | pdata->data_width[tmp] = BIT(arr[tmp] & 0x07); |
83 | } |
84 | |
85 | /* If "data_width" and "data-width" both provided use the latter one */ |
86 | of_property_read_u32_array(np, propname: "data-width" , out_values: pdata->data_width, sz: nr_masters); |
87 | |
88 | memset32(s: pdata->multi_block, v: 1, n: nr_channels); |
89 | of_property_read_u32_array(np, propname: "multi-block" , out_values: pdata->multi_block, sz: nr_channels); |
90 | |
91 | memset32(s: pdata->max_burst, DW_DMA_MAX_BURST, n: nr_channels); |
92 | of_property_read_u32_array(np, propname: "snps,max-burst-len" , out_values: pdata->max_burst, sz: nr_channels); |
93 | |
94 | of_property_read_u32(np, propname: "snps,dma-protection-control" , out_value: &pdata->protctl); |
95 | if (pdata->protctl > CHAN_PROTCTL_MASK) |
96 | return NULL; |
97 | |
98 | return pdata; |
99 | } |
100 | |
101 | void dw_dma_of_controller_register(struct dw_dma *dw) |
102 | { |
103 | struct device *dev = dw->dma.dev; |
104 | int ret; |
105 | |
106 | if (!dev->of_node) |
107 | return; |
108 | |
109 | ret = of_dma_controller_register(np: dev->of_node, of_dma_xlate: dw_dma_of_xlate, data: dw); |
110 | if (ret) |
111 | dev_err(dev, "could not register of_dma_controller\n" ); |
112 | } |
113 | |
114 | void dw_dma_of_controller_free(struct dw_dma *dw) |
115 | { |
116 | struct device *dev = dw->dma.dev; |
117 | |
118 | if (!dev->of_node) |
119 | return; |
120 | |
121 | of_dma_controller_free(np: dev->of_node); |
122 | } |
123 | |