blob: 8c85fc180b9bd17b2370ba6e8da466726790b981 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Christophe Leroy907208c2017-07-06 10:23:22 +02002/*
3 * (C) Copyright 2000-2003
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
Christophe Leroy907208c2017-07-06 10:23:22 +02005 */
6
7/*
8 * MPC8xx Internal Memory Map Functions
9 */
10
Christophe Leroy907208c2017-07-06 10:23:22 +020011#include <command.h>
Simon Glass401d1c42020-10-30 21:38:53 -060012#include <asm/global_data.h>
Christophe Leroy907208c2017-07-06 10:23:22 +020013
Christophe Leroyee1e6002018-03-16 17:20:41 +010014#include <asm/immap_8xx.h>
Christophe Leroy18f8d4c2018-03-16 17:20:43 +010015#include <asm/cpm_8xx.h>
Christophe Leroy907208c2017-07-06 10:23:22 +020016#include <asm/iopin_8xx.h>
Christophe Leroyba3da732017-07-06 10:33:13 +020017#include <asm/io.h>
Christophe Leroy80ac19f2023-11-06 19:12:04 +010018#include <asm/ppc.h>
Christophe Leroy907208c2017-07-06 10:23:22 +020019
20DECLARE_GLOBAL_DATA_PTR;
21
Simon Glass09140112020-05-10 11:40:03 -060022static int do_siuinfo(struct cmd_tbl *cmdtp, int flag, int argc,
23 char *const argv[])
Christophe Leroy907208c2017-07-06 10:23:22 +020024{
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
Simon Glass09140112020-05-10 11:40:03 -060040static int do_memcinfo(struct cmd_tbl *cmdtp, int flag, int argc,
41 char *const argv[])
Christophe Leroy907208c2017-07-06 10:23:22 +020042{
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
Simon Glass09140112020-05-10 11:40:03 -060063static int do_carinfo(struct cmd_tbl *cmdtp, int flag, int argc,
64 char *const argv[])
Christophe Leroy907208c2017-07-06 10:23:22 +020065{
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
Christophe Leroy70fd0712017-07-06 10:33:17 +020077static void header(void)
Christophe Leroy907208c2017-07-06 10:23:22 +020078{
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
Christophe Leroy70fd0712017-07-06 10:33:17 +020095static void binary(char *label, uint value, int nbits)
Christophe Leroy907208c2017-07-06 10:23:22 +020096{
97 uint mask = 1 << (nbits - 1);
98 int i, second = (counter++ % 2);
99
100 if (second)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200101 putc(' ');
102 puts(label);
Christophe Leroy907208c2017-07-06 10:23:22 +0200103 for (i = 32 + 1; i != nbits; i--)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200104 putc(' ');
Christophe Leroy907208c2017-07-06 10:23:22 +0200105
106 while (mask != 0) {
107 if (value & mask)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200108 putc('1');
Christophe Leroy907208c2017-07-06 10:23:22 +0200109 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200110 putc('0');
Christophe Leroy907208c2017-07-06 10:23:22 +0200111 mask >>= 1;
112 }
113
114 if (second)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200115 putc('\n');
Christophe Leroy907208c2017-07-06 10:23:22 +0200116}
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
Simon Glass09140112020-05-10 11:40:03 -0600125static int do_iopinfo(struct cmd_tbl *cmdtp, int flag, int argc,
126 char *const argv[])
Christophe Leroy907208c2017-07-06 10:23:22 +0200127{
Christophe Leroyba3da732017-07-06 10:33:13 +0200128 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;
Christophe Leroy907208c2017-07-06 10:23:22 +0200132
133 counter = 0;
Christophe Leroy70fd0712017-07-06 10:33:17 +0200134 header();
Christophe Leroy907208c2017-07-06 10:23:22 +0200135
136 /*
137 * Ports A & B
138 */
139
140 l = &iop->iop_padir;
141 R = &immap->im_cpm.cp_pbdir;
Christophe Leroyba3da732017-07-06 10:33:13 +0200142 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);
Christophe Leroy907208c2017-07-06 10:23:22 +0200150
Christophe Leroy70fd0712017-07-06 10:33:17 +0200151 header();
Christophe Leroy907208c2017-07-06 10:23:22 +0200152
153 /*
154 * Ports C & D
155 */
156
157 l = &iop->iop_pcdir;
158 r = &iop->iop_pddir;
Christophe Leroyba3da732017-07-06 10:33:13 +0200159 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);
Christophe Leroy907208c2017-07-06 10:23:22 +0200165 r++;
Christophe Leroyba3da732017-07-06 10:33:13 +0200166 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);
Christophe Leroy907208c2017-07-06 10:23:22 +0200169
Christophe Leroy70fd0712017-07-06 10:33:17 +0200170 header();
Christophe Leroy907208c2017-07-06 10:23:22 +0200171 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 */
Simon Glass09140112020-05-10 11:40:03 -0600179static int do_iopset(struct cmd_tbl *cmdtp, int flag, int argc,
180 char *const argv[])
Christophe Leroy907208c2017-07-06 10:23:22 +0200181{
182 uint rcode = 0;
183 iopin_t iopin;
Christophe Leroy70fd0712017-07-06 10:33:17 +0200184 static uint port;
185 static uint pin;
186 static uint value;
Christophe Leroy907208c2017-07-06 10:23:22 +0200187 static enum {
188 DIR,
189 PAR,
190 SOR,
191 ODR,
192 DAT,
193 INT
194 } cmd = DAT;
195
196 if (argc != 5) {
Christophe Leroy70fd0712017-07-06 10:33:17 +0200197 puts("iopset PORT PIN CMD VALUE\n");
Christophe Leroy907208c2017-07-06 10:23:22 +0200198 return 1;
199 }
200 port = argv[1][0] - 'A';
201 if (port > 3)
202 port -= 0x20;
203 if (port > 3)
204 rcode = 1;
Christophe Leroy70fd0712017-07-06 10:33:17 +0200205 pin = simple_strtol(argv[2], NULL, 10);
Christophe Leroy907208c2017-07-06 10:23:22 +0200206 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:
Christophe Leroy70fd0712017-07-06 10:33:17 +0200232 printf("iopset: unknown command %s\n", argv[3]);
Christophe Leroy907208c2017-07-06 10:23:22 +0200233 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)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200248 iopin_set_out(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200249 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200250 iopin_set_in(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200251 break;
252 case PAR:
253 if (value)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200254 iopin_set_ded(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200255 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200256 iopin_set_gen(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200257 break;
258 case SOR:
259 if (value)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200260 iopin_set_opt2(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200261 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200262 iopin_set_opt1(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200263 break;
264 case ODR:
265 if (value)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200266 iopin_set_odr(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200267 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200268 iopin_set_act(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200269 break;
270 case DAT:
271 if (value)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200272 iopin_set_high(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200273 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200274 iopin_set_low(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200275 break;
276 case INT:
277 if (value)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200278 iopin_set_falledge(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200279 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200280 iopin_set_anyedge(&iopin);
Christophe Leroy907208c2017-07-06 10:23:22 +0200281 break;
282 }
Christophe Leroy907208c2017-07-06 10:23:22 +0200283 }
284 return rcode;
285}
286
Christophe Leroy70fd0712017-07-06 10:33:17 +0200287static void prbrg(int n, uint val)
Christophe Leroy907208c2017-07-06 10:23:22 +0200288{
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
Christophe Leroy70fd0712017-07-06 10:33:17 +0200295 printf("BRG%d:", n);
Christophe Leroy907208c2017-07-06 10:23:22 +0200296
297 if (val & CPM_BRG_RST)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200298 puts(" RESET");
Christophe Leroy907208c2017-07-06 10:23:22 +0200299 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200300 puts(" ");
Christophe Leroy907208c2017-07-06 10:23:22 +0200301
302 if (val & CPM_BRG_EN)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200303 puts(" ENABLED");
Christophe Leroy907208c2017-07-06 10:23:22 +0200304 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200305 puts(" DISABLED");
Christophe Leroy907208c2017-07-06 10:23:22 +0200306
Christophe Leroy70fd0712017-07-06 10:33:17 +0200307 printf(" EXTC=%d", extc);
Christophe Leroy907208c2017-07-06 10:23:22 +0200308
309 if (val & CPM_BRG_ATB)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200310 puts(" ATB");
Christophe Leroy907208c2017-07-06 10:23:22 +0200311 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200312 puts(" ");
Christophe Leroy907208c2017-07-06 10:23:22 +0200313
Christophe Leroy70fd0712017-07-06 10:33:17 +0200314 printf(" DIVIDER=%4d", cd);
Christophe Leroy907208c2017-07-06 10:23:22 +0200315 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
Christophe Leroy70fd0712017-07-06 10:33:17 +0200323 printf("=%6d bps", baudrate);
Christophe Leroy907208c2017-07-06 10:23:22 +0200324 } else {
Christophe Leroy70fd0712017-07-06 10:33:17 +0200325 puts(" ");
Christophe Leroy907208c2017-07-06 10:23:22 +0200326 }
327
328 if (val & CPM_BRG_DIV16)
Christophe Leroy70fd0712017-07-06 10:33:17 +0200329 puts(" DIV16");
Christophe Leroy907208c2017-07-06 10:23:22 +0200330 else
Christophe Leroy70fd0712017-07-06 10:33:17 +0200331 puts(" ");
Christophe Leroy907208c2017-07-06 10:23:22 +0200332
Christophe Leroy70fd0712017-07-06 10:33:17 +0200333 putc('\n');
Christophe Leroy907208c2017-07-06 10:23:22 +0200334}
335
Simon Glass09140112020-05-10 11:40:03 -0600336static int do_brginfo(struct cmd_tbl *cmdtp, int flag, int argc,
337 char *const argv[])
Christophe Leroy907208c2017-07-06 10:23:22 +0200338{
Christophe Leroyba3da732017-07-06 10:33:13 +0200339 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;
Christophe Leroy907208c2017-07-06 10:23:22 +0200342 int i = 1;
343
344 while (i <= 4)
Christophe Leroyba3da732017-07-06 10:33:13 +0200345 prbrg(i++, in_be32(p++));
Christophe Leroy907208c2017-07-06 10:23:22 +0200346
347 return 0;
348}
349
Christophe Leroyab0d8192018-03-16 17:20:57 +0100350#ifdef CONFIG_CMD_REGINFO
351void 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
Christophe Leroy907208c2017-07-06 10:23:22 +0200370/***************************************************/
371
372U_BOOT_CMD(
373 siuinfo, 1, 1, do_siuinfo,
374 "print System Interface Unit (SIU) registers",
375 ""
376);
377
378U_BOOT_CMD(
379 memcinfo, 1, 1, do_memcinfo,
380 "print Memory Controller registers",
381 ""
382);
383
384U_BOOT_CMD(
385 carinfo, 1, 1, do_carinfo,
386 "print Clocks and Reset registers",
387 ""
388);
389
390U_BOOT_CMD(
391 iopinfo, 1, 1, do_iopinfo,
392 "print I/O Port registers",
393 ""
394);
395
396U_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
402U_BOOT_CMD(
403 brginfo, 1, 1, do_brginfo,
404 "print Baud Rate Generator (BRG) registers",
405 ""
406);