1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2007 Michal Simek
4  *
5  * Michal  SIMEK <monstr@monstr.eu>
6  */
7 
8 /*
9  * Microblaze FSL support
10  */
11 
12 #include <common.h>
13 #include <config.h>
14 #include <command.h>
15 #include <asm/asm.h>
16 
do_frd(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])17 int do_frd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
18 {
19 	unsigned int fslnum;
20 	unsigned int num;
21 	unsigned int blocking;
22 
23 	if (argc < 2)
24 		return CMD_RET_USAGE;
25 
26 	fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16);
27 	blocking = (unsigned int)simple_strtoul (argv[2], NULL, 16);
28 	if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) {
29 		puts ("Bad number of FSL\n");
30 		return CMD_RET_USAGE;
31 	}
32 
33 	switch (fslnum) {
34 #if (XILINX_FSL_NUMBER > 0)
35 	case 0:
36 		switch (blocking) {
37 		case 0:	NGET (num, 0);
38 			break;
39 		case 1:	NCGET (num, 0);
40 			break;
41 		case 2:	GET (num, 0);
42 			break;
43 		case 3:	CGET (num, 0);
44 			break;
45 		default:
46 			return 2;
47 		}
48 		break;
49 #endif
50 #if (XILINX_FSL_NUMBER > 1)
51 	case 1:
52 		switch (blocking) {
53 		case 0:	NGET (num, 1);
54 			break;
55 		case 1:	NCGET (num, 1);
56 			break;
57 		case 2:	GET (num, 1);
58 			break;
59 		case 3:	CGET (num, 1);
60 			break;
61 		default:
62 			return 2;
63 		}
64 		break;
65 #endif
66 #if (XILINX_FSL_NUMBER > 2)
67 	case 2:
68 		switch (blocking) {
69 		case 0:	NGET (num, 2);
70 			break;
71 		case 1:	NCGET (num, 2);
72 			break;
73 		case 2:	GET (num, 2);
74 			break;
75 		case 3:	CGET (num, 2);
76 			break;
77 		default:
78 			return 2;
79 		}
80 		break;
81 #endif
82 #if (XILINX_FSL_NUMBER > 3)
83 	case 3:
84 		switch (blocking) {
85 		case 0:	NGET (num, 3);
86 			break;
87 		case 1:	NCGET (num, 3);
88 			break;
89 		case 2:	GET (num, 3);
90 			break;
91 		case 3:	CGET (num, 3);
92 			break;
93 		default:
94 			return 2;
95 		}
96 		break;
97 #endif
98 #if (XILINX_FSL_NUMBER > 4)
99 	case 4:
100 		switch (blocking) {
101 		case 0:	NGET (num, 4);
102 			break;
103 		case 1:	NCGET (num, 4);
104 			break;
105 		case 2:	GET (num, 4);
106 			break;
107 		case 3:	CGET (num, 4);
108 			break;
109 		default:
110 			return 2;
111 		}
112 		break;
113 #endif
114 #if (XILINX_FSL_NUMBER > 5)
115 	case 5:
116 		switch (blocking) {
117 		case 0:	NGET (num, 5);
118 			break;
119 		case 1:	NCGET (num, 5);
120 			break;
121 		case 2:	GET (num, 5);
122 			break;
123 		case 3:	CGET (num, 5);
124 			break;
125 		default:
126 			return 2;
127 		}
128 		break;
129 #endif
130 #if (XILINX_FSL_NUMBER > 6)
131 	case 6:
132 		switch (blocking) {
133 		case 0:	NGET (num, 6);
134 			break;
135 		case 1:	NCGET (num, 6);
136 			break;
137 		case 2:	GET (num, 6);
138 			break;
139 		case 3:	CGET (num, 6);
140 			break;
141 		default:
142 			return 2;
143 		}
144 		break;
145 #endif
146 #if (XILINX_FSL_NUMBER > 7)
147 	case 7:
148 		switch (blocking) {
149 		case 0:	NGET (num, 7);
150 			break;
151 		case 1:	NCGET (num, 7);
152 			break;
153 		case 2:	GET (num, 7);
154 			break;
155 		case 3:	CGET (num, 7);
156 			break;
157 		default:
158 			return 2;
159 		}
160 		break;
161 #endif
162 	default:
163 		return 1;
164 	}
165 
166 	printf ("%01x: 0x%08x - %s %s read\n", fslnum, num,
167 		blocking < 2  ? "non blocking" : "blocking",
168 		((blocking == 1) || (blocking == 3)) ? "control" : "data" );
169 	return 0;
170 }
171 
do_fwr(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])172 int do_fwr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
173 {
174 	unsigned int fslnum;
175 	unsigned int num;
176 	unsigned int blocking;
177 
178 	if (argc < 3)
179 		return CMD_RET_USAGE;
180 
181 	fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16);
182 	num = (unsigned int)simple_strtoul (argv[2], NULL, 16);
183 	blocking = (unsigned int)simple_strtoul (argv[3], NULL, 16);
184 	if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER)
185 		return CMD_RET_USAGE;
186 
187 	switch (fslnum) {
188 #if (XILINX_FSL_NUMBER > 0)
189 	case 0:
190 		switch (blocking) {
191 		case 0:	NPUT (num, 0);
192 			break;
193 		case 1:	NCPUT (num, 0);
194 			break;
195 		case 2:	PUT (num, 0);
196 			break;
197 		case 3:	CPUT (num, 0);
198 			break;
199 		default:
200 			return 2;
201 		}
202 		break;
203 #endif
204 #if (XILINX_FSL_NUMBER > 1)
205 	case 1:
206 		switch (blocking) {
207 		case 0:	NPUT (num, 1);
208 			break;
209 		case 1:	NCPUT (num, 1);
210 			break;
211 		case 2:	PUT (num, 1);
212 			break;
213 		case 3:	CPUT (num, 1);
214 			break;
215 		default:
216 			return 2;
217 		}
218 		break;
219 #endif
220 #if (XILINX_FSL_NUMBER > 2)
221 	case 2:
222 		switch (blocking) {
223 		case 0:	NPUT (num, 2);
224 			break;
225 		case 1:	NCPUT (num, 2);
226 			break;
227 		case 2:	PUT (num, 2);
228 			break;
229 		case 3:	CPUT (num, 2);
230 			break;
231 		default:
232 			return 2;
233 		}
234 		break;
235 #endif
236 #if (XILINX_FSL_NUMBER > 3)
237 	case 3:
238 		switch (blocking) {
239 		case 0:	NPUT (num, 3);
240 			break;
241 		case 1:	NCPUT (num, 3);
242 			break;
243 		case 2:	PUT (num, 3);
244 			break;
245 		case 3:	CPUT (num, 3);
246 			break;
247 		default:
248 			return 2;
249 		}
250 		break;
251 #endif
252 #if (XILINX_FSL_NUMBER > 4)
253 	case 4:
254 		switch (blocking) {
255 		case 0:	NPUT (num, 4);
256 			break;
257 		case 1:	NCPUT (num, 4);
258 			break;
259 		case 2:	PUT (num, 4);
260 			break;
261 		case 3:	CPUT (num, 4);
262 			break;
263 		default:
264 			return 2;
265 		}
266 		break;
267 #endif
268 #if (XILINX_FSL_NUMBER > 5)
269 	case 5:
270 		switch (blocking) {
271 		case 0:	NPUT (num, 5);
272 			break;
273 		case 1:	NCPUT (num, 5);
274 			break;
275 		case 2:	PUT (num, 5);
276 			break;
277 		case 3:	CPUT (num, 5);
278 			break;
279 		default:
280 			return 2;
281 		}
282 		break;
283 #endif
284 #if (XILINX_FSL_NUMBER > 6)
285 	case 6:
286 		switch (blocking) {
287 		case 0:	NPUT (num, 6);
288 			break;
289 		case 1:	NCPUT (num, 6);
290 			break;
291 		case 2:	PUT (num, 6);
292 			break;
293 		case 3:	CPUT (num, 6);
294 			break;
295 		default:
296 			return 2;
297 		}
298 		break;
299 #endif
300 #if (XILINX_FSL_NUMBER > 7)
301 	case 7:
302 		switch (blocking) {
303 		case 0:	NPUT (num, 7);
304 			break;
305 		case 1:	NCPUT (num, 7);
306 			break;
307 		case 2:	PUT (num, 7);
308 			break;
309 		case 3:	CPUT (num, 7);
310 			break;
311 		default:
312 			return 2;
313 		}
314 		break;
315 #endif
316 	default:
317 		return 1;
318 	}
319 
320 	printf ("%01x: 0x%08x - %s %s write\n", fslnum, num,
321 		blocking < 2  ? "non blocking" : "blocking",
322 		((blocking == 1) || (blocking == 3)) ? "control" : "data" );
323 	return 0;
324 
325 }
326 
do_rspr(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])327 int do_rspr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
328 {
329 	unsigned int reg = 0;
330 	unsigned int val = 0;
331 
332 	if (argc < 2)
333 		return CMD_RET_USAGE;
334 
335 	reg = (unsigned int)simple_strtoul (argv[1], NULL, 16);
336 	val = (unsigned int)simple_strtoul (argv[2], NULL, 16);
337 	switch (reg) {
338 	case 0x1:
339 		if (argc > 2) {
340 			MTS (val, rmsr);
341 			NOP;
342 			MFS (val, rmsr);
343 		} else {
344 			MFS (val, rmsr);
345 		}
346 		puts ("MSR");
347 		break;
348 	case 0x3:
349 		MFS (val, rear);
350 		puts ("EAR");
351 		break;
352 	case 0x5:
353 		MFS (val, resr);
354 		puts ("ESR");
355 		break;
356 	default:
357 		puts ("Unsupported register\n");
358 		return 1;
359 	}
360 	printf (": 0x%08x\n", val);
361 	return 0;
362 }
363 
364 /***************************************************/
365 
366 U_BOOT_CMD (frd, 3, 1, do_frd,
367 		"read data from FSL",
368 		"- [fslnum [0|1|2|3]]\n"
369 		" 0 - non blocking data read\n"
370 		" 1 - non blocking control read\n"
371 		" 2 - blocking data read\n"
372 		" 3 - blocking control read");
373 
374 U_BOOT_CMD (fwr, 4, 1, do_fwr,
375 		"write data to FSL",
376 		"- [fslnum [0|1|2|3]]\n"
377 		" 0 - non blocking data write\n"
378 		" 1 - non blocking control write\n"
379 		" 2 - blocking data write\n"
380 		" 3 - blocking control write");
381 
382 U_BOOT_CMD (rspr, 3, 1, do_rspr,
383 		"read/write special purpose register",
384 		"- reg_num [write value] read/write special purpose register\n"
385 		" 1 - MSR - Machine status register\n"
386 		" 3 - EAR - Exception address register\n"
387 		" 5 - ESR - Exception status register");
388