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