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