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