Lines Matching +full:stm32 +full:- +full:dma
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Pierre-Yves Mordret <pierre-yves.mordret@st.com>
8 * DMA Router driver for STM32 DMA MUX
10 * Based on TI DMA Crossbar driver
39 u32 dma_requests; /* Number of DMA requests connected to DMAMUX */
40 u32 dmamux_requests; /* Number of DMA requests routed toward DMAs */
42 unsigned long *dma_inuse; /* Used DMA channel */
46 u32 dma_reqs[]; /* Number of DMA Request per DMA masters.
47 * [0] holds number of DMA Masters.
68 /* Clear dma request */ in stm32_dmamux_free()
69 spin_lock_irqsave(&dmamux->lock, flags); in stm32_dmamux_free()
71 stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0); in stm32_dmamux_free()
72 clear_bit(mux->chan_id, dmamux->dma_inuse); in stm32_dmamux_free()
76 spin_unlock_irqrestore(&dmamux->lock, flags); in stm32_dmamux_free()
78 dev_dbg(dev, "Unmapping DMAMUX(%u) to DMA%u(%u)\n", in stm32_dmamux_free()
79 mux->request, mux->master, mux->chan_id); in stm32_dmamux_free()
87 struct platform_device *pdev = of_find_device_by_node(ofdma->of_node); in stm32_dmamux_route_allocate()
94 if (dma_spec->args_count != 3) { in stm32_dmamux_route_allocate()
95 dev_err(&pdev->dev, "invalid number of dma mux args\n"); in stm32_dmamux_route_allocate()
96 return ERR_PTR(-EINVAL); in stm32_dmamux_route_allocate()
99 if (dma_spec->args[0] > dmamux->dmamux_requests) { in stm32_dmamux_route_allocate()
100 dev_err(&pdev->dev, "invalid mux request number: %d\n", in stm32_dmamux_route_allocate()
101 dma_spec->args[0]); in stm32_dmamux_route_allocate()
102 return ERR_PTR(-EINVAL); in stm32_dmamux_route_allocate()
107 return ERR_PTR(-ENOMEM); in stm32_dmamux_route_allocate()
109 spin_lock_irqsave(&dmamux->lock, flags); in stm32_dmamux_route_allocate()
110 mux->chan_id = find_first_zero_bit(dmamux->dma_inuse, in stm32_dmamux_route_allocate()
111 dmamux->dma_requests); in stm32_dmamux_route_allocate()
113 if (mux->chan_id == dmamux->dma_requests) { in stm32_dmamux_route_allocate()
114 spin_unlock_irqrestore(&dmamux->lock, flags); in stm32_dmamux_route_allocate()
115 dev_err(&pdev->dev, "Run out of free DMA requests\n"); in stm32_dmamux_route_allocate()
116 ret = -ENOMEM; in stm32_dmamux_route_allocate()
119 set_bit(mux->chan_id, dmamux->dma_inuse); in stm32_dmamux_route_allocate()
120 spin_unlock_irqrestore(&dmamux->lock, flags); in stm32_dmamux_route_allocate()
122 /* Look for DMA Master */ in stm32_dmamux_route_allocate()
123 for (i = 1, min = 0, max = dmamux->dma_reqs[i]; in stm32_dmamux_route_allocate()
124 i <= dmamux->dma_reqs[0]; in stm32_dmamux_route_allocate()
125 min += dmamux->dma_reqs[i], max += dmamux->dma_reqs[++i]) in stm32_dmamux_route_allocate()
126 if (mux->chan_id < max) in stm32_dmamux_route_allocate()
128 mux->master = i - 1; in stm32_dmamux_route_allocate()
131 dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", i - 1); in stm32_dmamux_route_allocate()
132 if (!dma_spec->np) { in stm32_dmamux_route_allocate()
133 dev_err(&pdev->dev, "can't get dma master\n"); in stm32_dmamux_route_allocate()
134 ret = -EINVAL; in stm32_dmamux_route_allocate()
138 /* Set dma request */ in stm32_dmamux_route_allocate()
139 spin_lock_irqsave(&dmamux->lock, flags); in stm32_dmamux_route_allocate()
140 ret = pm_runtime_get_sync(&pdev->dev); in stm32_dmamux_route_allocate()
142 spin_unlock_irqrestore(&dmamux->lock, flags); in stm32_dmamux_route_allocate()
145 spin_unlock_irqrestore(&dmamux->lock, flags); in stm32_dmamux_route_allocate()
147 mux->request = dma_spec->args[0]; in stm32_dmamux_route_allocate()
149 /* craft DMA spec */ in stm32_dmamux_route_allocate()
150 dma_spec->args[3] = dma_spec->args[2]; in stm32_dmamux_route_allocate()
151 dma_spec->args[2] = dma_spec->args[1]; in stm32_dmamux_route_allocate()
152 dma_spec->args[1] = 0; in stm32_dmamux_route_allocate()
153 dma_spec->args[0] = mux->chan_id - min; in stm32_dmamux_route_allocate()
154 dma_spec->args_count = 4; in stm32_dmamux_route_allocate()
156 stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), in stm32_dmamux_route_allocate()
157 mux->request); in stm32_dmamux_route_allocate()
158 dev_dbg(&pdev->dev, "Mapping DMAMUX(%u) to DMA%u(%u)\n", in stm32_dmamux_route_allocate()
159 mux->request, mux->master, mux->chan_id); in stm32_dmamux_route_allocate()
164 clear_bit(mux->chan_id, dmamux->dma_inuse); in stm32_dmamux_route_allocate()
172 { .compatible = "st,stm32-dma", },
178 struct device_node *node = pdev->dev.of_node; in stm32_dmamux_probe()
189 return -ENODEV; in stm32_dmamux_probe()
191 count = device_property_count_u32(&pdev->dev, "dma-masters"); in stm32_dmamux_probe()
193 dev_err(&pdev->dev, "Can't get DMA master(s) node\n"); in stm32_dmamux_probe()
194 return -ENODEV; in stm32_dmamux_probe()
197 stm32_dmamux = devm_kzalloc(&pdev->dev, sizeof(*stm32_dmamux) + in stm32_dmamux_probe()
200 return -ENOMEM; in stm32_dmamux_probe()
204 dma_node = of_parse_phandle(node, "dma-masters", i - 1); in stm32_dmamux_probe()
208 dev_err(&pdev->dev, "DMA master is not supported\n"); in stm32_dmamux_probe()
210 return -EINVAL; in stm32_dmamux_probe()
213 if (of_property_read_u32(dma_node, "dma-requests", in stm32_dmamux_probe()
214 &stm32_dmamux->dma_reqs[i])) { in stm32_dmamux_probe()
215 dev_info(&pdev->dev, in stm32_dmamux_probe()
218 stm32_dmamux->dma_reqs[i] = in stm32_dmamux_probe()
221 dma_req += stm32_dmamux->dma_reqs[i]; in stm32_dmamux_probe()
226 dev_err(&pdev->dev, "Too many DMA Master Requests to manage\n"); in stm32_dmamux_probe()
227 return -ENODEV; in stm32_dmamux_probe()
230 stm32_dmamux->dma_requests = dma_req; in stm32_dmamux_probe()
231 stm32_dmamux->dma_reqs[0] = count; in stm32_dmamux_probe()
232 stm32_dmamux->dma_inuse = devm_kcalloc(&pdev->dev, in stm32_dmamux_probe()
236 if (!stm32_dmamux->dma_inuse) in stm32_dmamux_probe()
237 return -ENOMEM; in stm32_dmamux_probe()
239 if (device_property_read_u32(&pdev->dev, "dma-requests", in stm32_dmamux_probe()
240 &stm32_dmamux->dmamux_requests)) { in stm32_dmamux_probe()
241 stm32_dmamux->dmamux_requests = STM32_DMAMUX_MAX_REQUESTS; in stm32_dmamux_probe()
242 dev_warn(&pdev->dev, "DMAMUX defaulting on %u requests\n", in stm32_dmamux_probe()
243 stm32_dmamux->dmamux_requests); in stm32_dmamux_probe()
245 pm_runtime_get_noresume(&pdev->dev); in stm32_dmamux_probe()
248 iomem = devm_ioremap_resource(&pdev->dev, res); in stm32_dmamux_probe()
252 spin_lock_init(&stm32_dmamux->lock); in stm32_dmamux_probe()
254 stm32_dmamux->clk = devm_clk_get(&pdev->dev, NULL); in stm32_dmamux_probe()
255 if (IS_ERR(stm32_dmamux->clk)) in stm32_dmamux_probe()
256 return dev_err_probe(&pdev->dev, PTR_ERR(stm32_dmamux->clk), in stm32_dmamux_probe()
259 ret = clk_prepare_enable(stm32_dmamux->clk); in stm32_dmamux_probe()
261 dev_err(&pdev->dev, "clk_prep_enable error: %d\n", ret); in stm32_dmamux_probe()
265 rst = devm_reset_control_get(&pdev->dev, NULL); in stm32_dmamux_probe()
268 if (ret == -EPROBE_DEFER) in stm32_dmamux_probe()
276 stm32_dmamux->iomem = iomem; in stm32_dmamux_probe()
277 stm32_dmamux->dmarouter.dev = &pdev->dev; in stm32_dmamux_probe()
278 stm32_dmamux->dmarouter.route_free = stm32_dmamux_free; in stm32_dmamux_probe()
281 pm_runtime_set_active(&pdev->dev); in stm32_dmamux_probe()
282 pm_runtime_enable(&pdev->dev); in stm32_dmamux_probe()
284 pm_runtime_get_noresume(&pdev->dev); in stm32_dmamux_probe()
287 for (i = 0; i < stm32_dmamux->dma_requests; i++) in stm32_dmamux_probe()
288 stm32_dmamux_write(stm32_dmamux->iomem, STM32_DMAMUX_CCR(i), 0); in stm32_dmamux_probe()
290 pm_runtime_put(&pdev->dev); in stm32_dmamux_probe()
293 &stm32_dmamux->dmarouter); in stm32_dmamux_probe()
300 clk_disable_unprepare(stm32_dmamux->clk); in stm32_dmamux_probe()
311 clk_disable_unprepare(stm32_dmamux->clk); in stm32_dmamux_runtime_suspend()
322 ret = clk_prepare_enable(stm32_dmamux->clk); in stm32_dmamux_runtime_resume()
324 dev_err(&pdev->dev, "failed to prepare_enable clock\n"); in stm32_dmamux_runtime_resume()
343 for (i = 0; i < stm32_dmamux->dma_requests; i++) in stm32_dmamux_suspend()
344 stm32_dmamux->ccr[i] = stm32_dmamux_read(stm32_dmamux->iomem, in stm32_dmamux_suspend()
368 for (i = 0; i < stm32_dmamux->dma_requests; i++) in stm32_dmamux_resume()
369 stm32_dmamux_write(stm32_dmamux->iomem, STM32_DMAMUX_CCR(i), in stm32_dmamux_resume()
370 stm32_dmamux->ccr[i]); in stm32_dmamux_resume()
385 { .compatible = "st,stm32h7-dmamux" },
392 .name = "stm32-dmamux",
404 MODULE_DESCRIPTION("DMA Router driver for STM32 DMA MUX");
406 MODULE_AUTHOR("Pierre-Yves Mordret <pierre-yves.mordret@st.com>");