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