Automatic date update in version.in
[binutils-gdb.git] / sim / bfin / dv-bfin_sic.c
blobbe5fc47071af364e57248e3fa8ae2a23de7c0fc7
1 /* Blackfin System Interrupt Controller (SIC) model.
3 Copyright (C) 2010-2024 Free Software Foundation, Inc.
4 Contributed by Analog Devices, Inc.
6 This file is part of simulators.
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.
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.
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/>. */
21 /* This must come before any other includes. */
22 #include "defs.h"
24 #include "sim-main.h"
25 #include "devices.h"
26 #include "dv-bfin_sic.h"
27 #include "dv-bfin_cec.h"
29 struct bfin_sic
31 /* We assume first element is the base. */
32 bu32 base;
34 /* Order after here is important -- matches hardware MMR layout. */
35 bu16 BFIN_MMR_16(swrst);
36 bu16 BFIN_MMR_16(syscr);
37 bu16 BFIN_MMR_16(rvect); /* XXX: BF59x has a 32bit AUX_REVID here. */
38 union {
39 struct {
40 bu32 imask0;
41 bu32 iar0, iar1, iar2, iar3;
42 bu32 isr0, iwr0;
43 bu32 _pad0[9];
44 bu32 imask1;
45 bu32 iar4, iar5, iar6, iar7;
46 bu32 isr1, iwr1;
47 } bf52x;
48 struct {
49 bu32 imask;
50 bu32 iar0, iar1, iar2, iar3;
51 bu32 isr, iwr;
52 } bf537;
53 struct {
54 bu32 imask0, imask1, imask2;
55 bu32 isr0, isr1, isr2;
56 bu32 iwr0, iwr1, iwr2;
57 bu32 iar0, iar1, iar2, iar3;
58 bu32 iar4, iar5, iar6, iar7;
59 bu32 iar8, iar9, iar10, iar11;
60 } bf54x;
61 struct {
62 bu32 imask0, imask1;
63 bu32 iar0, iar1, iar2, iar3;
64 bu32 iar4, iar5, iar6, iar7;
65 bu32 isr0, isr1;
66 bu32 iwr0, iwr1;
67 } bf561;
70 #define mmr_base() offsetof(struct bfin_sic, swrst)
71 #define mmr_offset(mmr) (offsetof(struct bfin_sic, mmr) - mmr_base())
72 #define mmr_idx(mmr) (mmr_offset (mmr) / 4)
74 static const char * const bf52x_mmr_names[] =
76 "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IAR0", "SIC_IAR1",
77 "SIC_IAR2", "SIC_IAR3", "SIC_ISR0", "SIC_IWR0",
78 [mmr_idx (bf52x.imask1)] = "SIC_IMASK1", "SIC_IAR4", "SIC_IAR5",
79 "SIC_IAR6", "SIC_IAR7", "SIC_ISR1", "SIC_IWR1",
81 static const char * const bf537_mmr_names[] =
83 "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK", "SIC_IAR0", "SIC_IAR1",
84 "SIC_IAR2", "SIC_IAR3", "SIC_ISR", "SIC_IWR",
86 static const char * const bf54x_mmr_names[] =
88 "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1", "SIC_IMASK2",
89 "SIC_ISR0", "SIC_ISR1", "SIC_ISR2", "SIC_IWR0", "SIC_IWR1", "SIC_IWR2",
90 "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
91 "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
92 "SIC_IAR8", "SIC_IAR9", "SIC_IAR10", "SIC_IAR11",
94 static const char * const bf561_mmr_names[] =
96 "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1",
97 "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
98 "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
99 "SIC_ISR0", "SIC_ISR1", "SIC_IWR0", "SIC_IWR1",
101 static const char * const *mmr_names;
102 #define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
104 static void
105 bfin_sic_forward_interrupts (struct hw *me, bu32 *isr, bu32 *imask, bu32 *iar)
107 int my_port;
108 bu32 ipend;
110 /* Process pending and unmasked interrupts. */
111 ipend = *isr & *imask;
113 /* Usually none are pending unmasked, so avoid bit twiddling. */
114 if (!ipend)
115 return;
117 for (my_port = 0; my_port < 32; ++my_port)
119 bu32 iar_idx, iar_off, iar_val;
120 bu32 bit = (1 << my_port);
122 /* This bit isn't pending, so check next one. */
123 if (!(ipend & bit))
124 continue;
126 /* The IAR registers map the System input to the Core output.
127 Every 4 bits in the IAR are used to map to IVG{7..15}. */
128 iar_idx = my_port / 8;
129 iar_off = (my_port % 8) * 4;
130 iar_val = (iar[iar_idx] & (0xf << iar_off)) >> iar_off;
131 HW_TRACE ((me, "forwarding int %i to CEC", IVG7 + iar_val));
132 hw_port_event (me, IVG7 + iar_val, 1);
136 static void
137 bfin_sic_52x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
139 bfin_sic_forward_interrupts (me, &sic->bf52x.isr0, &sic->bf52x.imask0, &sic->bf52x.iar0);
140 bfin_sic_forward_interrupts (me, &sic->bf52x.isr1, &sic->bf52x.imask1, &sic->bf52x.iar4);
143 static unsigned
144 bfin_sic_52x_io_write_buffer (struct hw *me, const void *source, int space,
145 address_word addr, unsigned nr_bytes)
147 struct bfin_sic *sic = hw_data (me);
148 bu32 mmr_off;
149 bu32 value;
150 bu32 *value32p;
151 void *valuep;
153 /* Invalid access mode is higher priority than missing register. */
154 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
155 return 0;
157 if (nr_bytes == 4)
158 value = dv_load_4 (source);
159 else
160 value = dv_load_2 (source);
162 mmr_off = addr - sic->base;
163 valuep = (void *)((uintptr_t)sic + mmr_base() + mmr_off);
164 value32p = valuep;
166 HW_TRACE_WRITE ();
168 /* XXX: Discard all SIC writes for now. */
169 switch (mmr_off)
171 case mmr_offset(swrst):
172 /* XXX: This should trigger a software reset ... */
173 break;
174 case mmr_offset(syscr):
175 /* XXX: what to do ... */
176 break;
177 case mmr_offset(bf52x.imask0):
178 case mmr_offset(bf52x.imask1):
179 bfin_sic_52x_forward_interrupts (me, sic);
180 *value32p = value;
181 break;
182 case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
183 case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
184 case mmr_offset(bf52x.iwr0):
185 case mmr_offset(bf52x.iwr1):
186 *value32p = value;
187 break;
188 case mmr_offset(bf52x.isr0):
189 case mmr_offset(bf52x.isr1):
190 /* ISR is read-only. */
191 break;
192 default:
193 /* XXX: Should discard other writes. */
197 return nr_bytes;
200 static unsigned
201 bfin_sic_52x_io_read_buffer (struct hw *me, void *dest, int space,
202 address_word addr, unsigned nr_bytes)
204 struct bfin_sic *sic = hw_data (me);
205 bu32 mmr_off;
206 bu16 *value16p;
207 bu32 *value32p;
208 void *valuep;
210 /* Invalid access mode is higher priority than missing register. */
211 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
212 return 0;
214 mmr_off = addr - sic->base;
215 valuep = (void *)((uintptr_t)sic + mmr_base() + mmr_off);
216 value16p = valuep;
217 value32p = valuep;
219 HW_TRACE_READ ();
221 switch (mmr_off)
223 case mmr_offset(swrst):
224 case mmr_offset(syscr):
225 case mmr_offset(rvect):
226 dv_store_2 (dest, *value16p);
227 break;
228 case mmr_offset(bf52x.imask0):
229 case mmr_offset(bf52x.imask1):
230 case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
231 case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
232 case mmr_offset(bf52x.iwr0):
233 case mmr_offset(bf52x.iwr1):
234 case mmr_offset(bf52x.isr0):
235 case mmr_offset(bf52x.isr1):
236 dv_store_4 (dest, *value32p);
237 break;
238 default:
239 if (nr_bytes == 2)
240 dv_store_2 (dest, 0);
241 else
242 dv_store_4 (dest, 0);
243 break;
246 return nr_bytes;
249 static void
250 bfin_sic_537_forward_interrupts (struct hw *me, struct bfin_sic *sic)
252 bfin_sic_forward_interrupts (me, &sic->bf537.isr, &sic->bf537.imask, &sic->bf537.iar0);
255 static unsigned
256 bfin_sic_537_io_write_buffer (struct hw *me, const void *source, int space,
257 address_word addr, unsigned nr_bytes)
259 struct bfin_sic *sic = hw_data (me);
260 bu32 mmr_off;
261 bu32 value;
262 bu32 *value32p;
263 void *valuep;
265 /* Invalid access mode is higher priority than missing register. */
266 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
267 return 0;
269 if (nr_bytes == 4)
270 value = dv_load_4 (source);
271 else
272 value = dv_load_2 (source);
274 mmr_off = addr - sic->base;
275 valuep = (void *)((uintptr_t)sic + mmr_base() + mmr_off);
276 value32p = valuep;
278 HW_TRACE_WRITE ();
280 /* XXX: Discard all SIC writes for now. */
281 switch (mmr_off)
283 case mmr_offset(swrst):
284 /* XXX: This should trigger a software reset ... */
285 break;
286 case mmr_offset(syscr):
287 /* XXX: what to do ... */
288 break;
289 case mmr_offset(bf537.imask):
290 bfin_sic_537_forward_interrupts (me, sic);
291 *value32p = value;
292 break;
293 case mmr_offset(bf537.iar0):
294 case mmr_offset(bf537.iar1):
295 case mmr_offset(bf537.iar2):
296 case mmr_offset(bf537.iar3):
297 case mmr_offset(bf537.iwr):
298 *value32p = value;
299 break;
300 case mmr_offset(bf537.isr):
301 /* ISR is read-only. */
302 break;
303 default:
304 /* XXX: Should discard other writes. */
308 return nr_bytes;
311 static unsigned
312 bfin_sic_537_io_read_buffer (struct hw *me, void *dest, int space,
313 address_word addr, unsigned nr_bytes)
315 struct bfin_sic *sic = hw_data (me);
316 bu32 mmr_off;
317 bu16 *value16p;
318 bu32 *value32p;
319 void *valuep;
321 /* Invalid access mode is higher priority than missing register. */
322 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
323 return 0;
325 mmr_off = addr - sic->base;
326 valuep = (void *)((uintptr_t)sic + mmr_base() + mmr_off);
327 value16p = valuep;
328 value32p = valuep;
330 HW_TRACE_READ ();
332 switch (mmr_off)
334 case mmr_offset(swrst):
335 case mmr_offset(syscr):
336 case mmr_offset(rvect):
337 dv_store_2 (dest, *value16p);
338 break;
339 case mmr_offset(bf537.imask):
340 case mmr_offset(bf537.iar0):
341 case mmr_offset(bf537.iar1):
342 case mmr_offset(bf537.iar2):
343 case mmr_offset(bf537.iar3):
344 case mmr_offset(bf537.isr):
345 case mmr_offset(bf537.iwr):
346 dv_store_4 (dest, *value32p);
347 break;
348 default:
349 if (nr_bytes == 2)
350 dv_store_2 (dest, 0);
351 else
352 dv_store_4 (dest, 0);
353 break;
356 return nr_bytes;
359 static void
360 bfin_sic_54x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
362 bfin_sic_forward_interrupts (me, &sic->bf54x.isr0, &sic->bf54x.imask0, &sic->bf54x.iar0);
363 bfin_sic_forward_interrupts (me, &sic->bf54x.isr1, &sic->bf54x.imask1, &sic->bf54x.iar4);
364 bfin_sic_forward_interrupts (me, &sic->bf54x.isr2, &sic->bf54x.imask2, &sic->bf54x.iar8);
367 static unsigned
368 bfin_sic_54x_io_write_buffer (struct hw *me, const void *source, int space,
369 address_word addr, unsigned nr_bytes)
371 struct bfin_sic *sic = hw_data (me);
372 bu32 mmr_off;
373 bu32 value;
374 bu32 *value32p;
375 void *valuep;
377 /* Invalid access mode is higher priority than missing register. */
378 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
379 return 0;
381 if (nr_bytes == 4)
382 value = dv_load_4 (source);
383 else
384 value = dv_load_2 (source);
386 mmr_off = addr - sic->base;
387 valuep = (void *)((uintptr_t)sic + mmr_base() + mmr_off);
388 value32p = valuep;
390 HW_TRACE_WRITE ();
392 /* XXX: Discard all SIC writes for now. */
393 switch (mmr_off)
395 case mmr_offset(swrst):
396 /* XXX: This should trigger a software reset ... */
397 break;
398 case mmr_offset(syscr):
399 /* XXX: what to do ... */
400 break;
401 case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
402 bfin_sic_54x_forward_interrupts (me, sic);
403 *value32p = value;
404 break;
405 case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
406 case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
407 *value32p = value;
408 break;
409 case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
410 /* ISR is read-only. */
411 break;
412 default:
413 /* XXX: Should discard other writes. */
417 return nr_bytes;
420 static unsigned
421 bfin_sic_54x_io_read_buffer (struct hw *me, void *dest, int space,
422 address_word addr, unsigned nr_bytes)
424 struct bfin_sic *sic = hw_data (me);
425 bu32 mmr_off;
426 bu16 *value16p;
427 bu32 *value32p;
428 void *valuep;
430 /* Invalid access mode is higher priority than missing register. */
431 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
432 return 0;
434 mmr_off = addr - sic->base;
435 valuep = (void *)((uintptr_t)sic + mmr_base() + mmr_off);
436 value16p = valuep;
437 value32p = valuep;
439 HW_TRACE_READ ();
441 switch (mmr_off)
443 case mmr_offset(swrst):
444 case mmr_offset(syscr):
445 case mmr_offset(rvect):
446 dv_store_2 (dest, *value16p);
447 break;
448 case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
449 case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
450 case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
451 case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
452 dv_store_4 (dest, *value32p);
453 break;
454 default:
455 if (nr_bytes == 2)
456 dv_store_2 (dest, 0);
457 else
458 dv_store_4 (dest, 0);
459 break;
462 return nr_bytes;
465 static void
466 bfin_sic_561_forward_interrupts (struct hw *me, struct bfin_sic *sic)
468 bfin_sic_forward_interrupts (me, &sic->bf561.isr0, &sic->bf561.imask0, &sic->bf561.iar0);
469 bfin_sic_forward_interrupts (me, &sic->bf561.isr1, &sic->bf561.imask1, &sic->bf561.iar4);
472 static unsigned
473 bfin_sic_561_io_write_buffer (struct hw *me, const void *source, int space,
474 address_word addr, unsigned nr_bytes)
476 struct bfin_sic *sic = hw_data (me);
477 bu32 mmr_off;
478 bu32 value;
479 bu32 *value32p;
480 void *valuep;
482 /* Invalid access mode is higher priority than missing register. */
483 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
484 return 0;
486 if (nr_bytes == 4)
487 value = dv_load_4 (source);
488 else
489 value = dv_load_2 (source);
491 mmr_off = addr - sic->base;
492 valuep = (void *)((uintptr_t)sic + mmr_base() + mmr_off);
493 value32p = valuep;
495 HW_TRACE_WRITE ();
497 /* XXX: Discard all SIC writes for now. */
498 switch (mmr_off)
500 case mmr_offset(swrst):
501 /* XXX: This should trigger a software reset ... */
502 break;
503 case mmr_offset(syscr):
504 /* XXX: what to do ... */
505 break;
506 case mmr_offset(bf561.imask0):
507 case mmr_offset(bf561.imask1):
508 bfin_sic_561_forward_interrupts (me, sic);
509 *value32p = value;
510 break;
511 case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
512 case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
513 case mmr_offset(bf561.iwr0):
514 case mmr_offset(bf561.iwr1):
515 *value32p = value;
516 break;
517 case mmr_offset(bf561.isr0):
518 case mmr_offset(bf561.isr1):
519 /* ISR is read-only. */
520 break;
521 default:
522 /* XXX: Should discard other writes. */
526 return nr_bytes;
529 static unsigned
530 bfin_sic_561_io_read_buffer (struct hw *me, void *dest, int space,
531 address_word addr, unsigned nr_bytes)
533 struct bfin_sic *sic = hw_data (me);
534 bu32 mmr_off;
535 bu16 *value16p;
536 bu32 *value32p;
537 void *valuep;
539 /* Invalid access mode is higher priority than missing register. */
540 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
541 return 0;
543 mmr_off = addr - sic->base;
544 valuep = (void *)((uintptr_t)sic + mmr_base() + mmr_off);
545 value16p = valuep;
546 value32p = valuep;
548 HW_TRACE_READ ();
550 switch (mmr_off)
552 case mmr_offset(swrst):
553 case mmr_offset(syscr):
554 case mmr_offset(rvect):
555 dv_store_2 (dest, *value16p);
556 break;
557 case mmr_offset(bf561.imask0):
558 case mmr_offset(bf561.imask1):
559 case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
560 case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
561 case mmr_offset(bf561.iwr0):
562 case mmr_offset(bf561.iwr1):
563 case mmr_offset(bf561.isr0):
564 case mmr_offset(bf561.isr1):
565 dv_store_4 (dest, *value32p);
566 break;
567 default:
568 if (nr_bytes == 2)
569 dv_store_2 (dest, 0);
570 else
571 dv_store_4 (dest, 0);
572 break;
575 return nr_bytes;
578 /* Give each SIC its own base to make it easier to extract the pin at
579 runtime. The pin is used as its bit position in the SIC MMRs. */
580 #define ENC(sic, pin) (((sic) << 8) + (pin))
581 #define DEC_PIN(pin) ((pin) % 0x100)
582 #define DEC_SIC(pin) ((pin) >> 8)
584 /* It would be nice to declare just one set of input_ports, and then
585 have the device tree instantiate multiple SICs, but the MMR layout
586 on the BF54x/BF561 makes this pretty hard to pull off since their
587 regs are interwoven in the address space. */
589 #define BFIN_SIC_TO_CEC_PORTS \
590 { "ivg7", IVG7, 0, output_port, }, \
591 { "ivg8", IVG8, 0, output_port, }, \
592 { "ivg9", IVG9, 0, output_port, }, \
593 { "ivg10", IVG10, 0, output_port, }, \
594 { "ivg11", IVG11, 0, output_port, }, \
595 { "ivg12", IVG12, 0, output_port, }, \
596 { "ivg13", IVG13, 0, output_port, }, \
597 { "ivg14", IVG14, 0, output_port, }, \
598 { "ivg15", IVG15, 0, output_port, },
600 #define SIC_PORTS(n) \
601 { "int0@"#n, ENC(n, 0), 0, input_port, }, \
602 { "int1@"#n, ENC(n, 1), 0, input_port, }, \
603 { "int2@"#n, ENC(n, 2), 0, input_port, }, \
604 { "int3@"#n, ENC(n, 3), 0, input_port, }, \
605 { "int4@"#n, ENC(n, 4), 0, input_port, }, \
606 { "int5@"#n, ENC(n, 5), 0, input_port, }, \
607 { "int6@"#n, ENC(n, 6), 0, input_port, }, \
608 { "int7@"#n, ENC(n, 7), 0, input_port, }, \
609 { "int8@"#n, ENC(n, 8), 0, input_port, }, \
610 { "int9@"#n, ENC(n, 9), 0, input_port, }, \
611 { "int10@"#n, ENC(n, 10), 0, input_port, }, \
612 { "int11@"#n, ENC(n, 11), 0, input_port, }, \
613 { "int12@"#n, ENC(n, 12), 0, input_port, }, \
614 { "int13@"#n, ENC(n, 13), 0, input_port, }, \
615 { "int14@"#n, ENC(n, 14), 0, input_port, }, \
616 { "int15@"#n, ENC(n, 15), 0, input_port, }, \
617 { "int16@"#n, ENC(n, 16), 0, input_port, }, \
618 { "int17@"#n, ENC(n, 17), 0, input_port, }, \
619 { "int18@"#n, ENC(n, 18), 0, input_port, }, \
620 { "int19@"#n, ENC(n, 19), 0, input_port, }, \
621 { "int20@"#n, ENC(n, 20), 0, input_port, }, \
622 { "int21@"#n, ENC(n, 21), 0, input_port, }, \
623 { "int22@"#n, ENC(n, 22), 0, input_port, }, \
624 { "int23@"#n, ENC(n, 23), 0, input_port, }, \
625 { "int24@"#n, ENC(n, 24), 0, input_port, }, \
626 { "int25@"#n, ENC(n, 25), 0, input_port, }, \
627 { "int26@"#n, ENC(n, 26), 0, input_port, }, \
628 { "int27@"#n, ENC(n, 27), 0, input_port, }, \
629 { "int28@"#n, ENC(n, 28), 0, input_port, }, \
630 { "int29@"#n, ENC(n, 29), 0, input_port, }, \
631 { "int30@"#n, ENC(n, 30), 0, input_port, }, \
632 { "int31@"#n, ENC(n, 31), 0, input_port, },
634 static const struct hw_port_descriptor bfin_sic1_ports[] =
636 BFIN_SIC_TO_CEC_PORTS
637 SIC_PORTS(0)
638 { NULL, 0, 0, 0, },
641 static const struct hw_port_descriptor bfin_sic2_ports[] =
643 BFIN_SIC_TO_CEC_PORTS
644 SIC_PORTS(0)
645 SIC_PORTS(1)
646 { NULL, 0, 0, 0, },
649 static const struct hw_port_descriptor bfin_sic3_ports[] =
651 BFIN_SIC_TO_CEC_PORTS
652 SIC_PORTS(0)
653 SIC_PORTS(1)
654 SIC_PORTS(2)
655 { NULL, 0, 0, 0, },
658 static const struct hw_port_descriptor bfin_sic_561_ports[] =
660 { "sup_irq@0", 0, 0, output_port, },
661 { "sup_irq@1", 1, 0, output_port, },
662 BFIN_SIC_TO_CEC_PORTS
663 SIC_PORTS(0)
664 SIC_PORTS(1)
665 { NULL, 0, 0, 0, },
668 static void
669 bfin_sic_port_event (struct hw *me, bu32 *isr, bu32 bit, int level)
671 if (level)
672 *isr |= bit;
673 else
674 *isr &= ~bit;
677 static void
678 bfin_sic_52x_port_event (struct hw *me, int my_port, struct hw *source,
679 int source_port, int level)
681 struct bfin_sic *sic = hw_data (me);
682 bu32 idx = DEC_SIC (my_port);
683 bu32 pin = DEC_PIN (my_port);
684 bu32 bit = 1 << pin;
686 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
687 level, my_port, idx, pin));
689 /* SIC only exists to forward interrupts from the system to the CEC. */
690 switch (idx)
692 case 0: bfin_sic_port_event (me, &sic->bf52x.isr0, bit, level); break;
693 case 1: bfin_sic_port_event (me, &sic->bf52x.isr1, bit, level); break;
696 /* XXX: Handle SIC wakeup source ?
697 if (sic->bf52x.iwr0 & bit)
698 What to do ?;
699 if (sic->bf52x.iwr1 & bit)
700 What to do ?;
703 bfin_sic_52x_forward_interrupts (me, sic);
706 static void
707 bfin_sic_537_port_event (struct hw *me, int my_port, struct hw *source,
708 int source_port, int level)
710 struct bfin_sic *sic = hw_data (me);
711 bu32 idx = DEC_SIC (my_port);
712 bu32 pin = DEC_PIN (my_port);
713 bu32 bit = 1 << pin;
715 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
716 level, my_port, idx, pin));
718 /* SIC only exists to forward interrupts from the system to the CEC. */
719 bfin_sic_port_event (me, &sic->bf537.isr, bit, level);
721 /* XXX: Handle SIC wakeup source ?
722 if (sic->bf537.iwr & bit)
723 What to do ?;
726 bfin_sic_537_forward_interrupts (me, sic);
729 static void
730 bfin_sic_54x_port_event (struct hw *me, int my_port, struct hw *source,
731 int source_port, int level)
733 struct bfin_sic *sic = hw_data (me);
734 bu32 idx = DEC_SIC (my_port);
735 bu32 pin = DEC_PIN (my_port);
736 bu32 bit = 1 << pin;
738 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
739 level, my_port, idx, pin));
741 /* SIC only exists to forward interrupts from the system to the CEC. */
742 switch (idx)
744 case 0: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
745 case 1: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
746 case 2: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
749 /* XXX: Handle SIC wakeup source ?
750 if (sic->bf54x.iwr0 & bit)
751 What to do ?;
752 if (sic->bf54x.iwr1 & bit)
753 What to do ?;
754 if (sic->bf54x.iwr2 & bit)
755 What to do ?;
758 bfin_sic_54x_forward_interrupts (me, sic);
761 static void
762 bfin_sic_561_port_event (struct hw *me, int my_port, struct hw *source,
763 int source_port, int level)
765 struct bfin_sic *sic = hw_data (me);
766 bu32 idx = DEC_SIC (my_port);
767 bu32 pin = DEC_PIN (my_port);
768 bu32 bit = 1 << pin;
770 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
771 level, my_port, idx, pin));
773 /* SIC only exists to forward interrupts from the system to the CEC. */
774 switch (idx)
776 case 0: bfin_sic_port_event (me, &sic->bf561.isr0, bit, level); break;
777 case 1: bfin_sic_port_event (me, &sic->bf561.isr1, bit, level); break;
780 /* XXX: Handle SIC wakeup source ?
781 if (sic->bf561.iwr0 & bit)
782 What to do ?;
783 if (sic->bf561.iwr1 & bit)
784 What to do ?;
787 bfin_sic_561_forward_interrupts (me, sic);
790 static void
791 attach_bfin_sic_regs (struct hw *me, struct bfin_sic *sic)
793 address_word attach_address;
794 int attach_space;
795 unsigned attach_size;
796 reg_property_spec reg;
798 if (hw_find_property (me, "reg") == NULL)
799 hw_abort (me, "Missing \"reg\" property");
801 if (!hw_find_reg_array_property (me, "reg", 0, &reg))
802 hw_abort (me, "\"reg\" property must contain three addr/size entries");
804 hw_unit_address_to_attach_address (hw_parent (me),
805 &reg.address,
806 &attach_space, &attach_address, me);
807 hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
809 if (attach_size != BFIN_MMR_SIC_SIZE)
810 hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_SIC_SIZE);
812 hw_attach_address (hw_parent (me),
813 0, attach_space, attach_address, attach_size, me);
815 sic->base = attach_address;
818 static void
819 bfin_sic_finish (struct hw *me)
821 struct bfin_sic *sic;
823 sic = HW_ZALLOC (me, struct bfin_sic);
825 set_hw_data (me, sic);
826 attach_bfin_sic_regs (me, sic);
828 switch (hw_find_integer_property (me, "type"))
830 case 500 ... 509:
831 set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
832 set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
833 set_hw_ports (me, bfin_sic2_ports);
834 set_hw_port_event (me, bfin_sic_52x_port_event);
835 mmr_names = bf52x_mmr_names;
837 /* Initialize the SIC. */
838 sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
839 sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
840 sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
841 sic->bf52x.iar0 = 0x00000000;
842 sic->bf52x.iar1 = 0x22111000;
843 sic->bf52x.iar2 = 0x33332222;
844 sic->bf52x.iar3 = 0x44444433;
845 sic->bf52x.iar4 = 0x55555555;
846 sic->bf52x.iar5 = 0x06666655;
847 sic->bf52x.iar6 = 0x33333003;
848 sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
849 break;
850 case 510 ... 519:
851 set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
852 set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
853 set_hw_ports (me, bfin_sic2_ports);
854 set_hw_port_event (me, bfin_sic_52x_port_event);
855 mmr_names = bf52x_mmr_names;
857 /* Initialize the SIC. */
858 sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
859 sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
860 sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
861 sic->bf52x.iar0 = 0x00000000;
862 sic->bf52x.iar1 = 0x11000000;
863 sic->bf52x.iar2 = 0x33332222;
864 sic->bf52x.iar3 = 0x44444433;
865 sic->bf52x.iar4 = 0x55555555;
866 sic->bf52x.iar5 = 0x06666655;
867 sic->bf52x.iar6 = 0x33333000;
868 sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
869 break;
870 case 522 ... 527:
871 set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
872 set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
873 set_hw_ports (me, bfin_sic2_ports);
874 set_hw_port_event (me, bfin_sic_52x_port_event);
875 mmr_names = bf52x_mmr_names;
877 /* Initialize the SIC. */
878 sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
879 sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
880 sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
881 sic->bf52x.iar0 = 0x00000000;
882 sic->bf52x.iar1 = 0x11000000;
883 sic->bf52x.iar2 = 0x33332222;
884 sic->bf52x.iar3 = 0x44444433;
885 sic->bf52x.iar4 = 0x55555555;
886 sic->bf52x.iar5 = 0x06666655;
887 sic->bf52x.iar6 = 0x33333000;
888 sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
889 break;
890 case 531 ... 533:
891 set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
892 set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
893 set_hw_ports (me, bfin_sic1_ports);
894 set_hw_port_event (me, bfin_sic_537_port_event);
895 mmr_names = bf537_mmr_names;
897 /* Initialize the SIC. */
898 sic->bf537.imask = 0;
899 sic->bf537.isr = 0;
900 sic->bf537.iwr = 0xFFFFFFFF;
901 sic->bf537.iar0 = 0x10000000;
902 sic->bf537.iar1 = 0x33322221;
903 sic->bf537.iar2 = 0x66655444;
904 sic->bf537.iar3 = 0; /* XXX: fix this */
905 break;
906 case 534:
907 case 536:
908 case 537:
909 set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
910 set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
911 set_hw_ports (me, bfin_sic1_ports);
912 set_hw_port_event (me, bfin_sic_537_port_event);
913 mmr_names = bf537_mmr_names;
915 /* Initialize the SIC. */
916 sic->bf537.imask = 0;
917 sic->bf537.isr = 0;
918 sic->bf537.iwr = 0xFFFFFFFF;
919 sic->bf537.iar0 = 0x22211000;
920 sic->bf537.iar1 = 0x43333332;
921 sic->bf537.iar2 = 0x55555444;
922 sic->bf537.iar3 = 0x66655555;
923 break;
924 case 538 ... 539:
925 set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
926 set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
927 set_hw_ports (me, bfin_sic2_ports);
928 set_hw_port_event (me, bfin_sic_52x_port_event);
929 mmr_names = bf52x_mmr_names;
931 /* Initialize the SIC. */
932 sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
933 sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
934 sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
935 sic->bf52x.iar0 = 0x10000000;
936 sic->bf52x.iar1 = 0x33322221;
937 sic->bf52x.iar2 = 0x66655444;
938 sic->bf52x.iar3 = 0x00000000;
939 sic->bf52x.iar4 = 0x32222220;
940 sic->bf52x.iar5 = 0x44433333;
941 sic->bf52x.iar6 = 0x00444664;
942 sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
943 break;
944 case 540 ... 549:
945 set_hw_io_read_buffer (me, bfin_sic_54x_io_read_buffer);
946 set_hw_io_write_buffer (me, bfin_sic_54x_io_write_buffer);
947 set_hw_ports (me, bfin_sic3_ports);
948 set_hw_port_event (me, bfin_sic_54x_port_event);
949 mmr_names = bf54x_mmr_names;
951 /* Initialize the SIC. */
952 sic->bf54x.imask0 = sic->bf54x.imask1 = sic->bf54x.imask2 = 0;
953 sic->bf54x.isr0 = sic->bf54x.isr1 = sic->bf54x.isr2 = 0;
954 sic->bf54x.iwr0 = sic->bf54x.iwr1 = sic->bf54x.iwr2 = 0xFFFFFFFF;
955 sic->bf54x.iar0 = 0x10000000;
956 sic->bf54x.iar1 = 0x33322221;
957 sic->bf54x.iar2 = 0x66655444;
958 sic->bf54x.iar3 = 0x00000000;
959 sic->bf54x.iar4 = 0x32222220;
960 sic->bf54x.iar5 = 0x44433333;
961 sic->bf54x.iar6 = 0x00444664;
962 sic->bf54x.iar7 = 0x00000000;
963 sic->bf54x.iar8 = 0x44111111;
964 sic->bf54x.iar9 = 0x44444444;
965 sic->bf54x.iar10 = 0x44444444;
966 sic->bf54x.iar11 = 0x55444444;
967 break;
968 case 561:
969 set_hw_io_read_buffer (me, bfin_sic_561_io_read_buffer);
970 set_hw_io_write_buffer (me, bfin_sic_561_io_write_buffer);
971 set_hw_ports (me, bfin_sic_561_ports);
972 set_hw_port_event (me, bfin_sic_561_port_event);
973 mmr_names = bf561_mmr_names;
975 /* Initialize the SIC. */
976 sic->bf561.imask0 = sic->bf561.imask1 = 0;
977 sic->bf561.isr0 = sic->bf561.isr1 = 0;
978 sic->bf561.iwr0 = sic->bf561.iwr1 = 0xFFFFFFFF;
979 sic->bf561.iar0 = 0x00000000;
980 sic->bf561.iar1 = 0x11111000;
981 sic->bf561.iar2 = 0x21111111;
982 sic->bf561.iar3 = 0x22222222;
983 sic->bf561.iar4 = 0x33333222;
984 sic->bf561.iar5 = 0x43333333;
985 sic->bf561.iar6 = 0x21144444;
986 sic->bf561.iar7 = 0x00006552;
987 break;
988 case 590 ... 599:
989 set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
990 set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
991 set_hw_ports (me, bfin_sic1_ports);
992 set_hw_port_event (me, bfin_sic_537_port_event);
993 mmr_names = bf537_mmr_names;
995 /* Initialize the SIC. */
996 sic->bf537.imask = 0;
997 sic->bf537.isr = 0;
998 sic->bf537.iwr = 0xFFFFFFFF;
999 sic->bf537.iar0 = 0x00000000;
1000 sic->bf537.iar1 = 0x33322221;
1001 sic->bf537.iar2 = 0x55444443;
1002 sic->bf537.iar3 = 0x66600005;
1003 break;
1004 default:
1005 hw_abort (me, "no support for SIC on this Blackfin model yet");
1009 const struct hw_descriptor dv_bfin_sic_descriptor[] =
1011 {"bfin_sic", bfin_sic_finish,},
1012 {NULL, NULL},