1 /* Blackfin System Interrupt Controller (SIC) model.
3 Copyright (C) 2010-2023 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. */
26 #include "dv-bfin_sic.h"
27 #include "dv-bfin_cec.h"
31 /* We assume first element is the 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. */
41 bu32 iar0
, iar1
, iar2
, iar3
;
45 bu32 iar4
, iar5
, iar6
, iar7
;
50 bu32 iar0
, iar1
, iar2
, iar3
;
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
;
63 bu32 iar0
, iar1
, iar2
, iar3
;
64 bu32 iar4
, iar5
, iar6
, iar7
;
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>")
105 bfin_sic_forward_interrupts (struct hw
*me
, bu32
*isr
, bu32
*imask
, bu32
*iar
)
110 /* Process pending and unmasked interrupts. */
111 ipend
= *isr
& *imask
;
113 /* Usually none are pending unmasked, so avoid bit twiddling. */
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. */
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);
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
);
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
);
154 /* Invalid access mode is higher priority than missing register. */
155 if (!dv_bfin_mmr_require_16_32 (me
, addr
, nr_bytes
, true))
159 value
= dv_load_4 (source
);
161 value
= dv_load_2 (source
);
163 mmr_off
= addr
- sic
->base
;
164 valuep
= (void *)((uintptr_t)sic
+ mmr_base() + mmr_off
);
170 /* XXX: Discard all SIC writes for now. */
173 case mmr_offset(swrst
):
174 /* XXX: This should trigger a software reset ... */
176 case mmr_offset(syscr
):
177 /* XXX: what to do ... */
179 case mmr_offset(bf52x
.imask0
):
180 case mmr_offset(bf52x
.imask1
):
181 bfin_sic_52x_forward_interrupts (me
, sic
);
184 case mmr_offset(bf52x
.iar0
) ... mmr_offset(bf52x
.iar3
):
185 case mmr_offset(bf52x
.iar4
) ... mmr_offset(bf52x
.iar7
):
186 case mmr_offset(bf52x
.iwr0
):
187 case mmr_offset(bf52x
.iwr1
):
190 case mmr_offset(bf52x
.isr0
):
191 case mmr_offset(bf52x
.isr1
):
192 /* ISR is read-only. */
195 /* XXX: Should discard other writes. */
203 bfin_sic_52x_io_read_buffer (struct hw
*me
, void *dest
, int space
,
204 address_word addr
, unsigned nr_bytes
)
206 struct bfin_sic
*sic
= hw_data (me
);
212 /* Invalid access mode is higher priority than missing register. */
213 if (!dv_bfin_mmr_require_16_32 (me
, addr
, nr_bytes
, false))
216 mmr_off
= addr
- sic
->base
;
217 valuep
= (void *)((uintptr_t)sic
+ mmr_base() + mmr_off
);
225 case mmr_offset(swrst
):
226 case mmr_offset(syscr
):
227 case mmr_offset(rvect
):
228 dv_store_2 (dest
, *value16p
);
230 case mmr_offset(bf52x
.imask0
):
231 case mmr_offset(bf52x
.imask1
):
232 case mmr_offset(bf52x
.iar0
) ... mmr_offset(bf52x
.iar3
):
233 case mmr_offset(bf52x
.iar4
) ... mmr_offset(bf52x
.iar7
):
234 case mmr_offset(bf52x
.iwr0
):
235 case mmr_offset(bf52x
.iwr1
):
236 case mmr_offset(bf52x
.isr0
):
237 case mmr_offset(bf52x
.isr1
):
238 dv_store_4 (dest
, *value32p
);
242 dv_store_2 (dest
, 0);
244 dv_store_4 (dest
, 0);
252 bfin_sic_537_forward_interrupts (struct hw
*me
, struct bfin_sic
*sic
)
254 bfin_sic_forward_interrupts (me
, &sic
->bf537
.isr
, &sic
->bf537
.imask
, &sic
->bf537
.iar0
);
258 bfin_sic_537_io_write_buffer (struct hw
*me
, const void *source
, int space
,
259 address_word addr
, unsigned nr_bytes
)
261 struct bfin_sic
*sic
= hw_data (me
);
268 /* Invalid access mode is higher priority than missing register. */
269 if (!dv_bfin_mmr_require_16_32 (me
, addr
, nr_bytes
, true))
273 value
= dv_load_4 (source
);
275 value
= dv_load_2 (source
);
277 mmr_off
= addr
- sic
->base
;
278 valuep
= (void *)((uintptr_t)sic
+ mmr_base() + mmr_off
);
284 /* XXX: Discard all SIC writes for now. */
287 case mmr_offset(swrst
):
288 /* XXX: This should trigger a software reset ... */
290 case mmr_offset(syscr
):
291 /* XXX: what to do ... */
293 case mmr_offset(bf537
.imask
):
294 bfin_sic_537_forward_interrupts (me
, sic
);
297 case mmr_offset(bf537
.iar0
):
298 case mmr_offset(bf537
.iar1
):
299 case mmr_offset(bf537
.iar2
):
300 case mmr_offset(bf537
.iar3
):
301 case mmr_offset(bf537
.iwr
):
304 case mmr_offset(bf537
.isr
):
305 /* ISR is read-only. */
308 /* XXX: Should discard other writes. */
316 bfin_sic_537_io_read_buffer (struct hw
*me
, void *dest
, int space
,
317 address_word addr
, unsigned nr_bytes
)
319 struct bfin_sic
*sic
= hw_data (me
);
325 /* Invalid access mode is higher priority than missing register. */
326 if (!dv_bfin_mmr_require_16_32 (me
, addr
, nr_bytes
, false))
329 mmr_off
= addr
- sic
->base
;
330 valuep
= (void *)((uintptr_t)sic
+ mmr_base() + mmr_off
);
338 case mmr_offset(swrst
):
339 case mmr_offset(syscr
):
340 case mmr_offset(rvect
):
341 dv_store_2 (dest
, *value16p
);
343 case mmr_offset(bf537
.imask
):
344 case mmr_offset(bf537
.iar0
):
345 case mmr_offset(bf537
.iar1
):
346 case mmr_offset(bf537
.iar2
):
347 case mmr_offset(bf537
.iar3
):
348 case mmr_offset(bf537
.isr
):
349 case mmr_offset(bf537
.iwr
):
350 dv_store_4 (dest
, *value32p
);
354 dv_store_2 (dest
, 0);
356 dv_store_4 (dest
, 0);
364 bfin_sic_54x_forward_interrupts (struct hw
*me
, struct bfin_sic
*sic
)
366 bfin_sic_forward_interrupts (me
, &sic
->bf54x
.isr0
, &sic
->bf54x
.imask0
, &sic
->bf54x
.iar0
);
367 bfin_sic_forward_interrupts (me
, &sic
->bf54x
.isr1
, &sic
->bf54x
.imask1
, &sic
->bf54x
.iar4
);
368 bfin_sic_forward_interrupts (me
, &sic
->bf54x
.isr2
, &sic
->bf54x
.imask2
, &sic
->bf54x
.iar8
);
372 bfin_sic_54x_io_write_buffer (struct hw
*me
, const void *source
, int space
,
373 address_word addr
, unsigned nr_bytes
)
375 struct bfin_sic
*sic
= hw_data (me
);
382 /* Invalid access mode is higher priority than missing register. */
383 if (!dv_bfin_mmr_require_16_32 (me
, addr
, nr_bytes
, true))
387 value
= dv_load_4 (source
);
389 value
= dv_load_2 (source
);
391 mmr_off
= addr
- sic
->base
;
392 valuep
= (void *)((uintptr_t)sic
+ mmr_base() + mmr_off
);
398 /* XXX: Discard all SIC writes for now. */
401 case mmr_offset(swrst
):
402 /* XXX: This should trigger a software reset ... */
404 case mmr_offset(syscr
):
405 /* XXX: what to do ... */
407 case mmr_offset(bf54x
.imask0
) ... mmr_offset(bf54x
.imask2
):
408 bfin_sic_54x_forward_interrupts (me
, sic
);
411 case mmr_offset(bf54x
.iar0
) ... mmr_offset(bf54x
.iar11
):
412 case mmr_offset(bf54x
.iwr0
) ... mmr_offset(bf54x
.iwr2
):
415 case mmr_offset(bf54x
.isr0
) ... mmr_offset(bf54x
.isr2
):
416 /* ISR is read-only. */
419 /* XXX: Should discard other writes. */
427 bfin_sic_54x_io_read_buffer (struct hw
*me
, void *dest
, int space
,
428 address_word addr
, unsigned nr_bytes
)
430 struct bfin_sic
*sic
= hw_data (me
);
436 /* Invalid access mode is higher priority than missing register. */
437 if (!dv_bfin_mmr_require_16_32 (me
, addr
, nr_bytes
, false))
440 mmr_off
= addr
- sic
->base
;
441 valuep
= (void *)((uintptr_t)sic
+ mmr_base() + mmr_off
);
449 case mmr_offset(swrst
):
450 case mmr_offset(syscr
):
451 case mmr_offset(rvect
):
452 dv_store_2 (dest
, *value16p
);
454 case mmr_offset(bf54x
.imask0
) ... mmr_offset(bf54x
.imask2
):
455 case mmr_offset(bf54x
.iar0
) ... mmr_offset(bf54x
.iar11
):
456 case mmr_offset(bf54x
.iwr0
) ... mmr_offset(bf54x
.iwr2
):
457 case mmr_offset(bf54x
.isr0
) ... mmr_offset(bf54x
.isr2
):
458 dv_store_4 (dest
, *value32p
);
462 dv_store_2 (dest
, 0);
464 dv_store_4 (dest
, 0);
472 bfin_sic_561_forward_interrupts (struct hw
*me
, struct bfin_sic
*sic
)
474 bfin_sic_forward_interrupts (me
, &sic
->bf561
.isr0
, &sic
->bf561
.imask0
, &sic
->bf561
.iar0
);
475 bfin_sic_forward_interrupts (me
, &sic
->bf561
.isr1
, &sic
->bf561
.imask1
, &sic
->bf561
.iar4
);
479 bfin_sic_561_io_write_buffer (struct hw
*me
, const void *source
, int space
,
480 address_word addr
, unsigned nr_bytes
)
482 struct bfin_sic
*sic
= hw_data (me
);
489 /* Invalid access mode is higher priority than missing register. */
490 if (!dv_bfin_mmr_require_16_32 (me
, addr
, nr_bytes
, true))
494 value
= dv_load_4 (source
);
496 value
= dv_load_2 (source
);
498 mmr_off
= addr
- sic
->base
;
499 valuep
= (void *)((uintptr_t)sic
+ mmr_base() + mmr_off
);
505 /* XXX: Discard all SIC writes for now. */
508 case mmr_offset(swrst
):
509 /* XXX: This should trigger a software reset ... */
511 case mmr_offset(syscr
):
512 /* XXX: what to do ... */
514 case mmr_offset(bf561
.imask0
):
515 case mmr_offset(bf561
.imask1
):
516 bfin_sic_561_forward_interrupts (me
, sic
);
519 case mmr_offset(bf561
.iar0
) ... mmr_offset(bf561
.iar3
):
520 case mmr_offset(bf561
.iar4
) ... mmr_offset(bf561
.iar7
):
521 case mmr_offset(bf561
.iwr0
):
522 case mmr_offset(bf561
.iwr1
):
525 case mmr_offset(bf561
.isr0
):
526 case mmr_offset(bf561
.isr1
):
527 /* ISR is read-only. */
530 /* XXX: Should discard other writes. */
538 bfin_sic_561_io_read_buffer (struct hw
*me
, void *dest
, int space
,
539 address_word addr
, unsigned nr_bytes
)
541 struct bfin_sic
*sic
= hw_data (me
);
547 /* Invalid access mode is higher priority than missing register. */
548 if (!dv_bfin_mmr_require_16_32 (me
, addr
, nr_bytes
, false))
551 mmr_off
= addr
- sic
->base
;
552 valuep
= (void *)((uintptr_t)sic
+ mmr_base() + mmr_off
);
560 case mmr_offset(swrst
):
561 case mmr_offset(syscr
):
562 case mmr_offset(rvect
):
563 dv_store_2 (dest
, *value16p
);
565 case mmr_offset(bf561
.imask0
):
566 case mmr_offset(bf561
.imask1
):
567 case mmr_offset(bf561
.iar0
) ... mmr_offset(bf561
.iar3
):
568 case mmr_offset(bf561
.iar4
) ... mmr_offset(bf561
.iar7
):
569 case mmr_offset(bf561
.iwr0
):
570 case mmr_offset(bf561
.iwr1
):
571 case mmr_offset(bf561
.isr0
):
572 case mmr_offset(bf561
.isr1
):
573 dv_store_4 (dest
, *value32p
);
577 dv_store_2 (dest
, 0);
579 dv_store_4 (dest
, 0);
586 /* Give each SIC its own base to make it easier to extract the pin at
587 runtime. The pin is used as its bit position in the SIC MMRs. */
588 #define ENC(sic, pin) (((sic) << 8) + (pin))
589 #define DEC_PIN(pin) ((pin) % 0x100)
590 #define DEC_SIC(pin) ((pin) >> 8)
592 /* It would be nice to declare just one set of input_ports, and then
593 have the device tree instantiate multiple SICs, but the MMR layout
594 on the BF54x/BF561 makes this pretty hard to pull off since their
595 regs are interwoven in the address space. */
597 #define BFIN_SIC_TO_CEC_PORTS \
598 { "ivg7", IVG7, 0, output_port, }, \
599 { "ivg8", IVG8, 0, output_port, }, \
600 { "ivg9", IVG9, 0, output_port, }, \
601 { "ivg10", IVG10, 0, output_port, }, \
602 { "ivg11", IVG11, 0, output_port, }, \
603 { "ivg12", IVG12, 0, output_port, }, \
604 { "ivg13", IVG13, 0, output_port, }, \
605 { "ivg14", IVG14, 0, output_port, }, \
606 { "ivg15", IVG15, 0, output_port, },
608 #define SIC_PORTS(n) \
609 { "int0@"#n, ENC(n, 0), 0, input_port, }, \
610 { "int1@"#n, ENC(n, 1), 0, input_port, }, \
611 { "int2@"#n, ENC(n, 2), 0, input_port, }, \
612 { "int3@"#n, ENC(n, 3), 0, input_port, }, \
613 { "int4@"#n, ENC(n, 4), 0, input_port, }, \
614 { "int5@"#n, ENC(n, 5), 0, input_port, }, \
615 { "int6@"#n, ENC(n, 6), 0, input_port, }, \
616 { "int7@"#n, ENC(n, 7), 0, input_port, }, \
617 { "int8@"#n, ENC(n, 8), 0, input_port, }, \
618 { "int9@"#n, ENC(n, 9), 0, input_port, }, \
619 { "int10@"#n, ENC(n, 10), 0, input_port, }, \
620 { "int11@"#n, ENC(n, 11), 0, input_port, }, \
621 { "int12@"#n, ENC(n, 12), 0, input_port, }, \
622 { "int13@"#n, ENC(n, 13), 0, input_port, }, \
623 { "int14@"#n, ENC(n, 14), 0, input_port, }, \
624 { "int15@"#n, ENC(n, 15), 0, input_port, }, \
625 { "int16@"#n, ENC(n, 16), 0, input_port, }, \
626 { "int17@"#n, ENC(n, 17), 0, input_port, }, \
627 { "int18@"#n, ENC(n, 18), 0, input_port, }, \
628 { "int19@"#n, ENC(n, 19), 0, input_port, }, \
629 { "int20@"#n, ENC(n, 20), 0, input_port, }, \
630 { "int21@"#n, ENC(n, 21), 0, input_port, }, \
631 { "int22@"#n, ENC(n, 22), 0, input_port, }, \
632 { "int23@"#n, ENC(n, 23), 0, input_port, }, \
633 { "int24@"#n, ENC(n, 24), 0, input_port, }, \
634 { "int25@"#n, ENC(n, 25), 0, input_port, }, \
635 { "int26@"#n, ENC(n, 26), 0, input_port, }, \
636 { "int27@"#n, ENC(n, 27), 0, input_port, }, \
637 { "int28@"#n, ENC(n, 28), 0, input_port, }, \
638 { "int29@"#n, ENC(n, 29), 0, input_port, }, \
639 { "int30@"#n, ENC(n, 30), 0, input_port, }, \
640 { "int31@"#n, ENC(n, 31), 0, input_port, },
642 static const struct hw_port_descriptor bfin_sic1_ports
[] =
644 BFIN_SIC_TO_CEC_PORTS
649 static const struct hw_port_descriptor bfin_sic2_ports
[] =
651 BFIN_SIC_TO_CEC_PORTS
657 static const struct hw_port_descriptor bfin_sic3_ports
[] =
659 BFIN_SIC_TO_CEC_PORTS
666 static const struct hw_port_descriptor bfin_sic_561_ports
[] =
668 { "sup_irq@0", 0, 0, output_port
, },
669 { "sup_irq@1", 1, 0, output_port
, },
670 BFIN_SIC_TO_CEC_PORTS
677 bfin_sic_port_event (struct hw
*me
, bu32
*isr
, bu32 bit
, int level
)
686 bfin_sic_52x_port_event (struct hw
*me
, int my_port
, struct hw
*source
,
687 int source_port
, int level
)
689 struct bfin_sic
*sic
= hw_data (me
);
690 bu32 idx
= DEC_SIC (my_port
);
691 bu32 pin
= DEC_PIN (my_port
);
694 HW_TRACE ((me
, "processing level %i from port %i (SIC %u pin %u)",
695 level
, my_port
, idx
, pin
));
697 /* SIC only exists to forward interrupts from the system to the CEC. */
700 case 0: bfin_sic_port_event (me
, &sic
->bf52x
.isr0
, bit
, level
); break;
701 case 1: bfin_sic_port_event (me
, &sic
->bf52x
.isr1
, bit
, level
); break;
704 /* XXX: Handle SIC wakeup source ?
705 if (sic->bf52x.iwr0 & bit)
707 if (sic->bf52x.iwr1 & bit)
711 bfin_sic_52x_forward_interrupts (me
, sic
);
715 bfin_sic_537_port_event (struct hw
*me
, int my_port
, struct hw
*source
,
716 int source_port
, int level
)
718 struct bfin_sic
*sic
= hw_data (me
);
719 bu32 idx
= DEC_SIC (my_port
);
720 bu32 pin
= DEC_PIN (my_port
);
723 HW_TRACE ((me
, "processing level %i from port %i (SIC %u pin %u)",
724 level
, my_port
, idx
, pin
));
726 /* SIC only exists to forward interrupts from the system to the CEC. */
727 bfin_sic_port_event (me
, &sic
->bf537
.isr
, bit
, level
);
729 /* XXX: Handle SIC wakeup source ?
730 if (sic->bf537.iwr & bit)
734 bfin_sic_537_forward_interrupts (me
, sic
);
738 bfin_sic_54x_port_event (struct hw
*me
, int my_port
, struct hw
*source
,
739 int source_port
, int level
)
741 struct bfin_sic
*sic
= hw_data (me
);
742 bu32 idx
= DEC_SIC (my_port
);
743 bu32 pin
= DEC_PIN (my_port
);
746 HW_TRACE ((me
, "processing level %i from port %i (SIC %u pin %u)",
747 level
, my_port
, idx
, pin
));
749 /* SIC only exists to forward interrupts from the system to the CEC. */
752 case 0: bfin_sic_port_event (me
, &sic
->bf54x
.isr0
, bit
, level
); break;
753 case 1: bfin_sic_port_event (me
, &sic
->bf54x
.isr0
, bit
, level
); break;
754 case 2: bfin_sic_port_event (me
, &sic
->bf54x
.isr0
, bit
, level
); break;
757 /* XXX: Handle SIC wakeup source ?
758 if (sic->bf54x.iwr0 & bit)
760 if (sic->bf54x.iwr1 & bit)
762 if (sic->bf54x.iwr2 & bit)
766 bfin_sic_54x_forward_interrupts (me
, sic
);
770 bfin_sic_561_port_event (struct hw
*me
, int my_port
, struct hw
*source
,
771 int source_port
, int level
)
773 struct bfin_sic
*sic
= hw_data (me
);
774 bu32 idx
= DEC_SIC (my_port
);
775 bu32 pin
= DEC_PIN (my_port
);
778 HW_TRACE ((me
, "processing level %i from port %i (SIC %u pin %u)",
779 level
, my_port
, idx
, pin
));
781 /* SIC only exists to forward interrupts from the system to the CEC. */
784 case 0: bfin_sic_port_event (me
, &sic
->bf561
.isr0
, bit
, level
); break;
785 case 1: bfin_sic_port_event (me
, &sic
->bf561
.isr1
, bit
, level
); break;
788 /* XXX: Handle SIC wakeup source ?
789 if (sic->bf561.iwr0 & bit)
791 if (sic->bf561.iwr1 & bit)
795 bfin_sic_561_forward_interrupts (me
, sic
);
799 attach_bfin_sic_regs (struct hw
*me
, struct bfin_sic
*sic
)
801 address_word attach_address
;
803 unsigned attach_size
;
804 reg_property_spec reg
;
806 if (hw_find_property (me
, "reg") == NULL
)
807 hw_abort (me
, "Missing \"reg\" property");
809 if (!hw_find_reg_array_property (me
, "reg", 0, ®
))
810 hw_abort (me
, "\"reg\" property must contain three addr/size entries");
812 hw_unit_address_to_attach_address (hw_parent (me
),
814 &attach_space
, &attach_address
, me
);
815 hw_unit_size_to_attach_size (hw_parent (me
), ®
.size
, &attach_size
, me
);
817 if (attach_size
!= BFIN_MMR_SIC_SIZE
)
818 hw_abort (me
, "\"reg\" size must be %#x", BFIN_MMR_SIC_SIZE
);
820 hw_attach_address (hw_parent (me
),
821 0, attach_space
, attach_address
, attach_size
, me
);
823 sic
->base
= attach_address
;
827 bfin_sic_finish (struct hw
*me
)
829 struct bfin_sic
*sic
;
831 sic
= HW_ZALLOC (me
, struct bfin_sic
);
833 set_hw_data (me
, sic
);
834 attach_bfin_sic_regs (me
, sic
);
836 switch (hw_find_integer_property (me
, "type"))
839 set_hw_io_read_buffer (me
, bfin_sic_52x_io_read_buffer
);
840 set_hw_io_write_buffer (me
, bfin_sic_52x_io_write_buffer
);
841 set_hw_ports (me
, bfin_sic2_ports
);
842 set_hw_port_event (me
, bfin_sic_52x_port_event
);
843 mmr_names
= bf52x_mmr_names
;
845 /* Initialize the SIC. */
846 sic
->bf52x
.imask0
= sic
->bf52x
.imask1
= 0;
847 sic
->bf52x
.isr0
= sic
->bf52x
.isr1
= 0;
848 sic
->bf52x
.iwr0
= sic
->bf52x
.iwr1
= 0xFFFFFFFF;
849 sic
->bf52x
.iar0
= 0x00000000;
850 sic
->bf52x
.iar1
= 0x22111000;
851 sic
->bf52x
.iar2
= 0x33332222;
852 sic
->bf52x
.iar3
= 0x44444433;
853 sic
->bf52x
.iar4
= 0x55555555;
854 sic
->bf52x
.iar5
= 0x06666655;
855 sic
->bf52x
.iar6
= 0x33333003;
856 sic
->bf52x
.iar7
= 0x00000000; /* XXX: Find and fix */
859 set_hw_io_read_buffer (me
, bfin_sic_52x_io_read_buffer
);
860 set_hw_io_write_buffer (me
, bfin_sic_52x_io_write_buffer
);
861 set_hw_ports (me
, bfin_sic2_ports
);
862 set_hw_port_event (me
, bfin_sic_52x_port_event
);
863 mmr_names
= bf52x_mmr_names
;
865 /* Initialize the SIC. */
866 sic
->bf52x
.imask0
= sic
->bf52x
.imask1
= 0;
867 sic
->bf52x
.isr0
= sic
->bf52x
.isr1
= 0;
868 sic
->bf52x
.iwr0
= sic
->bf52x
.iwr1
= 0xFFFFFFFF;
869 sic
->bf52x
.iar0
= 0x00000000;
870 sic
->bf52x
.iar1
= 0x11000000;
871 sic
->bf52x
.iar2
= 0x33332222;
872 sic
->bf52x
.iar3
= 0x44444433;
873 sic
->bf52x
.iar4
= 0x55555555;
874 sic
->bf52x
.iar5
= 0x06666655;
875 sic
->bf52x
.iar6
= 0x33333000;
876 sic
->bf52x
.iar7
= 0x00000000; /* XXX: Find and fix */
879 set_hw_io_read_buffer (me
, bfin_sic_52x_io_read_buffer
);
880 set_hw_io_write_buffer (me
, bfin_sic_52x_io_write_buffer
);
881 set_hw_ports (me
, bfin_sic2_ports
);
882 set_hw_port_event (me
, bfin_sic_52x_port_event
);
883 mmr_names
= bf52x_mmr_names
;
885 /* Initialize the SIC. */
886 sic
->bf52x
.imask0
= sic
->bf52x
.imask1
= 0;
887 sic
->bf52x
.isr0
= sic
->bf52x
.isr1
= 0;
888 sic
->bf52x
.iwr0
= sic
->bf52x
.iwr1
= 0xFFFFFFFF;
889 sic
->bf52x
.iar0
= 0x00000000;
890 sic
->bf52x
.iar1
= 0x11000000;
891 sic
->bf52x
.iar2
= 0x33332222;
892 sic
->bf52x
.iar3
= 0x44444433;
893 sic
->bf52x
.iar4
= 0x55555555;
894 sic
->bf52x
.iar5
= 0x06666655;
895 sic
->bf52x
.iar6
= 0x33333000;
896 sic
->bf52x
.iar7
= 0x00000000; /* XXX: Find and fix */
899 set_hw_io_read_buffer (me
, bfin_sic_537_io_read_buffer
);
900 set_hw_io_write_buffer (me
, bfin_sic_537_io_write_buffer
);
901 set_hw_ports (me
, bfin_sic1_ports
);
902 set_hw_port_event (me
, bfin_sic_537_port_event
);
903 mmr_names
= bf537_mmr_names
;
905 /* Initialize the SIC. */
906 sic
->bf537
.imask
= 0;
908 sic
->bf537
.iwr
= 0xFFFFFFFF;
909 sic
->bf537
.iar0
= 0x10000000;
910 sic
->bf537
.iar1
= 0x33322221;
911 sic
->bf537
.iar2
= 0x66655444;
912 sic
->bf537
.iar3
= 0; /* XXX: fix this */
917 set_hw_io_read_buffer (me
, bfin_sic_537_io_read_buffer
);
918 set_hw_io_write_buffer (me
, bfin_sic_537_io_write_buffer
);
919 set_hw_ports (me
, bfin_sic1_ports
);
920 set_hw_port_event (me
, bfin_sic_537_port_event
);
921 mmr_names
= bf537_mmr_names
;
923 /* Initialize the SIC. */
924 sic
->bf537
.imask
= 0;
926 sic
->bf537
.iwr
= 0xFFFFFFFF;
927 sic
->bf537
.iar0
= 0x22211000;
928 sic
->bf537
.iar1
= 0x43333332;
929 sic
->bf537
.iar2
= 0x55555444;
930 sic
->bf537
.iar3
= 0x66655555;
933 set_hw_io_read_buffer (me
, bfin_sic_52x_io_read_buffer
);
934 set_hw_io_write_buffer (me
, bfin_sic_52x_io_write_buffer
);
935 set_hw_ports (me
, bfin_sic2_ports
);
936 set_hw_port_event (me
, bfin_sic_52x_port_event
);
937 mmr_names
= bf52x_mmr_names
;
939 /* Initialize the SIC. */
940 sic
->bf52x
.imask0
= sic
->bf52x
.imask1
= 0;
941 sic
->bf52x
.isr0
= sic
->bf52x
.isr1
= 0;
942 sic
->bf52x
.iwr0
= sic
->bf52x
.iwr1
= 0xFFFFFFFF;
943 sic
->bf52x
.iar0
= 0x10000000;
944 sic
->bf52x
.iar1
= 0x33322221;
945 sic
->bf52x
.iar2
= 0x66655444;
946 sic
->bf52x
.iar3
= 0x00000000;
947 sic
->bf52x
.iar4
= 0x32222220;
948 sic
->bf52x
.iar5
= 0x44433333;
949 sic
->bf52x
.iar6
= 0x00444664;
950 sic
->bf52x
.iar7
= 0x00000000; /* XXX: Find and fix */
953 set_hw_io_read_buffer (me
, bfin_sic_54x_io_read_buffer
);
954 set_hw_io_write_buffer (me
, bfin_sic_54x_io_write_buffer
);
955 set_hw_ports (me
, bfin_sic3_ports
);
956 set_hw_port_event (me
, bfin_sic_54x_port_event
);
957 mmr_names
= bf54x_mmr_names
;
959 /* Initialize the SIC. */
960 sic
->bf54x
.imask0
= sic
->bf54x
.imask1
= sic
->bf54x
.imask2
= 0;
961 sic
->bf54x
.isr0
= sic
->bf54x
.isr1
= sic
->bf54x
.isr2
= 0;
962 sic
->bf54x
.iwr0
= sic
->bf54x
.iwr1
= sic
->bf54x
.iwr2
= 0xFFFFFFFF;
963 sic
->bf54x
.iar0
= 0x10000000;
964 sic
->bf54x
.iar1
= 0x33322221;
965 sic
->bf54x
.iar2
= 0x66655444;
966 sic
->bf54x
.iar3
= 0x00000000;
967 sic
->bf54x
.iar4
= 0x32222220;
968 sic
->bf54x
.iar5
= 0x44433333;
969 sic
->bf54x
.iar6
= 0x00444664;
970 sic
->bf54x
.iar7
= 0x00000000;
971 sic
->bf54x
.iar8
= 0x44111111;
972 sic
->bf54x
.iar9
= 0x44444444;
973 sic
->bf54x
.iar10
= 0x44444444;
974 sic
->bf54x
.iar11
= 0x55444444;
977 set_hw_io_read_buffer (me
, bfin_sic_561_io_read_buffer
);
978 set_hw_io_write_buffer (me
, bfin_sic_561_io_write_buffer
);
979 set_hw_ports (me
, bfin_sic_561_ports
);
980 set_hw_port_event (me
, bfin_sic_561_port_event
);
981 mmr_names
= bf561_mmr_names
;
983 /* Initialize the SIC. */
984 sic
->bf561
.imask0
= sic
->bf561
.imask1
= 0;
985 sic
->bf561
.isr0
= sic
->bf561
.isr1
= 0;
986 sic
->bf561
.iwr0
= sic
->bf561
.iwr1
= 0xFFFFFFFF;
987 sic
->bf561
.iar0
= 0x00000000;
988 sic
->bf561
.iar1
= 0x11111000;
989 sic
->bf561
.iar2
= 0x21111111;
990 sic
->bf561
.iar3
= 0x22222222;
991 sic
->bf561
.iar4
= 0x33333222;
992 sic
->bf561
.iar5
= 0x43333333;
993 sic
->bf561
.iar6
= 0x21144444;
994 sic
->bf561
.iar7
= 0x00006552;
997 set_hw_io_read_buffer (me
, bfin_sic_537_io_read_buffer
);
998 set_hw_io_write_buffer (me
, bfin_sic_537_io_write_buffer
);
999 set_hw_ports (me
, bfin_sic1_ports
);
1000 set_hw_port_event (me
, bfin_sic_537_port_event
);
1001 mmr_names
= bf537_mmr_names
;
1003 /* Initialize the SIC. */
1004 sic
->bf537
.imask
= 0;
1006 sic
->bf537
.iwr
= 0xFFFFFFFF;
1007 sic
->bf537
.iar0
= 0x00000000;
1008 sic
->bf537
.iar1
= 0x33322221;
1009 sic
->bf537
.iar2
= 0x55444443;
1010 sic
->bf537
.iar3
= 0x66600005;
1013 hw_abort (me
, "no support for SIC on this Blackfin model yet");
1017 const struct hw_descriptor dv_bfin_sic_descriptor
[] =
1019 {"bfin_sic", bfin_sic_finish
,},