sim: bfin: respect the port level on signals to the SIC
[binutils-gdb.git] / sim / bfin / dv-bfin_sic.c
1 /* Blackfin System Interrupt Controller (SIC) model.
2
3 Copyright (C) 2010-2011 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 #include "config.h"
22
23 #include "sim-main.h"
24 #include "devices.h"
25 #include "dv-bfin_sic.h"
26 #include "dv-bfin_cec.h"
27
28 struct bfin_sic
29 {
30 /* We assume first element is the base. */
31 bu32 base;
32
33 /* Order after here is important -- matches hardware MMR layout. */
34 bu16 BFIN_MMR_16(swrst);
35 bu16 BFIN_MMR_16(syscr);
36 bu16 BFIN_MMR_16(rvect); /* XXX: BF59x has a 32bit AUX_REVID here. */
37 union {
38 struct {
39 bu32 imask0;
40 bu32 iar0, iar1, iar2, iar3;
41 bu32 isr0, iwr0;
42 bu32 _pad0[9];
43 bu32 imask1;
44 bu32 iar4, iar5, iar6, iar7;
45 bu32 isr1, iwr1;
46 } bf52x;
47 struct {
48 bu32 imask;
49 bu32 iar0, iar1, iar2, iar3;
50 bu32 isr, iwr;
51 } bf537;
52 struct {
53 bu32 imask0, imask1, imask2;
54 bu32 isr0, isr1, isr2;
55 bu32 iwr0, iwr1, iwr2;
56 bu32 iar0, iar1, iar2, iar3;
57 bu32 iar4, iar5, iar6, iar7;
58 bu32 iar8, iar9, iar10, iar11;
59 } bf54x;
60 struct {
61 bu32 imask0, imask1;
62 bu32 iar0, iar1, iar2, iar3;
63 bu32 iar4, iar5, iar6, iar7;
64 bu32 isr0, isr1;
65 bu32 iwr0, iwr1;
66 } bf561;
67 };
68 };
69 #define mmr_base() offsetof(struct bfin_sic, swrst)
70 #define mmr_offset(mmr) (offsetof(struct bfin_sic, mmr) - mmr_base())
71 #define mmr_idx(mmr) (mmr_offset (mmr) / 4)
72
73 static const char * const bf52x_mmr_names[] =
74 {
75 "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IAR0", "SIC_IAR1",
76 "SIC_IAR2", "SIC_IAR3", "SIC_ISR0", "SIC_IWR0",
77 [mmr_idx (bf52x.imask1)] = "SIC_IMASK1", "SIC_IAR4", "SIC_IAR5",
78 "SIC_IAR6", "SIC_IAR7", "SIC_ISR1", "SIC_IWR1",
79 };
80 static const char * const bf537_mmr_names[] =
81 {
82 "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK", "SIC_IAR0", "SIC_IAR1",
83 "SIC_IAR2", "SIC_IAR3", "SIC_ISR", "SIC_IWR",
84 };
85 static const char * const bf54x_mmr_names[] =
86 {
87 "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1", "SIC_IMASK2",
88 "SIC_ISR0", "SIC_ISR1", "SIC_ISR2", "SIC_IWR0", "SIC_IWR1", "SIC_IWR2",
89 "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
90 "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
91 "SIC_IAR8", "SIC_IAR9", "SIC_IAR10", "SIC_IAR11",
92 };
93 static const char * const bf561_mmr_names[] =
94 {
95 "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1",
96 "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
97 "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
98 "SIC_ISR0", "SIC_ISR1", "SIC_IWR0", "SIC_IWR1",
99 };
100 static const char * const *mmr_names;
101 #define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
102
103 static void
104 bfin_sic_forward_interrupts (struct hw *me, bu32 *isr, bu32 *imask, bu32 *iar)
105 {
106 int my_port;
107 bu32 ipend;
108
109 /* Process pending and unmasked interrupts. */
110 ipend = *isr & *imask;
111
112 /* Usually none are pending unmasked, so avoid bit twiddling. */
113 if (!ipend)
114 return;
115
116 for (my_port = 0; my_port < 32; ++my_port)
117 {
118 bu32 iar_idx, iar_off, iar_val;
119 bu32 bit = (1 << my_port);
120
121 /* This bit isn't pending, so check next one. */
122 if (!(ipend & bit))
123 continue;
124
125 /* The IAR registers map the System input to the Core output.
126 Every 4 bits in the IAR are used to map to IVG{7..15}. */
127 iar_idx = my_port / 8;
128 iar_off = (my_port % 8) * 4;
129 iar_val = (iar[iar_idx] & (0xf << iar_off)) >> iar_off;
130 HW_TRACE ((me, "forwarding int %i to CEC", IVG7 + iar_val));
131 hw_port_event (me, IVG7 + iar_val, 1);
132 }
133 }
134
135 static void
136 bfin_sic_52x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
137 {
138 bfin_sic_forward_interrupts (me, &sic->bf52x.isr0, &sic->bf52x.imask0, &sic->bf52x.iar0);
139 bfin_sic_forward_interrupts (me, &sic->bf52x.isr1, &sic->bf52x.imask1, &sic->bf52x.iar4);
140 }
141
142 static unsigned
143 bfin_sic_52x_io_write_buffer (struct hw *me, const void *source, int space,
144 address_word addr, unsigned nr_bytes)
145 {
146 struct bfin_sic *sic = hw_data (me);
147 bu32 mmr_off;
148 bu32 value;
149 bu16 *value16p;
150 bu32 *value32p;
151 void *valuep;
152
153 if (nr_bytes == 4)
154 value = dv_load_4 (source);
155 else
156 value = dv_load_2 (source);
157
158 mmr_off = addr - sic->base;
159 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
160 value16p = valuep;
161 value32p = valuep;
162
163 HW_TRACE_WRITE ();
164
165 /* XXX: Discard all SIC writes for now. */
166 switch (mmr_off)
167 {
168 case mmr_offset(swrst):
169 /* XXX: This should trigger a software reset ... */
170 break;
171 case mmr_offset(syscr):
172 /* XXX: what to do ... */
173 break;
174 case mmr_offset(bf52x.imask0):
175 case mmr_offset(bf52x.imask1):
176 bfin_sic_52x_forward_interrupts (me, sic);
177 *value32p = value;
178 break;
179 case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
180 case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
181 case mmr_offset(bf52x.iwr0):
182 case mmr_offset(bf52x.iwr1):
183 *value32p = value;
184 break;
185 case mmr_offset(bf52x.isr0):
186 case mmr_offset(bf52x.isr1):
187 /* ISR is read-only. */
188 break;
189 default:
190 /* XXX: Should discard other writes. */
191 ;
192 }
193
194 return nr_bytes;
195 }
196
197 static unsigned
198 bfin_sic_52x_io_read_buffer (struct hw *me, void *dest, int space,
199 address_word addr, unsigned nr_bytes)
200 {
201 struct bfin_sic *sic = hw_data (me);
202 bu32 mmr_off;
203 bu16 *value16p;
204 bu32 *value32p;
205 void *valuep;
206
207 mmr_off = addr - sic->base;
208 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
209 value16p = valuep;
210 value32p = valuep;
211
212 HW_TRACE_READ ();
213
214 switch (mmr_off)
215 {
216 case mmr_offset(swrst):
217 case mmr_offset(syscr):
218 case mmr_offset(rvect):
219 dv_store_2 (dest, *value16p);
220 break;
221 case mmr_offset(bf52x.imask0):
222 case mmr_offset(bf52x.imask1):
223 case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
224 case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
225 case mmr_offset(bf52x.iwr0):
226 case mmr_offset(bf52x.iwr1):
227 case mmr_offset(bf52x.isr0):
228 case mmr_offset(bf52x.isr1):
229 dv_store_4 (dest, *value32p);
230 break;
231 default:
232 if (nr_bytes == 2)
233 dv_store_2 (dest, 0);
234 else
235 dv_store_4 (dest, 0);
236 break;
237 }
238
239 return nr_bytes;
240 }
241
242 static void
243 bfin_sic_537_forward_interrupts (struct hw *me, struct bfin_sic *sic)
244 {
245 bfin_sic_forward_interrupts (me, &sic->bf537.isr, &sic->bf537.imask, &sic->bf537.iar0);
246 }
247
248 static unsigned
249 bfin_sic_537_io_write_buffer (struct hw *me, const void *source, int space,
250 address_word addr, unsigned nr_bytes)
251 {
252 struct bfin_sic *sic = hw_data (me);
253 bu32 mmr_off;
254 bu32 value;
255 bu16 *value16p;
256 bu32 *value32p;
257 void *valuep;
258
259 if (nr_bytes == 4)
260 value = dv_load_4 (source);
261 else
262 value = dv_load_2 (source);
263
264 mmr_off = addr - sic->base;
265 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
266 value16p = valuep;
267 value32p = valuep;
268
269 HW_TRACE_WRITE ();
270
271 /* XXX: Discard all SIC writes for now. */
272 switch (mmr_off)
273 {
274 case mmr_offset(swrst):
275 /* XXX: This should trigger a software reset ... */
276 break;
277 case mmr_offset(syscr):
278 /* XXX: what to do ... */
279 break;
280 case mmr_offset(bf537.imask):
281 bfin_sic_537_forward_interrupts (me, sic);
282 *value32p = value;
283 break;
284 case mmr_offset(bf537.iar0):
285 case mmr_offset(bf537.iar1):
286 case mmr_offset(bf537.iar2):
287 case mmr_offset(bf537.iar3):
288 case mmr_offset(bf537.iwr):
289 *value32p = value;
290 break;
291 case mmr_offset(bf537.isr):
292 /* ISR is read-only. */
293 break;
294 default:
295 /* XXX: Should discard other writes. */
296 ;
297 }
298
299 return nr_bytes;
300 }
301
302 static unsigned
303 bfin_sic_537_io_read_buffer (struct hw *me, void *dest, int space,
304 address_word addr, unsigned nr_bytes)
305 {
306 struct bfin_sic *sic = hw_data (me);
307 bu32 mmr_off;
308 bu16 *value16p;
309 bu32 *value32p;
310 void *valuep;
311
312 mmr_off = addr - sic->base;
313 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
314 value16p = valuep;
315 value32p = valuep;
316
317 HW_TRACE_READ ();
318
319 switch (mmr_off)
320 {
321 case mmr_offset(swrst):
322 case mmr_offset(syscr):
323 case mmr_offset(rvect):
324 dv_store_2 (dest, *value16p);
325 break;
326 case mmr_offset(bf537.imask):
327 case mmr_offset(bf537.iar0):
328 case mmr_offset(bf537.iar1):
329 case mmr_offset(bf537.iar2):
330 case mmr_offset(bf537.iar3):
331 case mmr_offset(bf537.isr):
332 case mmr_offset(bf537.iwr):
333 dv_store_4 (dest, *value32p);
334 break;
335 default:
336 if (nr_bytes == 2)
337 dv_store_2 (dest, 0);
338 else
339 dv_store_4 (dest, 0);
340 break;
341 }
342
343 return nr_bytes;
344 }
345
346 static void
347 bfin_sic_54x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
348 {
349 bfin_sic_forward_interrupts (me, &sic->bf54x.isr0, &sic->bf54x.imask0, &sic->bf54x.iar0);
350 bfin_sic_forward_interrupts (me, &sic->bf54x.isr1, &sic->bf54x.imask1, &sic->bf54x.iar4);
351 bfin_sic_forward_interrupts (me, &sic->bf54x.isr2, &sic->bf54x.imask2, &sic->bf54x.iar8);
352 }
353
354 static unsigned
355 bfin_sic_54x_io_write_buffer (struct hw *me, const void *source, int space,
356 address_word addr, unsigned nr_bytes)
357 {
358 struct bfin_sic *sic = hw_data (me);
359 bu32 mmr_off;
360 bu32 value;
361 bu16 *value16p;
362 bu32 *value32p;
363 void *valuep;
364
365 if (nr_bytes == 4)
366 value = dv_load_4 (source);
367 else
368 value = dv_load_2 (source);
369
370 mmr_off = addr - sic->base;
371 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
372 value16p = valuep;
373 value32p = valuep;
374
375 HW_TRACE_WRITE ();
376
377 /* XXX: Discard all SIC writes for now. */
378 switch (mmr_off)
379 {
380 case mmr_offset(swrst):
381 /* XXX: This should trigger a software reset ... */
382 break;
383 case mmr_offset(syscr):
384 /* XXX: what to do ... */
385 break;
386 case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
387 bfin_sic_54x_forward_interrupts (me, sic);
388 *value32p = value;
389 break;
390 case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
391 case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
392 *value32p = value;
393 break;
394 case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
395 /* ISR is read-only. */
396 break;
397 default:
398 /* XXX: Should discard other writes. */
399 ;
400 }
401
402 return nr_bytes;
403 }
404
405 static unsigned
406 bfin_sic_54x_io_read_buffer (struct hw *me, void *dest, int space,
407 address_word addr, unsigned nr_bytes)
408 {
409 struct bfin_sic *sic = hw_data (me);
410 bu32 mmr_off;
411 bu16 *value16p;
412 bu32 *value32p;
413 void *valuep;
414
415 mmr_off = addr - sic->base;
416 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
417 value16p = valuep;
418 value32p = valuep;
419
420 HW_TRACE_READ ();
421
422 switch (mmr_off)
423 {
424 case mmr_offset(swrst):
425 case mmr_offset(syscr):
426 case mmr_offset(rvect):
427 dv_store_2 (dest, *value16p);
428 break;
429 case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
430 case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
431 case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
432 case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
433 dv_store_4 (dest, *value32p);
434 break;
435 default:
436 if (nr_bytes == 2)
437 dv_store_2 (dest, 0);
438 else
439 dv_store_4 (dest, 0);
440 break;
441 }
442
443 return nr_bytes;
444 }
445
446 static void
447 bfin_sic_561_forward_interrupts (struct hw *me, struct bfin_sic *sic)
448 {
449 bfin_sic_forward_interrupts (me, &sic->bf561.isr0, &sic->bf561.imask0, &sic->bf561.iar0);
450 bfin_sic_forward_interrupts (me, &sic->bf561.isr1, &sic->bf561.imask1, &sic->bf561.iar4);
451 }
452
453 static unsigned
454 bfin_sic_561_io_write_buffer (struct hw *me, const void *source, int space,
455 address_word addr, unsigned nr_bytes)
456 {
457 struct bfin_sic *sic = hw_data (me);
458 bu32 mmr_off;
459 bu32 value;
460 bu16 *value16p;
461 bu32 *value32p;
462 void *valuep;
463
464 if (nr_bytes == 4)
465 value = dv_load_4 (source);
466 else
467 value = dv_load_2 (source);
468
469 mmr_off = addr - sic->base;
470 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
471 value16p = valuep;
472 value32p = valuep;
473
474 HW_TRACE_WRITE ();
475
476 /* XXX: Discard all SIC writes for now. */
477 switch (mmr_off)
478 {
479 case mmr_offset(swrst):
480 /* XXX: This should trigger a software reset ... */
481 break;
482 case mmr_offset(syscr):
483 /* XXX: what to do ... */
484 break;
485 case mmr_offset(bf561.imask0):
486 case mmr_offset(bf561.imask1):
487 bfin_sic_561_forward_interrupts (me, sic);
488 *value32p = value;
489 break;
490 case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
491 case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
492 case mmr_offset(bf561.iwr0):
493 case mmr_offset(bf561.iwr1):
494 *value32p = value;
495 break;
496 case mmr_offset(bf561.isr0):
497 case mmr_offset(bf561.isr1):
498 /* ISR is read-only. */
499 break;
500 default:
501 /* XXX: Should discard other writes. */
502 ;
503 }
504
505 return nr_bytes;
506 }
507
508 static unsigned
509 bfin_sic_561_io_read_buffer (struct hw *me, void *dest, int space,
510 address_word addr, unsigned nr_bytes)
511 {
512 struct bfin_sic *sic = hw_data (me);
513 bu32 mmr_off;
514 bu16 *value16p;
515 bu32 *value32p;
516 void *valuep;
517
518 mmr_off = addr - sic->base;
519 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
520 value16p = valuep;
521 value32p = valuep;
522
523 HW_TRACE_READ ();
524
525 switch (mmr_off)
526 {
527 case mmr_offset(swrst):
528 case mmr_offset(syscr):
529 case mmr_offset(rvect):
530 dv_store_2 (dest, *value16p);
531 break;
532 case mmr_offset(bf561.imask0):
533 case mmr_offset(bf561.imask1):
534 case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
535 case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
536 case mmr_offset(bf561.iwr0):
537 case mmr_offset(bf561.iwr1):
538 case mmr_offset(bf561.isr0):
539 case mmr_offset(bf561.isr1):
540 dv_store_4 (dest, *value32p);
541 break;
542 default:
543 if (nr_bytes == 2)
544 dv_store_2 (dest, 0);
545 else
546 dv_store_4 (dest, 0);
547 break;
548 }
549
550 return nr_bytes;
551 }
552
553 /* XXX: This doesn't handle DMA<->peripheral mappings. */
554 #define BFIN_SIC_TO_CEC_PORTS \
555 { "ivg7", IVG7, 0, output_port, }, \
556 { "ivg8", IVG8, 0, output_port, }, \
557 { "ivg9", IVG9, 0, output_port, }, \
558 { "ivg10", IVG10, 0, output_port, }, \
559 { "ivg11", IVG11, 0, output_port, }, \
560 { "ivg12", IVG12, 0, output_port, }, \
561 { "ivg13", IVG13, 0, output_port, }, \
562 { "ivg14", IVG14, 0, output_port, }, \
563 { "ivg15", IVG15, 0, output_port, },
564
565 /* Give each SIC its own base to make it easier to extract the pin at
566 runtime. The pin is used as its bit position in the SIC MMRs. */
567 #define ENC(sic, pin) (((sic) << 8) + (pin))
568 #define DEC_PIN(pin) ((pin) % 0x100)
569 #define DEC_SIC(pin) ((pin) >> 8)
570
571 static const struct hw_port_descriptor bfin_sic_50x_ports[] =
572 {
573 BFIN_SIC_TO_CEC_PORTS
574 /* SIC0 */
575 { "pll", ENC(0, 0), 0, input_port, },
576 { "dma_stat", ENC(0, 1), 0, input_port, },
577 { "ppi@0", ENC(0, 2), 0, input_port, },
578 { "sport@0_stat", ENC(0, 3), 0, input_port, },
579 { "sport@1_stat", ENC(0, 4), 0, input_port, },
580 { "uart2@0_stat", ENC(0, 5), 0, input_port, },
581 { "uart2@1_stat", ENC(0, 6), 0, input_port, },
582 { "spi@0", ENC(0, 7), 0, input_port, },
583 { "spi@1", ENC(0, 8), 0, input_port, },
584 { "can_stat", ENC(0, 9), 0, input_port, },
585 { "rsi_int0", ENC(0, 10), 0, input_port, },
586 /*{ "reserved", ENC(0, 11), 0, input_port, },*/
587 { "counter@0", ENC(0, 12), 0, input_port, },
588 { "counter@1", ENC(0, 13), 0, input_port, },
589 { "dma@0", ENC(0, 14), 0, input_port, },
590 { "dma@1", ENC(0, 15), 0, input_port, },
591 { "dma@2", ENC(0, 16), 0, input_port, },
592 { "dma@3", ENC(0, 17), 0, input_port, },
593 { "dma@4", ENC(0, 18), 0, input_port, },
594 { "dma@5", ENC(0, 19), 0, input_port, },
595 { "dma@6", ENC(0, 20), 0, input_port, },
596 { "dma@7", ENC(0, 21), 0, input_port, },
597 { "dma@8", ENC(0, 22), 0, input_port, },
598 { "dma@9", ENC(0, 23), 0, input_port, },
599 { "dma@10", ENC(0, 24), 0, input_port, },
600 { "dma@11", ENC(0, 25), 0, input_port, },
601 { "can_rx", ENC(0, 26), 0, input_port, },
602 { "can_tx", ENC(0, 27), 0, input_port, },
603 { "twi@0", ENC(0, 28), 0, input_port, },
604 { "portf_irq_a", ENC(0, 29), 0, input_port, },
605 { "portf_irq_b", ENC(0, 30), 0, input_port, },
606 /*{ "reserved", ENC(0, 31), 0, input_port, },*/
607 /* SIC1 */
608 { "gptimer@0", ENC(1, 0), 0, input_port, },
609 { "gptimer@1", ENC(1, 1), 0, input_port, },
610 { "gptimer@2", ENC(1, 2), 0, input_port, },
611 { "gptimer@3", ENC(1, 3), 0, input_port, },
612 { "gptimer@4", ENC(1, 4), 0, input_port, },
613 { "gptimer@5", ENC(1, 5), 0, input_port, },
614 { "gptimer@6", ENC(1, 6), 0, input_port, },
615 { "gptimer@7", ENC(1, 7), 0, input_port, },
616 { "portg_irq_a", ENC(1, 8), 0, input_port, },
617 { "portg_irq_b", ENC(1, 9), 0, input_port, },
618 { "mdma@0", ENC(1, 10), 0, input_port, },
619 { "mdma@1", ENC(1, 11), 0, input_port, },
620 { "wdog", ENC(1, 12), 0, input_port, },
621 { "porth_irq_a", ENC(1, 13), 0, input_port, },
622 { "porth_irq_b", ENC(1, 14), 0, input_port, },
623 { "acm_stat", ENC(1, 15), 0, input_port, },
624 { "acm_int", ENC(1, 16), 0, input_port, },
625 /*{ "reserved", ENC(1, 17), 0, input_port, },*/
626 /*{ "reserved", ENC(1, 18), 0, input_port, },*/
627 { "pwm@0_trip", ENC(1, 19), 0, input_port, },
628 { "pwm@0_sync", ENC(1, 20), 0, input_port, },
629 { "pwm@1_trip", ENC(1, 21), 0, input_port, },
630 { "pwm@1_sync", ENC(1, 22), 0, input_port, },
631 { "rsi_int1", ENC(1, 23), 0, input_port, },
632 { NULL, 0, 0, 0, },
633 };
634
635 static const struct hw_port_descriptor bfin_sic_51x_ports[] =
636 {
637 BFIN_SIC_TO_CEC_PORTS
638 /* SIC0 */
639 { "pll", ENC(0, 0), 0, input_port, },
640 { "dma_stat", ENC(0, 1), 0, input_port, },
641 { "dmar0_block", ENC(0, 2), 0, input_port, },
642 { "dmar1_block", ENC(0, 3), 0, input_port, },
643 { "dmar0_over", ENC(0, 4), 0, input_port, },
644 { "dmar1_over", ENC(0, 5), 0, input_port, },
645 { "ppi@0", ENC(0, 6), 0, input_port, },
646 { "emac_stat", ENC(0, 7), 0, input_port, },
647 { "sport@0_stat", ENC(0, 8), 0, input_port, },
648 { "sport@1_stat", ENC(0, 9), 0, input_port, },
649 { "ptp_err", ENC(0, 10), 0, input_port, },
650 /*{ "reserved", ENC(0, 11), 0, input_port, },*/
651 { "uart@0_stat", ENC(0, 12), 0, input_port, },
652 { "uart@1_stat", ENC(0, 13), 0, input_port, },
653 { "rtc", ENC(0, 14), 0, input_port, },
654 { "dma@0", ENC(0, 15), 0, input_port, },
655 { "dma@3", ENC(0, 16), 0, input_port, },
656 { "dma@4", ENC(0, 17), 0, input_port, },
657 { "dma@5", ENC(0, 18), 0, input_port, },
658 { "dma@6", ENC(0, 19), 0, input_port, },
659 { "twi@0", ENC(0, 20), 0, input_port, },
660 { "dma@7", ENC(0, 21), 0, input_port, },
661 { "dma@8", ENC(0, 22), 0, input_port, },
662 { "dma@9", ENC(0, 23), 0, input_port, },
663 { "dma@10", ENC(0, 24), 0, input_port, },
664 { "dma@11", ENC(0, 25), 0, input_port, },
665 { "otp", ENC(0, 26), 0, input_port, },
666 { "counter", ENC(0, 27), 0, input_port, },
667 { "dma@1", ENC(0, 28), 0, input_port, },
668 { "porth_irq_a", ENC(0, 29), 0, input_port, },
669 { "dma@2", ENC(0, 30), 0, input_port, },
670 { "porth_irq_b", ENC(0, 31), 0, input_port, },
671 /* SIC1 */
672 { "gptimer@0", ENC(1, 0), 0, input_port, },
673 { "gptimer@1", ENC(1, 1), 0, input_port, },
674 { "gptimer@2", ENC(1, 2), 0, input_port, },
675 { "gptimer@3", ENC(1, 3), 0, input_port, },
676 { "gptimer@4", ENC(1, 4), 0, input_port, },
677 { "gptimer@5", ENC(1, 5), 0, input_port, },
678 { "gptimer@6", ENC(1, 6), 0, input_port, },
679 { "gptimer@7", ENC(1, 7), 0, input_port, },
680 { "portg_irq_a", ENC(1, 8), 0, input_port, },
681 { "portg_irq_b", ENC(1, 9), 0, input_port, },
682 { "mdma@0", ENC(1, 10), 0, input_port, },
683 { "mdma@1", ENC(1, 11), 0, input_port, },
684 { "wdog", ENC(1, 12), 0, input_port, },
685 { "portf_irq_a", ENC(1, 13), 0, input_port, },
686 { "portf_irq_b", ENC(1, 14), 0, input_port, },
687 { "spi@0", ENC(1, 15), 0, input_port, },
688 { "spi@1", ENC(1, 16), 0, input_port, },
689 /*{ "reserved", ENC(1, 17), 0, input_port, },*/
690 /*{ "reserved", ENC(1, 18), 0, input_port, },*/
691 { "rsi_int0", ENC(1, 19), 0, input_port, },
692 { "rsi_int1", ENC(1, 20), 0, input_port, },
693 { "pwm_trip", ENC(1, 21), 0, input_port, },
694 { "pwm_sync", ENC(1, 22), 0, input_port, },
695 { "ptp_stat", ENC(1, 23), 0, input_port, },
696 { NULL, 0, 0, 0, },
697 };
698
699 static const struct hw_port_descriptor bfin_sic_52x_ports[] =
700 {
701 BFIN_SIC_TO_CEC_PORTS
702 /* SIC0 */
703 { "pll", ENC(0, 0), 0, input_port, },
704 { "dma_stat", ENC(0, 1), 0, input_port, },
705 { "dmar0_block", ENC(0, 2), 0, input_port, },
706 { "dmar1_block", ENC(0, 3), 0, input_port, },
707 { "dmar0_over", ENC(0, 4), 0, input_port, },
708 { "dmar1_over", ENC(0, 5), 0, input_port, },
709 { "ppi@0", ENC(0, 6), 0, input_port, },
710 { "emac_stat", ENC(0, 7), 0, input_port, },
711 { "sport@0_stat", ENC(0, 8), 0, input_port, },
712 { "sport@1_stat", ENC(0, 9), 0, input_port, },
713 /*{ "reserved", ENC(0, 10), 0, input_port, },*/
714 /*{ "reserved", ENC(0, 11), 0, input_port, },*/
715 { "uart@0_stat", ENC(0, 12), 0, input_port, },
716 { "uart@1_stat", ENC(0, 13), 0, input_port, },
717 { "rtc", ENC(0, 14), 0, input_port, },
718 { "dma@0", ENC(0, 15), 0, input_port, },
719 { "dma@3", ENC(0, 16), 0, input_port, },
720 { "dma@4", ENC(0, 17), 0, input_port, },
721 { "dma@5", ENC(0, 18), 0, input_port, },
722 { "dma@6", ENC(0, 19), 0, input_port, },
723 { "twi@0", ENC(0, 20), 0, input_port, },
724 { "dma@7", ENC(0, 21), 0, input_port, },
725 { "dma@8", ENC(0, 22), 0, input_port, },
726 { "dma@9", ENC(0, 23), 0, input_port, },
727 { "dma@10", ENC(0, 24), 0, input_port, },
728 { "dma@11", ENC(0, 25), 0, input_port, },
729 { "otp", ENC(0, 26), 0, input_port, },
730 { "counter", ENC(0, 27), 0, input_port, },
731 { "dma@1", ENC(0, 28), 0, input_port, },
732 { "porth_irq_a", ENC(0, 29), 0, input_port, },
733 { "dma@2", ENC(0, 30), 0, input_port, },
734 { "porth_irq_b", ENC(0, 31), 0, input_port, },
735 /* SIC1 */
736 { "gptimer@0", ENC(1, 0), 0, input_port, },
737 { "gptimer@1", ENC(1, 1), 0, input_port, },
738 { "gptimer@2", ENC(1, 2), 0, input_port, },
739 { "gptimer@3", ENC(1, 3), 0, input_port, },
740 { "gptimer@4", ENC(1, 4), 0, input_port, },
741 { "gptimer@5", ENC(1, 5), 0, input_port, },
742 { "gptimer@6", ENC(1, 6), 0, input_port, },
743 { "gptimer@7", ENC(1, 7), 0, input_port, },
744 { "portg_irq_a", ENC(1, 8), 0, input_port, },
745 { "portg_irq_b", ENC(1, 9), 0, input_port, },
746 { "mdma@0", ENC(1, 10), 0, input_port, },
747 { "mdma@1", ENC(1, 11), 0, input_port, },
748 { "wdog", ENC(1, 12), 0, input_port, },
749 { "portf_irq_a", ENC(1, 13), 0, input_port, },
750 { "portf_irq_b", ENC(1, 14), 0, input_port, },
751 { "spi@0", ENC(1, 15), 0, input_port, },
752 { "nfc_stat", ENC(1, 16), 0, input_port, },
753 { "hostdp_stat", ENC(1, 17), 0, input_port, },
754 { "hostdp_done", ENC(1, 18), 0, input_port, },
755 { "usb_int0", ENC(1, 20), 0, input_port, },
756 { "usb_int1", ENC(1, 21), 0, input_port, },
757 { "usb_int2", ENC(1, 22), 0, input_port, },
758 { NULL, 0, 0, 0, },
759 };
760
761 static void
762 bfin_sic_port_event (struct hw *me, bu32 *isr, bu32 bit, int level)
763 {
764 if (level)
765 *isr |= bit;
766 else
767 *isr &= ~bit;
768 }
769
770 static void
771 bfin_sic_52x_port_event (struct hw *me, int my_port, struct hw *source,
772 int source_port, int level)
773 {
774 struct bfin_sic *sic = hw_data (me);
775 bu32 idx = DEC_SIC (my_port);
776 bu32 pin = DEC_PIN (my_port);
777 bu32 bit = 1 << pin;
778
779 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
780 level, my_port, idx, pin));
781
782 /* SIC only exists to forward interrupts from the system to the CEC. */
783 switch (idx)
784 {
785 case 0: bfin_sic_port_event (me, &sic->bf52x.isr0, bit, level); break;
786 case 1: bfin_sic_port_event (me, &sic->bf52x.isr1, bit, level); break;
787 }
788
789 /* XXX: Handle SIC wakeup source ?
790 if (sic->bf52x.iwr0 & bit)
791 What to do ?;
792 if (sic->bf52x.iwr1 & bit)
793 What to do ?;
794 */
795
796 bfin_sic_52x_forward_interrupts (me, sic);
797 }
798
799 static const struct hw_port_descriptor bfin_sic_533_ports[] =
800 {
801 BFIN_SIC_TO_CEC_PORTS
802 { "pll", ENC(0, 0), 0, input_port, },
803 { "dma_stat", ENC(0, 1), 0, input_port, },
804 { "ppi@0", ENC(0, 2), 0, input_port, },
805 { "sport@0_stat", ENC(0, 3), 0, input_port, },
806 { "sport@1_stat", ENC(0, 4), 0, input_port, },
807 { "spi@0", ENC(0, 5), 0, input_port, },
808 { "uart@0_stat", ENC(0, 6), 0, input_port, },
809 { "rtc", ENC(0, 7), 0, input_port, },
810 { "dma@0", ENC(0, 8), 0, input_port, },
811 { "dma@1", ENC(0, 9), 0, input_port, },
812 { "dma@2", ENC(0, 10), 0, input_port, },
813 { "dma@3", ENC(0, 11), 0, input_port, },
814 { "dma@4", ENC(0, 12), 0, input_port, },
815 { "dma@5", ENC(0, 13), 0, input_port, },
816 { "dma@6", ENC(0, 14), 0, input_port, },
817 { "dma@7", ENC(0, 15), 0, input_port, },
818 { "gptimer@0", ENC(0, 16), 0, input_port, },
819 { "gptimer@1", ENC(0, 17), 0, input_port, },
820 { "gptimer@2", ENC(0, 18), 0, input_port, },
821 { "portf_irq_a", ENC(0, 19), 0, input_port, },
822 { "portf_irq_b", ENC(0, 20), 0, input_port, },
823 { "mdma@0", ENC(0, 21), 0, input_port, },
824 { "mdma@1", ENC(0, 22), 0, input_port, },
825 { "wdog", ENC(0, 23), 0, input_port, },
826 { NULL, 0, 0, 0, },
827 };
828
829 /* The encoding here is uglier due to multiple sources being muxed into
830 the same interrupt line. So give each pin an arbitrary "SIC" so that
831 the resulting id is unique across all ports. */
832 static const struct hw_port_descriptor bfin_sic_537_ports[] =
833 {
834 BFIN_SIC_TO_CEC_PORTS
835 { "pll", ENC(0, 0), 0, input_port, },
836 { "dma_stat", ENC(0, 1), 0, input_port, },
837 { "dmar0_block", ENC(1, 1), 0, input_port, },
838 { "dmar1_block", ENC(2, 1), 0, input_port, },
839 { "dmar0_over", ENC(3, 1), 0, input_port, },
840 { "dmar1_over", ENC(4, 1), 0, input_port, },
841 { "can_stat", ENC(0, 2), 0, input_port, },
842 { "emac_stat", ENC(1, 2), 0, input_port, },
843 { "sport@0_stat", ENC(2, 2), 0, input_port, },
844 { "sport@1_stat", ENC(3, 2), 0, input_port, },
845 { "ppi@0", ENC(4, 2), 0, input_port, },
846 { "spi@0", ENC(5, 2), 0, input_port, },
847 { "uart@0_stat", ENC(6, 2), 0, input_port, },
848 { "uart@1_stat", ENC(7, 2), 0, input_port, },
849 { "rtc", ENC(0, 3), 0, input_port, },
850 { "dma@0", ENC(0, 4), 0, input_port, },
851 { "dma@3", ENC(0, 5), 0, input_port, },
852 { "dma@4", ENC(0, 6), 0, input_port, },
853 { "dma@5", ENC(0, 7), 0, input_port, },
854 { "dma@6", ENC(0, 8), 0, input_port, },
855 { "twi@0", ENC(0, 9), 0, input_port, },
856 { "dma@7", ENC(0, 10), 0, input_port, },
857 { "dma@8", ENC(0, 11), 0, input_port, },
858 { "dma@9", ENC(0, 12), 0, input_port, },
859 { "dma@10", ENC(0, 13), 0, input_port, },
860 { "dma@11", ENC(0, 14), 0, input_port, },
861 { "can_rx", ENC(0, 15), 0, input_port, },
862 { "can_tx", ENC(0, 16), 0, input_port, },
863 { "dma@1", ENC(0, 17), 0, input_port, },
864 { "porth_irq_a", ENC(1, 17), 0, input_port, },
865 { "dma@2", ENC(0, 18), 0, input_port, },
866 { "porth_irq_b", ENC(1, 18), 0, input_port, },
867 { "gptimer@0", ENC(0, 19), 0, input_port, },
868 { "gptimer@1", ENC(0, 20), 0, input_port, },
869 { "gptimer@2", ENC(0, 21), 0, input_port, },
870 { "gptimer@3", ENC(0, 22), 0, input_port, },
871 { "gptimer@4", ENC(0, 23), 0, input_port, },
872 { "gptimer@5", ENC(0, 24), 0, input_port, },
873 { "gptimer@6", ENC(0, 25), 0, input_port, },
874 { "gptimer@7", ENC(0, 26), 0, input_port, },
875 { "portf_irq_a", ENC(0, 27), 0, input_port, },
876 { "portg_irq_a", ENC(1, 27), 0, input_port, },
877 { "portg_irq_b", ENC(0, 28), 0, input_port, },
878 { "mdma@0", ENC(0, 29), 0, input_port, },
879 { "mdma@1", ENC(0, 30), 0, input_port, },
880 { "wdog", ENC(0, 31), 0, input_port, },
881 { "portf_irq_b", ENC(1, 31), 0, input_port, },
882 { NULL, 0, 0, 0, },
883 };
884
885 static void
886 bfin_sic_537_port_event (struct hw *me, int my_port, struct hw *source,
887 int source_port, int level)
888 {
889 struct bfin_sic *sic = hw_data (me);
890 bu32 idx = DEC_SIC (my_port);
891 bu32 pin = DEC_PIN (my_port);
892 bu32 bit = 1 << pin;
893
894 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
895 level, my_port, idx, pin));
896
897 /* SIC only exists to forward interrupts from the system to the CEC. */
898 bfin_sic_port_event (me, &sic->bf537.isr, bit, level);
899
900 /* XXX: Handle SIC wakeup source ?
901 if (sic->bf537.iwr & bit)
902 What to do ?;
903 */
904
905 bfin_sic_537_forward_interrupts (me, sic);
906 }
907
908 static const struct hw_port_descriptor bfin_sic_538_ports[] =
909 {
910 BFIN_SIC_TO_CEC_PORTS
911 /* SIC0 */
912 { "pll", ENC(0, 0), 0, input_port, },
913 { "dmac@0_stat", ENC(0, 1), 0, input_port, },
914 { "ppi@0", ENC(0, 2), 0, input_port, },
915 { "sport@0_stat", ENC(0, 3), 0, input_port, },
916 { "sport@1_stat", ENC(0, 4), 0, input_port, },
917 { "spi@0", ENC(0, 5), 0, input_port, },
918 { "uart@0_stat", ENC(0, 6), 0, input_port, },
919 { "rtc", ENC(0, 7), 0, input_port, },
920 { "dma@0", ENC(0, 8), 0, input_port, },
921 { "dma@1", ENC(0, 9), 0, input_port, },
922 { "dma@2", ENC(0, 10), 0, input_port, },
923 { "dma@3", ENC(0, 11), 0, input_port, },
924 { "dma@4", ENC(0, 12), 0, input_port, },
925 { "dma@5", ENC(0, 13), 0, input_port, },
926 { "dma@6", ENC(0, 14), 0, input_port, },
927 { "dma@7", ENC(0, 15), 0, input_port, },
928 { "gptimer@0", ENC(0, 16), 0, input_port, },
929 { "gptimer@1", ENC(0, 17), 0, input_port, },
930 { "gptimer@2", ENC(0, 18), 0, input_port, },
931 { "portf_irq_a", ENC(0, 19), 0, input_port, },
932 { "portf_irq_b", ENC(0, 20), 0, input_port, },
933 { "mdma@0", ENC(0, 21), 0, input_port, },
934 { "mdma@1", ENC(0, 22), 0, input_port, },
935 { "wdog", ENC(0, 23), 0, input_port, },
936 { "dmac@1_stat", ENC(0, 24), 0, input_port, },
937 { "sport@2_stat", ENC(0, 25), 0, input_port, },
938 { "sport@3_stat", ENC(0, 26), 0, input_port, },
939 /*{ "reserved", ENC(0, 27), 0, input_port, },*/
940 { "spi@1", ENC(0, 28), 0, input_port, },
941 { "spi@2", ENC(0, 29), 0, input_port, },
942 { "uart@1_stat", ENC(0, 30), 0, input_port, },
943 { "uart@2_stat", ENC(0, 31), 0, input_port, },
944 /* SIC1 */
945 { "can_stat", ENC(1, 0), 0, input_port, },
946 { "dma@8", ENC(1, 1), 0, input_port, },
947 { "dma@9", ENC(1, 2), 0, input_port, },
948 { "dma@10", ENC(1, 3), 0, input_port, },
949 { "dma@11", ENC(1, 4), 0, input_port, },
950 { "dma@12", ENC(1, 5), 0, input_port, },
951 { "dma@13", ENC(1, 6), 0, input_port, },
952 { "dma@14", ENC(1, 7), 0, input_port, },
953 { "dma@15", ENC(1, 8), 0, input_port, },
954 { "dma@16", ENC(1, 9), 0, input_port, },
955 { "dma@17", ENC(1, 10), 0, input_port, },
956 { "dma@18", ENC(1, 11), 0, input_port, },
957 { "dma@19", ENC(1, 12), 0, input_port, },
958 { "twi@0", ENC(1, 13), 0, input_port, },
959 { "twi@1", ENC(1, 14), 0, input_port, },
960 { "can_rx", ENC(1, 15), 0, input_port, },
961 { "can_tx", ENC(1, 16), 0, input_port, },
962 { "mdma@2", ENC(1, 17), 0, input_port, },
963 { "mdma@3", ENC(1, 18), 0, input_port, },
964 { NULL, 0, 0, 0, },
965 };
966
967 static const struct hw_port_descriptor bfin_sic_54x_ports[] =
968 {
969 BFIN_SIC_TO_CEC_PORTS
970 /* SIC0 */
971 { "pll", ENC(0, 0), 0, input_port, },
972 { "dmac@0_stat", ENC(0, 1), 0, input_port, },
973 { "eppi@0", ENC(0, 2), 0, input_port, },
974 { "sport@0_stat", ENC(0, 3), 0, input_port, },
975 { "sport@1_stat", ENC(0, 4), 0, input_port, },
976 { "spi@0", ENC(0, 5), 0, input_port, },
977 { "uart2@0_stat", ENC(0, 6), 0, input_port, },
978 { "rtc", ENC(0, 7), 0, input_port, },
979 { "dma@12", ENC(0, 8), 0, input_port, },
980 { "dma@0", ENC(0, 9), 0, input_port, },
981 { "dma@1", ENC(0, 10), 0, input_port, },
982 { "dma@2", ENC(0, 11), 0, input_port, },
983 { "dma@3", ENC(0, 12), 0, input_port, },
984 { "dma@4", ENC(0, 13), 0, input_port, },
985 { "dma@6", ENC(0, 14), 0, input_port, },
986 { "dma@7", ENC(0, 15), 0, input_port, },
987 { "gptimer@8", ENC(0, 16), 0, input_port, },
988 { "gptimer@9", ENC(0, 17), 0, input_port, },
989 { "gptimer@10", ENC(0, 18), 0, input_port, },
990 { "pint@0", ENC(0, 19), 0, input_port, },
991 { "pint@1", ENC(0, 20), 0, input_port, },
992 { "mdma@0", ENC(0, 21), 0, input_port, },
993 { "mdma@1", ENC(0, 22), 0, input_port, },
994 { "wdog", ENC(0, 23), 0, input_port, },
995 { "dmac@1_stat", ENC(0, 24), 0, input_port, },
996 { "sport@2_stat", ENC(0, 25), 0, input_port, },
997 { "sport@3_stat", ENC(0, 26), 0, input_port, },
998 { "mxvr", ENC(0, 27), 0, input_port, },
999 { "spi@1", ENC(0, 28), 0, input_port, },
1000 { "spi@2", ENC(0, 29), 0, input_port, },
1001 { "uart2@1_stat", ENC(0, 30), 0, input_port, },
1002 { "uart2@2_stat", ENC(0, 31), 0, input_port, },
1003 /* SIC1 */
1004 { "can@0_stat", ENC(1, 0), 0, input_port, },
1005 { "dma@18", ENC(1, 1), 0, input_port, },
1006 { "dma@19", ENC(1, 2), 0, input_port, },
1007 { "dma@20", ENC(1, 3), 0, input_port, },
1008 { "dma@21", ENC(1, 4), 0, input_port, },
1009 { "dma@13", ENC(1, 5), 0, input_port, },
1010 { "dma@14", ENC(1, 6), 0, input_port, },
1011 { "dma@5", ENC(1, 7), 0, input_port, },
1012 { "dma@23", ENC(1, 8), 0, input_port, },
1013 { "dma@8", ENC(1, 9), 0, input_port, },
1014 { "dma@9", ENC(1, 10), 0, input_port, },
1015 { "dma@10", ENC(1, 11), 0, input_port, },
1016 { "dma@11", ENC(1, 12), 0, input_port, },
1017 { "twi@0", ENC(1, 13), 0, input_port, },
1018 { "twi@1", ENC(1, 14), 0, input_port, },
1019 { "can@0_rx", ENC(1, 15), 0, input_port, },
1020 { "can@0_tx", ENC(1, 16), 0, input_port, },
1021 { "mdma@2", ENC(1, 17), 0, input_port, },
1022 { "mdma@3", ENC(1, 18), 0, input_port, },
1023 { "mxvr_stat", ENC(1, 19), 0, input_port, },
1024 { "mxvr_message", ENC(1, 20), 0, input_port, },
1025 { "mxvr_packet", ENC(1, 21), 0, input_port, },
1026 { "eppi@1", ENC(1, 22), 0, input_port, },
1027 { "eppi@2", ENC(1, 23), 0, input_port, },
1028 { "uart2@3_stat", ENC(1, 24), 0, input_port, },
1029 { "hostdp", ENC(1, 25), 0, input_port, },
1030 /*{ "reserved", ENC(1, 26), 0, input_port, },*/
1031 { "pixc_stat", ENC(1, 27), 0, input_port, },
1032 { "nfc", ENC(1, 28), 0, input_port, },
1033 { "atapi", ENC(1, 29), 0, input_port, },
1034 { "can@1_stat", ENC(1, 30), 0, input_port, },
1035 { "dmar", ENC(1, 31), 0, input_port, },
1036 /* SIC2 */
1037 { "dma@15", ENC(2, 0), 0, input_port, },
1038 { "dma@16", ENC(2, 1), 0, input_port, },
1039 { "dma@17", ENC(2, 2), 0, input_port, },
1040 { "dma@22", ENC(2, 3), 0, input_port, },
1041 { "counter", ENC(2, 4), 0, input_port, },
1042 { "key", ENC(2, 5), 0, input_port, },
1043 { "can@1_rx", ENC(2, 6), 0, input_port, },
1044 { "can@1_tx", ENC(2, 7), 0, input_port, },
1045 { "sdh_mask0", ENC(2, 8), 0, input_port, },
1046 { "sdh_mask1", ENC(2, 9), 0, input_port, },
1047 /*{ "reserved", ENC(2, 10), 0, input_port, },*/
1048 { "usb_int0", ENC(2, 11), 0, input_port, },
1049 { "usb_int1", ENC(2, 12), 0, input_port, },
1050 { "usb_int2", ENC(2, 13), 0, input_port, },
1051 { "usb_dma", ENC(2, 14), 0, input_port, },
1052 { "otpsec", ENC(2, 15), 0, input_port, },
1053 /*{ "reserved", ENC(2, 16), 0, input_port, },*/
1054 /*{ "reserved", ENC(2, 17), 0, input_port, },*/
1055 /*{ "reserved", ENC(2, 18), 0, input_port, },*/
1056 /*{ "reserved", ENC(2, 19), 0, input_port, },*/
1057 /*{ "reserved", ENC(2, 20), 0, input_port, },*/
1058 /*{ "reserved", ENC(2, 21), 0, input_port, },*/
1059 { "gptimer@0", ENC(2, 22), 0, input_port, },
1060 { "gptimer@1", ENC(2, 23), 0, input_port, },
1061 { "gptimer@2", ENC(2, 24), 0, input_port, },
1062 { "gptimer@3", ENC(2, 25), 0, input_port, },
1063 { "gptimer@4", ENC(2, 26), 0, input_port, },
1064 { "gptimer@5", ENC(2, 27), 0, input_port, },
1065 { "gptimer@6", ENC(2, 28), 0, input_port, },
1066 { "gptimer@7", ENC(2, 29), 0, input_port, },
1067 { "pint2", ENC(2, 30), 0, input_port, },
1068 { "pint3", ENC(2, 31), 0, input_port, },
1069 { NULL, 0, 0, 0, },
1070 };
1071
1072 static void
1073 bfin_sic_54x_port_event (struct hw *me, int my_port, struct hw *source,
1074 int source_port, int level)
1075 {
1076 struct bfin_sic *sic = hw_data (me);
1077 bu32 idx = DEC_SIC (my_port);
1078 bu32 pin = DEC_PIN (my_port);
1079 bu32 bit = 1 << pin;
1080
1081 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
1082 level, my_port, idx, pin));
1083
1084 /* SIC only exists to forward interrupts from the system to the CEC. */
1085 switch (idx)
1086 {
1087 case 0: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
1088 case 1: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
1089 case 2: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
1090 }
1091
1092 /* XXX: Handle SIC wakeup source ?
1093 if (sic->bf54x.iwr0 & bit)
1094 What to do ?;
1095 if (sic->bf54x.iwr1 & bit)
1096 What to do ?;
1097 if (sic->bf54x.iwr2 & bit)
1098 What to do ?;
1099 */
1100
1101 bfin_sic_54x_forward_interrupts (me, sic);
1102 }
1103
1104 static const struct hw_port_descriptor bfin_sic_561_ports[] =
1105 {
1106 BFIN_SIC_TO_CEC_PORTS
1107 /* SIC0 */
1108 { "pll", ENC(0, 0), 0, input_port, },
1109 { "dmac@0_stat", ENC(0, 1), 0, input_port, },
1110 { "dmac@1_stat", ENC(0, 2), 0, input_port, },
1111 { "imdma_stat", ENC(0, 3), 0, input_port, },
1112 { "ppi@0", ENC(0, 4), 0, input_port, },
1113 { "ppi@1", ENC(0, 5), 0, input_port, },
1114 { "sport@0_stat", ENC(0, 6), 0, input_port, },
1115 { "sport@1_stat", ENC(0, 7), 0, input_port, },
1116 { "spi@0", ENC(0, 8), 0, input_port, },
1117 { "uart@0_stat", ENC(0, 9), 0, input_port, },
1118 /*{ "reserved", ENC(0, 10), 0, input_port, },*/
1119 { "dma@12", ENC(0, 11), 0, input_port, },
1120 { "dma@13", ENC(0, 12), 0, input_port, },
1121 { "dma@14", ENC(0, 13), 0, input_port, },
1122 { "dma@15", ENC(0, 14), 0, input_port, },
1123 { "dma@16", ENC(0, 15), 0, input_port, },
1124 { "dma@17", ENC(0, 16), 0, input_port, },
1125 { "dma@18", ENC(0, 17), 0, input_port, },
1126 { "dma@19", ENC(0, 18), 0, input_port, },
1127 { "dma@20", ENC(0, 19), 0, input_port, },
1128 { "dma@21", ENC(0, 20), 0, input_port, },
1129 { "dma@22", ENC(0, 21), 0, input_port, },
1130 { "dma@23", ENC(0, 22), 0, input_port, },
1131 { "dma@0", ENC(0, 23), 0, input_port, },
1132 { "dma@1", ENC(0, 24), 0, input_port, },
1133 { "dma@2", ENC(0, 25), 0, input_port, },
1134 { "dma@3", ENC(0, 26), 0, input_port, },
1135 { "dma@4", ENC(0, 27), 0, input_port, },
1136 { "dma@5", ENC(0, 28), 0, input_port, },
1137 { "dma@6", ENC(0, 29), 0, input_port, },
1138 { "dma@7", ENC(0, 30), 0, input_port, },
1139 { "dma@8", ENC(0, 31), 0, input_port, },
1140 /* SIC1 */
1141 { "dma@9", ENC(1, 0), 0, input_port, },
1142 { "dma@10", ENC(1, 1), 0, input_port, },
1143 { "dma@11", ENC(1, 2), 0, input_port, },
1144 { "gptimer@0", ENC(1, 3), 0, input_port, },
1145 { "gptimer@1", ENC(1, 4), 0, input_port, },
1146 { "gptimer@2", ENC(1, 5), 0, input_port, },
1147 { "gptimer@3", ENC(1, 6), 0, input_port, },
1148 { "gptimer@4", ENC(1, 7), 0, input_port, },
1149 { "gptimer@5", ENC(1, 8), 0, input_port, },
1150 { "gptimer@6", ENC(1, 9), 0, input_port, },
1151 { "gptimer@7", ENC(1, 10), 0, input_port, },
1152 { "gptimer@8", ENC(1, 11), 0, input_port, },
1153 { "gptimer@9", ENC(1, 12), 0, input_port, },
1154 { "gptimer@10", ENC(1, 13), 0, input_port, },
1155 { "gptimer@11", ENC(1, 14), 0, input_port, },
1156 { "portf_irq_a", ENC(1, 15), 0, input_port, },
1157 { "portf_irq_b", ENC(1, 16), 0, input_port, },
1158 { "portg_irq_a", ENC(1, 17), 0, input_port, },
1159 { "portg_irq_b", ENC(1, 18), 0, input_port, },
1160 { "porth_irq_a", ENC(1, 19), 0, input_port, },
1161 { "porth_irq_b", ENC(1, 20), 0, input_port, },
1162 { "mdma@0", ENC(1, 21), 0, input_port, },
1163 { "mdma@1", ENC(1, 22), 0, input_port, },
1164 { "mdma@2", ENC(1, 23), 0, input_port, },
1165 { "mdma@3", ENC(1, 24), 0, input_port, },
1166 { "imdma@0", ENC(1, 25), 0, input_port, },
1167 { "imdma@1", ENC(1, 26), 0, input_port, },
1168 { "wdog", ENC(1, 27), 0, input_port, },
1169 /*{ "reserved", ENC(1, 28), 0, input_port, },*/
1170 /*{ "reserved", ENC(1, 29), 0, input_port, },*/
1171 { "sup_irq_0", ENC(1, 30), 0, input_port, },
1172 { "sup_irq_1", ENC(1, 31), 0, input_port, },
1173 { NULL, 0, 0, 0, },
1174 };
1175
1176 static void
1177 bfin_sic_561_port_event (struct hw *me, int my_port, struct hw *source,
1178 int source_port, int level)
1179 {
1180 struct bfin_sic *sic = hw_data (me);
1181 bu32 idx = DEC_SIC (my_port);
1182 bu32 pin = DEC_PIN (my_port);
1183 bu32 bit = 1 << pin;
1184
1185 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
1186 level, my_port, idx, pin));
1187
1188 /* SIC only exists to forward interrupts from the system to the CEC. */
1189 switch (idx)
1190 {
1191 case 0: bfin_sic_port_event (me, &sic->bf561.isr0, bit, level); break;
1192 case 1: bfin_sic_port_event (me, &sic->bf561.isr1, bit, level); break;
1193 }
1194
1195 /* XXX: Handle SIC wakeup source ?
1196 if (sic->bf561.iwr0 & bit)
1197 What to do ?;
1198 if (sic->bf561.iwr1 & bit)
1199 What to do ?;
1200 */
1201
1202 bfin_sic_561_forward_interrupts (me, sic);
1203 }
1204
1205 static const struct hw_port_descriptor bfin_sic_59x_ports[] =
1206 {
1207 BFIN_SIC_TO_CEC_PORTS
1208 { "pll", ENC(0, 0), 0, input_port, },
1209 { "dma_stat", ENC(0, 1), 0, input_port, },
1210 { "ppi@0", ENC(0, 2), 0, input_port, },
1211 { "sport@0_stat", ENC(0, 3), 0, input_port, },
1212 { "sport@1_stat", ENC(0, 4), 0, input_port, },
1213 { "spi@0", ENC(0, 5), 0, input_port, },
1214 { "spi@1", ENC(0, 6), 0, input_port, },
1215 { "uart@0_stat", ENC(0, 7), 0, input_port, },
1216 { "dma@0", ENC(0, 8), 0, input_port, },
1217 { "dma@1", ENC(0, 9), 0, input_port, },
1218 { "dma@2", ENC(0, 10), 0, input_port, },
1219 { "dma@3", ENC(0, 11), 0, input_port, },
1220 { "dma@4", ENC(0, 12), 0, input_port, },
1221 { "dma@5", ENC(0, 13), 0, input_port, },
1222 { "dma@6", ENC(0, 14), 0, input_port, },
1223 { "dma@7", ENC(0, 15), 0, input_port, },
1224 { "dma@8", ENC(0, 16), 0, input_port, },
1225 { "portf_irq_a", ENC(0, 17), 0, input_port, },
1226 { "portf_irq_b", ENC(0, 18), 0, input_port, },
1227 { "gptimer@0", ENC(0, 19), 0, input_port, },
1228 { "gptimer@1", ENC(0, 20), 0, input_port, },
1229 { "gptimer@2", ENC(0, 21), 0, input_port, },
1230 { "portg_irq_a", ENC(0, 22), 0, input_port, },
1231 { "portg_irq_b", ENC(0, 23), 0, input_port, },
1232 { "twi@0", ENC(0, 24), 0, input_port, },
1233 /* XXX: 25 - 28 are supposed to be reserved; see comment in machs.c:bf592_dmac[] */
1234 { "dma@9", ENC(0, 25), 0, input_port, },
1235 { "dma@10", ENC(0, 26), 0, input_port, },
1236 { "dma@11", ENC(0, 27), 0, input_port, },
1237 { "dma@12", ENC(0, 28), 0, input_port, },
1238 /*{ "reserved", ENC(0, 25), 0, input_port, },*/
1239 /*{ "reserved", ENC(0, 26), 0, input_port, },*/
1240 /*{ "reserved", ENC(0, 27), 0, input_port, },*/
1241 /*{ "reserved", ENC(0, 28), 0, input_port, },*/
1242 { "mdma@0", ENC(0, 29), 0, input_port, },
1243 { "mdma@1", ENC(0, 30), 0, input_port, },
1244 { "wdog", ENC(0, 31), 0, input_port, },
1245 { NULL, 0, 0, 0, },
1246 };
1247
1248 static void
1249 attach_bfin_sic_regs (struct hw *me, struct bfin_sic *sic)
1250 {
1251 address_word attach_address;
1252 int attach_space;
1253 unsigned attach_size;
1254 reg_property_spec reg;
1255
1256 if (hw_find_property (me, "reg") == NULL)
1257 hw_abort (me, "Missing \"reg\" property");
1258
1259 if (!hw_find_reg_array_property (me, "reg", 0, &reg))
1260 hw_abort (me, "\"reg\" property must contain three addr/size entries");
1261
1262 hw_unit_address_to_attach_address (hw_parent (me),
1263 &reg.address,
1264 &attach_space, &attach_address, me);
1265 hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
1266
1267 if (attach_size != BFIN_MMR_SIC_SIZE)
1268 hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_SIC_SIZE);
1269
1270 hw_attach_address (hw_parent (me),
1271 0, attach_space, attach_address, attach_size, me);
1272
1273 sic->base = attach_address;
1274 }
1275
1276 static void
1277 bfin_sic_finish (struct hw *me)
1278 {
1279 struct bfin_sic *sic;
1280
1281 sic = HW_ZALLOC (me, struct bfin_sic);
1282
1283 set_hw_data (me, sic);
1284 attach_bfin_sic_regs (me, sic);
1285
1286 switch (hw_find_integer_property (me, "type"))
1287 {
1288 case 500 ... 509:
1289 set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
1290 set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
1291 set_hw_ports (me, bfin_sic_50x_ports);
1292 set_hw_port_event (me, bfin_sic_52x_port_event);
1293 mmr_names = bf52x_mmr_names;
1294
1295 /* Initialize the SIC. */
1296 sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
1297 sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
1298 sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
1299 sic->bf52x.iar0 = 0x00000000;
1300 sic->bf52x.iar1 = 0x22111000;
1301 sic->bf52x.iar2 = 0x33332222;
1302 sic->bf52x.iar3 = 0x44444433;
1303 sic->bf52x.iar4 = 0x55555555;
1304 sic->bf52x.iar5 = 0x06666655;
1305 sic->bf52x.iar6 = 0x33333003;
1306 sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
1307 break;
1308 case 510 ... 519:
1309 set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
1310 set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
1311 set_hw_ports (me, bfin_sic_51x_ports);
1312 set_hw_port_event (me, bfin_sic_52x_port_event);
1313 mmr_names = bf52x_mmr_names;
1314
1315 /* Initialize the SIC. */
1316 sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
1317 sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
1318 sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
1319 sic->bf52x.iar0 = 0x00000000;
1320 sic->bf52x.iar1 = 0x11000000;
1321 sic->bf52x.iar2 = 0x33332222;
1322 sic->bf52x.iar3 = 0x44444433;
1323 sic->bf52x.iar4 = 0x55555555;
1324 sic->bf52x.iar5 = 0x06666655;
1325 sic->bf52x.iar6 = 0x33333000;
1326 sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
1327 break;
1328 case 522 ... 527:
1329 set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
1330 set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
1331 set_hw_ports (me, bfin_sic_52x_ports);
1332 set_hw_port_event (me, bfin_sic_52x_port_event);
1333 mmr_names = bf52x_mmr_names;
1334
1335 /* Initialize the SIC. */
1336 sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
1337 sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
1338 sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
1339 sic->bf52x.iar0 = 0x00000000;
1340 sic->bf52x.iar1 = 0x11000000;
1341 sic->bf52x.iar2 = 0x33332222;
1342 sic->bf52x.iar3 = 0x44444433;
1343 sic->bf52x.iar4 = 0x55555555;
1344 sic->bf52x.iar5 = 0x06666655;
1345 sic->bf52x.iar6 = 0x33333000;
1346 sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
1347 break;
1348 case 531 ... 533:
1349 set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
1350 set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
1351 set_hw_ports (me, bfin_sic_533_ports);
1352 set_hw_port_event (me, bfin_sic_537_port_event);
1353 mmr_names = bf537_mmr_names;
1354
1355 /* Initialize the SIC. */
1356 sic->bf537.imask = 0;
1357 sic->bf537.isr = 0;
1358 sic->bf537.iwr = 0xFFFFFFFF;
1359 sic->bf537.iar0 = 0x10000000;
1360 sic->bf537.iar1 = 0x33322221;
1361 sic->bf537.iar2 = 0x66655444;
1362 sic->bf537.iar3 = 0; /* XXX: fix this */
1363 break;
1364 case 534:
1365 case 536:
1366 case 537:
1367 set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
1368 set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
1369 set_hw_ports (me, bfin_sic_537_ports);
1370 set_hw_port_event (me, bfin_sic_537_port_event);
1371 mmr_names = bf537_mmr_names;
1372
1373 /* Initialize the SIC. */
1374 sic->bf537.imask = 0;
1375 sic->bf537.isr = 0;
1376 sic->bf537.iwr = 0xFFFFFFFF;
1377 sic->bf537.iar0 = 0x22211000;
1378 sic->bf537.iar1 = 0x43333332;
1379 sic->bf537.iar2 = 0x55555444;
1380 sic->bf537.iar3 = 0x66655555;
1381 break;
1382 case 538 ... 539:
1383 set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
1384 set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
1385 set_hw_ports (me, bfin_sic_538_ports);
1386 set_hw_port_event (me, bfin_sic_52x_port_event);
1387 mmr_names = bf52x_mmr_names;
1388
1389 /* Initialize the SIC. */
1390 sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
1391 sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
1392 sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
1393 sic->bf52x.iar0 = 0x10000000;
1394 sic->bf52x.iar1 = 0x33322221;
1395 sic->bf52x.iar2 = 0x66655444;
1396 sic->bf52x.iar3 = 0x00000000;
1397 sic->bf52x.iar4 = 0x32222220;
1398 sic->bf52x.iar5 = 0x44433333;
1399 sic->bf52x.iar6 = 0x00444664;
1400 sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
1401 break;
1402 case 540 ... 549:
1403 set_hw_io_read_buffer (me, bfin_sic_54x_io_read_buffer);
1404 set_hw_io_write_buffer (me, bfin_sic_54x_io_write_buffer);
1405 set_hw_ports (me, bfin_sic_54x_ports);
1406 set_hw_port_event (me, bfin_sic_54x_port_event);
1407 mmr_names = bf54x_mmr_names;
1408
1409 /* Initialize the SIC. */
1410 sic->bf54x.imask0 = sic->bf54x.imask1 = sic->bf54x.imask2 = 0;
1411 sic->bf54x.isr0 = sic->bf54x.isr1 = sic->bf54x.isr2 = 0;
1412 sic->bf54x.iwr0 = sic->bf54x.iwr1 = sic->bf54x.iwr1 = 0xFFFFFFFF;
1413 sic->bf54x.iar0 = 0x10000000;
1414 sic->bf54x.iar1 = 0x33322221;
1415 sic->bf54x.iar2 = 0x66655444;
1416 sic->bf54x.iar3 = 0x00000000;
1417 sic->bf54x.iar4 = 0x32222220;
1418 sic->bf54x.iar5 = 0x44433333;
1419 sic->bf54x.iar6 = 0x00444664;
1420 sic->bf54x.iar7 = 0x00000000;
1421 sic->bf54x.iar8 = 0x44111111;
1422 sic->bf54x.iar9 = 0x44444444;
1423 sic->bf54x.iar10 = 0x44444444;
1424 sic->bf54x.iar11 = 0x55444444;
1425 break;
1426 case 561:
1427 set_hw_io_read_buffer (me, bfin_sic_561_io_read_buffer);
1428 set_hw_io_write_buffer (me, bfin_sic_561_io_write_buffer);
1429 set_hw_ports (me, bfin_sic_561_ports);
1430 set_hw_port_event (me, bfin_sic_561_port_event);
1431 mmr_names = bf561_mmr_names;
1432
1433 /* Initialize the SIC. */
1434 sic->bf561.imask0 = sic->bf561.imask1 = 0;
1435 sic->bf561.isr0 = sic->bf561.isr1 = 0;
1436 sic->bf561.iwr0 = sic->bf561.iwr1 = 0xFFFFFFFF;
1437 sic->bf561.iar0 = 0x00000000;
1438 sic->bf561.iar1 = 0x11111000;
1439 sic->bf561.iar2 = 0x21111111;
1440 sic->bf561.iar3 = 0x22222222;
1441 sic->bf561.iar4 = 0x33333222;
1442 sic->bf561.iar5 = 0x43333333;
1443 sic->bf561.iar6 = 0x21144444;
1444 sic->bf561.iar7 = 0x00006552;
1445 break;
1446 case 590 ... 599:
1447 set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
1448 set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
1449 set_hw_ports (me, bfin_sic_59x_ports);
1450 set_hw_port_event (me, bfin_sic_537_port_event);
1451 mmr_names = bf537_mmr_names;
1452
1453 /* Initialize the SIC. */
1454 sic->bf537.imask = 0;
1455 sic->bf537.isr = 0;
1456 sic->bf537.iwr = 0xFFFFFFFF;
1457 sic->bf537.iar0 = 0x00000000;
1458 sic->bf537.iar1 = 0x33322221;
1459 sic->bf537.iar2 = 0x55444443;
1460 sic->bf537.iar3 = 0x66600005;
1461 break;
1462 default:
1463 hw_abort (me, "no support for SIC on this Blackfin model yet");
1464 }
1465 }
1466
1467 const struct hw_descriptor dv_bfin_sic_descriptor[] =
1468 {
1469 {"bfin_sic", bfin_sic_finish,},
1470 {NULL, NULL},
1471 };