blob: 28afe488db0d24599278ebf674141c71f91fb546 [file] [log] [blame]
Greg Malysa04b97d62025-02-26 12:30:31 -05001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Analog Devices DMA controller driver
4 *
5 * (C) Copyright 2024 - Analog Devices, Inc.
6 *
7 * Written and/or maintained by Timesys Corporation
8 *
9 * Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
10 * Contact: Greg Malysa <greg.malysa@timesys.com>
11 * Contact: Ian Roberts <ian.roberts@timesys.com>
12 *
13 */
14#include <dm.h>
15#include <dma.h>
16#include <dma-uclass.h>
17#include <dm/device_compat.h>
18#include <linux/errno.h>
19#include <linux/io.h>
20
21#define HAS_MDMA BIT(0)
22
23#define REG_ADDRSTART 0x04
24#define REG_CFG 0x08
25#define REG_XCNT 0x0C
26#define REG_XMOD 0x10
27#define REG_STAT 0x30
28
29#define BITP_DMA_CFG_MSIZE 8
30#define BITP_DMA_CFG_PSIZE 4
31#define BITM_DMA_CFG_WNR 0x00000002
32#define BITM_DMA_CFG_EN 0x00000001
33#define ENUM_DMA_CFG_XCNT_INT 0x00100000
34
35#define BITP_DMA_STAT_PBWID 12
36#define BITP_DMA_STAT_ERRC 4
37#define BITM_DMA_STAT_PBWID 0x00003000
38#define BITM_DMA_STAT_ERRC 0x00000070
39#define BITM_DMA_STAT_PIRQ 0x00000004
40#define BITM_DMA_STAT_IRQERR 0x00000002
41#define BITM_DMA_STAT_IRQDONE 0x00000001
42
43#define DMA_MDMA_SRC_DEFAULT_CONFIG(psize, msize) \
44 (BITM_DMA_CFG_EN | ((psize) << BITP_DMA_CFG_PSIZE) | ((msize) << BITP_DMA_CFG_MSIZE))
45#define DMA_MDMA_DST_DEFAULT_CONFIG(psize, msize) \
46 (BITM_DMA_CFG_EN | BITM_DMA_CFG_WNR | ENUM_DMA_CFG_XCNT_INT | \
47 ((psize) << BITP_DMA_CFG_PSIZE) | ((msize) << BITP_DMA_CFG_MSIZE))
48
49struct adi_dma_channel {
50 int id;
51 struct adi_dma *dma;
52 void __iomem *iosrc;
53 void __iomem *iodest;
54};
55
56struct adi_dma {
57 struct udevice *dev;
58 struct adi_dma_channel channels[1];
59 void __iomem *ioaddr;
60 unsigned long hw_cfg;
61};
62
63static const struct udevice_id dma_dt_ids[] = {
64 { .compatible = "adi,mdma-controller", .data = HAS_MDMA },
65 { }
66};
67
68static u8 adi_dma_get_msize(u32 n_bytecount, u32 n_address)
69{
70 /* Calculate MSIZE, PSIZE, XCNT and XMOD */
71 u8 n_msize = 0;
72 u32 n_value = n_bytecount | n_address;
73 u32 n_mask = 0x1;
74
75 for (n_msize = 0; n_msize < 5; n_msize++, n_mask <<= 1) {
76 if ((n_value & n_mask) == n_mask)
77 break;
78 }
79
80 return n_msize;
81}
82
83static int adi_dma_get_ch_error(void __iomem *ch)
84{
85 u32 cause = (ioread32(ch + REG_STAT) & BITM_DMA_STAT_ERRC) >>
86 BITP_DMA_STAT_ERRC;
87 switch (cause) {
88 case 0:
89 return -EINVAL;
90 case 1:
91 return -EBUSY;
92 case 2:
93 return -EFAULT;
94 case 3:
95 fallthrough;
96 case 5:
97 fallthrough;
98 case 6:
99 fallthrough;
100 default:
101 return -EIO;
102 }
103}
104
105static int adi_mdma_transfer(struct udevice *dev, int direction,
106 dma_addr_t dst, dma_addr_t src, size_t len)
107{
108 struct adi_dma *priv = dev_get_priv(dev);
109 void __iomem *chsrc = priv->channels[0].iosrc;
110 void __iomem *chdst = priv->channels[0].iodest;
111
112 int result = 0;
113 u32 reg;
114 u32 bytecount = len;
115
116 u8 n_srcmsize;
117 u8 n_dstmsize;
118 u8 n_srcpsize;
119 u8 n_dstpsize;
120 u8 n_psize;
121 u32 srcconfig;
122 u32 dstconfig;
123 u8 srcpsizemax = (ioread32(chsrc + REG_STAT) & BITM_DMA_STAT_PBWID) >>
124 BITP_DMA_STAT_PBWID;
125 u8 dstpsizemax = (ioread32(chdst + REG_STAT) & BITM_DMA_STAT_PBWID) >>
126 BITP_DMA_STAT_PBWID;
127
128 const u32 CLRSTAT = (BITM_DMA_STAT_IRQDONE | BITM_DMA_STAT_IRQERR |
129 BITM_DMA_STAT_PIRQ);
130
131 if (len == 0)
132 return -EINVAL;
133
134 /* Clear DMA status */
135 iowrite32(CLRSTAT, chsrc + REG_STAT);
136 iowrite32(CLRSTAT, chdst + REG_STAT);
137
138 /* Calculate MSIZE, PSIZE, XCNT and XMOD */
139 n_srcmsize = adi_dma_get_msize(bytecount, src);
140 n_dstmsize = adi_dma_get_msize(bytecount, dst);
141 n_srcpsize = min(n_srcmsize, srcpsizemax);
142 n_dstpsize = min(n_dstmsize, dstpsizemax);
143 n_psize = min(n_srcpsize, n_dstpsize);
144
145 srcconfig = DMA_MDMA_SRC_DEFAULT_CONFIG(n_psize, n_srcmsize);
146 dstconfig = DMA_MDMA_DST_DEFAULT_CONFIG(n_psize, n_dstmsize);
147
148 /* Load the DMA descriptors */
149 iowrite32(src, chsrc + REG_ADDRSTART);
150 iowrite32(bytecount >> n_srcmsize, chsrc + REG_XCNT);
151 iowrite32(1 << n_srcmsize, chsrc + REG_XMOD);
152 iowrite32(dst, chdst + REG_ADDRSTART);
153 iowrite32(bytecount >> n_dstmsize, chdst + REG_XCNT);
154 iowrite32(1 << n_dstmsize, chdst + REG_XMOD);
155
156 iowrite32(dstconfig, chdst + REG_CFG);
157 iowrite32(srcconfig, chsrc + REG_CFG);
158
159 /* Wait for DMA to complete while checking for a DMA error */
160 do {
161 reg = ioread32(chsrc + REG_STAT);
162 if ((reg & BITM_DMA_STAT_IRQERR) == BITM_DMA_STAT_IRQERR) {
163 result = adi_dma_get_ch_error(chsrc);
164 break;
165 }
166 reg = ioread32(chdst + REG_STAT);
167 if ((reg & BITM_DMA_STAT_IRQERR) == BITM_DMA_STAT_IRQERR) {
168 result = adi_dma_get_ch_error(chdst);
169 break;
170 }
171 } while ((reg & BITM_DMA_STAT_IRQDONE) == 0);
172
173 clrbits_32(chsrc + REG_CFG, 1);
174 clrbits_32(chdst + REG_CFG, 1);
175
176 return result;
177}
178
179static int adi_dma_init_channel(struct adi_dma *dma,
180 struct adi_dma_channel *channel, ofnode node)
181{
182 u32 offset;
183
184 if (ofnode_read_u32(node, "adi,id", &channel->id)) {
185 dev_err(dma->dev, "Missing adi,id for channel %s\n",
186 ofnode_get_name(node));
187 return -ENOENT;
188 }
189
190 if (ofnode_read_u32(node, "adi,src-offset", &offset)) {
191 dev_err(dma->dev, "Missing adi,src-offset for channel %s\n",
192 ofnode_get_name(node));
193 return -ENOENT;
194 }
195
196 channel->iosrc = dma->ioaddr + offset;
197 channel->dma = dma;
198
199 if (dma->hw_cfg & HAS_MDMA) {
200 if (ofnode_read_u32(node, "adi,dest-offset", &offset)) {
201 dev_err(dma->dev,
202 "Missing adi,dest-offset for channel %s\n",
203 ofnode_get_name(node));
204 return -ENOENT;
205 }
206 channel->iodest = dma->ioaddr + offset;
207 }
208
209 return 0;
210}
211
212static int adi_dma_probe(struct udevice *dev)
213{
214 struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
215 struct adi_dma *priv = dev_get_priv(dev);
216 ofnode node, child;
217
218 priv->hw_cfg = dev_get_driver_data(dev);
219 if (priv->hw_cfg & HAS_MDMA)
220 uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM;
221
222 priv->ioaddr = dev_remap_addr(dev);
223 if (!priv->ioaddr)
224 return -EINVAL;
225
226 node = dev_read_first_subnode(dev);
227 if (!ofnode_valid(node)) {
228 dev_err(dev,
229 "Error: device tree DMA channel config missing!\n");
230 return -ENODEV;
231 }
232
233 node = dev_ofnode(dev);
234 ofnode_for_each_subnode(child, node) {
235 adi_dma_init_channel(priv, priv->channels, child);
236 break; //Only 1 channel supported for now
237 }
238
239 return 0;
240}
241
242static const struct dma_ops adi_dma_ops = {
243 .transfer = adi_mdma_transfer,
244};
245
246U_BOOT_DRIVER(adi_dma) = {
247 .name = "adi_dma",
248 .id = UCLASS_DMA,
249 .of_match = dma_dt_ids,
250 .ops = &adi_dma_ops,
251 .probe = adi_dma_probe,
252 .priv_auto = sizeof(struct adi_dma),
253};