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