dv-bfin_sic.c 28 KB

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