scc.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. /*
  2. * (C) Copyright 2009 Stefan Roese <sr@denx.de>, DENX Software Engineering
  3. *
  4. * Copyright (C) 2006 Micronas GmbH
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  19. * MA 02111-1307 USA
  20. */
  21. #include <common.h>
  22. #include <asm/errno.h>
  23. #include "vct.h"
  24. /*
  25. * List of statically defined buffers per SCC.
  26. * The first entry in the table is the number of fixed buffers
  27. * followed by the list of buffer IDs
  28. */
  29. static u32 buffer_list_0[] = { 6, 120, 121, 122, 123, 139, 140 };
  30. static u32 buffer_list_1[] = { 6, 120, 121, 122, 123, 139, 140 };
  31. static u32 buffer_list_2[] = { 5, 124, 125, 126, 139, 140 };
  32. static u32 buffer_list_3[] = { 5, 124, 125, 126, 139, 140 };
  33. static u32 buffer_list_4[] = { 5, 124, 125, 126, 139, 140 };
  34. static u32 buffer_list_5[] = { 3, 127, 139, 140 };
  35. static u32 buffer_list_6[] = { 3, 127, 139, 140 };
  36. static u32 buffer_list_7[] = { 6, 128, 129, 130, 131, 139, 140 };
  37. static u32 buffer_list_8[] = { 6, 128, 129, 130, 131, 139, 140 };
  38. static u32 buffer_list_9[] = { 5, 124, 125, 126, 139, 140 };
  39. static u32 buffer_list_10[] = { 5, 124, 125, 126, 139, 140 };
  40. static u32 buffer_list_11[] = { 5, 124, 125, 126, 139, 140 };
  41. static u32 buffer_list_12[] = { 6, 132, 133, 134, 135, 139, 140 };
  42. static u32 buffer_list_13[] = { 6, 132, 133, 134, 135, 139, 140 };
  43. static u32 buffer_list_14[] = { 4, 137, 138, 139, 140 };
  44. static u32 buffer_list_15[] = { 6, 136, 136, 137, 138, 139, 140 };
  45. /** Issue#7674 (new) - DP/DVP buffer assignment */
  46. static u32 buffer_list_16[] = { 6, 106, 108, 109, 107, 139, 140 };
  47. static u32 buffer_list_17[] = { 6, 106, 110, 107, 111, 139, 140 };
  48. static u32 buffer_list_18[] = { 6, 106, 113, 107, 114, 139, 140 };
  49. static u32 buffer_list_19[] = { 3, 112, 139, 140 };
  50. static u32 buffer_list_20[] = { 35, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  51. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  52. 79, 80, 81, 82, 83, 84, 85, 86, 139, 140 };
  53. static u32 buffer_list_21[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  54. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  55. 139, 140 };
  56. static u32 buffer_list_22[] = { 81, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  57. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  58. 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
  59. 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  60. 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
  61. 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
  62. 73, 74, 75, 76, 77, 78, 139, 140 };
  63. static u32 buffer_list_23[] = { 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  64. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  65. 88, 89, 139, 140 };
  66. static u32 buffer_list_24[] = { 6, 90, 91, 92, 93, 139, 140 };
  67. static u32 buffer_list_25[] = { 18, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  68. 100, 101, 102, 103, 104, 105, 139, 140 };
  69. static u32 buffer_list_26[] = { 5, 94, 95, 96, 139, 140 };
  70. static u32 buffer_list_27[] = { 5, 97, 98, 99, 139, 140 };
  71. static u32 buffer_list_28[] = { 5, 100, 101, 102, 139, 140 };
  72. static u32 buffer_list_29[] = { 5, 103, 104, 105, 139, 140 };
  73. static u32 buffer_list_30[] = { 10, 108, 109, 110, 111, 113, 114, 116, 117,
  74. 139, 140 };
  75. static u32 buffer_list_31[] = { 13, 106, 107, 108, 109, 110, 111, 113, 114,
  76. 115, 116, 117, 139, 140 };
  77. static u32 buffer_list_32[] = { 13, 106, 107, 108, 109, 110, 111, 113, 114,
  78. 115, 116, 117, 139, 140 };
  79. static u32 buffer_list_33[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  80. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  81. 139, 140 };
  82. static u32 buffer_list_34[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  83. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  84. 139, 140 };
  85. static u32 buffer_list_35[] = { 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  86. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  87. 87, 139, 140 };
  88. static u32 buffer_list_36[] = { 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  89. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  90. 87, 139, 140 };
  91. static u32 buffer_list_37[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  92. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  93. 139, 140 };
  94. static u32 buffer_list_38[] = { 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  95. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  96. 118, 119, 139, 140 };
  97. static u32 buffer_list_39[] = { 91, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  98. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  99. 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
  100. 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  101. 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
  102. 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
  103. 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
  104. 85, 86, 118, 119, 139, 140 };
  105. static u32 buffer_list_40[] = { 0 };
  106. /*
  107. * List of statically defined vcid.csize values.
  108. * The first entry in the table is the number of possible csize values
  109. * followed by the list of data path values in bits.
  110. */
  111. static u32 csize_list_0[] = { 2, 0, 1 };
  112. static u32 csize_list_1[] = { 2, 0, 1 };
  113. static u32 csize_list_2[] = { 1, 1 };
  114. static u32 csize_list_3[] = { 1, 1 };
  115. static u32 csize_list_4[] = { 1, 1 };
  116. static u32 csize_list_5[] = { 1, 0 };
  117. static u32 csize_list_6[] = { 1, 0 };
  118. static u32 csize_list_7[] = { 1, 1 };
  119. static u32 csize_list_8[] = { 1, 1 };
  120. static u32 csize_list_9[] = { 1, 1 };
  121. static u32 csize_list_10[] = { 1, 1 };
  122. static u32 csize_list_11[] = { 1, 1 };
  123. static u32 csize_list_12[] = { 1, 1 };
  124. static u32 csize_list_13[] = { 1, 1 };
  125. static u32 csize_list_14[] = { 1, 2 };
  126. static u32 csize_list_15[] = { 1, 4 };
  127. static u32 csize_list_16[] = { 3, 0, 1, 2 };
  128. static u32 csize_list_17[] = { 3, 0, 1, 2 };
  129. static u32 csize_list_18[] = { 3, 0, 1, 2 };
  130. static u32 csize_list_19[] = { 1, 2 };
  131. static u32 csize_list_20[] = { 1, 0 };
  132. static u32 csize_list_21[] = { 1, 0 };
  133. static u32 csize_list_22[] = { 1, 2 };
  134. static u32 csize_list_23[] = { 1, 3 };
  135. static u32 csize_list_24[] = { 1, 3 };
  136. static u32 csize_list_25[] = { 1, 3 };
  137. static u32 csize_list_26[] = { 1, 0 };
  138. static u32 csize_list_27[] = { 1, 0 };
  139. static u32 csize_list_28[] = { 1, 0 };
  140. static u32 csize_list_29[] = { 1, 0 };
  141. static u32 csize_list_30[] = { 1, 2 };
  142. static u32 csize_list_31[] = { 1, 2 };
  143. static u32 csize_list_32[] = { 1, 2 };
  144. static u32 csize_list_33[] = { 1, 2 };
  145. static u32 csize_list_34[] = { 1, 2 };
  146. static u32 csize_list_35[] = { 1, 2 };
  147. static u32 csize_list_36[] = { 1, 2 };
  148. static u32 csize_list_37[] = { 2, 0, 1 };
  149. static u32 csize_list_38[] = { 1, 2 };
  150. static u32 csize_list_39[] = { 1, 3 };
  151. static u32 csize_list_40[] = { 1, 3 };
  152. /*
  153. * SCC_Configuration table
  154. */
  155. static const struct scc_descriptor scc_descriptor_table[] = {
  156. /* scn scc_name profile SCC scc_id mci_id rd wr m p fh si cfg sta */
  157. {"fe_", "fe_3dcomb_wr", STRM_P, SCC0_BASE, 0, 0, 0, 4, 1, 1, 0, 0, 0, 1,
  158. buffer_list_0, csize_list_0},
  159. {"fe_", "fe_3dcomb_rd", STRM_P, SCC1_BASE, 1, 18, 4, 0, 1, 1, 0, 1, 0,
  160. 1, buffer_list_1, csize_list_1},
  161. {"di_", "di_tnr_wr", STRM_P, SCC2_BASE, 2, 1, 0, 3, 1, 1, 0, 2, 0, 1,
  162. buffer_list_2, csize_list_2},
  163. {"di_", "di_tnr_field_rd", STRM_P, SCC3_BASE, 3, 19, 3, 0, 1, 1, 0, 3,
  164. 0, 1, buffer_list_3, csize_list_3},
  165. {"di_", "di_tnr_frame_rd", STRM_P, SCC4_BASE, 4, 20, 3, 0, 1, 1, 0, 4,
  166. 0, 1, buffer_list_4, csize_list_4},
  167. {"di_", "di_mval_wr", STRM_P, SCC5_BASE, 5, 2, 0, 1, 1, 1, 0, 5, 0, 1,
  168. buffer_list_5, csize_list_5},
  169. {"di_", "di_mval_rd", STRM_P, SCC6_BASE, 6, 21, 1, 0, 1, 1, 0, 6, 0, 1,
  170. buffer_list_6, csize_list_6},
  171. {"rc_", "rc_frame_wr", STRM_P, SCC7_BASE, 7, 3, 0, 4, 1, 1, 0, 7, 0, 1,
  172. buffer_list_7, csize_list_7},
  173. {"rc_", "rc_frame0_rd", STRM_P, SCC8_BASE, 8, 22, 4, 0, 1, 1, 0, 8, 0,
  174. 1, buffer_list_8, csize_list_8},
  175. {"opt", "opt_field0_rd", STRM_P, SCC9_BASE, 9, 23, 3, 0, 1, 1, 0, 9, 0,
  176. 1, buffer_list_9, csize_list_9},
  177. {"opt", "opt_field1_rd", STRM_P, SCC10_BASE, 10, 24, 3, 0, 1, 1, 0, 10,
  178. 0, 1, buffer_list_10, csize_list_10},
  179. {"opt", "opt_field2_rd", STRM_P, SCC11_BASE, 11, 25, 3, 0, 1, 1, 0, 11,
  180. 0, 1, buffer_list_11, csize_list_11},
  181. {"pip", "pip_frame_wr", STRM_P, SCC12_BASE, 12, 4, 0, 4, 1, 1, 0, 12, 0,
  182. 1, buffer_list_12, csize_list_12},
  183. {"pip", "pip_frame_rd", STRM_P, SCC13_BASE, 13, 26, 4, 0, 1, 1, 0, 13,
  184. 0, 1, buffer_list_13, csize_list_13},
  185. {"dp_", "dp_agpu_rd", STRM_P, SCC14_BASE, 14, 27, 2, 0, 2, 1, 0, 14, 0,
  186. 1, buffer_list_14, csize_list_14},
  187. {"ewa", "ewarp_rw", SRMD, SCC15_BASE, 15, 11, 1, 1, 0, 0, 0, -1, 0, 0,
  188. buffer_list_15, csize_list_15},
  189. {"dp_", "dp_osd_rd", STRM_P, SCC16_BASE, 16, 28, 3, 0, 2, 1, 0, 15, 0,
  190. 1, buffer_list_16, csize_list_16},
  191. {"dp_", "dp_graphic_rd", STRM_P, SCC17_BASE, 17, 29, 3, 0, 2, 1, 0, 16,
  192. 0, 1, buffer_list_17, csize_list_17},
  193. {"dvp", "dvp_osd_rd", STRM_P, SCC18_BASE, 18, 30, 2, 0, 2, 1, 0, 17, 0,
  194. 1, buffer_list_18, csize_list_18},
  195. {"dvp", "dvp_vbi_rd", STRM_D, SCC19_BASE, 19, 31, 1, 0, 0, 1, 0, -1, 0,
  196. 0, buffer_list_19, csize_list_19},
  197. {"tsi", "tsio_wr", STRM_P, SCC20_BASE, 20, 5, 0, 8, 2, 1, 1, -1, 0, 0,
  198. buffer_list_20, csize_list_20},
  199. {"tsi", "tsio_rd", STRM_P, SCC21_BASE, 21, 32, 4, 0, 2, 1, 1, -1, 0, 0,
  200. buffer_list_21, csize_list_21},
  201. {"tsd", "tsd_wr", SRMD, SCC22_BASE, 22, 6, 0, 64, 0, 0, 1, -1, 0, 0,
  202. buffer_list_22, csize_list_22},
  203. {"vd_", "vd_ud_st_rw", SRMD, SCC23_BASE, 23, 12, 2, 2, 0, 0, 1, -1, 0,
  204. 0, buffer_list_23, csize_list_23},
  205. {"vd_", "vd_frr_rd", SRMD, SCC24_BASE, 24, 33, 4, 0, 0, 0, 0, -1, 0, 0,
  206. buffer_list_24, csize_list_24},
  207. {"vd_", "vd_frw_disp_wr", SRMD, SCC25_BASE, 25, 7, 0, 16, 0, 0, 0, -1,
  208. 0, 0, buffer_list_25, csize_list_25},
  209. {"mr_", "mr_vd_m_y_rd", STRM_P, SCC26_BASE, 26, 34, 3, 0, 2, 1, 0, 18,
  210. 0, 1, buffer_list_26, csize_list_26},
  211. {"mr_", "mr_vd_m_c_rd", STRM_P, SCC27_BASE, 27, 35, 3, 0, 2, 1, 0, 19,
  212. 0, 1, buffer_list_27, csize_list_27},
  213. {"mr_", "mr_vd_s_y_rd", STRM_P, SCC28_BASE, 28, 36, 3, 0, 2, 1, 0, 20,
  214. 0, 1, buffer_list_28, csize_list_28},
  215. {"mr_", "mr_vd_s_c_rd", STRM_P, SCC29_BASE, 29, 37, 3, 0, 2, 1, 0, 21,
  216. 0, 1, buffer_list_29, csize_list_29},
  217. {"ga_", "ga_wr", STRM_P, SCC30_BASE, 30, 8, 0, 1, 1, 1, 0, -1, 1, 1,
  218. buffer_list_30, csize_list_30},
  219. {"ga_", "ga_src1_rd", STRM_P, SCC31_BASE, 31, 38, 1, 0, 1, 1, 0, -1, 1,
  220. 1, buffer_list_31, csize_list_31},
  221. {"ga_", "ga_src2_rd", STRM_P, SCC32_BASE, 32, 39, 1, 0, 1, 1, 0, -1, 1,
  222. 1, buffer_list_32, csize_list_32},
  223. {"ad_", "ad_rd", STRM_D, SCC33_BASE, 33, 40, 2, 0, 0, 1, 1, -1, 0, 0,
  224. buffer_list_33, csize_list_33},
  225. {"ad_", "ad_wr", STRM_D, SCC34_BASE, 34, 9, 0, 3, 0, 1, 1, -1, 0, 0,
  226. buffer_list_34, csize_list_34},
  227. {"abp", "abp_rd", STRM_D, SCC35_BASE, 35, 41, 5, 0, 0, 1, 1, -1, 0, 0,
  228. buffer_list_35, csize_list_35},
  229. {"abp", "abp_wr", STRM_D, SCC36_BASE, 36, 10, 0, 3, 0, 1, 1, -1, 0, 0,
  230. buffer_list_36, csize_list_36},
  231. {"ebi", "ebi_rw", STRM_P, SCC37_BASE, 37, 13, 4, 4, 2, 1, 1, -1, 0, 0,
  232. buffer_list_37, csize_list_37},
  233. {"usb", "usb_rw", SRMD, SCC38_BASE, 38, 14, 1, 1, 0, 0, 1, -1, 0, 0,
  234. buffer_list_38, csize_list_38},
  235. {"cpu", "cpu1_spdma_rw", SRMD, SCC39_BASE, 39, 15, 1, 1, 0, 0, 1, -1, 0,
  236. 0, buffer_list_39, csize_list_39},
  237. {"cpu", "cpu1_bridge_rw", SRMD, SCC40_BASE, 40, 16, 0, 0, 0, 0, 0, -1,
  238. 0, 0, buffer_list_40, csize_list_40},
  239. };
  240. /* DMA state structures for read and write channels for each SCC */
  241. static struct scc_dma_state scc_state_rd_0[] = { {-1} };
  242. static struct scc_dma_state scc_state_wr_0[] = { {0}, {0}, {0}, {0} };
  243. static struct scc_dma_state scc_state_rd_1[] = { {0}, {0}, {0}, {0} };
  244. static struct scc_dma_state scc_state_wr_1[] = { {-1} };
  245. static struct scc_dma_state scc_state_rd_2[] = { {-1} };
  246. static struct scc_dma_state scc_state_wr_2[] = { {0}, {0}, {0} };
  247. static struct scc_dma_state scc_state_rd_3[] = { {0}, {0}, {0} };
  248. static struct scc_dma_state scc_state_wr_3[] = { {-1} };
  249. static struct scc_dma_state scc_state_rd_4[] = { {0}, {0}, {0} };
  250. static struct scc_dma_state scc_state_wr_4[] = { {-1} };
  251. static struct scc_dma_state scc_state_rd_5[] = { {-1} };
  252. static struct scc_dma_state scc_state_wr_5[] = { {0} };
  253. static struct scc_dma_state scc_state_rd_6[] = { {0} };
  254. static struct scc_dma_state scc_state_wr_6[] = { {-1} };
  255. static struct scc_dma_state scc_state_rd_7[] = { {-1} };
  256. static struct scc_dma_state scc_state_wr_7[] = { {0}, {0}, {0}, {0} };
  257. static struct scc_dma_state scc_state_rd_8[] = { {0}, {0}, {0}, {0} };
  258. static struct scc_dma_state scc_state_wr_8[] = { {-1} };
  259. static struct scc_dma_state scc_state_rd_9[] = { {0}, {0}, {0}, };
  260. static struct scc_dma_state scc_state_wr_9[] = { {-1} };
  261. static struct scc_dma_state scc_state_rd_10[] = { {0}, {0}, {0} };
  262. static struct scc_dma_state scc_state_wr_10[] = { {-1} };
  263. static struct scc_dma_state scc_state_rd_11[] = { {0}, {0}, {0} };
  264. static struct scc_dma_state scc_state_wr_11[] = { {-1} };
  265. static struct scc_dma_state scc_state_rd_12[] = { {-1} };
  266. static struct scc_dma_state scc_state_wr_12[] = { {0}, {0}, {0}, {0} };
  267. static struct scc_dma_state scc_state_rd_13[] = { {0}, {0}, {0}, {0} };
  268. static struct scc_dma_state scc_state_wr_13[] = { {-1} };
  269. static struct scc_dma_state scc_state_rd_14[] = { {0}, {0} };
  270. static struct scc_dma_state scc_state_wr_14[] = { {-1} };
  271. static struct scc_dma_state scc_state_rd_15[] = { {0} };
  272. static struct scc_dma_state scc_state_wr_15[] = { {0} };
  273. static struct scc_dma_state scc_state_rd_16[] = { {0}, {0}, {0} };
  274. static struct scc_dma_state scc_state_wr_16[] = { {-1} };
  275. static struct scc_dma_state scc_state_rd_17[] = { {0}, {0}, {0} };
  276. static struct scc_dma_state scc_state_wr_17[] = { {-1} };
  277. static struct scc_dma_state scc_state_rd_18[] = { {0}, {0} };
  278. static struct scc_dma_state scc_state_wr_18[] = { {-1} };
  279. static struct scc_dma_state scc_state_rd_19[] = { {0} };
  280. static struct scc_dma_state scc_state_wr_19[] = { {-1} };
  281. static struct scc_dma_state scc_state_rd_20[] = { {-1} };
  282. static struct scc_dma_state scc_state_wr_20[] = {
  283. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} };
  284. static struct scc_dma_state scc_state_rd_21[] = { {0}, {0}, {0}, {0} };
  285. static struct scc_dma_state scc_state_wr_21[] = { {-1} };
  286. static struct scc_dma_state scc_state_rd_22[] = { {-1} };
  287. static struct scc_dma_state scc_state_wr_22[] = {
  288. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
  289. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
  290. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
  291. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
  292. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} };
  293. static struct scc_dma_state scc_state_rd_23[] = { {0}, {0} };
  294. static struct scc_dma_state scc_state_wr_23[] = { {0}, {0} };
  295. static struct scc_dma_state scc_state_rd_24[] = { {0}, {0}, {0}, {0} };
  296. static struct scc_dma_state scc_state_wr_24[] = { {-1} };
  297. static struct scc_dma_state scc_state_rd_25[] = { {-1} };
  298. static struct scc_dma_state scc_state_wr_25[] = {
  299. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
  300. {0}, {0} };
  301. static struct scc_dma_state scc_state_rd_26[] = { {0}, {0}, {0} };
  302. static struct scc_dma_state scc_state_wr_26[] = { {-1} };
  303. static struct scc_dma_state scc_state_rd_27[] = { {0}, {0}, {0} };
  304. static struct scc_dma_state scc_state_wr_27[] = { {-1} };
  305. static struct scc_dma_state scc_state_rd_28[] = { {0}, {0}, {0} };
  306. static struct scc_dma_state scc_state_wr_28[] = { {-1} };
  307. static struct scc_dma_state scc_state_rd_29[] = { {0}, {0}, {0} };
  308. static struct scc_dma_state scc_state_wr_29[] = { {-1} };
  309. static struct scc_dma_state scc_state_rd_30[] = { {-1} };
  310. static struct scc_dma_state scc_state_wr_30[] = { {0} };
  311. static struct scc_dma_state scc_state_rd_31[] = { {0} };
  312. static struct scc_dma_state scc_state_wr_31[] = { {-1} };
  313. static struct scc_dma_state scc_state_rd_32[] = { {0} };
  314. static struct scc_dma_state scc_state_wr_32[] = { {-1} };
  315. static struct scc_dma_state scc_state_rd_33[] = { {0}, {0} };
  316. static struct scc_dma_state scc_state_wr_33[] = { {-1} };
  317. static struct scc_dma_state scc_state_rd_34[] = { {-1} };
  318. static struct scc_dma_state scc_state_wr_34[] = { {0}, {0}, {0} };
  319. static struct scc_dma_state scc_state_rd_35[] = { {0}, {0}, {0}, {0}, {0} };
  320. static struct scc_dma_state scc_state_wr_35[] = { {-1} };
  321. static struct scc_dma_state scc_state_rd_36[] = { {-1} };
  322. static struct scc_dma_state scc_state_wr_36[] = { {0}, {0}, {0} };
  323. static struct scc_dma_state scc_state_rd_37[] = { {0}, {0}, {0}, {0} };
  324. static struct scc_dma_state scc_state_wr_37[] = { {0}, {0}, {0}, {0} };
  325. static struct scc_dma_state scc_state_rd_38[] = { {0} };
  326. static struct scc_dma_state scc_state_wr_38[] = { {0} };
  327. static struct scc_dma_state scc_state_rd_39[] = { {0} };
  328. static struct scc_dma_state scc_state_wr_39[] = { {0} };
  329. static struct scc_dma_state scc_state_rd_40[] = { {-1} };
  330. static struct scc_dma_state scc_state_wr_40[] = { {-1} };
  331. /* DMA state references to access from the driver */
  332. static struct scc_dma_state *scc_state_rd[] = {
  333. scc_state_rd_0,
  334. scc_state_rd_1,
  335. scc_state_rd_2,
  336. scc_state_rd_3,
  337. scc_state_rd_4,
  338. scc_state_rd_5,
  339. scc_state_rd_6,
  340. scc_state_rd_7,
  341. scc_state_rd_8,
  342. scc_state_rd_9,
  343. scc_state_rd_10,
  344. scc_state_rd_11,
  345. scc_state_rd_12,
  346. scc_state_rd_13,
  347. scc_state_rd_14,
  348. scc_state_rd_15,
  349. scc_state_rd_16,
  350. scc_state_rd_17,
  351. scc_state_rd_18,
  352. scc_state_rd_19,
  353. scc_state_rd_20,
  354. scc_state_rd_21,
  355. scc_state_rd_22,
  356. scc_state_rd_23,
  357. scc_state_rd_24,
  358. scc_state_rd_25,
  359. scc_state_rd_26,
  360. scc_state_rd_27,
  361. scc_state_rd_28,
  362. scc_state_rd_29,
  363. scc_state_rd_30,
  364. scc_state_rd_31,
  365. scc_state_rd_32,
  366. scc_state_rd_33,
  367. scc_state_rd_34,
  368. scc_state_rd_35,
  369. scc_state_rd_36,
  370. scc_state_rd_37,
  371. scc_state_rd_38,
  372. scc_state_rd_39,
  373. scc_state_rd_40,
  374. };
  375. static struct scc_dma_state *scc_state_wr[] = {
  376. scc_state_wr_0,
  377. scc_state_wr_1,
  378. scc_state_wr_2,
  379. scc_state_wr_3,
  380. scc_state_wr_4,
  381. scc_state_wr_5,
  382. scc_state_wr_6,
  383. scc_state_wr_7,
  384. scc_state_wr_8,
  385. scc_state_wr_9,
  386. scc_state_wr_10,
  387. scc_state_wr_11,
  388. scc_state_wr_12,
  389. scc_state_wr_13,
  390. scc_state_wr_14,
  391. scc_state_wr_15,
  392. scc_state_wr_16,
  393. scc_state_wr_17,
  394. scc_state_wr_18,
  395. scc_state_wr_19,
  396. scc_state_wr_20,
  397. scc_state_wr_21,
  398. scc_state_wr_22,
  399. scc_state_wr_23,
  400. scc_state_wr_24,
  401. scc_state_wr_25,
  402. scc_state_wr_26,
  403. scc_state_wr_27,
  404. scc_state_wr_28,
  405. scc_state_wr_29,
  406. scc_state_wr_30,
  407. scc_state_wr_31,
  408. scc_state_wr_32,
  409. scc_state_wr_33,
  410. scc_state_wr_34,
  411. scc_state_wr_35,
  412. scc_state_wr_36,
  413. scc_state_wr_37,
  414. scc_state_wr_38,
  415. scc_state_wr_39,
  416. scc_state_wr_40,
  417. };
  418. static u32 scc_takeover_mode = SCC_TO_IMMEDIATE;
  419. /* Change mode of the SPDMA for given direction */
  420. static u32 scc_agu_mode_sp = AGU_BYPASS;
  421. /* Change mode of the USB for given direction */
  422. static u32 scc_agu_mode_usb = AGU_BYPASS;
  423. static union scc_softwareconfiguration scc_software_configuration[SCC_MAX];
  424. static u32 dma_fsm[4][4] = {
  425. /* DMA_CMD_RESET DMA_CMD_SETUP DMA_CMD_START DMA_CMD_STOP */
  426. /* DMA_STATE_RESET */
  427. {DMA_STATE_RESET, DMA_STATE_SETUP, DMA_STATE_ERROR, DMA_STATE_ERROR},
  428. /* DMA_STATE_SETUP */
  429. {DMA_STATE_RESET, DMA_STATE_SETUP, DMA_STATE_START, DMA_STATE_SETUP},
  430. /* DMA_STATE_START */
  431. {DMA_STATE_RESET, DMA_STATE_ERROR, DMA_STATE_START, DMA_STATE_SETUP},
  432. /* DMA_STATE_ERROR */
  433. {DMA_STATE_RESET, DMA_STATE_ERROR, DMA_STATE_ERROR, DMA_STATE_ERROR},
  434. };
  435. static void dma_state_process(struct scc_dma_state *dma_state, u32 cmd)
  436. {
  437. dma_state->dma_status = dma_fsm[dma_state->dma_status][cmd];
  438. dma_state->dma_cmd = cmd;
  439. }
  440. static void dma_state_process_dma_command(struct scc_dma_state *dma_state,
  441. u32 dma_cmd)
  442. {
  443. dma_state->dma_cmd = dma_cmd;
  444. switch (dma_cmd) {
  445. case DMA_START:
  446. case DMA_START_FH_RESET:
  447. dma_state_process(dma_state, DMA_CMD_START);
  448. break;
  449. case DMA_STOP:
  450. dma_state_process(dma_state, DMA_CMD_STOP);
  451. break;
  452. default:
  453. break;
  454. }
  455. }
  456. static void scc_takeover_dma(enum scc_id id, u32 dma_id, u32 drs)
  457. {
  458. union scc_cmd dma_cmd;
  459. dma_cmd.reg = 0;
  460. /* Prepare the takeover for the DMA channel */
  461. dma_cmd.bits.action = DMA_TAKEOVER;
  462. dma_cmd.bits.id = dma_id;
  463. dma_cmd.bits.rid = TO_DMA_CFG; /* this is DMA_CFG register takeover */
  464. if (drs == DMA_WRITE)
  465. dma_cmd.bits.drs = DMA_WRITE;
  466. reg_write(SCC_CMD(scc_descriptor_table[id].base_address), dma_cmd.reg);
  467. }
  468. int scc_dma_cmd(enum scc_id id, u32 cmd, u32 dma_id, u32 drs)
  469. {
  470. union scc_cmd dma_cmd;
  471. struct scc_dma_state *dma_state;
  472. if ((id >= SCC_MAX) || (id < 0))
  473. return -EINVAL;
  474. dma_cmd.reg = 0;
  475. /* Prepare the takeover for the DMA channel */
  476. dma_cmd.bits.action = cmd;
  477. dma_cmd.bits.id = dma_id;
  478. if (drs == DMA_WRITE) {
  479. dma_cmd.bits.drs = DMA_WRITE;
  480. dma_state = &scc_state_wr[id][dma_id];
  481. } else {
  482. dma_state = &scc_state_rd[id][dma_id];
  483. }
  484. dma_state->scc_id = id;
  485. dma_state->dma_id = dma_id;
  486. dma_state_process_dma_command(dma_state, cmd);
  487. reg_write(SCC_CMD(scc_descriptor_table[id].base_address), dma_cmd.reg);
  488. return 0;
  489. }
  490. int scc_set_usb_address_generation_mode(u32 agu_mode)
  491. {
  492. if (AGU_ACTIVE == agu_mode) {
  493. /* Ensure both DMAs are stopped */
  494. scc_dma_cmd(SCC_USB_RW, DMA_STOP, 0, DMA_WRITE);
  495. scc_dma_cmd(SCC_USB_RW, DMA_STOP, 0, DMA_READ);
  496. } else {
  497. agu_mode = AGU_BYPASS;
  498. }
  499. scc_agu_mode_usb = agu_mode;
  500. return 0;
  501. }
  502. int scc_setup_dma(enum scc_id id, u32 buffer_tag,
  503. u32 type, u32 fh_mode, u32 drs, u32 dma_id)
  504. {
  505. struct scc_dma_state *dma_state;
  506. int return_value = 0;
  507. union scc_dma_cfg dma_cfg;
  508. u32 *buffer_tag_list = scc_descriptor_table[id].buffer_tag_list;
  509. u32 tag_count, t, t_valid;
  510. if ((id >= SCC_MAX) || (id < 0))
  511. return -EINVAL;
  512. /* if the register is only configured by hw, cannot write! */
  513. if (1 == scc_descriptor_table[id].hw_dma_cfg)
  514. return -EACCES;
  515. if (DMA_WRITE == drs) {
  516. if (dma_id >= scc_descriptor_table[id].p_dma_channels_wr)
  517. return -EINVAL;
  518. dma_state = &scc_state_wr[id][dma_id];
  519. } else {
  520. if (dma_id >= scc_descriptor_table[id].p_dma_channels_rd)
  521. return -EINVAL;
  522. dma_state = &scc_state_rd[id][dma_id];
  523. }
  524. /* Compose the DMA configuration register */
  525. tag_count = buffer_tag_list[0];
  526. t_valid = 0;
  527. for (t = 1; t <= tag_count; t++) {
  528. if (buffer_tag == buffer_tag_list[t]) {
  529. /* Tag found - validate */
  530. t_valid = 1;
  531. break;
  532. }
  533. }
  534. if (!t_valid)
  535. return -EACCES;
  536. /*
  537. * Read the register first -- two functions write into the register
  538. * it does not make sense to read the DMA config back, because there
  539. * are two register configuration sets (drs)
  540. */
  541. dma_cfg.reg = 0;
  542. dma_cfg.bits.buffer_id = buffer_tag;
  543. dma_state_process(dma_state, DMA_CMD_SETUP);
  544. /*
  545. * This is Packet CFG set select - usable for TSIO, EBI and those SCCs
  546. * which habe 2 packet configs
  547. */
  548. dma_cfg.bits.packet_cfg_id =
  549. scc_software_configuration[id].bits.packet_select;
  550. if (type == DMA_CYCLIC)
  551. dma_cfg.bits.buffer_type = 1;
  552. else
  553. dma_cfg.bits.buffer_type = 0;
  554. if (fh_mode == USE_FH)
  555. dma_cfg.bits.fh_mode = 1;
  556. else
  557. dma_cfg.bits.fh_mode = 0;
  558. if (id == SCC_CPU1_SPDMA_RW)
  559. dma_cfg.bits.agu_mode = scc_agu_mode_sp;
  560. if (id == SCC_USB_RW)
  561. dma_cfg.bits.agu_mode = scc_agu_mode_usb;
  562. reg_write(SCC_DMA_CFG(scc_descriptor_table[id].base_address),
  563. dma_cfg.reg);
  564. /* The DMA_CFG needs a takeover! */
  565. if (SCC_TO_IMMEDIATE == scc_takeover_mode)
  566. scc_takeover_dma(id, dma_id, drs);
  567. /* if (buffer_tag is not used) */
  568. dma_state->buffer_tag = buffer_tag;
  569. dma_state->scc_id = id;
  570. dma_state->dma_id = dma_id;
  571. return return_value;
  572. }
  573. int scc_enable(enum scc_id id, u32 value)
  574. {
  575. if ((id >= SCC_MAX) || (id < 0))
  576. return -EINVAL;
  577. if (value == 0) {
  578. scc_software_configuration[id].bits.enable_status = 0;
  579. } else {
  580. value = 1;
  581. scc_software_configuration[id].bits.enable_status = 1;
  582. }
  583. reg_write(SCC_ENABLE(scc_descriptor_table[id].base_address), value);
  584. return 0;
  585. }
  586. static inline void ehb(void)
  587. {
  588. __asm__ __volatile__(
  589. " .set mips32r2 \n"
  590. " ehb \n"
  591. " .set mips0 \n");
  592. }
  593. int scc_reset(enum scc_id id, u32 value)
  594. {
  595. if ((id >= SCC_MAX) || (id < 0))
  596. return -EINVAL;
  597. /* Invert value to the strait logic from the negative hardware logic */
  598. if (value == 0)
  599. value = 1;
  600. else
  601. value = 0;
  602. /* Write the value to the register */
  603. reg_write(SCC_RESET(scc_descriptor_table[id].base_address), value);
  604. /* sync flush */
  605. asm("sync"); /* request bus write queue flush */
  606. ehb(); /* wait until previous bus commit instr has finished */
  607. asm("nop"); /* wait for flush to occur */
  608. asm("nop"); /* wait for flush to occur */
  609. udelay(100);
  610. return 0;
  611. }