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