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
28struct 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
73static 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};
80static 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};
85static 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};
93static 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};
100static const char * const *mmr_names;
101#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
102
103static void
104bfin_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
135static void
136bfin_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
142static unsigned
143bfin_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
197static unsigned
198bfin_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
242static void
243bfin_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
248static unsigned
249bfin_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
302static unsigned
303bfin_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
346static void
347bfin_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
354static unsigned
355bfin_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
405static unsigned
406bfin_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
446static void
447bfin_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
453static unsigned
454bfin_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
508static unsigned
509bfin_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
571static 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
635static 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
699static 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
761static void
762bfin_sic_52x_port_event (struct hw *me, int my_port, struct hw *source,
763			 int source_port, int level)
764{
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;
769
770  HW_TRACE ((me, "processing system int from %i (SIC %u pin %u)",
771	     my_port, idx, pin));
772
773  /* SIC only exists to forward interrupts from the system to the CEC.  */
774  switch (idx)
775    {
776    case 0: sic->bf52x.isr0 |= bit; break;
777    case 1: sic->bf52x.isr1 |= bit; break;
778    }
779
780  /* XXX: Handle SIC wakeup source ?
781  if (sic->bf52x.iwr0 & bit)
782    What to do ?;
783  if (sic->bf52x.iwr1 & bit)
784    What to do ?;
785   */
786
787  bfin_sic_52x_forward_interrupts (me, sic);
788}
789
790static const struct hw_port_descriptor bfin_sic_533_ports[] =
791{
792  BFIN_SIC_TO_CEC_PORTS
793  { "pll",             ENC(0,  0), 0, input_port, },
794  { "dma_stat",        ENC(0,  1), 0, input_port, },
795  { "ppi@0",           ENC(0,  2), 0, input_port, },
796  { "sport@0_stat",    ENC(0,  3), 0, input_port, },
797  { "sport@1_stat",    ENC(0,  4), 0, input_port, },
798  { "spi@0",           ENC(0,  5), 0, input_port, },
799  { "uart@0_stat",     ENC(0,  6), 0, input_port, },
800  { "rtc",             ENC(0,  7), 0, input_port, },
801  { "dma@0",           ENC(0,  8), 0, input_port, },
802  { "dma@1",           ENC(0,  9), 0, input_port, },
803  { "dma@2",           ENC(0, 10), 0, input_port, },
804  { "dma@3",           ENC(0, 11), 0, input_port, },
805  { "dma@4",           ENC(0, 12), 0, input_port, },
806  { "dma@5",           ENC(0, 13), 0, input_port, },
807  { "dma@6",           ENC(0, 14), 0, input_port, },
808  { "dma@7",           ENC(0, 15), 0, input_port, },
809  { "gptimer@0",       ENC(0, 16), 0, input_port, },
810  { "gptimer@1",       ENC(0, 17), 0, input_port, },
811  { "gptimer@2",       ENC(0, 18), 0, input_port, },
812  { "portf_irq_a",     ENC(0, 19), 0, input_port, },
813  { "portf_irq_b",     ENC(0, 20), 0, input_port, },
814  { "mdma@0",          ENC(0, 21), 0, input_port, },
815  { "mdma@1",          ENC(0, 22), 0, input_port, },
816  { "wdog",            ENC(0, 23), 0, input_port, },
817  { NULL, 0, 0, 0, },
818};
819
820/* The encoding here is uglier due to multiple sources being muxed into
821   the same interrupt line.  So give each pin an arbitrary "SIC" so that
822   the resulting id is unique across all ports.  */
823static const struct hw_port_descriptor bfin_sic_537_ports[] =
824{
825  BFIN_SIC_TO_CEC_PORTS
826  { "pll",             ENC(0,  0), 0, input_port, },
827  { "dma_stat",        ENC(0,  1), 0, input_port, },
828  { "dmar0_block",     ENC(1,  1), 0, input_port, },
829  { "dmar1_block",     ENC(2,  1), 0, input_port, },
830  { "dmar0_over",      ENC(3,  1), 0, input_port, },
831  { "dmar1_over",      ENC(4,  1), 0, input_port, },
832  { "can_stat",        ENC(0,  2), 0, input_port, },
833  { "emac_stat",       ENC(1,  2), 0, input_port, },
834  { "sport@0_stat",    ENC(2,  2), 0, input_port, },
835  { "sport@1_stat",    ENC(3,  2), 0, input_port, },
836  { "ppi@0",           ENC(4,  2), 0, input_port, },
837  { "spi@0",           ENC(5,  2), 0, input_port, },
838  { "uart@0_stat",     ENC(6,  2), 0, input_port, },
839  { "uart@1_stat",     ENC(7,  2), 0, input_port, },
840  { "rtc",             ENC(0,  3), 0, input_port, },
841  { "dma@0",           ENC(0,  4), 0, input_port, },
842  { "dma@3",           ENC(0,  5), 0, input_port, },
843  { "dma@4",           ENC(0,  6), 0, input_port, },
844  { "dma@5",           ENC(0,  7), 0, input_port, },
845  { "dma@6",           ENC(0,  8), 0, input_port, },
846  { "twi@0",           ENC(0,  9), 0, input_port, },
847  { "dma@7",           ENC(0, 10), 0, input_port, },
848  { "dma@8",           ENC(0, 11), 0, input_port, },
849  { "dma@9",           ENC(0, 12), 0, input_port, },
850  { "dma@10",          ENC(0, 13), 0, input_port, },
851  { "dma@11",          ENC(0, 14), 0, input_port, },
852  { "can_rx",          ENC(0, 15), 0, input_port, },
853  { "can_tx",          ENC(0, 16), 0, input_port, },
854  { "dma@1",           ENC(0, 17), 0, input_port, },
855  { "porth_irq_a",     ENC(1, 17), 0, input_port, },
856  { "dma@2",           ENC(0, 18), 0, input_port, },
857  { "porth_irq_b",     ENC(1, 18), 0, input_port, },
858  { "gptimer@0",       ENC(0, 19), 0, input_port, },
859  { "gptimer@1",       ENC(0, 20), 0, input_port, },
860  { "gptimer@2",       ENC(0, 21), 0, input_port, },
861  { "gptimer@3",       ENC(0, 22), 0, input_port, },
862  { "gptimer@4",       ENC(0, 23), 0, input_port, },
863  { "gptimer@5",       ENC(0, 24), 0, input_port, },
864  { "gptimer@6",       ENC(0, 25), 0, input_port, },
865  { "gptimer@7",       ENC(0, 26), 0, input_port, },
866  { "portf_irq_a",     ENC(0, 27), 0, input_port, },
867  { "portg_irq_a",     ENC(1, 27), 0, input_port, },
868  { "portg_irq_b",     ENC(0, 28), 0, input_port, },
869  { "mdma@0",          ENC(0, 29), 0, input_port, },
870  { "mdma@1",          ENC(0, 30), 0, input_port, },
871  { "wdog",            ENC(0, 31), 0, input_port, },
872  { "portf_irq_b",     ENC(1, 31), 0, input_port, },
873  { NULL, 0, 0, 0, },
874};
875
876static void
877bfin_sic_537_port_event (struct hw *me, int my_port, struct hw *source,
878			 int source_port, int level)
879{
880  struct bfin_sic *sic = hw_data (me);
881  bu32 idx = DEC_SIC (my_port);
882  bu32 pin = DEC_PIN (my_port);
883  bu32 bit = 1 << pin;
884
885  HW_TRACE ((me, "processing system int from %i (SIC %u pin %u)",
886	     my_port, idx, pin));
887
888  /* SIC only exists to forward interrupts from the system to the CEC.  */
889  sic->bf537.isr |= bit;
890
891  /* XXX: Handle SIC wakeup source ?
892  if (sic->bf537.iwr & bit)
893    What to do ?;
894   */
895
896  bfin_sic_537_forward_interrupts (me, sic);
897}
898
899static const struct hw_port_descriptor bfin_sic_538_ports[] =
900{
901  BFIN_SIC_TO_CEC_PORTS
902  /* SIC0 */
903  { "pll",             ENC(0,  0), 0, input_port, },
904  { "dmac@0_stat",     ENC(0,  1), 0, input_port, },
905  { "ppi@0",           ENC(0,  2), 0, input_port, },
906  { "sport@0_stat",    ENC(0,  3), 0, input_port, },
907  { "sport@1_stat",    ENC(0,  4), 0, input_port, },
908  { "spi@0",           ENC(0,  5), 0, input_port, },
909  { "uart@0_stat",     ENC(0,  6), 0, input_port, },
910  { "rtc",             ENC(0,  7), 0, input_port, },
911  { "dma@0",           ENC(0,  8), 0, input_port, },
912  { "dma@1",           ENC(0,  9), 0, input_port, },
913  { "dma@2",           ENC(0, 10), 0, input_port, },
914  { "dma@3",           ENC(0, 11), 0, input_port, },
915  { "dma@4",           ENC(0, 12), 0, input_port, },
916  { "dma@5",           ENC(0, 13), 0, input_port, },
917  { "dma@6",           ENC(0, 14), 0, input_port, },
918  { "dma@7",           ENC(0, 15), 0, input_port, },
919  { "gptimer@0",       ENC(0, 16), 0, input_port, },
920  { "gptimer@1",       ENC(0, 17), 0, input_port, },
921  { "gptimer@2",       ENC(0, 18), 0, input_port, },
922  { "portf_irq_a",     ENC(0, 19), 0, input_port, },
923  { "portf_irq_b",     ENC(0, 20), 0, input_port, },
924  { "mdma@0",          ENC(0, 21), 0, input_port, },
925  { "mdma@1",          ENC(0, 22), 0, input_port, },
926  { "wdog",            ENC(0, 23), 0, input_port, },
927  { "dmac@1_stat",     ENC(0, 24), 0, input_port, },
928  { "sport@2_stat",    ENC(0, 25), 0, input_port, },
929  { "sport@3_stat",    ENC(0, 26), 0, input_port, },
930/*{ "reserved",        ENC(0, 27), 0, input_port, },*/
931  { "spi@1",           ENC(0, 28), 0, input_port, },
932  { "spi@2",           ENC(0, 29), 0, input_port, },
933  { "uart@1_stat",     ENC(0, 30), 0, input_port, },
934  { "uart@2_stat",     ENC(0, 31), 0, input_port, },
935  /* SIC1 */
936  { "can_stat",        ENC(1,  0), 0, input_port, },
937  { "dma@8",           ENC(1,  1), 0, input_port, },
938  { "dma@9",           ENC(1,  2), 0, input_port, },
939  { "dma@10",          ENC(1,  3), 0, input_port, },
940  { "dma@11",          ENC(1,  4), 0, input_port, },
941  { "dma@12",          ENC(1,  5), 0, input_port, },
942  { "dma@13",          ENC(1,  6), 0, input_port, },
943  { "dma@14",          ENC(1,  7), 0, input_port, },
944  { "dma@15",          ENC(1,  8), 0, input_port, },
945  { "dma@16",          ENC(1,  9), 0, input_port, },
946  { "dma@17",          ENC(1, 10), 0, input_port, },
947  { "dma@18",          ENC(1, 11), 0, input_port, },
948  { "dma@19",          ENC(1, 12), 0, input_port, },
949  { "twi@0",           ENC(1, 13), 0, input_port, },
950  { "twi@1",           ENC(1, 14), 0, input_port, },
951  { "can_rx",          ENC(1, 15), 0, input_port, },
952  { "can_tx",          ENC(1, 16), 0, input_port, },
953  { "mdma@2",          ENC(1, 17), 0, input_port, },
954  { "mdma@3",          ENC(1, 18), 0, input_port, },
955  { NULL, 0, 0, 0, },
956};
957
958static const struct hw_port_descriptor bfin_sic_54x_ports[] =
959{
960  BFIN_SIC_TO_CEC_PORTS
961  /* SIC0 */
962  { "pll",             ENC(0,  0), 0, input_port, },
963  { "dmac@0_stat",     ENC(0,  1), 0, input_port, },
964  { "eppi@0",          ENC(0,  2), 0, input_port, },
965  { "sport@0_stat",    ENC(0,  3), 0, input_port, },
966  { "sport@1_stat",    ENC(0,  4), 0, input_port, },
967  { "spi@0",           ENC(0,  5), 0, input_port, },
968  { "uart2@0_stat",    ENC(0,  6), 0, input_port, },
969  { "rtc",             ENC(0,  7), 0, input_port, },
970  { "dma@12",          ENC(0,  8), 0, input_port, },
971  { "dma@0",           ENC(0,  9), 0, input_port, },
972  { "dma@1",           ENC(0, 10), 0, input_port, },
973  { "dma@2",           ENC(0, 11), 0, input_port, },
974  { "dma@3",           ENC(0, 12), 0, input_port, },
975  { "dma@4",           ENC(0, 13), 0, input_port, },
976  { "dma@6",           ENC(0, 14), 0, input_port, },
977  { "dma@7",           ENC(0, 15), 0, input_port, },
978  { "gptimer@8",       ENC(0, 16), 0, input_port, },
979  { "gptimer@9",       ENC(0, 17), 0, input_port, },
980  { "gptimer@10",      ENC(0, 18), 0, input_port, },
981  { "pint@0",          ENC(0, 19), 0, input_port, },
982  { "pint@1",          ENC(0, 20), 0, input_port, },
983  { "mdma@0",          ENC(0, 21), 0, input_port, },
984  { "mdma@1",          ENC(0, 22), 0, input_port, },
985  { "wdog",            ENC(0, 23), 0, input_port, },
986  { "dmac@1_stat",     ENC(0, 24), 0, input_port, },
987  { "sport@2_stat",    ENC(0, 25), 0, input_port, },
988  { "sport@3_stat",    ENC(0, 26), 0, input_port, },
989  { "mxvr",            ENC(0, 27), 0, input_port, },
990  { "spi@1",           ENC(0, 28), 0, input_port, },
991  { "spi@2",           ENC(0, 29), 0, input_port, },
992  { "uart2@1_stat",    ENC(0, 30), 0, input_port, },
993  { "uart2@2_stat",    ENC(0, 31), 0, input_port, },
994  /* SIC1 */
995  { "can@0_stat",      ENC(1,  0), 0, input_port, },
996  { "dma@18",          ENC(1,  1), 0, input_port, },
997  { "dma@19",          ENC(1,  2), 0, input_port, },
998  { "dma@20",          ENC(1,  3), 0, input_port, },
999  { "dma@21",          ENC(1,  4), 0, input_port, },
1000  { "dma@13",          ENC(1,  5), 0, input_port, },
1001  { "dma@14",          ENC(1,  6), 0, input_port, },
1002  { "dma@5",           ENC(1,  7), 0, input_port, },
1003  { "dma@23",          ENC(1,  8), 0, input_port, },
1004  { "dma@8",           ENC(1,  9), 0, input_port, },
1005  { "dma@9",           ENC(1, 10), 0, input_port, },
1006  { "dma@10",          ENC(1, 11), 0, input_port, },
1007  { "dma@11",          ENC(1, 12), 0, input_port, },
1008  { "twi@0",           ENC(1, 13), 0, input_port, },
1009  { "twi@1",           ENC(1, 14), 0, input_port, },
1010  { "can@0_rx",        ENC(1, 15), 0, input_port, },
1011  { "can@0_tx",        ENC(1, 16), 0, input_port, },
1012  { "mdma@2",          ENC(1, 17), 0, input_port, },
1013  { "mdma@3",          ENC(1, 18), 0, input_port, },
1014  { "mxvr_stat",       ENC(1, 19), 0, input_port, },
1015  { "mxvr_message",    ENC(1, 20), 0, input_port, },
1016  { "mxvr_packet",     ENC(1, 21), 0, input_port, },
1017  { "eppi@1",          ENC(1, 22), 0, input_port, },
1018  { "eppi@2",          ENC(1, 23), 0, input_port, },
1019  { "uart2@3_stat",    ENC(1, 24), 0, input_port, },
1020  { "hostdp",          ENC(1, 25), 0, input_port, },
1021/*{ "reserved",        ENC(1, 26), 0, input_port, },*/
1022  { "pixc_stat",       ENC(1, 27), 0, input_port, },
1023  { "nfc",             ENC(1, 28), 0, input_port, },
1024  { "atapi",           ENC(1, 29), 0, input_port, },
1025  { "can@1_stat",      ENC(1, 30), 0, input_port, },
1026  { "dmar",            ENC(1, 31), 0, input_port, },
1027  /* SIC2 */
1028  { "dma@15",          ENC(2,  0), 0, input_port, },
1029  { "dma@16",          ENC(2,  1), 0, input_port, },
1030  { "dma@17",          ENC(2,  2), 0, input_port, },
1031  { "dma@22",          ENC(2,  3), 0, input_port, },
1032  { "counter",         ENC(2,  4), 0, input_port, },
1033  { "key",             ENC(2,  5), 0, input_port, },
1034  { "can@1_rx",        ENC(2,  6), 0, input_port, },
1035  { "can@1_tx",        ENC(2,  7), 0, input_port, },
1036  { "sdh_mask0",       ENC(2,  8), 0, input_port, },
1037  { "sdh_mask1",       ENC(2,  9), 0, input_port, },
1038/*{ "reserved",        ENC(2, 10), 0, input_port, },*/
1039  { "usb_int0",        ENC(2, 11), 0, input_port, },
1040  { "usb_int1",        ENC(2, 12), 0, input_port, },
1041  { "usb_int2",        ENC(2, 13), 0, input_port, },
1042  { "usb_dma",         ENC(2, 14), 0, input_port, },
1043  { "otpsec",          ENC(2, 15), 0, input_port, },
1044/*{ "reserved",        ENC(2, 16), 0, input_port, },*/
1045/*{ "reserved",        ENC(2, 17), 0, input_port, },*/
1046/*{ "reserved",        ENC(2, 18), 0, input_port, },*/
1047/*{ "reserved",        ENC(2, 19), 0, input_port, },*/
1048/*{ "reserved",        ENC(2, 20), 0, input_port, },*/
1049/*{ "reserved",        ENC(2, 21), 0, input_port, },*/
1050  { "gptimer@0",       ENC(2, 22), 0, input_port, },
1051  { "gptimer@1",       ENC(2, 23), 0, input_port, },
1052  { "gptimer@2",       ENC(2, 24), 0, input_port, },
1053  { "gptimer@3",       ENC(2, 25), 0, input_port, },
1054  { "gptimer@4",       ENC(2, 26), 0, input_port, },
1055  { "gptimer@5",       ENC(2, 27), 0, input_port, },
1056  { "gptimer@6",       ENC(2, 28), 0, input_port, },
1057  { "gptimer@7",       ENC(2, 29), 0, input_port, },
1058  { "pint2",           ENC(2, 30), 0, input_port, },
1059  { "pint3",           ENC(2, 31), 0, input_port, },
1060  { NULL, 0, 0, 0, },
1061};
1062
1063static void
1064bfin_sic_54x_port_event (struct hw *me, int my_port, struct hw *source,
1065			 int source_port, int level)
1066{
1067  struct bfin_sic *sic = hw_data (me);
1068  bu32 idx = DEC_SIC (my_port);
1069  bu32 pin = DEC_PIN (my_port);
1070  bu32 bit = 1 << pin;
1071
1072  HW_TRACE ((me, "processing system int from %i (SIC %u pin %u)",
1073	     my_port, idx, pin));
1074
1075  /* SIC only exists to forward interrupts from the system to the CEC.  */
1076  switch (idx)
1077    {
1078    case 0: sic->bf54x.isr0 |= bit; break;
1079    case 1: sic->bf54x.isr1 |= bit; break;
1080    case 2: sic->bf54x.isr2 |= bit; break;
1081    }
1082
1083  /* XXX: Handle SIC wakeup source ?
1084  if (sic->bf54x.iwr0 & bit)
1085    What to do ?;
1086  if (sic->bf54x.iwr1 & bit)
1087    What to do ?;
1088  if (sic->bf54x.iwr2 & bit)
1089    What to do ?;
1090   */
1091
1092  bfin_sic_54x_forward_interrupts (me, sic);
1093}
1094
1095static const struct hw_port_descriptor bfin_sic_561_ports[] =
1096{
1097  BFIN_SIC_TO_CEC_PORTS
1098  /* SIC0 */
1099  { "pll",             ENC(0,  0), 0, input_port, },
1100  { "dmac@0_stat",     ENC(0,  1), 0, input_port, },
1101  { "dmac@1_stat",     ENC(0,  2), 0, input_port, },
1102  { "imdma_stat",      ENC(0,  3), 0, input_port, },
1103  { "ppi@0",           ENC(0,  4), 0, input_port, },
1104  { "ppi@1",           ENC(0,  5), 0, input_port, },
1105  { "sport@0_stat",    ENC(0,  6), 0, input_port, },
1106  { "sport@1_stat",    ENC(0,  7), 0, input_port, },
1107  { "spi@0",           ENC(0,  8), 0, input_port, },
1108  { "uart@0_stat",     ENC(0,  9), 0, input_port, },
1109/*{ "reserved",        ENC(0, 10), 0, input_port, },*/
1110  { "dma@12",          ENC(0, 11), 0, input_port, },
1111  { "dma@13",          ENC(0, 12), 0, input_port, },
1112  { "dma@14",          ENC(0, 13), 0, input_port, },
1113  { "dma@15",          ENC(0, 14), 0, input_port, },
1114  { "dma@16",          ENC(0, 15), 0, input_port, },
1115  { "dma@17",          ENC(0, 16), 0, input_port, },
1116  { "dma@18",          ENC(0, 17), 0, input_port, },
1117  { "dma@19",          ENC(0, 18), 0, input_port, },
1118  { "dma@20",          ENC(0, 19), 0, input_port, },
1119  { "dma@21",          ENC(0, 20), 0, input_port, },
1120  { "dma@22",          ENC(0, 21), 0, input_port, },
1121  { "dma@23",          ENC(0, 22), 0, input_port, },
1122  { "dma@0",           ENC(0, 23), 0, input_port, },
1123  { "dma@1",           ENC(0, 24), 0, input_port, },
1124  { "dma@2",           ENC(0, 25), 0, input_port, },
1125  { "dma@3",           ENC(0, 26), 0, input_port, },
1126  { "dma@4",           ENC(0, 27), 0, input_port, },
1127  { "dma@5",           ENC(0, 28), 0, input_port, },
1128  { "dma@6",           ENC(0, 29), 0, input_port, },
1129  { "dma@7",           ENC(0, 30), 0, input_port, },
1130  { "dma@8",           ENC(0, 31), 0, input_port, },
1131  /* SIC1 */
1132  { "dma@9",           ENC(1,  0), 0, input_port, },
1133  { "dma@10",          ENC(1,  1), 0, input_port, },
1134  { "dma@11",          ENC(1,  2), 0, input_port, },
1135  { "gptimer@0",       ENC(1,  3), 0, input_port, },
1136  { "gptimer@1",       ENC(1,  4), 0, input_port, },
1137  { "gptimer@2",       ENC(1,  5), 0, input_port, },
1138  { "gptimer@3",       ENC(1,  6), 0, input_port, },
1139  { "gptimer@4",       ENC(1,  7), 0, input_port, },
1140  { "gptimer@5",       ENC(1,  8), 0, input_port, },
1141  { "gptimer@6",       ENC(1,  9), 0, input_port, },
1142  { "gptimer@7",       ENC(1, 10), 0, input_port, },
1143  { "gptimer@8",       ENC(1, 11), 0, input_port, },
1144  { "gptimer@9",       ENC(1, 12), 0, input_port, },
1145  { "gptimer@10",      ENC(1, 13), 0, input_port, },
1146  { "gptimer@11",      ENC(1, 14), 0, input_port, },
1147  { "portf_irq_a",     ENC(1, 15), 0, input_port, },
1148  { "portf_irq_b",     ENC(1, 16), 0, input_port, },
1149  { "portg_irq_a",     ENC(1, 17), 0, input_port, },
1150  { "portg_irq_b",     ENC(1, 18), 0, input_port, },
1151  { "porth_irq_a",     ENC(1, 19), 0, input_port, },
1152  { "porth_irq_b",     ENC(1, 20), 0, input_port, },
1153  { "mdma@0",          ENC(1, 21), 0, input_port, },
1154  { "mdma@1",          ENC(1, 22), 0, input_port, },
1155  { "mdma@2",          ENC(1, 23), 0, input_port, },
1156  { "mdma@3",          ENC(1, 24), 0, input_port, },
1157  { "imdma@0",         ENC(1, 25), 0, input_port, },
1158  { "imdma@1",         ENC(1, 26), 0, input_port, },
1159  { "wdog",            ENC(1, 27), 0, input_port, },
1160/*{ "reserved",        ENC(1, 28), 0, input_port, },*/
1161/*{ "reserved",        ENC(1, 29), 0, input_port, },*/
1162  { "sup_irq_0",       ENC(1, 30), 0, input_port, },
1163  { "sup_irq_1",       ENC(1, 31), 0, input_port, },
1164  { NULL, 0, 0, 0, },
1165};
1166
1167static void
1168bfin_sic_561_port_event (struct hw *me, int my_port, struct hw *source,
1169			 int source_port, int level)
1170{
1171  struct bfin_sic *sic = hw_data (me);
1172  bu32 idx = DEC_SIC (my_port);
1173  bu32 pin = DEC_PIN (my_port);
1174  bu32 bit = 1 << pin;
1175
1176  HW_TRACE ((me, "processing system int from %i (SIC %u pin %u)",
1177	     my_port, idx, pin));
1178
1179  /* SIC only exists to forward interrupts from the system to the CEC.  */
1180  switch (idx)
1181    {
1182    case 0: sic->bf561.isr0 |= bit; break;
1183    case 1: sic->bf561.isr1 |= bit; break;
1184    }
1185
1186  /* XXX: Handle SIC wakeup source ?
1187  if (sic->bf561.iwr0 & bit)
1188    What to do ?;
1189  if (sic->bf561.iwr1 & bit)
1190    What to do ?;
1191   */
1192
1193  bfin_sic_561_forward_interrupts (me, sic);
1194}
1195
1196static const struct hw_port_descriptor bfin_sic_59x_ports[] =
1197{
1198  BFIN_SIC_TO_CEC_PORTS
1199  { "pll",             ENC(0,  0), 0, input_port, },
1200  { "dma_stat",        ENC(0,  1), 0, input_port, },
1201  { "ppi@0",           ENC(0,  2), 0, input_port, },
1202  { "sport@0_stat",    ENC(0,  3), 0, input_port, },
1203  { "sport@1_stat",    ENC(0,  4), 0, input_port, },
1204  { "spi@0",           ENC(0,  5), 0, input_port, },
1205  { "spi@1",           ENC(0,  6), 0, input_port, },
1206  { "uart@0_stat",     ENC(0,  7), 0, input_port, },
1207  { "dma@0",           ENC(0,  8), 0, input_port, },
1208  { "dma@1",           ENC(0,  9), 0, input_port, },
1209  { "dma@2",           ENC(0, 10), 0, input_port, },
1210  { "dma@3",           ENC(0, 11), 0, input_port, },
1211  { "dma@4",           ENC(0, 12), 0, input_port, },
1212  { "dma@5",           ENC(0, 13), 0, input_port, },
1213  { "dma@6",           ENC(0, 14), 0, input_port, },
1214  { "dma@7",           ENC(0, 15), 0, input_port, },
1215  { "dma@8",           ENC(0, 16), 0, input_port, },
1216  { "portf_irq_a",     ENC(0, 17), 0, input_port, },
1217  { "portf_irq_b",     ENC(0, 18), 0, input_port, },
1218  { "gptimer@0",       ENC(0, 19), 0, input_port, },
1219  { "gptimer@1",       ENC(0, 20), 0, input_port, },
1220  { "gptimer@2",       ENC(0, 21), 0, input_port, },
1221  { "portg_irq_a",     ENC(0, 22), 0, input_port, },
1222  { "portg_irq_b",     ENC(0, 23), 0, input_port, },
1223  { "twi@0",           ENC(0, 24), 0, input_port, },
1224/* XXX: 25 - 28 are supposed to be reserved; see comment in machs.c:bf592_dmac[]  */
1225  { "dma@9",           ENC(0, 25), 0, input_port, },
1226  { "dma@10",          ENC(0, 26), 0, input_port, },
1227  { "dma@11",          ENC(0, 27), 0, input_port, },
1228  { "dma@12",          ENC(0, 28), 0, input_port, },
1229/*{ "reserved",        ENC(0, 25), 0, input_port, },*/
1230/*{ "reserved",        ENC(0, 26), 0, input_port, },*/
1231/*{ "reserved",        ENC(0, 27), 0, input_port, },*/
1232/*{ "reserved",        ENC(0, 28), 0, input_port, },*/
1233  { "mdma@0",          ENC(0, 29), 0, input_port, },
1234  { "mdma@1",          ENC(0, 30), 0, input_port, },
1235  { "wdog",            ENC(0, 31), 0, input_port, },
1236  { NULL, 0, 0, 0, },
1237};
1238
1239static void
1240attach_bfin_sic_regs (struct hw *me, struct bfin_sic *sic)
1241{
1242  address_word attach_address;
1243  int attach_space;
1244  unsigned attach_size;
1245  reg_property_spec reg;
1246
1247  if (hw_find_property (me, "reg") == NULL)
1248    hw_abort (me, "Missing \"reg\" property");
1249
1250  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
1251    hw_abort (me, "\"reg\" property must contain three addr/size entries");
1252
1253  hw_unit_address_to_attach_address (hw_parent (me),
1254				     &reg.address,
1255				     &attach_space, &attach_address, me);
1256  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
1257
1258  if (attach_size != BFIN_MMR_SIC_SIZE)
1259    hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_SIC_SIZE);
1260
1261  hw_attach_address (hw_parent (me),
1262		     0, attach_space, attach_address, attach_size, me);
1263
1264  sic->base = attach_address;
1265}
1266
1267static void
1268bfin_sic_finish (struct hw *me)
1269{
1270  struct bfin_sic *sic;
1271
1272  sic = HW_ZALLOC (me, struct bfin_sic);
1273
1274  set_hw_data (me, sic);
1275  attach_bfin_sic_regs (me, sic);
1276
1277  switch (hw_find_integer_property (me, "type"))
1278    {
1279    case 500 ... 509:
1280      set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
1281      set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
1282      set_hw_ports (me, bfin_sic_50x_ports);
1283      set_hw_port_event (me, bfin_sic_52x_port_event);
1284      mmr_names = bf52x_mmr_names;
1285
1286      /* Initialize the SIC.  */
1287      sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
1288      sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
1289      sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
1290      sic->bf52x.iar0 = 0x00000000;
1291      sic->bf52x.iar1 = 0x22111000;
1292      sic->bf52x.iar2 = 0x33332222;
1293      sic->bf52x.iar3 = 0x44444433;
1294      sic->bf52x.iar4 = 0x55555555;
1295      sic->bf52x.iar5 = 0x06666655;
1296      sic->bf52x.iar6 = 0x33333003;
1297      sic->bf52x.iar7 = 0x00000000;	/* XXX: Find and fix */
1298      break;
1299    case 510 ... 519:
1300      set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
1301      set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
1302      set_hw_ports (me, bfin_sic_51x_ports);
1303      set_hw_port_event (me, bfin_sic_52x_port_event);
1304      mmr_names = bf52x_mmr_names;
1305
1306      /* Initialize the SIC.  */
1307      sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
1308      sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
1309      sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
1310      sic->bf52x.iar0 = 0x00000000;
1311      sic->bf52x.iar1 = 0x11000000;
1312      sic->bf52x.iar2 = 0x33332222;
1313      sic->bf52x.iar3 = 0x44444433;
1314      sic->bf52x.iar4 = 0x55555555;
1315      sic->bf52x.iar5 = 0x06666655;
1316      sic->bf52x.iar6 = 0x33333000;
1317      sic->bf52x.iar7 = 0x00000000;	/* XXX: Find and fix */
1318      break;
1319    case 522 ... 527:
1320      set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
1321      set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
1322      set_hw_ports (me, bfin_sic_52x_ports);
1323      set_hw_port_event (me, bfin_sic_52x_port_event);
1324      mmr_names = bf52x_mmr_names;
1325
1326      /* Initialize the SIC.  */
1327      sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
1328      sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
1329      sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
1330      sic->bf52x.iar0 = 0x00000000;
1331      sic->bf52x.iar1 = 0x11000000;
1332      sic->bf52x.iar2 = 0x33332222;
1333      sic->bf52x.iar3 = 0x44444433;
1334      sic->bf52x.iar4 = 0x55555555;
1335      sic->bf52x.iar5 = 0x06666655;
1336      sic->bf52x.iar6 = 0x33333000;
1337      sic->bf52x.iar7 = 0x00000000;	/* XXX: Find and fix */
1338      break;
1339    case 531 ... 533:
1340      set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
1341      set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
1342      set_hw_ports (me, bfin_sic_533_ports);
1343      set_hw_port_event (me, bfin_sic_537_port_event);
1344      mmr_names = bf537_mmr_names;
1345
1346      /* Initialize the SIC.  */
1347      sic->bf537.imask = 0;
1348      sic->bf537.isr = 0;
1349      sic->bf537.iwr = 0xFFFFFFFF;
1350      sic->bf537.iar0 = 0x10000000;
1351      sic->bf537.iar1 = 0x33322221;
1352      sic->bf537.iar2 = 0x66655444;
1353      sic->bf537.iar3 = 0; /* XXX: fix this */
1354      break;
1355    case 534:
1356    case 536:
1357    case 537:
1358      set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
1359      set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
1360      set_hw_ports (me, bfin_sic_537_ports);
1361      set_hw_port_event (me, bfin_sic_537_port_event);
1362      mmr_names = bf537_mmr_names;
1363
1364      /* Initialize the SIC.  */
1365      sic->bf537.imask = 0;
1366      sic->bf537.isr = 0;
1367      sic->bf537.iwr = 0xFFFFFFFF;
1368      sic->bf537.iar0 = 0x22211000;
1369      sic->bf537.iar1 = 0x43333332;
1370      sic->bf537.iar2 = 0x55555444;
1371      sic->bf537.iar3 = 0x66655555;
1372      break;
1373    case 538 ... 539:
1374      set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
1375      set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
1376      set_hw_ports (me, bfin_sic_538_ports);
1377      set_hw_port_event (me, bfin_sic_52x_port_event);
1378      mmr_names = bf52x_mmr_names;
1379
1380      /* Initialize the SIC.  */
1381      sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
1382      sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
1383      sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
1384      sic->bf52x.iar0 = 0x10000000;
1385      sic->bf52x.iar1 = 0x33322221;
1386      sic->bf52x.iar2 = 0x66655444;
1387      sic->bf52x.iar3 = 0x00000000;
1388      sic->bf52x.iar4 = 0x32222220;
1389      sic->bf52x.iar5 = 0x44433333;
1390      sic->bf52x.iar6 = 0x00444664;
1391      sic->bf52x.iar7 = 0x00000000;	/* XXX: Find and fix */
1392      break;
1393    case 540 ... 549:
1394      set_hw_io_read_buffer (me, bfin_sic_54x_io_read_buffer);
1395      set_hw_io_write_buffer (me, bfin_sic_54x_io_write_buffer);
1396      set_hw_ports (me, bfin_sic_54x_ports);
1397      set_hw_port_event (me, bfin_sic_54x_port_event);
1398      mmr_names = bf54x_mmr_names;
1399
1400      /* Initialize the SIC.  */
1401      sic->bf54x.imask0 = sic->bf54x.imask1 = sic->bf54x.imask2 = 0;
1402      sic->bf54x.isr0 = sic->bf54x.isr1 = sic->bf54x.isr2 = 0;
1403      sic->bf54x.iwr0 = sic->bf54x.iwr1 = sic->bf54x.iwr1 = 0xFFFFFFFF;
1404      sic->bf54x.iar0 = 0x10000000;
1405      sic->bf54x.iar1 = 0x33322221;
1406      sic->bf54x.iar2 = 0x66655444;
1407      sic->bf54x.iar3 = 0x00000000;
1408      sic->bf54x.iar4 = 0x32222220;
1409      sic->bf54x.iar5 = 0x44433333;
1410      sic->bf54x.iar6 = 0x00444664;
1411      sic->bf54x.iar7 = 0x00000000;
1412      sic->bf54x.iar8 = 0x44111111;
1413      sic->bf54x.iar9 = 0x44444444;
1414      sic->bf54x.iar10 = 0x44444444;
1415      sic->bf54x.iar11 = 0x55444444;
1416      break;
1417    case 561:
1418      set_hw_io_read_buffer (me, bfin_sic_561_io_read_buffer);
1419      set_hw_io_write_buffer (me, bfin_sic_561_io_write_buffer);
1420      set_hw_ports (me, bfin_sic_561_ports);
1421      set_hw_port_event (me, bfin_sic_561_port_event);
1422      mmr_names = bf561_mmr_names;
1423
1424      /* Initialize the SIC.  */
1425      sic->bf561.imask0 = sic->bf561.imask1 = 0;
1426      sic->bf561.isr0 = sic->bf561.isr1 = 0;
1427      sic->bf561.iwr0 = sic->bf561.iwr1 = 0xFFFFFFFF;
1428      sic->bf561.iar0 = 0x00000000;
1429      sic->bf561.iar1 = 0x11111000;
1430      sic->bf561.iar2 = 0x21111111;
1431      sic->bf561.iar3 = 0x22222222;
1432      sic->bf561.iar4 = 0x33333222;
1433      sic->bf561.iar5 = 0x43333333;
1434      sic->bf561.iar6 = 0x21144444;
1435      sic->bf561.iar7 = 0x00006552;
1436      break;
1437    case 590 ... 599:
1438      set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
1439      set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
1440      set_hw_ports (me, bfin_sic_59x_ports);
1441      set_hw_port_event (me, bfin_sic_537_port_event);
1442      mmr_names = bf537_mmr_names;
1443
1444      /* Initialize the SIC.  */
1445      sic->bf537.imask = 0;
1446      sic->bf537.isr = 0;
1447      sic->bf537.iwr = 0xFFFFFFFF;
1448      sic->bf537.iar0 = 0x00000000;
1449      sic->bf537.iar1 = 0x33322221;
1450      sic->bf537.iar2 = 0x55444443;
1451      sic->bf537.iar3 = 0x66600005;
1452      break;
1453    default:
1454      hw_abort (me, "no support for SIC on this Blackfin model yet");
1455    }
1456}
1457
1458const struct hw_descriptor dv_bfin_sic_descriptor[] =
1459{
1460  {"bfin_sic", bfin_sic_finish,},
1461  {NULL, NULL},
1462};
1463