Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / powerpc / cpu / mpc8xx / immap.c
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
14 #include <asm/immap_8xx.h>
15 #include <asm/cpm_8xx.h>
16 #include <asm/iopin_8xx.h>
17 #include <asm/io.h>
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 static int do_siuinfo(struct cmd_tbl *cmdtp, int flag, int argc,
22                       char *const argv[])
23 {
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));
36         return 0;
37 }
38
39 static int do_memcinfo(struct cmd_tbl *cmdtp, int flag, int argc,
40                        char *const argv[])
41 {
42         immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
43         memctl8xx_t __iomem *memctl = &immap->im_memctl;
44         int nbanks = 8;
45         uint __iomem *p = &memctl->memc_br0;
46         int i;
47
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));
59         return 0;
60 }
61
62 static int do_carinfo(struct cmd_tbl *cmdtp, int flag, int argc,
63                       char *const argv[])
64 {
65         immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
66         car8xx_t __iomem *car = &immap->im_clkrst;
67
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));
71         return 0;
72 }
73
74 static int counter;
75
76 static void header(void)
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
94 static void binary(char *label, uint value, int nbits)
95 {
96         uint mask = 1 << (nbits - 1);
97         int i, second = (counter++ % 2);
98
99         if (second)
100                 putc(' ');
101         puts(label);
102         for (i = 32 + 1; i != nbits; i--)
103                 putc(' ');
104
105         while (mask != 0) {
106                 if (value & mask)
107                         putc('1');
108                 else
109                         putc('0');
110                 mask >>= 1;
111         }
112
113         if (second)
114                 putc('\n');
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
124 static int do_iopinfo(struct cmd_tbl *cmdtp, int flag, int argc,
125                       char *const argv[])
126 {
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;
131
132         counter = 0;
133         header();
134
135         /*
136          * Ports A & B
137          */
138
139         l = &iop->iop_padir;
140         R = &immap->im_cpm.cp_pbdir;
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);
149
150         header();
151
152         /*
153          * Ports C & D
154          */
155
156         l = &iop->iop_pcdir;
157         r = &iop->iop_pddir;
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);
164         r++;
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);
168
169         header();
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  */
178 static int do_iopset(struct cmd_tbl *cmdtp, int flag, int argc,
179                      char *const argv[])
180 {
181         uint rcode = 0;
182         iopin_t iopin;
183         static uint port;
184         static uint pin;
185         static uint value;
186         static enum {
187                 DIR,
188                 PAR,
189                 SOR,
190                 ODR,
191                 DAT,
192                 INT
193         } cmd = DAT;
194
195         if (argc != 5) {
196                 puts("iopset PORT PIN CMD VALUE\n");
197                 return 1;
198         }
199         port = argv[1][0] - 'A';
200         if (port > 3)
201                 port -= 0x20;
202         if (port > 3)
203                 rcode = 1;
204         pin = simple_strtol(argv[2], NULL, 10);
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:
231                 printf("iopset: unknown command %s\n", argv[3]);
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)
247                                 iopin_set_out(&iopin);
248                         else
249                                 iopin_set_in(&iopin);
250                         break;
251                 case PAR:
252                         if (value)
253                                 iopin_set_ded(&iopin);
254                         else
255                                 iopin_set_gen(&iopin);
256                         break;
257                 case SOR:
258                         if (value)
259                                 iopin_set_opt2(&iopin);
260                         else
261                                 iopin_set_opt1(&iopin);
262                         break;
263                 case ODR:
264                         if (value)
265                                 iopin_set_odr(&iopin);
266                         else
267                                 iopin_set_act(&iopin);
268                         break;
269                 case DAT:
270                         if (value)
271                                 iopin_set_high(&iopin);
272                         else
273                                 iopin_set_low(&iopin);
274                         break;
275                 case INT:
276                         if (value)
277                                 iopin_set_falledge(&iopin);
278                         else
279                                 iopin_set_anyedge(&iopin);
280                         break;
281                 }
282         }
283         return rcode;
284 }
285
286 static void prbrg(int n, uint val)
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
294         printf("BRG%d:", n);
295
296         if (val & CPM_BRG_RST)
297                 puts(" RESET");
298         else
299                 puts("      ");
300
301         if (val & CPM_BRG_EN)
302                 puts("  ENABLED");
303         else
304                 puts(" DISABLED");
305
306         printf(" EXTC=%d", extc);
307
308         if (val & CPM_BRG_ATB)
309                 puts(" ATB");
310         else
311                 puts("    ");
312
313         printf(" DIVIDER=%4d", cd);
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
322                 printf("=%6d bps", baudrate);
323         } else {
324                 puts("           ");
325         }
326
327         if (val & CPM_BRG_DIV16)
328                 puts(" DIV16");
329         else
330                 puts("      ");
331
332         putc('\n');
333 }
334
335 static int do_brginfo(struct cmd_tbl *cmdtp, int flag, int argc,
336                       char *const argv[])
337 {
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;
341         int i = 1;
342
343         while (i <= 4)
344                 prbrg(i++, in_be32(p++));
345
346         return 0;
347 }
348
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
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 );