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, ®)) 1251 hw_abort (me, "\"reg\" property must contain three addr/size entries"); 1252 1253 hw_unit_address_to_attach_address (hw_parent (me), 1254 ®.address, 1255 &attach_space, &attach_address, me); 1256 hw_unit_size_to_attach_size (hw_parent (me), ®.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