packaging: Add python3-base dependency
[platform/upstream/gdb.git] / sim / bfin / dv-bfin_dmac.c
1 /* Blackfin Direct Memory Access (DMA) Controller model.
2
3    Copyright (C) 2010-2023 Free Software Foundation, Inc.
4    Contributed by Analog Devices, Inc.
5
6    This file is part of simulators.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 /* This must come before any other includes.  */
22 #include "defs.h"
23
24 #include "sim-main.h"
25 #include "sim-hw.h"
26 #include "devices.h"
27 #include "hw-device.h"
28 #include "dv-bfin_dma.h"
29 #include "dv-bfin_dmac.h"
30
31 struct bfin_dmac
32 {
33   /* This top portion matches common dv_bfin struct.  */
34   bu32 base;
35   struct hw *dma_master;
36   bool acked;
37
38   const char * const *pmap;
39   unsigned int pmap_count;
40 };
41
42 struct hw *
43 bfin_dmac_get_peer (struct hw *dma, bu16 pmap)
44 {
45   struct hw *ret, *me;
46   struct bfin_dmac *dmac;
47   char peer[100];
48
49   me = hw_parent (dma);
50   dmac = hw_data (me);
51   if (pmap & CTYPE)
52     {
53       /* MDMA channel.  */
54       unsigned int chan_num = dv_get_bus_num (dma);
55       if (chan_num & 1)
56         chan_num &= ~1;
57       else
58         chan_num |= 1;
59       sprintf (peer, "%s/bfin_dma@%u", hw_path (me), chan_num);
60     }
61   else
62     {
63       unsigned int idx = pmap >> 12;
64       if (idx >= dmac->pmap_count)
65         hw_abort (me, "Invalid DMA peripheral_map %#x", pmap);
66       else
67         sprintf (peer, "/core/bfin_%s", dmac->pmap[idx]);
68     }
69
70   ret = hw_tree_find_device (me, peer);
71   if (!ret)
72     hw_abort (me, "Unable to locate peer for %s (pmap:%#x %s)",
73               hw_name (dma), pmap, peer);
74   return ret;
75 }
76
77 bu16
78 bfin_dmac_default_pmap (struct hw *dma)
79 {
80   unsigned int chan_num = dv_get_bus_num (dma);
81
82   if (chan_num < BFIN_DMAC_MDMA_BASE)
83     return (chan_num % 12) << 12;
84   else
85     return CTYPE;       /* MDMA */
86 }
87
88 static const char * const bfin_dmac_50x_pmap[] =
89 {
90   "ppi@0", "rsi", "sport@0", "sport@0", "sport@1", "sport@1",
91   "spi@0", "spi@1", "uart2@0", "uart2@0", "uart2@1", "uart2@1",
92 };
93
94 /* XXX: Need to figure out how to handle portmuxed DMA channels.  */
95 static const struct hw_port_descriptor bfin_dmac_50x_ports[] =
96 {
97   { "ppi@0",       0, 0, input_port, },
98   { "rsi",         1, 0, input_port, },
99   { "sport@0_rx",  2, 0, input_port, },
100   { "sport@0_tx",  3, 0, input_port, },
101   { "sport@1_tx",  4, 0, input_port, },
102   { "sport@1_rx",  5, 0, input_port, },
103   { "spi@0",       6, 0, input_port, },
104   { "spi@1",       7, 0, input_port, },
105   { "uart2@0_rx",  8, 0, input_port, },
106   { "uart2@0_tx",  9, 0, input_port, },
107   { "uart2@1_rx", 10, 0, input_port, },
108   { "uart2@1_tx", 11, 0, input_port, },
109   { NULL, 0, 0, 0, },
110 };
111
112 static const char * const bfin_dmac_51x_pmap[] =
113 {
114   "ppi@0", "emac", "emac", "sport@0", "sport@0", "sport@1",
115   "sport@1", "spi@0", "uart@0", "uart@0", "uart@1", "uart@1",
116 };
117
118 /* XXX: Need to figure out how to handle portmuxed DMA channels.  */
119 static const struct hw_port_descriptor bfin_dmac_51x_ports[] =
120 {
121   { "ppi@0",       0, 0, input_port, },
122   { "emac_rx",     1, 0, input_port, },
123   { "emac_tx",     2, 0, input_port, },
124   { "sport@0_rx",  3, 0, input_port, },
125   { "sport@0_tx",  4, 0, input_port, },
126 /*{ "rsi",         4, 0, input_port, },*/
127   { "sport@1_tx",  5, 0, input_port, },
128 /*{ "spi@1",       5, 0, input_port, },*/
129   { "sport@1_rx",  6, 0, input_port, },
130   { "spi@0",       7, 0, input_port, },
131   { "uart@0_rx",   8, 0, input_port, },
132   { "uart@0_tx",   9, 0, input_port, },
133   { "uart@1_rx",  10, 0, input_port, },
134   { "uart@1_tx",  11, 0, input_port, },
135   { NULL, 0, 0, 0, },
136 };
137
138 static const char * const bfin_dmac_52x_pmap[] =
139 {
140   "ppi@0", "emac", "emac", "sport@0", "sport@0", "sport@1",
141   "sport@1", "spi", "uart@0", "uart@0", "uart@1", "uart@1",
142 };
143
144 /* XXX: Need to figure out how to handle portmuxed DMA channels
145         like PPI/NFC here which share DMA0.  */
146 static const struct hw_port_descriptor bfin_dmac_52x_ports[] =
147 {
148   { "ppi@0",       0, 0, input_port, },
149 /*{ "nfc",         0, 0, input_port, },*/
150   { "emac_rx",     1, 0, input_port, },
151 /*{ "hostdp",      1, 0, input_port, },*/
152   { "emac_tx",     2, 0, input_port, },
153 /*{ "nfc",         2, 0, input_port, },*/
154   { "sport@0_tx",  3, 0, input_port, },
155   { "sport@0_rx",  4, 0, input_port, },
156   { "sport@1_tx",  5, 0, input_port, },
157   { "sport@1_rx",  6, 0, input_port, },
158   { "spi",         7, 0, input_port, },
159   { "uart@0_tx",   8, 0, input_port, },
160   { "uart@0_rx",   9, 0, input_port, },
161   { "uart@1_tx",  10, 0, input_port, },
162   { "uart@1_rx",  11, 0, input_port, },
163   { NULL, 0, 0, 0, },
164 };
165
166 static const char * const bfin_dmac_533_pmap[] =
167 {
168   "ppi@0", "sport@0", "sport@0", "sport@1", "sport@1", "spi",
169   "uart@0", "uart@0",
170 };
171
172 static const struct hw_port_descriptor bfin_dmac_533_ports[] =
173 {
174   { "ppi@0",       0, 0, input_port, },
175   { "sport@0_tx",  1, 0, input_port, },
176   { "sport@0_rx",  2, 0, input_port, },
177   { "sport@1_tx",  3, 0, input_port, },
178   { "sport@1_rx",  4, 0, input_port, },
179   { "spi",         5, 0, input_port, },
180   { "uart@0_tx",   6, 0, input_port, },
181   { "uart@0_rx",   7, 0, input_port, },
182   { NULL, 0, 0, 0, },
183 };
184
185 static const char * const bfin_dmac_537_pmap[] =
186 {
187   "ppi@0", "emac", "emac", "sport@0", "sport@0", "sport@1",
188   "sport@1", "spi", "uart@0", "uart@0", "uart@1", "uart@1",
189 };
190
191 static const struct hw_port_descriptor bfin_dmac_537_ports[] =
192 {
193   { "ppi@0",       0, 0, input_port, },
194   { "emac_rx",     1, 0, input_port, },
195   { "emac_tx",     2, 0, input_port, },
196   { "sport@0_tx",  3, 0, input_port, },
197   { "sport@0_rx",  4, 0, input_port, },
198   { "sport@1_tx",  5, 0, input_port, },
199   { "sport@1_rx",  6, 0, input_port, },
200   { "spi",         7, 0, input_port, },
201   { "uart@0_tx",   8, 0, input_port, },
202   { "uart@0_rx",   9, 0, input_port, },
203   { "uart@1_tx",  10, 0, input_port, },
204   { "uart@1_rx",  11, 0, input_port, },
205   { NULL, 0, 0, 0, },
206 };
207
208 static const char * const bfin_dmac0_538_pmap[] =
209 {
210   "ppi@0", "sport@0", "sport@0", "sport@1", "sport@1", "spi@0",
211   "uart@0", "uart@0",
212 };
213
214 static const struct hw_port_descriptor bfin_dmac0_538_ports[] =
215 {
216   { "ppi@0",       0, 0, input_port, },
217   { "sport@0_rx",  1, 0, input_port, },
218   { "sport@0_tx",  2, 0, input_port, },
219   { "sport@1_rx",  3, 0, input_port, },
220   { "sport@1_tx",  4, 0, input_port, },
221   { "spi@0",       5, 0, input_port, },
222   { "uart@0_rx",   6, 0, input_port, },
223   { "uart@0_tx",   7, 0, input_port, },
224   { NULL, 0, 0, 0, },
225 };
226
227 static const char * const bfin_dmac1_538_pmap[] =
228 {
229   "sport@2", "sport@2", "sport@3", "sport@3", NULL, NULL,
230   "spi@1", "spi@2", "uart@1", "uart@1", "uart@2", "uart@2",
231 };
232
233 static const struct hw_port_descriptor bfin_dmac1_538_ports[] =
234 {
235   { "sport@2_rx",  0, 0, input_port, },
236   { "sport@2_tx",  1, 0, input_port, },
237   { "sport@3_rx",  2, 0, input_port, },
238   { "sport@3_tx",  3, 0, input_port, },
239   { "spi@1",       6, 0, input_port, },
240   { "spi@2",       7, 0, input_port, },
241   { "uart@1_rx",   8, 0, input_port, },
242   { "uart@1_tx",   9, 0, input_port, },
243   { "uart@2_rx",  10, 0, input_port, },
244   { "uart@2_tx",  11, 0, input_port, },
245   { NULL, 0, 0, 0, },
246 };
247
248 static const char * const bfin_dmac0_54x_pmap[] =
249 {
250   "sport@0", "sport@0", "sport@1", "sport@1", "spi@0", "spi@1",
251   "uart2@0", "uart2@0", "uart2@1", "uart2@1", "atapi", "atapi",
252 };
253
254 static const struct hw_port_descriptor bfin_dmac0_54x_ports[] =
255 {
256   { "sport@0_rx",  0, 0, input_port, },
257   { "sport@0_tx",  1, 0, input_port, },
258   { "sport@1_rx",  2, 0, input_port, },
259   { "sport@1_tx",  3, 0, input_port, },
260   { "spi@0",       4, 0, input_port, },
261   { "spi@1",       5, 0, input_port, },
262   { "uart2@0_rx",  6, 0, input_port, },
263   { "uart2@0_tx",  7, 0, input_port, },
264   { "uart2@1_rx",  8, 0, input_port, },
265   { "uart2@1_tx",  9, 0, input_port, },
266   { "atapi",      10, 0, input_port, },
267   { "atapi",      11, 0, input_port, },
268   { NULL, 0, 0, 0, },
269 };
270
271 static const char * const bfin_dmac1_54x_pmap[] =
272 {
273   "eppi@0", "eppi@1", "eppi@2", "pixc", "pixc", "pixc",
274   "sport@2", "sport@2", "sport@3", "sport@3", "sdh",
275   "spi@2", "uart2@2", "uart2@2", "uart2@3", "uart2@3",
276 };
277
278 static const struct hw_port_descriptor bfin_dmac1_54x_ports[] =
279 {
280   { "eppi@0",      0, 0, input_port, },
281   { "eppi@1",      1, 0, input_port, },
282   { "eppi@2",      2, 0, input_port, },
283   { "pixc",        3, 0, input_port, },
284   { "pixc",        4, 0, input_port, },
285   { "pixc",        5, 0, input_port, },
286   { "sport@2_rx",  6, 0, input_port, },
287   { "sport@2_tx",  7, 0, input_port, },
288   { "sport@3_rx",  8, 0, input_port, },
289   { "sport@3_tx",  9, 0, input_port, },
290   { "sdh",        10, 0, input_port, },
291 /*{ "nfc",        10, 0, input_port, },*/
292   { "spi@2",      11, 0, input_port, },
293   { "uart2@2_rx", 12, 0, input_port, },
294   { "uart2@2_tx", 13, 0, input_port, },
295   { "uart2@3_rx", 14, 0, input_port, },
296   { "uart2@3_tx", 15, 0, input_port, },
297   { NULL, 0, 0, 0, },
298 };
299
300 static const char * const bfin_dmac0_561_pmap[] =
301 {
302   "sport@0", "sport@0", "sport@1", "sport@1", "spi", "uart@0", "uart@0",
303 };
304
305 static const struct hw_port_descriptor bfin_dmac0_561_ports[] =
306 {
307   { "sport@0_rx",  0, 0, input_port, },
308   { "sport@0_tx",  1, 0, input_port, },
309   { "sport@1_rx",  2, 0, input_port, },
310   { "sport@1_tx",  3, 0, input_port, },
311   { "spi@0",       4, 0, input_port, },
312   { "uart@0_rx",   5, 0, input_port, },
313   { "uart@0_tx",   6, 0, input_port, },
314   { NULL, 0, 0, 0, },
315 };
316
317 static const char * const bfin_dmac1_561_pmap[] =
318 {
319   "ppi@0", "ppi@1",
320 };
321
322 static const struct hw_port_descriptor bfin_dmac1_561_ports[] =
323 {
324   { "ppi@0",       0, 0, input_port, },
325   { "ppi@1",       1, 0, input_port, },
326   { NULL, 0, 0, 0, },
327 };
328
329 static const char * const bfin_dmac_59x_pmap[] =
330 {
331   "ppi@0", "sport@0", "sport@0", "sport@1", "sport@1", "spi@0",
332   "spi@1", "uart@0", "uart@0",
333 };
334
335 static const struct hw_port_descriptor bfin_dmac_59x_ports[] =
336 {
337   { "ppi@0",       0, 0, input_port, },
338   { "sport@0_tx",  1, 0, input_port, },
339   { "sport@0_rx",  2, 0, input_port, },
340   { "sport@1_tx",  3, 0, input_port, },
341   { "sport@1_rx",  4, 0, input_port, },
342   { "spi@0",       5, 0, input_port, },
343   { "spi@1",       6, 0, input_port, },
344   { "uart@0_rx",   7, 0, input_port, },
345   { "uart@0_tx",   8, 0, input_port, },
346   { NULL, 0, 0, 0, },
347 };
348
349 static void
350 bfin_dmac_port_event (struct hw *me, int my_port, struct hw *source,
351                       int source_port, int level)
352 {
353   SIM_DESC sd = hw_system (me);
354   struct bfin_dmac *dmac = hw_data (me);
355   struct hw *dma = hw_child (me);
356
357   while (dma)
358     {
359       bu16 pmap;
360       sim_hw_io_read_buffer (sd, dma, &pmap, 0, 0x2c, sizeof (pmap));
361       pmap >>= 12;
362       if (pmap == my_port)
363         break;
364       dma = hw_sibling (dma);
365     }
366
367   if (!dma)
368     hw_abort (me, "no valid dma mapping found for %s", dmac->pmap[my_port]);
369
370   /* Have the DMA channel raise its interrupt to the SIC.  */
371   hw_port_event (dma, 0, 1);
372 }
373
374 static void
375 bfin_dmac_finish (struct hw *me)
376 {
377   struct bfin_dmac *dmac;
378   unsigned int dmac_num = dv_get_bus_num (me);
379
380   dmac = HW_ZALLOC (me, struct bfin_dmac);
381
382   set_hw_data (me, dmac);
383   set_hw_port_event (me, bfin_dmac_port_event);
384
385   /* Initialize the DMA Controller.  */
386   if (hw_find_property (me, "type") == NULL)
387     hw_abort (me, "Missing \"type\" property");
388
389   switch (hw_find_integer_property (me, "type"))
390     {
391     case 500 ... 509:
392       if (dmac_num != 0)
393         hw_abort (me, "this Blackfin only has a DMAC0");
394       dmac->pmap = bfin_dmac_50x_pmap;
395       dmac->pmap_count = ARRAY_SIZE (bfin_dmac_50x_pmap);
396       set_hw_ports (me, bfin_dmac_50x_ports);
397       break;
398     case 510 ... 519:
399       if (dmac_num != 0)
400         hw_abort (me, "this Blackfin only has a DMAC0");
401       dmac->pmap = bfin_dmac_51x_pmap;
402       dmac->pmap_count = ARRAY_SIZE (bfin_dmac_51x_pmap);
403       set_hw_ports (me, bfin_dmac_51x_ports);
404       break;
405     case 522 ... 527:
406       if (dmac_num != 0)
407         hw_abort (me, "this Blackfin only has a DMAC0");
408       dmac->pmap = bfin_dmac_52x_pmap;
409       dmac->pmap_count = ARRAY_SIZE (bfin_dmac_52x_pmap);
410       set_hw_ports (me, bfin_dmac_52x_ports);
411       break;
412     case 531 ... 533:
413       if (dmac_num != 0)
414         hw_abort (me, "this Blackfin only has a DMAC0");
415       dmac->pmap = bfin_dmac_533_pmap;
416       dmac->pmap_count = ARRAY_SIZE (bfin_dmac_533_pmap);
417       set_hw_ports (me, bfin_dmac_533_ports);
418       break;
419     case 534:
420     case 536:
421     case 537:
422       if (dmac_num != 0)
423         hw_abort (me, "this Blackfin only has a DMAC0");
424       dmac->pmap = bfin_dmac_537_pmap;
425       dmac->pmap_count = ARRAY_SIZE (bfin_dmac_537_pmap);
426       set_hw_ports (me, bfin_dmac_537_ports);
427       break;
428     case 538 ... 539:
429       switch (dmac_num)
430         {
431         case 0:
432           dmac->pmap = bfin_dmac0_538_pmap;
433           dmac->pmap_count = ARRAY_SIZE (bfin_dmac0_538_pmap);
434           set_hw_ports (me, bfin_dmac0_538_ports);
435           break;
436         case 1:
437           dmac->pmap = bfin_dmac1_538_pmap;
438           dmac->pmap_count = ARRAY_SIZE (bfin_dmac1_538_pmap);
439           set_hw_ports (me, bfin_dmac1_538_ports);
440           break;
441         default:
442           hw_abort (me, "this Blackfin only has a DMAC0 & DMAC1");
443         }
444       break;
445     case 540 ... 549:
446       switch (dmac_num)
447         {
448         case 0:
449           dmac->pmap = bfin_dmac0_54x_pmap;
450           dmac->pmap_count = ARRAY_SIZE (bfin_dmac0_54x_pmap);
451           set_hw_ports (me, bfin_dmac0_54x_ports);
452           break;
453         case 1:
454           dmac->pmap = bfin_dmac1_54x_pmap;
455           dmac->pmap_count = ARRAY_SIZE (bfin_dmac1_54x_pmap);
456           set_hw_ports (me, bfin_dmac1_54x_ports);
457           break;
458         default:
459           hw_abort (me, "this Blackfin only has a DMAC0 & DMAC1");
460         }
461       break;
462     case 561:
463       switch (dmac_num)
464         {
465         case 0:
466           dmac->pmap = bfin_dmac0_561_pmap;
467           dmac->pmap_count = ARRAY_SIZE (bfin_dmac0_561_pmap);
468           set_hw_ports (me, bfin_dmac0_561_ports);
469           break;
470         case 1:
471           dmac->pmap = bfin_dmac1_561_pmap;
472           dmac->pmap_count = ARRAY_SIZE (bfin_dmac1_561_pmap);
473           set_hw_ports (me, bfin_dmac1_561_ports);
474           break;
475         default:
476           hw_abort (me, "this Blackfin only has a DMAC0 & DMAC1");
477         }
478       break;
479     case 590 ... 599:
480       if (dmac_num != 0)
481         hw_abort (me, "this Blackfin only has a DMAC0");
482       dmac->pmap = bfin_dmac_59x_pmap;
483       dmac->pmap_count = ARRAY_SIZE (bfin_dmac_59x_pmap);
484       set_hw_ports (me, bfin_dmac_59x_ports);
485       break;
486     default:
487       hw_abort (me, "no support for DMAC on this Blackfin model yet");
488     }
489 }
490
491 const struct hw_descriptor dv_bfin_dmac_descriptor[] =
492 {
493   {"bfin_dmac", bfin_dmac_finish,},
494   {NULL, NULL},
495 };