xref: /openbmc/u-boot/board/micronas/vct/scc.c (revision ee7bb5be)
1 /*
2  * (C) Copyright 2009 Stefan Roese <sr@denx.de>, DENX Software Engineering
3  *
4  * Copyright (C) 2006 Micronas GmbH
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
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 }
657