123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989 |
- /* Blackfin System Interrupt Controller (SIC) model.
- Copyright (C) 2010-2015 Free Software Foundation, Inc.
- Contributed by Analog Devices, Inc.
- This file is part of simulators.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #include "config.h"
- #include "sim-main.h"
- #include "devices.h"
- #include "dv-bfin_sic.h"
- #include "dv-bfin_cec.h"
- struct bfin_sic
- {
- /* We assume first element is the base. */
- bu32 base;
- /* Order after here is important -- matches hardware MMR layout. */
- bu16 BFIN_MMR_16(swrst);
- bu16 BFIN_MMR_16(syscr);
- bu16 BFIN_MMR_16(rvect); /* XXX: BF59x has a 32bit AUX_REVID here. */
- union {
- struct {
- bu32 imask0;
- bu32 iar0, iar1, iar2, iar3;
- bu32 isr0, iwr0;
- bu32 _pad0[9];
- bu32 imask1;
- bu32 iar4, iar5, iar6, iar7;
- bu32 isr1, iwr1;
- } bf52x;
- struct {
- bu32 imask;
- bu32 iar0, iar1, iar2, iar3;
- bu32 isr, iwr;
- } bf537;
- struct {
- bu32 imask0, imask1, imask2;
- bu32 isr0, isr1, isr2;
- bu32 iwr0, iwr1, iwr2;
- bu32 iar0, iar1, iar2, iar3;
- bu32 iar4, iar5, iar6, iar7;
- bu32 iar8, iar9, iar10, iar11;
- } bf54x;
- struct {
- bu32 imask0, imask1;
- bu32 iar0, iar1, iar2, iar3;
- bu32 iar4, iar5, iar6, iar7;
- bu32 isr0, isr1;
- bu32 iwr0, iwr1;
- } bf561;
- };
- };
- #define mmr_base() offsetof(struct bfin_sic, swrst)
- #define mmr_offset(mmr) (offsetof(struct bfin_sic, mmr) - mmr_base())
- #define mmr_idx(mmr) (mmr_offset (mmr) / 4)
- static const char * const bf52x_mmr_names[] =
- {
- "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IAR0", "SIC_IAR1",
- "SIC_IAR2", "SIC_IAR3", "SIC_ISR0", "SIC_IWR0",
- [mmr_idx (bf52x.imask1)] = "SIC_IMASK1", "SIC_IAR4", "SIC_IAR5",
- "SIC_IAR6", "SIC_IAR7", "SIC_ISR1", "SIC_IWR1",
- };
- static const char * const bf537_mmr_names[] =
- {
- "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK", "SIC_IAR0", "SIC_IAR1",
- "SIC_IAR2", "SIC_IAR3", "SIC_ISR", "SIC_IWR",
- };
- static const char * const bf54x_mmr_names[] =
- {
- "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1", "SIC_IMASK2",
- "SIC_ISR0", "SIC_ISR1", "SIC_ISR2", "SIC_IWR0", "SIC_IWR1", "SIC_IWR2",
- "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
- "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
- "SIC_IAR8", "SIC_IAR9", "SIC_IAR10", "SIC_IAR11",
- };
- static const char * const bf561_mmr_names[] =
- {
- "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1",
- "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
- "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
- "SIC_ISR0", "SIC_ISR1", "SIC_IWR0", "SIC_IWR1",
- };
- static const char * const *mmr_names;
- #define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
- static void
- bfin_sic_forward_interrupts (struct hw *me, bu32 *isr, bu32 *imask, bu32 *iar)
- {
- int my_port;
- bu32 ipend;
- /* Process pending and unmasked interrupts. */
- ipend = *isr & *imask;
- /* Usually none are pending unmasked, so avoid bit twiddling. */
- if (!ipend)
- return;
- for (my_port = 0; my_port < 32; ++my_port)
- {
- bu32 iar_idx, iar_off, iar_val;
- bu32 bit = (1 << my_port);
- /* This bit isn't pending, so check next one. */
- if (!(ipend & bit))
- continue;
- /* The IAR registers map the System input to the Core output.
- Every 4 bits in the IAR are used to map to IVG{7..15}. */
- iar_idx = my_port / 8;
- iar_off = (my_port % 8) * 4;
- iar_val = (iar[iar_idx] & (0xf << iar_off)) >> iar_off;
- HW_TRACE ((me, "forwarding int %i to CEC", IVG7 + iar_val));
- hw_port_event (me, IVG7 + iar_val, 1);
- }
- }
- static void
- bfin_sic_52x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
- {
- bfin_sic_forward_interrupts (me, &sic->bf52x.isr0, &sic->bf52x.imask0, &sic->bf52x.iar0);
- bfin_sic_forward_interrupts (me, &sic->bf52x.isr1, &sic->bf52x.imask1, &sic->bf52x.iar4);
- }
- static unsigned
- bfin_sic_52x_io_write_buffer (struct hw *me, const void *source, int space,
- address_word addr, unsigned nr_bytes)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 mmr_off;
- bu32 value;
- bu16 *value16p;
- bu32 *value32p;
- void *valuep;
- if (nr_bytes == 4)
- value = dv_load_4 (source);
- else
- value = dv_load_2 (source);
- mmr_off = addr - sic->base;
- valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
- value16p = valuep;
- value32p = valuep;
- HW_TRACE_WRITE ();
- /* XXX: Discard all SIC writes for now. */
- switch (mmr_off)
- {
- case mmr_offset(swrst):
- /* XXX: This should trigger a software reset ... */
- break;
- case mmr_offset(syscr):
- /* XXX: what to do ... */
- break;
- case mmr_offset(bf52x.imask0):
- case mmr_offset(bf52x.imask1):
- bfin_sic_52x_forward_interrupts (me, sic);
- *value32p = value;
- break;
- case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
- case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
- case mmr_offset(bf52x.iwr0):
- case mmr_offset(bf52x.iwr1):
- *value32p = value;
- break;
- case mmr_offset(bf52x.isr0):
- case mmr_offset(bf52x.isr1):
- /* ISR is read-only. */
- break;
- default:
- /* XXX: Should discard other writes. */
- ;
- }
- return nr_bytes;
- }
- static unsigned
- bfin_sic_52x_io_read_buffer (struct hw *me, void *dest, int space,
- address_word addr, unsigned nr_bytes)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 mmr_off;
- bu16 *value16p;
- bu32 *value32p;
- void *valuep;
- mmr_off = addr - sic->base;
- valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
- value16p = valuep;
- value32p = valuep;
- HW_TRACE_READ ();
- switch (mmr_off)
- {
- case mmr_offset(swrst):
- case mmr_offset(syscr):
- case mmr_offset(rvect):
- dv_store_2 (dest, *value16p);
- break;
- case mmr_offset(bf52x.imask0):
- case mmr_offset(bf52x.imask1):
- case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
- case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
- case mmr_offset(bf52x.iwr0):
- case mmr_offset(bf52x.iwr1):
- case mmr_offset(bf52x.isr0):
- case mmr_offset(bf52x.isr1):
- dv_store_4 (dest, *value32p);
- break;
- default:
- if (nr_bytes == 2)
- dv_store_2 (dest, 0);
- else
- dv_store_4 (dest, 0);
- break;
- }
- return nr_bytes;
- }
- static void
- bfin_sic_537_forward_interrupts (struct hw *me, struct bfin_sic *sic)
- {
- bfin_sic_forward_interrupts (me, &sic->bf537.isr, &sic->bf537.imask, &sic->bf537.iar0);
- }
- static unsigned
- bfin_sic_537_io_write_buffer (struct hw *me, const void *source, int space,
- address_word addr, unsigned nr_bytes)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 mmr_off;
- bu32 value;
- bu16 *value16p;
- bu32 *value32p;
- void *valuep;
- if (nr_bytes == 4)
- value = dv_load_4 (source);
- else
- value = dv_load_2 (source);
- mmr_off = addr - sic->base;
- valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
- value16p = valuep;
- value32p = valuep;
- HW_TRACE_WRITE ();
- /* XXX: Discard all SIC writes for now. */
- switch (mmr_off)
- {
- case mmr_offset(swrst):
- /* XXX: This should trigger a software reset ... */
- break;
- case mmr_offset(syscr):
- /* XXX: what to do ... */
- break;
- case mmr_offset(bf537.imask):
- bfin_sic_537_forward_interrupts (me, sic);
- *value32p = value;
- break;
- case mmr_offset(bf537.iar0):
- case mmr_offset(bf537.iar1):
- case mmr_offset(bf537.iar2):
- case mmr_offset(bf537.iar3):
- case mmr_offset(bf537.iwr):
- *value32p = value;
- break;
- case mmr_offset(bf537.isr):
- /* ISR is read-only. */
- break;
- default:
- /* XXX: Should discard other writes. */
- ;
- }
- return nr_bytes;
- }
- static unsigned
- bfin_sic_537_io_read_buffer (struct hw *me, void *dest, int space,
- address_word addr, unsigned nr_bytes)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 mmr_off;
- bu16 *value16p;
- bu32 *value32p;
- void *valuep;
- mmr_off = addr - sic->base;
- valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
- value16p = valuep;
- value32p = valuep;
- HW_TRACE_READ ();
- switch (mmr_off)
- {
- case mmr_offset(swrst):
- case mmr_offset(syscr):
- case mmr_offset(rvect):
- dv_store_2 (dest, *value16p);
- break;
- case mmr_offset(bf537.imask):
- case mmr_offset(bf537.iar0):
- case mmr_offset(bf537.iar1):
- case mmr_offset(bf537.iar2):
- case mmr_offset(bf537.iar3):
- case mmr_offset(bf537.isr):
- case mmr_offset(bf537.iwr):
- dv_store_4 (dest, *value32p);
- break;
- default:
- if (nr_bytes == 2)
- dv_store_2 (dest, 0);
- else
- dv_store_4 (dest, 0);
- break;
- }
- return nr_bytes;
- }
- static void
- bfin_sic_54x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
- {
- bfin_sic_forward_interrupts (me, &sic->bf54x.isr0, &sic->bf54x.imask0, &sic->bf54x.iar0);
- bfin_sic_forward_interrupts (me, &sic->bf54x.isr1, &sic->bf54x.imask1, &sic->bf54x.iar4);
- bfin_sic_forward_interrupts (me, &sic->bf54x.isr2, &sic->bf54x.imask2, &sic->bf54x.iar8);
- }
- static unsigned
- bfin_sic_54x_io_write_buffer (struct hw *me, const void *source, int space,
- address_word addr, unsigned nr_bytes)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 mmr_off;
- bu32 value;
- bu16 *value16p;
- bu32 *value32p;
- void *valuep;
- if (nr_bytes == 4)
- value = dv_load_4 (source);
- else
- value = dv_load_2 (source);
- mmr_off = addr - sic->base;
- valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
- value16p = valuep;
- value32p = valuep;
- HW_TRACE_WRITE ();
- /* XXX: Discard all SIC writes for now. */
- switch (mmr_off)
- {
- case mmr_offset(swrst):
- /* XXX: This should trigger a software reset ... */
- break;
- case mmr_offset(syscr):
- /* XXX: what to do ... */
- break;
- case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
- bfin_sic_54x_forward_interrupts (me, sic);
- *value32p = value;
- break;
- case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
- case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
- *value32p = value;
- break;
- case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
- /* ISR is read-only. */
- break;
- default:
- /* XXX: Should discard other writes. */
- ;
- }
- return nr_bytes;
- }
- static unsigned
- bfin_sic_54x_io_read_buffer (struct hw *me, void *dest, int space,
- address_word addr, unsigned nr_bytes)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 mmr_off;
- bu16 *value16p;
- bu32 *value32p;
- void *valuep;
- mmr_off = addr - sic->base;
- valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
- value16p = valuep;
- value32p = valuep;
- HW_TRACE_READ ();
- switch (mmr_off)
- {
- case mmr_offset(swrst):
- case mmr_offset(syscr):
- case mmr_offset(rvect):
- dv_store_2 (dest, *value16p);
- break;
- case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
- case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
- case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
- case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
- dv_store_4 (dest, *value32p);
- break;
- default:
- if (nr_bytes == 2)
- dv_store_2 (dest, 0);
- else
- dv_store_4 (dest, 0);
- break;
- }
- return nr_bytes;
- }
- static void
- bfin_sic_561_forward_interrupts (struct hw *me, struct bfin_sic *sic)
- {
- bfin_sic_forward_interrupts (me, &sic->bf561.isr0, &sic->bf561.imask0, &sic->bf561.iar0);
- bfin_sic_forward_interrupts (me, &sic->bf561.isr1, &sic->bf561.imask1, &sic->bf561.iar4);
- }
- static unsigned
- bfin_sic_561_io_write_buffer (struct hw *me, const void *source, int space,
- address_word addr, unsigned nr_bytes)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 mmr_off;
- bu32 value;
- bu16 *value16p;
- bu32 *value32p;
- void *valuep;
- if (nr_bytes == 4)
- value = dv_load_4 (source);
- else
- value = dv_load_2 (source);
- mmr_off = addr - sic->base;
- valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
- value16p = valuep;
- value32p = valuep;
- HW_TRACE_WRITE ();
- /* XXX: Discard all SIC writes for now. */
- switch (mmr_off)
- {
- case mmr_offset(swrst):
- /* XXX: This should trigger a software reset ... */
- break;
- case mmr_offset(syscr):
- /* XXX: what to do ... */
- break;
- case mmr_offset(bf561.imask0):
- case mmr_offset(bf561.imask1):
- bfin_sic_561_forward_interrupts (me, sic);
- *value32p = value;
- break;
- case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
- case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
- case mmr_offset(bf561.iwr0):
- case mmr_offset(bf561.iwr1):
- *value32p = value;
- break;
- case mmr_offset(bf561.isr0):
- case mmr_offset(bf561.isr1):
- /* ISR is read-only. */
- break;
- default:
- /* XXX: Should discard other writes. */
- ;
- }
- return nr_bytes;
- }
- static unsigned
- bfin_sic_561_io_read_buffer (struct hw *me, void *dest, int space,
- address_word addr, unsigned nr_bytes)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 mmr_off;
- bu16 *value16p;
- bu32 *value32p;
- void *valuep;
- mmr_off = addr - sic->base;
- valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
- value16p = valuep;
- value32p = valuep;
- HW_TRACE_READ ();
- switch (mmr_off)
- {
- case mmr_offset(swrst):
- case mmr_offset(syscr):
- case mmr_offset(rvect):
- dv_store_2 (dest, *value16p);
- break;
- case mmr_offset(bf561.imask0):
- case mmr_offset(bf561.imask1):
- case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
- case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
- case mmr_offset(bf561.iwr0):
- case mmr_offset(bf561.iwr1):
- case mmr_offset(bf561.isr0):
- case mmr_offset(bf561.isr1):
- dv_store_4 (dest, *value32p);
- break;
- default:
- if (nr_bytes == 2)
- dv_store_2 (dest, 0);
- else
- dv_store_4 (dest, 0);
- break;
- }
- return nr_bytes;
- }
- /* Give each SIC its own base to make it easier to extract the pin at
- runtime. The pin is used as its bit position in the SIC MMRs. */
- #define ENC(sic, pin) (((sic) << 8) + (pin))
- #define DEC_PIN(pin) ((pin) % 0x100)
- #define DEC_SIC(pin) ((pin) >> 8)
- /* It would be nice to declare just one set of input_ports, and then
- have the device tree instantiate multiple SICs, but the MMR layout
- on the BF54x/BF561 makes this pretty hard to pull off since their
- regs are interwoven in the address space. */
- #define BFIN_SIC_TO_CEC_PORTS \
- { "ivg7", IVG7, 0, output_port, }, \
- { "ivg8", IVG8, 0, output_port, }, \
- { "ivg9", IVG9, 0, output_port, }, \
- { "ivg10", IVG10, 0, output_port, }, \
- { "ivg11", IVG11, 0, output_port, }, \
- { "ivg12", IVG12, 0, output_port, }, \
- { "ivg13", IVG13, 0, output_port, }, \
- { "ivg14", IVG14, 0, output_port, }, \
- { "ivg15", IVG15, 0, output_port, },
- #define SIC_PORTS(n) \
- { "int0@"#n, ENC(n, 0), 0, input_port, }, \
- { "int1@"#n, ENC(n, 1), 0, input_port, }, \
- { "int2@"#n, ENC(n, 2), 0, input_port, }, \
- { "int3@"#n, ENC(n, 3), 0, input_port, }, \
- { "int4@"#n, ENC(n, 4), 0, input_port, }, \
- { "int5@"#n, ENC(n, 5), 0, input_port, }, \
- { "int6@"#n, ENC(n, 6), 0, input_port, }, \
- { "int7@"#n, ENC(n, 7), 0, input_port, }, \
- { "int8@"#n, ENC(n, 8), 0, input_port, }, \
- { "int9@"#n, ENC(n, 9), 0, input_port, }, \
- { "int10@"#n, ENC(n, 10), 0, input_port, }, \
- { "int11@"#n, ENC(n, 11), 0, input_port, }, \
- { "int12@"#n, ENC(n, 12), 0, input_port, }, \
- { "int13@"#n, ENC(n, 13), 0, input_port, }, \
- { "int14@"#n, ENC(n, 14), 0, input_port, }, \
- { "int15@"#n, ENC(n, 15), 0, input_port, }, \
- { "int16@"#n, ENC(n, 16), 0, input_port, }, \
- { "int17@"#n, ENC(n, 17), 0, input_port, }, \
- { "int18@"#n, ENC(n, 18), 0, input_port, }, \
- { "int19@"#n, ENC(n, 19), 0, input_port, }, \
- { "int20@"#n, ENC(n, 20), 0, input_port, }, \
- { "int21@"#n, ENC(n, 21), 0, input_port, }, \
- { "int22@"#n, ENC(n, 22), 0, input_port, }, \
- { "int23@"#n, ENC(n, 23), 0, input_port, }, \
- { "int24@"#n, ENC(n, 24), 0, input_port, }, \
- { "int25@"#n, ENC(n, 25), 0, input_port, }, \
- { "int26@"#n, ENC(n, 26), 0, input_port, }, \
- { "int27@"#n, ENC(n, 27), 0, input_port, }, \
- { "int28@"#n, ENC(n, 28), 0, input_port, }, \
- { "int29@"#n, ENC(n, 29), 0, input_port, }, \
- { "int30@"#n, ENC(n, 30), 0, input_port, }, \
- { "int31@"#n, ENC(n, 31), 0, input_port, },
- static const struct hw_port_descriptor bfin_sic1_ports[] =
- {
- BFIN_SIC_TO_CEC_PORTS
- SIC_PORTS(0)
- { NULL, 0, 0, 0, },
- };
- static const struct hw_port_descriptor bfin_sic2_ports[] =
- {
- BFIN_SIC_TO_CEC_PORTS
- SIC_PORTS(0)
- SIC_PORTS(1)
- { NULL, 0, 0, 0, },
- };
- static const struct hw_port_descriptor bfin_sic3_ports[] =
- {
- BFIN_SIC_TO_CEC_PORTS
- SIC_PORTS(0)
- SIC_PORTS(1)
- SIC_PORTS(2)
- { NULL, 0, 0, 0, },
- };
- static const struct hw_port_descriptor bfin_sic_561_ports[] =
- {
- { "sup_irq@0", 0, 0, output_port, },
- { "sup_irq@1", 1, 0, output_port, },
- BFIN_SIC_TO_CEC_PORTS
- SIC_PORTS(0)
- SIC_PORTS(1)
- { NULL, 0, 0, 0, },
- };
- static void
- bfin_sic_port_event (struct hw *me, bu32 *isr, bu32 bit, int level)
- {
- if (level)
- *isr |= bit;
- else
- *isr &= ~bit;
- }
- static void
- bfin_sic_52x_port_event (struct hw *me, int my_port, struct hw *source,
- int source_port, int level)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 idx = DEC_SIC (my_port);
- bu32 pin = DEC_PIN (my_port);
- bu32 bit = 1 << pin;
- HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
- level, my_port, idx, pin));
- /* SIC only exists to forward interrupts from the system to the CEC. */
- switch (idx)
- {
- case 0: bfin_sic_port_event (me, &sic->bf52x.isr0, bit, level); break;
- case 1: bfin_sic_port_event (me, &sic->bf52x.isr1, bit, level); break;
- }
- /* XXX: Handle SIC wakeup source ?
- if (sic->bf52x.iwr0 & bit)
- What to do ?;
- if (sic->bf52x.iwr1 & bit)
- What to do ?;
- */
- bfin_sic_52x_forward_interrupts (me, sic);
- }
- static void
- bfin_sic_537_port_event (struct hw *me, int my_port, struct hw *source,
- int source_port, int level)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 idx = DEC_SIC (my_port);
- bu32 pin = DEC_PIN (my_port);
- bu32 bit = 1 << pin;
- HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
- level, my_port, idx, pin));
- /* SIC only exists to forward interrupts from the system to the CEC. */
- bfin_sic_port_event (me, &sic->bf537.isr, bit, level);
- /* XXX: Handle SIC wakeup source ?
- if (sic->bf537.iwr & bit)
- What to do ?;
- */
- bfin_sic_537_forward_interrupts (me, sic);
- }
- static void
- bfin_sic_54x_port_event (struct hw *me, int my_port, struct hw *source,
- int source_port, int level)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 idx = DEC_SIC (my_port);
- bu32 pin = DEC_PIN (my_port);
- bu32 bit = 1 << pin;
- HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
- level, my_port, idx, pin));
- /* SIC only exists to forward interrupts from the system to the CEC. */
- switch (idx)
- {
- case 0: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
- case 1: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
- case 2: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
- }
- /* XXX: Handle SIC wakeup source ?
- if (sic->bf54x.iwr0 & bit)
- What to do ?;
- if (sic->bf54x.iwr1 & bit)
- What to do ?;
- if (sic->bf54x.iwr2 & bit)
- What to do ?;
- */
- bfin_sic_54x_forward_interrupts (me, sic);
- }
- static void
- bfin_sic_561_port_event (struct hw *me, int my_port, struct hw *source,
- int source_port, int level)
- {
- struct bfin_sic *sic = hw_data (me);
- bu32 idx = DEC_SIC (my_port);
- bu32 pin = DEC_PIN (my_port);
- bu32 bit = 1 << pin;
- HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
- level, my_port, idx, pin));
- /* SIC only exists to forward interrupts from the system to the CEC. */
- switch (idx)
- {
- case 0: bfin_sic_port_event (me, &sic->bf561.isr0, bit, level); break;
- case 1: bfin_sic_port_event (me, &sic->bf561.isr1, bit, level); break;
- }
- /* XXX: Handle SIC wakeup source ?
- if (sic->bf561.iwr0 & bit)
- What to do ?;
- if (sic->bf561.iwr1 & bit)
- What to do ?;
- */
- bfin_sic_561_forward_interrupts (me, sic);
- }
- static void
- attach_bfin_sic_regs (struct hw *me, struct bfin_sic *sic)
- {
- address_word attach_address;
- int attach_space;
- unsigned attach_size;
- reg_property_spec reg;
- if (hw_find_property (me, "reg") == NULL)
- hw_abort (me, "Missing \"reg\" property");
- if (!hw_find_reg_array_property (me, "reg", 0, ®))
- hw_abort (me, "\"reg\" property must contain three addr/size entries");
- hw_unit_address_to_attach_address (hw_parent (me),
- ®.address,
- &attach_space, &attach_address, me);
- hw_unit_size_to_attach_size (hw_parent (me), ®.size, &attach_size, me);
- if (attach_size != BFIN_MMR_SIC_SIZE)
- hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_SIC_SIZE);
- hw_attach_address (hw_parent (me),
- 0, attach_space, attach_address, attach_size, me);
- sic->base = attach_address;
- }
- static void
- bfin_sic_finish (struct hw *me)
- {
- struct bfin_sic *sic;
- sic = HW_ZALLOC (me, struct bfin_sic);
- set_hw_data (me, sic);
- attach_bfin_sic_regs (me, sic);
- switch (hw_find_integer_property (me, "type"))
- {
- case 500 ... 509:
- set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
- set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
- set_hw_ports (me, bfin_sic2_ports);
- set_hw_port_event (me, bfin_sic_52x_port_event);
- mmr_names = bf52x_mmr_names;
- /* Initialize the SIC. */
- sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
- sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
- sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
- sic->bf52x.iar0 = 0x00000000;
- sic->bf52x.iar1 = 0x22111000;
- sic->bf52x.iar2 = 0x33332222;
- sic->bf52x.iar3 = 0x44444433;
- sic->bf52x.iar4 = 0x55555555;
- sic->bf52x.iar5 = 0x06666655;
- sic->bf52x.iar6 = 0x33333003;
- sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
- break;
- case 510 ... 519:
- set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
- set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
- set_hw_ports (me, bfin_sic2_ports);
- set_hw_port_event (me, bfin_sic_52x_port_event);
- mmr_names = bf52x_mmr_names;
- /* Initialize the SIC. */
- sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
- sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
- sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
- sic->bf52x.iar0 = 0x00000000;
- sic->bf52x.iar1 = 0x11000000;
- sic->bf52x.iar2 = 0x33332222;
- sic->bf52x.iar3 = 0x44444433;
- sic->bf52x.iar4 = 0x55555555;
- sic->bf52x.iar5 = 0x06666655;
- sic->bf52x.iar6 = 0x33333000;
- sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
- break;
- case 522 ... 527:
- set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
- set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
- set_hw_ports (me, bfin_sic2_ports);
- set_hw_port_event (me, bfin_sic_52x_port_event);
- mmr_names = bf52x_mmr_names;
- /* Initialize the SIC. */
- sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
- sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
- sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
- sic->bf52x.iar0 = 0x00000000;
- sic->bf52x.iar1 = 0x11000000;
- sic->bf52x.iar2 = 0x33332222;
- sic->bf52x.iar3 = 0x44444433;
- sic->bf52x.iar4 = 0x55555555;
- sic->bf52x.iar5 = 0x06666655;
- sic->bf52x.iar6 = 0x33333000;
- sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
- break;
- case 531 ... 533:
- set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
- set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
- set_hw_ports (me, bfin_sic1_ports);
- set_hw_port_event (me, bfin_sic_537_port_event);
- mmr_names = bf537_mmr_names;
- /* Initialize the SIC. */
- sic->bf537.imask = 0;
- sic->bf537.isr = 0;
- sic->bf537.iwr = 0xFFFFFFFF;
- sic->bf537.iar0 = 0x10000000;
- sic->bf537.iar1 = 0x33322221;
- sic->bf537.iar2 = 0x66655444;
- sic->bf537.iar3 = 0; /* XXX: fix this */
- break;
- case 534:
- case 536:
- case 537:
- set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
- set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
- set_hw_ports (me, bfin_sic1_ports);
- set_hw_port_event (me, bfin_sic_537_port_event);
- mmr_names = bf537_mmr_names;
- /* Initialize the SIC. */
- sic->bf537.imask = 0;
- sic->bf537.isr = 0;
- sic->bf537.iwr = 0xFFFFFFFF;
- sic->bf537.iar0 = 0x22211000;
- sic->bf537.iar1 = 0x43333332;
- sic->bf537.iar2 = 0x55555444;
- sic->bf537.iar3 = 0x66655555;
- break;
- case 538 ... 539:
- set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
- set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
- set_hw_ports (me, bfin_sic2_ports);
- set_hw_port_event (me, bfin_sic_52x_port_event);
- mmr_names = bf52x_mmr_names;
- /* Initialize the SIC. */
- sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
- sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
- sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
- sic->bf52x.iar0 = 0x10000000;
- sic->bf52x.iar1 = 0x33322221;
- sic->bf52x.iar2 = 0x66655444;
- sic->bf52x.iar3 = 0x00000000;
- sic->bf52x.iar4 = 0x32222220;
- sic->bf52x.iar5 = 0x44433333;
- sic->bf52x.iar6 = 0x00444664;
- sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
- break;
- case 540 ... 549:
- set_hw_io_read_buffer (me, bfin_sic_54x_io_read_buffer);
- set_hw_io_write_buffer (me, bfin_sic_54x_io_write_buffer);
- set_hw_ports (me, bfin_sic3_ports);
- set_hw_port_event (me, bfin_sic_54x_port_event);
- mmr_names = bf54x_mmr_names;
- /* Initialize the SIC. */
- sic->bf54x.imask0 = sic->bf54x.imask1 = sic->bf54x.imask2 = 0;
- sic->bf54x.isr0 = sic->bf54x.isr1 = sic->bf54x.isr2 = 0;
- sic->bf54x.iwr0 = sic->bf54x.iwr1 = sic->bf54x.iwr2 = 0xFFFFFFFF;
- sic->bf54x.iar0 = 0x10000000;
- sic->bf54x.iar1 = 0x33322221;
- sic->bf54x.iar2 = 0x66655444;
- sic->bf54x.iar3 = 0x00000000;
- sic->bf54x.iar4 = 0x32222220;
- sic->bf54x.iar5 = 0x44433333;
- sic->bf54x.iar6 = 0x00444664;
- sic->bf54x.iar7 = 0x00000000;
- sic->bf54x.iar8 = 0x44111111;
- sic->bf54x.iar9 = 0x44444444;
- sic->bf54x.iar10 = 0x44444444;
- sic->bf54x.iar11 = 0x55444444;
- break;
- case 561:
- set_hw_io_read_buffer (me, bfin_sic_561_io_read_buffer);
- set_hw_io_write_buffer (me, bfin_sic_561_io_write_buffer);
- set_hw_ports (me, bfin_sic_561_ports);
- set_hw_port_event (me, bfin_sic_561_port_event);
- mmr_names = bf561_mmr_names;
- /* Initialize the SIC. */
- sic->bf561.imask0 = sic->bf561.imask1 = 0;
- sic->bf561.isr0 = sic->bf561.isr1 = 0;
- sic->bf561.iwr0 = sic->bf561.iwr1 = 0xFFFFFFFF;
- sic->bf561.iar0 = 0x00000000;
- sic->bf561.iar1 = 0x11111000;
- sic->bf561.iar2 = 0x21111111;
- sic->bf561.iar3 = 0x22222222;
- sic->bf561.iar4 = 0x33333222;
- sic->bf561.iar5 = 0x43333333;
- sic->bf561.iar6 = 0x21144444;
- sic->bf561.iar7 = 0x00006552;
- break;
- case 590 ... 599:
- set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
- set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
- set_hw_ports (me, bfin_sic1_ports);
- set_hw_port_event (me, bfin_sic_537_port_event);
- mmr_names = bf537_mmr_names;
- /* Initialize the SIC. */
- sic->bf537.imask = 0;
- sic->bf537.isr = 0;
- sic->bf537.iwr = 0xFFFFFFFF;
- sic->bf537.iar0 = 0x00000000;
- sic->bf537.iar1 = 0x33322221;
- sic->bf537.iar2 = 0x55444443;
- sic->bf537.iar3 = 0x66600005;
- break;
- default:
- hw_abort (me, "no support for SIC on this Blackfin model yet");
- }
- }
- const struct hw_descriptor dv_bfin_sic_descriptor[] =
- {
- {"bfin_sic", bfin_sic_finish,},
- {NULL, NULL},
- };
|