blob: 63cc664e926f4466c3d37b9784e906de35230727 [file] [log] [blame]
Christophe Leroy907208c2017-07-06 10:23:22 +02001/*
2 * (C) Copyright 2000-2003
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8/*
9 * MPC8xx Internal Memory Map Functions
10 */
11
12#include <common.h>
13#include <command.h>
14
Christophe Leroy907208c2017-07-06 10:23:22 +020015#include <asm/8xx_immap.h>
16#include <commproc.h>
17#include <asm/iopin_8xx.h>
Christophe Leroyba3da732017-07-06 10:33:13 +020018#include <asm/io.h>
Christophe Leroy907208c2017-07-06 10:23:22 +020019
20DECLARE_GLOBAL_DATA_PTR;
21
22int
23do_siuinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
24{
Christophe Leroyba3da732017-07-06 10:33:13 +020025 immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
26 sysconf8xx_t __iomem *sc = &immap->im_siu_conf;
Christophe Leroy907208c2017-07-06 10:23:22 +020027
Christophe Leroyba3da732017-07-06 10:33:13 +020028 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));
Christophe Leroy907208c2017-07-06 10:23:22 +020037 return 0;
38}
39
40int
41do_memcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
42{
Christophe Leroyba3da732017-07-06 10:33:13 +020043 immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
44 memctl8xx_t __iomem *memctl = &immap->im_memctl;
Christophe Leroy907208c2017-07-06 10:23:22 +020045 int nbanks = 8;
Christophe Leroyba3da732017-07-06 10:33:13 +020046 uint __iomem *p = &memctl->memc_br0;
Christophe Leroy907208c2017-07-06 10:23:22 +020047 int i;
48
Christophe Leroyba3da732017-07-06 10:33:13 +020049 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));
Christophe Leroy907208c2017-07-06 10:23:22 +020052
Christophe Leroyba3da732017-07-06 10:33:13 +020053 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));
Christophe Leroy907208c2017-07-06 10:23:22 +020060 return 0;
61}
62
63int
64do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
65{
Christophe Leroyba3da732017-07-06 10:33:13 +020066 immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
67 car8xx_t __iomem *car = &immap->im_clkrst;
Christophe Leroy907208c2017-07-06 10:23:22 +020068
Christophe Leroyba3da732017-07-06 10:33:13 +020069 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));
Christophe Leroy907208c2017-07-06 10:23:22 +020072 return 0;
73}
74
75static int counter;
76
77static void
78header(void)
79{
80 char *data = "\
81 -------------------------------- --------------------------------\
82 00000000001111111111222222222233 00000000001111111111222222222233\
83 01234567890123456789012345678901 01234567890123456789012345678901\
84 -------------------------------- --------------------------------\
85 ";
86 int i;
87
88 if (counter % 2)
89 putc('\n');
90 counter = 0;
91
92 for (i = 0; i < 4; i++, data += 79)
93 printf("%.79s\n", data);
94}
95
96static void binary (char *label, uint value, int nbits)
97{
98 uint mask = 1 << (nbits - 1);
99 int i, second = (counter++ % 2);
100
101 if (second)
102 putc (' ');
103 puts (label);
104 for (i = 32 + 1; i != nbits; i--)
105 putc (' ');
106
107 while (mask != 0) {
108 if (value & mask)
109 putc ('1');
110 else
111 putc ('0');
112 mask >>= 1;
113 }
114
115 if (second)
116 putc ('\n');
117}
118
119#define PA_NBITS 16
120#define PA_NB_ODR 8
121#define PB_NBITS 18
122#define PB_NB_ODR 16
123#define PC_NBITS 12
124#define PD_NBITS 13
125
126int
127do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
128{
Christophe Leroyba3da732017-07-06 10:33:13 +0200129 immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
130 iop8xx_t __iomem *iop = &immap->im_ioport;
131 ushort __iomem *l, *r;
132 uint __iomem *R;
Christophe Leroy907208c2017-07-06 10:23:22 +0200133
134 counter = 0;
135 header ();
136
137 /*
138 * Ports A & B
139 */
140
141 l = &iop->iop_padir;
142 R = &immap->im_cpm.cp_pbdir;
Christophe Leroyba3da732017-07-06 10:33:13 +0200143 binary("PA_DIR", in_be16(l++), PA_NBITS);
144 binary("PB_DIR", in_be32(R++), PB_NBITS);
145 binary("PA_PAR", in_be16(l++), PA_NBITS);
146 binary("PB_PAR", in_be32(R++), PB_NBITS);
147 binary("PA_ODR", in_be16(l++), PA_NB_ODR);
148 binary("PB_ODR", in_be32(R++), PB_NB_ODR);
149 binary("PA_DAT", in_be16(l++), PA_NBITS);
150 binary("PB_DAT", in_be32(R++), PB_NBITS);
Christophe Leroy907208c2017-07-06 10:23:22 +0200151
152 header ();
153
154 /*
155 * Ports C & D
156 */
157
158 l = &iop->iop_pcdir;
159 r = &iop->iop_pddir;
Christophe Leroyba3da732017-07-06 10:33:13 +0200160 binary("PC_DIR", in_be16(l++), PC_NBITS);
161 binary("PD_DIR", in_be16(r++), PD_NBITS);
162 binary("PC_PAR", in_be16(l++), PC_NBITS);
163 binary("PD_PAR", in_be16(r++), PD_NBITS);
164 binary("PC_SO ", in_be16(l++), PC_NBITS);
165 binary(" ", 0, 0);
Christophe Leroy907208c2017-07-06 10:23:22 +0200166 r++;
Christophe Leroyba3da732017-07-06 10:33:13 +0200167 binary("PC_DAT", in_be16(l++), PC_NBITS);
168 binary("PD_DAT", in_be16(r++), PD_NBITS);
169 binary("PC_INT", in_be16(l++), PC_NBITS);
Christophe Leroy907208c2017-07-06 10:23:22 +0200170
171 header ();
172 return 0;
173}
174
175/*
176 * set the io pins
177 * this needs a clean up for smaller tighter code
178 * use *uint and set the address based on cmd + port
179 */
180int
181do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
182{
183 uint rcode = 0;
184 iopin_t iopin;
185 static uint port = 0;
186 static uint pin = 0;
187 static uint value = 0;
188 static enum {
189 DIR,
190 PAR,
191 SOR,
192 ODR,
193 DAT,
194 INT
195 } cmd = DAT;
196
197 if (argc != 5) {
198 puts ("iopset PORT PIN CMD VALUE\n");
199 return 1;
200 }
201 port = argv[1][0] - 'A';
202 if (port > 3)
203 port -= 0x20;
204 if (port > 3)
205 rcode = 1;
206 pin = simple_strtol (argv[2], NULL, 10);
207 if (pin > 31)
208 rcode = 1;
209
210
211 switch (argv[3][0]) {
212 case 'd':
213 if (argv[3][1] == 'a')
214 cmd = DAT;
215 else if (argv[3][1] == 'i')
216 cmd = DIR;
217 else
218 rcode = 1;
219 break;
220 case 'p':
221 cmd = PAR;
222 break;
223 case 'o':
224 cmd = ODR;
225 break;
226 case 's':
227 cmd = SOR;
228 break;
229 case 'i':
230 cmd = INT;
231 break;
232 default:
233 printf ("iopset: unknown command %s\n", argv[3]);
234 rcode = 1;
235 }
236 if (argv[4][0] == '1')
237 value = 1;
238 else if (argv[4][0] == '0')
239 value = 0;
240 else
241 rcode = 1;
242 if (rcode == 0) {
243 iopin.port = port;
244 iopin.pin = pin;
245 iopin.flag = 0;
246 switch (cmd) {
247 case DIR:
248 if (value)
249 iopin_set_out (&iopin);
250 else
251 iopin_set_in (&iopin);
252 break;
253 case PAR:
254 if (value)
255 iopin_set_ded (&iopin);
256 else
257 iopin_set_gen (&iopin);
258 break;
259 case SOR:
260 if (value)
261 iopin_set_opt2 (&iopin);
262 else
263 iopin_set_opt1 (&iopin);
264 break;
265 case ODR:
266 if (value)
267 iopin_set_odr (&iopin);
268 else
269 iopin_set_act (&iopin);
270 break;
271 case DAT:
272 if (value)
273 iopin_set_high (&iopin);
274 else
275 iopin_set_low (&iopin);
276 break;
277 case INT:
278 if (value)
279 iopin_set_falledge (&iopin);
280 else
281 iopin_set_anyedge (&iopin);
282 break;
283 }
284
285 }
286 return rcode;
287}
288
289static void prbrg (int n, uint val)
290{
291 uint extc = (val >> 14) & 3;
292 uint cd = (val & CPM_BRG_CD_MASK) >> 1;
293 uint div16 = (val & CPM_BRG_DIV16) != 0;
294
295 ulong clock = gd->cpu_clk;
296
297 printf ("BRG%d:", n);
298
299 if (val & CPM_BRG_RST)
300 puts (" RESET");
301 else
302 puts (" ");
303
304 if (val & CPM_BRG_EN)
305 puts (" ENABLED");
306 else
307 puts (" DISABLED");
308
309 printf (" EXTC=%d", extc);
310
311 if (val & CPM_BRG_ATB)
312 puts (" ATB");
313 else
314 puts (" ");
315
316 printf (" DIVIDER=%4d", cd);
317 if (extc == 0 && cd != 0) {
318 uint baudrate;
319
320 if (div16)
321 baudrate = (clock / 16) / (cd + 1);
322 else
323 baudrate = clock / (cd + 1);
324
325 printf ("=%6d bps", baudrate);
326 } else {
327 puts (" ");
328 }
329
330 if (val & CPM_BRG_DIV16)
331 puts (" DIV16");
332 else
333 puts (" ");
334
335 putc ('\n');
336}
337
338int
339do_brginfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
340{
Christophe Leroyba3da732017-07-06 10:33:13 +0200341 immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
342 cpm8xx_t __iomem *cp = &immap->im_cpm;
343 uint __iomem *p = &cp->cp_brgc1;
Christophe Leroy907208c2017-07-06 10:23:22 +0200344 int i = 1;
345
346 while (i <= 4)
Christophe Leroyba3da732017-07-06 10:33:13 +0200347 prbrg(i++, in_be32(p++));
Christophe Leroy907208c2017-07-06 10:23:22 +0200348
349 return 0;
350}
351
352/***************************************************/
353
354U_BOOT_CMD(
355 siuinfo, 1, 1, do_siuinfo,
356 "print System Interface Unit (SIU) registers",
357 ""
358);
359
360U_BOOT_CMD(
361 memcinfo, 1, 1, do_memcinfo,
362 "print Memory Controller registers",
363 ""
364);
365
366U_BOOT_CMD(
367 carinfo, 1, 1, do_carinfo,
368 "print Clocks and Reset registers",
369 ""
370);
371
372U_BOOT_CMD(
373 iopinfo, 1, 1, do_iopinfo,
374 "print I/O Port registers",
375 ""
376);
377
378U_BOOT_CMD(
379 iopset, 5, 0, do_iopset,
380 "set I/O Port registers",
381 "PORT PIN CMD VALUE\nPORT: A-D, PIN: 0-31, CMD: [dat|dir|odr|sor], VALUE: 0|1"
382);
383
384U_BOOT_CMD(
385 brginfo, 1, 1, do_brginfo,
386 "print Baud Rate Generator (BRG) registers",
387 ""
388);