1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2000-2003
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  */
6 
7 /*
8  * MPC8xx Internal Memory Map Functions
9  */
10 
11 #include <common.h>
12 #include <command.h>
13 #include <asm/global_data.h>
14 
15 #include <asm/immap_8xx.h>
16 #include <asm/cpm_8xx.h>
17 #include <asm/iopin_8xx.h>
18 #include <asm/io.h>
19 
20 DECLARE_GLOBAL_DATA_PTR;
21 
do_siuinfo(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])22 static int do_siuinfo(struct cmd_tbl *cmdtp, int flag, int argc,
23 		      char *const argv[])
24 {
25 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
26 	sysconf8xx_t __iomem *sc = &immap->im_siu_conf;
27 
28 	printf("SIUMCR= %08x SYPCR = %08x\n",
29 	       in_be32(&sc->sc_siumcr), in_be32(&sc->sc_sypcr));
30 	printf("SWT   = %08x\n", in_be32(&sc->sc_swt));
31 	printf("SIPEND= %08x SIMASK= %08x\n",
32 	       in_be32(&sc->sc_sipend), in_be32(&sc->sc_simask));
33 	printf("SIEL  = %08x SIVEC = %08x\n",
34 	       in_be32(&sc->sc_siel), in_be32(&sc->sc_sivec));
35 	printf("TESR  = %08x SDCR  = %08x\n",
36 	       in_be32(&sc->sc_tesr), in_be32(&sc->sc_sdcr));
37 	return 0;
38 }
39 
do_memcinfo(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])40 static int do_memcinfo(struct cmd_tbl *cmdtp, int flag, int argc,
41 		       char *const argv[])
42 {
43 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
44 	memctl8xx_t __iomem *memctl = &immap->im_memctl;
45 	int nbanks = 8;
46 	uint __iomem *p = &memctl->memc_br0;
47 	int i;
48 
49 	for (i = 0; i < nbanks; i++, p += 2)
50 		printf("BR%-2d  = %08x OR%-2d  = %08x\n",
51 		       i, in_be32(p), i, in_be32(p + 1));
52 
53 	printf("MAR   = %08x", in_be32(&memctl->memc_mar));
54 	printf(" MCR   = %08x\n", in_be32(&memctl->memc_mcr));
55 	printf("MAMR  = %08x MBMR  = %08x",
56 	       in_be32(&memctl->memc_mamr), in_be32(&memctl->memc_mbmr));
57 	printf("\nMSTAT =     %04x\n", in_be16(&memctl->memc_mstat));
58 	printf("MPTPR =     %04x MDR   = %08x\n",
59 	       in_be16(&memctl->memc_mptpr), in_be32(&memctl->memc_mdr));
60 	return 0;
61 }
62 
do_carinfo(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])63 static int do_carinfo(struct cmd_tbl *cmdtp, int flag, int argc,
64 		      char *const argv[])
65 {
66 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
67 	car8xx_t __iomem *car = &immap->im_clkrst;
68 
69 	printf("SCCR  = %08x\n", in_be32(&car->car_sccr));
70 	printf("PLPRCR= %08x\n", in_be32(&car->car_plprcr));
71 	printf("RSR   = %08x\n", in_be32(&car->car_rsr));
72 	return 0;
73 }
74 
75 static int counter;
76 
header(void)77 static void header(void)
78 {
79 	char *data = "\
80        --------------------------------        --------------------------------\
81        00000000001111111111222222222233        00000000001111111111222222222233\
82        01234567890123456789012345678901        01234567890123456789012345678901\
83        --------------------------------        --------------------------------\
84     ";
85 	int i;
86 
87 	if (counter % 2)
88 		putc('\n');
89 	counter = 0;
90 
91 	for (i = 0; i < 4; i++, data += 79)
92 		printf("%.79s\n", data);
93 }
94 
binary(char * label,uint value,int nbits)95 static void binary(char *label, uint value, int nbits)
96 {
97 	uint mask = 1 << (nbits - 1);
98 	int i, second = (counter++ % 2);
99 
100 	if (second)
101 		putc(' ');
102 	puts(label);
103 	for (i = 32 + 1; i != nbits; i--)
104 		putc(' ');
105 
106 	while (mask != 0) {
107 		if (value & mask)
108 			putc('1');
109 		else
110 			putc('0');
111 		mask >>= 1;
112 	}
113 
114 	if (second)
115 		putc('\n');
116 }
117 
118 #define PA_NBITS	16
119 #define PA_NB_ODR	 8
120 #define PB_NBITS	18
121 #define PB_NB_ODR	16
122 #define PC_NBITS	12
123 #define PD_NBITS	13
124 
do_iopinfo(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])125 static int do_iopinfo(struct cmd_tbl *cmdtp, int flag, int argc,
126 		      char *const argv[])
127 {
128 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
129 	iop8xx_t __iomem *iop = &immap->im_ioport;
130 	ushort __iomem *l, *r;
131 	uint __iomem *R;
132 
133 	counter = 0;
134 	header();
135 
136 	/*
137 	 * Ports A & B
138 	 */
139 
140 	l = &iop->iop_padir;
141 	R = &immap->im_cpm.cp_pbdir;
142 	binary("PA_DIR", in_be16(l++), PA_NBITS);
143 	binary("PB_DIR", in_be32(R++), PB_NBITS);
144 	binary("PA_PAR", in_be16(l++), PA_NBITS);
145 	binary("PB_PAR", in_be32(R++), PB_NBITS);
146 	binary("PA_ODR", in_be16(l++), PA_NB_ODR);
147 	binary("PB_ODR", in_be32(R++), PB_NB_ODR);
148 	binary("PA_DAT", in_be16(l++), PA_NBITS);
149 	binary("PB_DAT", in_be32(R++), PB_NBITS);
150 
151 	header();
152 
153 	/*
154 	 * Ports C & D
155 	 */
156 
157 	l = &iop->iop_pcdir;
158 	r = &iop->iop_pddir;
159 	binary("PC_DIR", in_be16(l++), PC_NBITS);
160 	binary("PD_DIR", in_be16(r++), PD_NBITS);
161 	binary("PC_PAR", in_be16(l++), PC_NBITS);
162 	binary("PD_PAR", in_be16(r++), PD_NBITS);
163 	binary("PC_SO ", in_be16(l++), PC_NBITS);
164 	binary("      ", 0, 0);
165 	r++;
166 	binary("PC_DAT", in_be16(l++), PC_NBITS);
167 	binary("PD_DAT", in_be16(r++), PD_NBITS);
168 	binary("PC_INT", in_be16(l++), PC_NBITS);
169 
170 	header();
171 	return 0;
172 }
173 
174 /*
175  * set the io pins
176  * this needs a clean up for smaller tighter code
177  * use *uint and set the address based on cmd + port
178  */
do_iopset(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])179 static int do_iopset(struct cmd_tbl *cmdtp, int flag, int argc,
180 		     char *const argv[])
181 {
182 	uint rcode = 0;
183 	iopin_t iopin;
184 	static uint port;
185 	static uint pin;
186 	static uint value;
187 	static enum {
188 		DIR,
189 		PAR,
190 		SOR,
191 		ODR,
192 		DAT,
193 		INT
194 	} cmd = DAT;
195 
196 	if (argc != 5) {
197 		puts("iopset PORT PIN CMD VALUE\n");
198 		return 1;
199 	}
200 	port = argv[1][0] - 'A';
201 	if (port > 3)
202 		port -= 0x20;
203 	if (port > 3)
204 		rcode = 1;
205 	pin = simple_strtol(argv[2], NULL, 10);
206 	if (pin > 31)
207 		rcode = 1;
208 
209 
210 	switch (argv[3][0]) {
211 	case 'd':
212 		if (argv[3][1] == 'a')
213 			cmd = DAT;
214 		else if (argv[3][1] == 'i')
215 			cmd = DIR;
216 		else
217 			rcode = 1;
218 		break;
219 	case 'p':
220 		cmd = PAR;
221 		break;
222 	case 'o':
223 		cmd = ODR;
224 		break;
225 	case 's':
226 		cmd = SOR;
227 		break;
228 	case 'i':
229 		cmd = INT;
230 		break;
231 	default:
232 		printf("iopset: unknown command %s\n", argv[3]);
233 		rcode = 1;
234 	}
235 	if (argv[4][0] == '1')
236 		value = 1;
237 	else if (argv[4][0] == '0')
238 		value = 0;
239 	else
240 		rcode = 1;
241 	if (rcode == 0) {
242 		iopin.port = port;
243 		iopin.pin = pin;
244 		iopin.flag = 0;
245 		switch (cmd) {
246 		case DIR:
247 			if (value)
248 				iopin_set_out(&iopin);
249 			else
250 				iopin_set_in(&iopin);
251 			break;
252 		case PAR:
253 			if (value)
254 				iopin_set_ded(&iopin);
255 			else
256 				iopin_set_gen(&iopin);
257 			break;
258 		case SOR:
259 			if (value)
260 				iopin_set_opt2(&iopin);
261 			else
262 				iopin_set_opt1(&iopin);
263 			break;
264 		case ODR:
265 			if (value)
266 				iopin_set_odr(&iopin);
267 			else
268 				iopin_set_act(&iopin);
269 			break;
270 		case DAT:
271 			if (value)
272 				iopin_set_high(&iopin);
273 			else
274 				iopin_set_low(&iopin);
275 			break;
276 		case INT:
277 			if (value)
278 				iopin_set_falledge(&iopin);
279 			else
280 				iopin_set_anyedge(&iopin);
281 			break;
282 		}
283 	}
284 	return rcode;
285 }
286 
prbrg(int n,uint val)287 static void prbrg(int n, uint val)
288 {
289 	uint extc = (val >> 14) & 3;
290 	uint cd = (val & CPM_BRG_CD_MASK) >> 1;
291 	uint div16 = (val & CPM_BRG_DIV16) != 0;
292 
293 	ulong clock = gd->cpu_clk;
294 
295 	printf("BRG%d:", n);
296 
297 	if (val & CPM_BRG_RST)
298 		puts(" RESET");
299 	else
300 		puts("      ");
301 
302 	if (val & CPM_BRG_EN)
303 		puts("  ENABLED");
304 	else
305 		puts(" DISABLED");
306 
307 	printf(" EXTC=%d", extc);
308 
309 	if (val & CPM_BRG_ATB)
310 		puts(" ATB");
311 	else
312 		puts("    ");
313 
314 	printf(" DIVIDER=%4d", cd);
315 	if (extc == 0 && cd != 0) {
316 		uint baudrate;
317 
318 		if (div16)
319 			baudrate = (clock / 16) / (cd + 1);
320 		else
321 			baudrate = clock / (cd + 1);
322 
323 		printf("=%6d bps", baudrate);
324 	} else {
325 		puts("           ");
326 	}
327 
328 	if (val & CPM_BRG_DIV16)
329 		puts(" DIV16");
330 	else
331 		puts("      ");
332 
333 	putc('\n');
334 }
335 
do_brginfo(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])336 static int do_brginfo(struct cmd_tbl *cmdtp, int flag, int argc,
337 		      char *const argv[])
338 {
339 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
340 	cpm8xx_t __iomem *cp = &immap->im_cpm;
341 	uint __iomem *p = &cp->cp_brgc1;
342 	int i = 1;
343 
344 	while (i <= 4)
345 		prbrg(i++, in_be32(p++));
346 
347 	return 0;
348 }
349 
350 #ifdef CONFIG_CMD_REGINFO
print_reginfo(void)351 void print_reginfo(void)
352 {
353 	immap_t __iomem     *immap  = (immap_t __iomem *)CONFIG_SYS_IMMR;
354 	sit8xx_t __iomem *timers = &immap->im_sit;
355 
356 	printf("\nSystem Configuration registers\n"
357 		"\tIMMR\t0x%08X\n", get_immr());
358 	do_siuinfo(NULL, 0, 0, NULL);
359 
360 	printf("Memory Controller Registers\n");
361 	do_memcinfo(NULL, 0, 0, NULL);
362 
363 	printf("\nSystem Integration Timers\n");
364 	printf("\tTBSCR\t0x%04X\tRTCSC\t0x%04X\n",
365 	       in_be16(&timers->sit_tbscr), in_be16(&timers->sit_rtcsc));
366 	printf("\tPISCR\t0x%04X\n", in_be16(&timers->sit_piscr));
367 }
368 #endif
369 
370 /***************************************************/
371 
372 U_BOOT_CMD(
373 	siuinfo,	1,	1,	do_siuinfo,
374 	"print System Interface Unit (SIU) registers",
375 	""
376 );
377 
378 U_BOOT_CMD(
379 	memcinfo,	1,	1,	do_memcinfo,
380 	"print Memory Controller registers",
381 	""
382 );
383 
384 U_BOOT_CMD(
385 	carinfo,	1,	1,	do_carinfo,
386 	"print Clocks and Reset registers",
387 	""
388 );
389 
390 U_BOOT_CMD(
391 	iopinfo,	1,	1,	do_iopinfo,
392 	"print I/O Port registers",
393 	""
394 );
395 
396 U_BOOT_CMD(
397 	iopset,	5,	0,	do_iopset,
398 	"set I/O Port registers",
399 	"PORT PIN CMD VALUE\nPORT: A-D, PIN: 0-31, CMD: [dat|dir|odr|sor], VALUE: 0|1"
400 );
401 
402 U_BOOT_CMD(
403 	brginfo,	1,	1,	do_brginfo,
404 	"print Baud Rate Generator (BRG) registers",
405 	""
406 );
407