Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / sim / bfin / dv-bfin_sic.c
CommitLineData
ef016f83
MF
1/* Blackfin System Interrupt Controller (SIC) model.
2
88b9d363 3 Copyright (C) 2010-2022 Free Software Foundation, Inc.
ef016f83
MF
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
6df01ab8
MF
21/* This must come before any other includes. */
22#include "defs.h"
ef016f83
MF
23
24#include "sim-main.h"
25#include "devices.h"
26#include "dv-bfin_sic.h"
27#include "dv-bfin_cec.h"
28
29struct bfin_sic
30{
31 /* We assume first element is the base. */
32 bu32 base;
33
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;
68 };
69};
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)
73
990d19fd
MF
74static const char * const bf52x_mmr_names[] =
75{
ef016f83
MF
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",
80};
990d19fd
MF
81static const char * const bf537_mmr_names[] =
82{
ef016f83
MF
83 "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK", "SIC_IAR0", "SIC_IAR1",
84 "SIC_IAR2", "SIC_IAR3", "SIC_ISR", "SIC_IWR",
85};
990d19fd
MF
86static const char * const bf54x_mmr_names[] =
87{
ef016f83
MF
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",
93};
990d19fd
MF
94static const char * const bf561_mmr_names[] =
95{
ef016f83
MF
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",
100};
101static const char * const *mmr_names;
102#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
103
104static void
105bfin_sic_forward_interrupts (struct hw *me, bu32 *isr, bu32 *imask, bu32 *iar)
106{
107 int my_port;
108 bu32 ipend;
109
110 /* Process pending and unmasked interrupts. */
111 ipend = *isr & *imask;
112
113 /* Usually none are pending unmasked, so avoid bit twiddling. */
114 if (!ipend)
115 return;
116
117 for (my_port = 0; my_port < 32; ++my_port)
118 {
119 bu32 iar_idx, iar_off, iar_val;
120 bu32 bit = (1 << my_port);
121
122 /* This bit isn't pending, so check next one. */
123 if (!(ipend & bit))
124 continue;
125
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;
a31d4fd9 131 HW_TRACE ((me, "forwarding int %i to CEC", IVG7 + iar_val));
ef016f83
MF
132 hw_port_event (me, IVG7 + iar_val, 1);
133 }
134}
135
136static void
137bfin_sic_52x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
138{
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);
141}
142
143static unsigned
144bfin_sic_52x_io_write_buffer (struct hw *me, const void *source, int space,
145 address_word addr, unsigned nr_bytes)
146{
147 struct bfin_sic *sic = hw_data (me);
148 bu32 mmr_off;
149 bu32 value;
150 bu16 *value16p;
151 bu32 *value32p;
152 void *valuep;
153
466b619e
MF
154 /* Invalid access mode is higher priority than missing register. */
155 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
156 return 0;
157
ef016f83
MF
158 if (nr_bytes == 4)
159 value = dv_load_4 (source);
160 else
161 value = dv_load_2 (source);
162
163 mmr_off = addr - sic->base;
164 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
165 value16p = valuep;
166 value32p = valuep;
167
168 HW_TRACE_WRITE ();
169
170 /* XXX: Discard all SIC writes for now. */
171 switch (mmr_off)
172 {
173 case mmr_offset(swrst):
174 /* XXX: This should trigger a software reset ... */
175 break;
176 case mmr_offset(syscr):
177 /* XXX: what to do ... */
178 break;
179 case mmr_offset(bf52x.imask0):
180 case mmr_offset(bf52x.imask1):
181 bfin_sic_52x_forward_interrupts (me, sic);
182 *value32p = value;
183 break;
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):
188 *value32p = value;
189 break;
190 case mmr_offset(bf52x.isr0):
191 case mmr_offset(bf52x.isr1):
192 /* ISR is read-only. */
193 break;
194 default:
195 /* XXX: Should discard other writes. */
196 ;
197 }
198
199 return nr_bytes;
200}
201
202static unsigned
203bfin_sic_52x_io_read_buffer (struct hw *me, void *dest, int space,
204 address_word addr, unsigned nr_bytes)
205{
206 struct bfin_sic *sic = hw_data (me);
207 bu32 mmr_off;
208 bu16 *value16p;
209 bu32 *value32p;
210 void *valuep;
211
466b619e
MF
212 /* Invalid access mode is higher priority than missing register. */
213 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
214 return 0;
215
ef016f83
MF
216 mmr_off = addr - sic->base;
217 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
218 value16p = valuep;
219 value32p = valuep;
220
221 HW_TRACE_READ ();
222
223 switch (mmr_off)
224 {
225 case mmr_offset(swrst):
226 case mmr_offset(syscr):
227 case mmr_offset(rvect):
228 dv_store_2 (dest, *value16p);
229 break;
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);
239 break;
240 default:
241 if (nr_bytes == 2)
242 dv_store_2 (dest, 0);
243 else
244 dv_store_4 (dest, 0);
245 break;
246 }
247
248 return nr_bytes;
249}
250
251static void
252bfin_sic_537_forward_interrupts (struct hw *me, struct bfin_sic *sic)
253{
254 bfin_sic_forward_interrupts (me, &sic->bf537.isr, &sic->bf537.imask, &sic->bf537.iar0);
255}
256
257static unsigned
258bfin_sic_537_io_write_buffer (struct hw *me, const void *source, int space,
259 address_word addr, unsigned nr_bytes)
260{
261 struct bfin_sic *sic = hw_data (me);
262 bu32 mmr_off;
263 bu32 value;
264 bu16 *value16p;
265 bu32 *value32p;
266 void *valuep;
267
466b619e
MF
268 /* Invalid access mode is higher priority than missing register. */
269 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
270 return 0;
271
ef016f83
MF
272 if (nr_bytes == 4)
273 value = dv_load_4 (source);
274 else
275 value = dv_load_2 (source);
276
277 mmr_off = addr - sic->base;
278 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
279 value16p = valuep;
280 value32p = valuep;
281
282 HW_TRACE_WRITE ();
283
284 /* XXX: Discard all SIC writes for now. */
285 switch (mmr_off)
286 {
287 case mmr_offset(swrst):
288 /* XXX: This should trigger a software reset ... */
289 break;
290 case mmr_offset(syscr):
291 /* XXX: what to do ... */
292 break;
293 case mmr_offset(bf537.imask):
294 bfin_sic_537_forward_interrupts (me, sic);
295 *value32p = value;
296 break;
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):
302 *value32p = value;
303 break;
304 case mmr_offset(bf537.isr):
305 /* ISR is read-only. */
306 break;
307 default:
308 /* XXX: Should discard other writes. */
309 ;
310 }
311
312 return nr_bytes;
313}
314
315static unsigned
316bfin_sic_537_io_read_buffer (struct hw *me, void *dest, int space,
317 address_word addr, unsigned nr_bytes)
318{
319 struct bfin_sic *sic = hw_data (me);
320 bu32 mmr_off;
321 bu16 *value16p;
322 bu32 *value32p;
323 void *valuep;
324
466b619e
MF
325 /* Invalid access mode is higher priority than missing register. */
326 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
327 return 0;
328
ef016f83
MF
329 mmr_off = addr - sic->base;
330 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
331 value16p = valuep;
332 value32p = valuep;
333
334 HW_TRACE_READ ();
335
336 switch (mmr_off)
337 {
338 case mmr_offset(swrst):
339 case mmr_offset(syscr):
340 case mmr_offset(rvect):
341 dv_store_2 (dest, *value16p);
342 break;
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);
351 break;
352 default:
353 if (nr_bytes == 2)
354 dv_store_2 (dest, 0);
355 else
356 dv_store_4 (dest, 0);
357 break;
358 }
359
360 return nr_bytes;
361}
362
363static void
364bfin_sic_54x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
365{
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);
369}
370
371static unsigned
372bfin_sic_54x_io_write_buffer (struct hw *me, const void *source, int space,
373 address_word addr, unsigned nr_bytes)
374{
375 struct bfin_sic *sic = hw_data (me);
376 bu32 mmr_off;
377 bu32 value;
378 bu16 *value16p;
379 bu32 *value32p;
380 void *valuep;
381
466b619e
MF
382 /* Invalid access mode is higher priority than missing register. */
383 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
384 return 0;
385
ef016f83
MF
386 if (nr_bytes == 4)
387 value = dv_load_4 (source);
388 else
389 value = dv_load_2 (source);
390
391 mmr_off = addr - sic->base;
392 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
393 value16p = valuep;
394 value32p = valuep;
395
396 HW_TRACE_WRITE ();
397
398 /* XXX: Discard all SIC writes for now. */
399 switch (mmr_off)
400 {
401 case mmr_offset(swrst):
402 /* XXX: This should trigger a software reset ... */
403 break;
404 case mmr_offset(syscr):
405 /* XXX: what to do ... */
406 break;
407 case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
408 bfin_sic_54x_forward_interrupts (me, sic);
409 *value32p = value;
410 break;
411 case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
412 case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
413 *value32p = value;
414 break;
415 case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
416 /* ISR is read-only. */
417 break;
418 default:
419 /* XXX: Should discard other writes. */
420 ;
421 }
422
423 return nr_bytes;
424}
425
426static unsigned
427bfin_sic_54x_io_read_buffer (struct hw *me, void *dest, int space,
428 address_word addr, unsigned nr_bytes)
429{
430 struct bfin_sic *sic = hw_data (me);
431 bu32 mmr_off;
432 bu16 *value16p;
433 bu32 *value32p;
434 void *valuep;
435
466b619e
MF
436 /* Invalid access mode is higher priority than missing register. */
437 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
438 return 0;
439
ef016f83
MF
440 mmr_off = addr - sic->base;
441 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
442 value16p = valuep;
443 value32p = valuep;
444
445 HW_TRACE_READ ();
446
447 switch (mmr_off)
448 {
449 case mmr_offset(swrst):
450 case mmr_offset(syscr):
451 case mmr_offset(rvect):
452 dv_store_2 (dest, *value16p);
453 break;
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);
459 break;
460 default:
461 if (nr_bytes == 2)
462 dv_store_2 (dest, 0);
463 else
464 dv_store_4 (dest, 0);
465 break;
466 }
467
468 return nr_bytes;
469}
470
471static void
472bfin_sic_561_forward_interrupts (struct hw *me, struct bfin_sic *sic)
473{
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);
476}
477
478static unsigned
479bfin_sic_561_io_write_buffer (struct hw *me, const void *source, int space,
480 address_word addr, unsigned nr_bytes)
481{
482 struct bfin_sic *sic = hw_data (me);
483 bu32 mmr_off;
484 bu32 value;
485 bu16 *value16p;
486 bu32 *value32p;
487 void *valuep;
488
466b619e
MF
489 /* Invalid access mode is higher priority than missing register. */
490 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
491 return 0;
492
ef016f83
MF
493 if (nr_bytes == 4)
494 value = dv_load_4 (source);
495 else
496 value = dv_load_2 (source);
497
498 mmr_off = addr - sic->base;
499 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
500 value16p = valuep;
501 value32p = valuep;
502
503 HW_TRACE_WRITE ();
504
505 /* XXX: Discard all SIC writes for now. */
506 switch (mmr_off)
507 {
508 case mmr_offset(swrst):
509 /* XXX: This should trigger a software reset ... */
510 break;
511 case mmr_offset(syscr):
512 /* XXX: what to do ... */
513 break;
514 case mmr_offset(bf561.imask0):
515 case mmr_offset(bf561.imask1):
516 bfin_sic_561_forward_interrupts (me, sic);
517 *value32p = value;
518 break;
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):
523 *value32p = value;
524 break;
525 case mmr_offset(bf561.isr0):
526 case mmr_offset(bf561.isr1):
527 /* ISR is read-only. */
528 break;
529 default:
530 /* XXX: Should discard other writes. */
531 ;
532 }
533
534 return nr_bytes;
535}
536
537static unsigned
538bfin_sic_561_io_read_buffer (struct hw *me, void *dest, int space,
539 address_word addr, unsigned nr_bytes)
540{
541 struct bfin_sic *sic = hw_data (me);
542 bu32 mmr_off;
543 bu16 *value16p;
544 bu32 *value32p;
545 void *valuep;
546
466b619e
MF
547 /* Invalid access mode is higher priority than missing register. */
548 if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
549 return 0;
550
ef016f83
MF
551 mmr_off = addr - sic->base;
552 valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
553 value16p = valuep;
554 value32p = valuep;
555
556 HW_TRACE_READ ();
557
558 switch (mmr_off)
559 {
560 case mmr_offset(swrst):
561 case mmr_offset(syscr):
562 case mmr_offset(rvect):
563 dv_store_2 (dest, *value16p);
564 break;
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);
574 break;
575 default:
576 if (nr_bytes == 2)
577 dv_store_2 (dest, 0);
578 else
579 dv_store_4 (dest, 0);
580 break;
581 }
582
583 return nr_bytes;
584}
585
082e1c4a
MF
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)
591
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. */
596
ef016f83
MF
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, },
607
082e1c4a
MF
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, },
641
642static const struct hw_port_descriptor bfin_sic1_ports[] =
643{
644 BFIN_SIC_TO_CEC_PORTS
645 SIC_PORTS(0)
646 { NULL, 0, 0, 0, },
647};
e4a861d1 648
082e1c4a 649static const struct hw_port_descriptor bfin_sic2_ports[] =
990d19fd 650{
ef016f83 651 BFIN_SIC_TO_CEC_PORTS
082e1c4a
MF
652 SIC_PORTS(0)
653 SIC_PORTS(1)
ef016f83
MF
654 { NULL, 0, 0, 0, },
655};
656
082e1c4a 657static const struct hw_port_descriptor bfin_sic3_ports[] =
990d19fd 658{
ef016f83 659 BFIN_SIC_TO_CEC_PORTS
082e1c4a
MF
660 SIC_PORTS(0)
661 SIC_PORTS(1)
662 SIC_PORTS(2)
ef016f83
MF
663 { NULL, 0, 0, 0, },
664};
665
082e1c4a 666static const struct hw_port_descriptor bfin_sic_561_ports[] =
990d19fd 667{
082e1c4a
MF
668 { "sup_irq@0", 0, 0, output_port, },
669 { "sup_irq@1", 1, 0, output_port, },
ef016f83 670 BFIN_SIC_TO_CEC_PORTS
082e1c4a
MF
671 SIC_PORTS(0)
672 SIC_PORTS(1)
ef016f83
MF
673 { NULL, 0, 0, 0, },
674};
675
e10d6db3
MF
676static void
677bfin_sic_port_event (struct hw *me, bu32 *isr, bu32 bit, int level)
678{
679 if (level)
680 *isr |= bit;
681 else
682 *isr &= ~bit;
683}
684
ef016f83
MF
685static void
686bfin_sic_52x_port_event (struct hw *me, int my_port, struct hw *source,
687 int source_port, int level)
688{
689 struct bfin_sic *sic = hw_data (me);
e4a861d1 690 bu32 idx = DEC_SIC (my_port);
a31d4fd9
MF
691 bu32 pin = DEC_PIN (my_port);
692 bu32 bit = 1 << pin;
693
e10d6db3
MF
694 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
695 level, my_port, idx, pin));
ef016f83
MF
696
697 /* SIC only exists to forward interrupts from the system to the CEC. */
698 switch (idx)
699 {
e10d6db3
MF
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;
ef016f83
MF
702 }
703
704 /* XXX: Handle SIC wakeup source ?
705 if (sic->bf52x.iwr0 & bit)
706 What to do ?;
707 if (sic->bf52x.iwr1 & bit)
708 What to do ?;
709 */
710
711 bfin_sic_52x_forward_interrupts (me, sic);
712}
713
ef016f83
MF
714static void
715bfin_sic_537_port_event (struct hw *me, int my_port, struct hw *source,
716 int source_port, int level)
717{
718 struct bfin_sic *sic = hw_data (me);
a31d4fd9
MF
719 bu32 idx = DEC_SIC (my_port);
720 bu32 pin = DEC_PIN (my_port);
721 bu32 bit = 1 << pin;
722
e10d6db3
MF
723 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
724 level, my_port, idx, pin));
ef016f83
MF
725
726 /* SIC only exists to forward interrupts from the system to the CEC. */
e10d6db3 727 bfin_sic_port_event (me, &sic->bf537.isr, bit, level);
ef016f83
MF
728
729 /* XXX: Handle SIC wakeup source ?
730 if (sic->bf537.iwr & bit)
731 What to do ?;
732 */
733
734 bfin_sic_537_forward_interrupts (me, sic);
735}
736
ef016f83
MF
737static void
738bfin_sic_54x_port_event (struct hw *me, int my_port, struct hw *source,
739 int source_port, int level)
740{
741 struct bfin_sic *sic = hw_data (me);
e4a861d1 742 bu32 idx = DEC_SIC (my_port);
a31d4fd9
MF
743 bu32 pin = DEC_PIN (my_port);
744 bu32 bit = 1 << pin;
745
e10d6db3
MF
746 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
747 level, my_port, idx, pin));
ef016f83
MF
748
749 /* SIC only exists to forward interrupts from the system to the CEC. */
750 switch (idx)
751 {
e10d6db3
MF
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;
ef016f83
MF
755 }
756
757 /* XXX: Handle SIC wakeup source ?
758 if (sic->bf54x.iwr0 & bit)
759 What to do ?;
760 if (sic->bf54x.iwr1 & bit)
761 What to do ?;
762 if (sic->bf54x.iwr2 & bit)
763 What to do ?;
764 */
765
766 bfin_sic_54x_forward_interrupts (me, sic);
767}
768
ef016f83
MF
769static void
770bfin_sic_561_port_event (struct hw *me, int my_port, struct hw *source,
771 int source_port, int level)
772{
773 struct bfin_sic *sic = hw_data (me);
e4a861d1 774 bu32 idx = DEC_SIC (my_port);
a31d4fd9
MF
775 bu32 pin = DEC_PIN (my_port);
776 bu32 bit = 1 << pin;
777
e10d6db3
MF
778 HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
779 level, my_port, idx, pin));
ef016f83
MF
780
781 /* SIC only exists to forward interrupts from the system to the CEC. */
782 switch (idx)
783 {
e10d6db3
MF
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;
ef016f83
MF
786 }
787
788 /* XXX: Handle SIC wakeup source ?
789 if (sic->bf561.iwr0 & bit)
790 What to do ?;
791 if (sic->bf561.iwr1 & bit)
792 What to do ?;
793 */
794
795 bfin_sic_561_forward_interrupts (me, sic);
796}
797
ef016f83
MF
798static void
799attach_bfin_sic_regs (struct hw *me, struct bfin_sic *sic)
800{
801 address_word attach_address;
802 int attach_space;
803 unsigned attach_size;
804 reg_property_spec reg;
805
806 if (hw_find_property (me, "reg") == NULL)
807 hw_abort (me, "Missing \"reg\" property");
808
809 if (!hw_find_reg_array_property (me, "reg", 0, &reg))
810 hw_abort (me, "\"reg\" property must contain three addr/size entries");
811
812 hw_unit_address_to_attach_address (hw_parent (me),
813 &reg.address,
814 &attach_space, &attach_address, me);
815 hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
816
817 if (attach_size != BFIN_MMR_SIC_SIZE)
818 hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_SIC_SIZE);
819
820 hw_attach_address (hw_parent (me),
821 0, attach_space, attach_address, attach_size, me);
822
823 sic->base = attach_address;
824}
825
826static void
827bfin_sic_finish (struct hw *me)
828{
829 struct bfin_sic *sic;
830
831 sic = HW_ZALLOC (me, struct bfin_sic);
832
833 set_hw_data (me, sic);
834 attach_bfin_sic_regs (me, sic);
835
836 switch (hw_find_integer_property (me, "type"))
837 {
838 case 500 ... 509:
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);
082e1c4a 841 set_hw_ports (me, bfin_sic2_ports);
ef016f83
MF
842 set_hw_port_event (me, bfin_sic_52x_port_event);
843 mmr_names = bf52x_mmr_names;
844
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 */
857 break;
858 case 510 ... 519:
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);
082e1c4a 861 set_hw_ports (me, bfin_sic2_ports);
ef016f83
MF
862 set_hw_port_event (me, bfin_sic_52x_port_event);
863 mmr_names = bf52x_mmr_names;
864
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 */
877 break;
878 case 522 ... 527:
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);
082e1c4a 881 set_hw_ports (me, bfin_sic2_ports);
ef016f83
MF
882 set_hw_port_event (me, bfin_sic_52x_port_event);
883 mmr_names = bf52x_mmr_names;
884
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 */
897 break;
898 case 531 ... 533:
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);
082e1c4a 901 set_hw_ports (me, bfin_sic1_ports);
e4a861d1 902 set_hw_port_event (me, bfin_sic_537_port_event);
ef016f83
MF
903 mmr_names = bf537_mmr_names;
904
905 /* Initialize the SIC. */
906 sic->bf537.imask = 0;
907 sic->bf537.isr = 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 */
913 break;
914 case 534:
915 case 536:
916 case 537:
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);
082e1c4a 919 set_hw_ports (me, bfin_sic1_ports);
ef016f83
MF
920 set_hw_port_event (me, bfin_sic_537_port_event);
921 mmr_names = bf537_mmr_names;
922
923 /* Initialize the SIC. */
924 sic->bf537.imask = 0;
925 sic->bf537.isr = 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;
931 break;
932 case 538 ... 539:
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);
082e1c4a 935 set_hw_ports (me, bfin_sic2_ports);
ef016f83
MF
936 set_hw_port_event (me, bfin_sic_52x_port_event);
937 mmr_names = bf52x_mmr_names;
938
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 */
951 break;
952 case 540 ... 549:
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);
082e1c4a 955 set_hw_ports (me, bfin_sic3_ports);
ef016f83
MF
956 set_hw_port_event (me, bfin_sic_54x_port_event);
957 mmr_names = bf54x_mmr_names;
958
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;
8d72c970 962 sic->bf54x.iwr0 = sic->bf54x.iwr1 = sic->bf54x.iwr2 = 0xFFFFFFFF;
ef016f83
MF
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;
975 break;
976 case 561:
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;
982
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;
995 break;
996 case 590 ... 599:
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);
082e1c4a 999 set_hw_ports (me, bfin_sic1_ports);
e4a861d1 1000 set_hw_port_event (me, bfin_sic_537_port_event);
ef016f83
MF
1001 mmr_names = bf537_mmr_names;
1002
1003 /* Initialize the SIC. */
1004 sic->bf537.imask = 0;
1005 sic->bf537.isr = 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;
1011 break;
1012 default:
1013 hw_abort (me, "no support for SIC on this Blackfin model yet");
1014 }
1015}
1016
81d126c3
MF
1017const struct hw_descriptor dv_bfin_sic_descriptor[] =
1018{
ef016f83
MF
1019 {"bfin_sic", bfin_sic_finish,},
1020 {NULL, NULL},
1021};
This page took 0.52507 seconds and 4 git commands to generate.