blob: 0d33cc4c28e62e7c27804067aed1f41c67fc4bef [file] [log] [blame]
Stefan Roeseae691e52009-01-21 17:24:49 +01001/*
2 * (C) Copyright 2009 Stefan Roese <sr@denx.de>, DENX Software Engineering
3 *
4 * Copyright (C) 2006 Micronas GmbH
5 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
Stefan Roeseae691e52009-01-21 17:24:49 +01007 */
8
9#include <common.h>
Masahiro Yamada1221ce42016-09-21 11:28:55 +090010#include <linux/errno.h>
Stefan Roeseae691e52009-01-21 17:24:49 +010011
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 */
19static u32 buffer_list_0[] = { 6, 120, 121, 122, 123, 139, 140 };
20static u32 buffer_list_1[] = { 6, 120, 121, 122, 123, 139, 140 };
21static u32 buffer_list_2[] = { 5, 124, 125, 126, 139, 140 };
22static u32 buffer_list_3[] = { 5, 124, 125, 126, 139, 140 };
23static u32 buffer_list_4[] = { 5, 124, 125, 126, 139, 140 };
24static u32 buffer_list_5[] = { 3, 127, 139, 140 };
25static u32 buffer_list_6[] = { 3, 127, 139, 140 };
26static u32 buffer_list_7[] = { 6, 128, 129, 130, 131, 139, 140 };
27static u32 buffer_list_8[] = { 6, 128, 129, 130, 131, 139, 140 };
28static u32 buffer_list_9[] = { 5, 124, 125, 126, 139, 140 };
29static u32 buffer_list_10[] = { 5, 124, 125, 126, 139, 140 };
30static u32 buffer_list_11[] = { 5, 124, 125, 126, 139, 140 };
31static u32 buffer_list_12[] = { 6, 132, 133, 134, 135, 139, 140 };
32static u32 buffer_list_13[] = { 6, 132, 133, 134, 135, 139, 140 };
33static u32 buffer_list_14[] = { 4, 137, 138, 139, 140 };
34static u32 buffer_list_15[] = { 6, 136, 136, 137, 138, 139, 140 };
35
36/** Issue#7674 (new) - DP/DVP buffer assignment */
37static u32 buffer_list_16[] = { 6, 106, 108, 109, 107, 139, 140 };
38static u32 buffer_list_17[] = { 6, 106, 110, 107, 111, 139, 140 };
39static u32 buffer_list_18[] = { 6, 106, 113, 107, 114, 139, 140 };
40static u32 buffer_list_19[] = { 3, 112, 139, 140 };
41static 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 };
44static 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 };
47static 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 };
54static 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 };
57static u32 buffer_list_24[] = { 6, 90, 91, 92, 93, 139, 140 };
58static u32 buffer_list_25[] = { 18, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
59 100, 101, 102, 103, 104, 105, 139, 140 };
60static u32 buffer_list_26[] = { 5, 94, 95, 96, 139, 140 };
61static u32 buffer_list_27[] = { 5, 97, 98, 99, 139, 140 };
62static u32 buffer_list_28[] = { 5, 100, 101, 102, 139, 140 };
63static u32 buffer_list_29[] = { 5, 103, 104, 105, 139, 140 };
64static u32 buffer_list_30[] = { 10, 108, 109, 110, 111, 113, 114, 116, 117,
65 139, 140 };
66static u32 buffer_list_31[] = { 13, 106, 107, 108, 109, 110, 111, 113, 114,
67 115, 116, 117, 139, 140 };
68static u32 buffer_list_32[] = { 13, 106, 107, 108, 109, 110, 111, 113, 114,
69 115, 116, 117, 139, 140 };
70static 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 };
73static 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 };
76static 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 };
79static 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 };
82static 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 };
85static 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 };
88static 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 };
96static 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 */
103static u32 csize_list_0[] = { 2, 0, 1 };
104static u32 csize_list_1[] = { 2, 0, 1 };
105static u32 csize_list_2[] = { 1, 1 };
106static u32 csize_list_3[] = { 1, 1 };
107static u32 csize_list_4[] = { 1, 1 };
108static u32 csize_list_5[] = { 1, 0 };
109static u32 csize_list_6[] = { 1, 0 };
110static u32 csize_list_7[] = { 1, 1 };
111static u32 csize_list_8[] = { 1, 1 };
112static u32 csize_list_9[] = { 1, 1 };
113static u32 csize_list_10[] = { 1, 1 };
114static u32 csize_list_11[] = { 1, 1 };
115static u32 csize_list_12[] = { 1, 1 };
116static u32 csize_list_13[] = { 1, 1 };
117static u32 csize_list_14[] = { 1, 2 };
118static u32 csize_list_15[] = { 1, 4 };
119static u32 csize_list_16[] = { 3, 0, 1, 2 };
120static u32 csize_list_17[] = { 3, 0, 1, 2 };
121static u32 csize_list_18[] = { 3, 0, 1, 2 };
122static u32 csize_list_19[] = { 1, 2 };
123static u32 csize_list_20[] = { 1, 0 };
124static u32 csize_list_21[] = { 1, 0 };
125static u32 csize_list_22[] = { 1, 2 };
126static u32 csize_list_23[] = { 1, 3 };
127static u32 csize_list_24[] = { 1, 3 };
128static u32 csize_list_25[] = { 1, 3 };
129static u32 csize_list_26[] = { 1, 0 };
130static u32 csize_list_27[] = { 1, 0 };
131static u32 csize_list_28[] = { 1, 0 };
132static u32 csize_list_29[] = { 1, 0 };
133static u32 csize_list_30[] = { 1, 2 };
134static u32 csize_list_31[] = { 1, 2 };
135static u32 csize_list_32[] = { 1, 2 };
136static u32 csize_list_33[] = { 1, 2 };
137static u32 csize_list_34[] = { 1, 2 };
138static u32 csize_list_35[] = { 1, 2 };
139static u32 csize_list_36[] = { 1, 2 };
140static u32 csize_list_37[] = { 2, 0, 1 };
141static u32 csize_list_38[] = { 1, 2 };
142static u32 csize_list_39[] = { 1, 3 };
143static u32 csize_list_40[] = { 1, 3 };
144
145/*
146 * SCC_Configuration table
147 */
148static 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
236static struct scc_dma_state scc_state_rd_0[] = { {-1} };
237static struct scc_dma_state scc_state_wr_0[] = { {0}, {0}, {0}, {0} };
238static struct scc_dma_state scc_state_rd_1[] = { {0}, {0}, {0}, {0} };
239static struct scc_dma_state scc_state_wr_1[] = { {-1} };
240static struct scc_dma_state scc_state_rd_2[] = { {-1} };
241static struct scc_dma_state scc_state_wr_2[] = { {0}, {0}, {0} };
242static struct scc_dma_state scc_state_rd_3[] = { {0}, {0}, {0} };
243static struct scc_dma_state scc_state_wr_3[] = { {-1} };
244static struct scc_dma_state scc_state_rd_4[] = { {0}, {0}, {0} };
245static struct scc_dma_state scc_state_wr_4[] = { {-1} };
246static struct scc_dma_state scc_state_rd_5[] = { {-1} };
247static struct scc_dma_state scc_state_wr_5[] = { {0} };
248static struct scc_dma_state scc_state_rd_6[] = { {0} };
249static struct scc_dma_state scc_state_wr_6[] = { {-1} };
250static struct scc_dma_state scc_state_rd_7[] = { {-1} };
251static struct scc_dma_state scc_state_wr_7[] = { {0}, {0}, {0}, {0} };
252static struct scc_dma_state scc_state_rd_8[] = { {0}, {0}, {0}, {0} };
253static struct scc_dma_state scc_state_wr_8[] = { {-1} };
254static struct scc_dma_state scc_state_rd_9[] = { {0}, {0}, {0}, };
255static struct scc_dma_state scc_state_wr_9[] = { {-1} };
256static struct scc_dma_state scc_state_rd_10[] = { {0}, {0}, {0} };
257static struct scc_dma_state scc_state_wr_10[] = { {-1} };
258static struct scc_dma_state scc_state_rd_11[] = { {0}, {0}, {0} };
259static struct scc_dma_state scc_state_wr_11[] = { {-1} };
260static struct scc_dma_state scc_state_rd_12[] = { {-1} };
261static struct scc_dma_state scc_state_wr_12[] = { {0}, {0}, {0}, {0} };
262static struct scc_dma_state scc_state_rd_13[] = { {0}, {0}, {0}, {0} };
263static struct scc_dma_state scc_state_wr_13[] = { {-1} };
264static struct scc_dma_state scc_state_rd_14[] = { {0}, {0} };
265static struct scc_dma_state scc_state_wr_14[] = { {-1} };
266static struct scc_dma_state scc_state_rd_15[] = { {0} };
267static struct scc_dma_state scc_state_wr_15[] = { {0} };
268static struct scc_dma_state scc_state_rd_16[] = { {0}, {0}, {0} };
269static struct scc_dma_state scc_state_wr_16[] = { {-1} };
270static struct scc_dma_state scc_state_rd_17[] = { {0}, {0}, {0} };
271static struct scc_dma_state scc_state_wr_17[] = { {-1} };
272static struct scc_dma_state scc_state_rd_18[] = { {0}, {0} };
273static struct scc_dma_state scc_state_wr_18[] = { {-1} };
274static struct scc_dma_state scc_state_rd_19[] = { {0} };
275static struct scc_dma_state scc_state_wr_19[] = { {-1} };
276static struct scc_dma_state scc_state_rd_20[] = { {-1} };
277static struct scc_dma_state scc_state_wr_20[] = {
278 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} };
279static struct scc_dma_state scc_state_rd_21[] = { {0}, {0}, {0}, {0} };
280static struct scc_dma_state scc_state_wr_21[] = { {-1} };
281static struct scc_dma_state scc_state_rd_22[] = { {-1} };
282static 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} };
288static struct scc_dma_state scc_state_rd_23[] = { {0}, {0} };
289static struct scc_dma_state scc_state_wr_23[] = { {0}, {0} };
290static struct scc_dma_state scc_state_rd_24[] = { {0}, {0}, {0}, {0} };
291static struct scc_dma_state scc_state_wr_24[] = { {-1} };
292static struct scc_dma_state scc_state_rd_25[] = { {-1} };
293static 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} };
296static struct scc_dma_state scc_state_rd_26[] = { {0}, {0}, {0} };
297static struct scc_dma_state scc_state_wr_26[] = { {-1} };
298static struct scc_dma_state scc_state_rd_27[] = { {0}, {0}, {0} };
299static struct scc_dma_state scc_state_wr_27[] = { {-1} };
300static struct scc_dma_state scc_state_rd_28[] = { {0}, {0}, {0} };
301static struct scc_dma_state scc_state_wr_28[] = { {-1} };
302static struct scc_dma_state scc_state_rd_29[] = { {0}, {0}, {0} };
303static struct scc_dma_state scc_state_wr_29[] = { {-1} };
304static struct scc_dma_state scc_state_rd_30[] = { {-1} };
305static struct scc_dma_state scc_state_wr_30[] = { {0} };
306static struct scc_dma_state scc_state_rd_31[] = { {0} };
307static struct scc_dma_state scc_state_wr_31[] = { {-1} };
308static struct scc_dma_state scc_state_rd_32[] = { {0} };
309static struct scc_dma_state scc_state_wr_32[] = { {-1} };
310static struct scc_dma_state scc_state_rd_33[] = { {0}, {0} };
311static struct scc_dma_state scc_state_wr_33[] = { {-1} };
312static struct scc_dma_state scc_state_rd_34[] = { {-1} };
313static struct scc_dma_state scc_state_wr_34[] = { {0}, {0}, {0} };
314static struct scc_dma_state scc_state_rd_35[] = { {0}, {0}, {0}, {0}, {0} };
315static struct scc_dma_state scc_state_wr_35[] = { {-1} };
316static struct scc_dma_state scc_state_rd_36[] = { {-1} };
317static struct scc_dma_state scc_state_wr_36[] = { {0}, {0}, {0} };
318static struct scc_dma_state scc_state_rd_37[] = { {0}, {0}, {0}, {0} };
319static struct scc_dma_state scc_state_wr_37[] = { {0}, {0}, {0}, {0} };
320static struct scc_dma_state scc_state_rd_38[] = { {0} };
321static struct scc_dma_state scc_state_wr_38[] = { {0} };
322static struct scc_dma_state scc_state_rd_39[] = { {0} };
323static struct scc_dma_state scc_state_wr_39[] = { {0} };
324static struct scc_dma_state scc_state_rd_40[] = { {-1} };
325static struct scc_dma_state scc_state_wr_40[] = { {-1} };
326
327/* DMA state references to access from the driver */
328static 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
372static 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
416static u32 scc_takeover_mode = SCC_TO_IMMEDIATE;
417
418/* Change mode of the SPDMA for given direction */
419static u32 scc_agu_mode_sp = AGU_BYPASS;
420
421/* Change mode of the USB for given direction */
422static u32 scc_agu_mode_usb = AGU_BYPASS;
423
424static union scc_softwareconfiguration scc_software_configuration[SCC_MAX];
425
426static 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
438static 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
444static 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
461static 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
477int 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
506int 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
521int 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
609int 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
625static inline void ehb(void)
626{
627 __asm__ __volatile__(
628 " .set mips32r2 \n"
629 " ehb \n"
630 " .set mips0 \n");
631}
632
633int 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}