// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. */ /* * MPC8xx Internal Memory Map Functions */ #include <common.h> #include <command.h> #include <asm/immap_8xx.h> #include <asm/cpm_8xx.h> #include <asm/iopin_8xx.h> #include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; static int do_siuinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; sysconf8xx_t __iomem *sc = &immap->im_siu_conf; printf("SIUMCR= %08x SYPCR = %08x\n", in_be32(&sc->sc_siumcr), in_be32(&sc->sc_sypcr)); printf("SWT = %08x\n", in_be32(&sc->sc_swt)); printf("SIPEND= %08x SIMASK= %08x\n", in_be32(&sc->sc_sipend), in_be32(&sc->sc_simask)); printf("SIEL = %08x SIVEC = %08x\n", in_be32(&sc->sc_siel), in_be32(&sc->sc_sivec)); printf("TESR = %08x SDCR = %08x\n", in_be32(&sc->sc_tesr), in_be32(&sc->sc_sdcr)); return 0; } static int do_memcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; memctl8xx_t __iomem *memctl = &immap->im_memctl; int nbanks = 8; uint __iomem *p = &memctl->memc_br0; int i; for (i = 0; i < nbanks; i++, p += 2) printf("BR%-2d = %08x OR%-2d = %08x\n", i, in_be32(p), i, in_be32(p + 1)); printf("MAR = %08x", in_be32(&memctl->memc_mar)); printf(" MCR = %08x\n", in_be32(&memctl->memc_mcr)); printf("MAMR = %08x MBMR = %08x", in_be32(&memctl->memc_mamr), in_be32(&memctl->memc_mbmr)); printf("\nMSTAT = %04x\n", in_be16(&memctl->memc_mstat)); printf("MPTPR = %04x MDR = %08x\n", in_be16(&memctl->memc_mptpr), in_be32(&memctl->memc_mdr)); return 0; } static int do_carinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; car8xx_t __iomem *car = &immap->im_clkrst; printf("SCCR = %08x\n", in_be32(&car->car_sccr)); printf("PLPRCR= %08x\n", in_be32(&car->car_plprcr)); printf("RSR = %08x\n", in_be32(&car->car_rsr)); return 0; } static int counter; static void header(void) { char *data = "\ -------------------------------- --------------------------------\ 00000000001111111111222222222233 00000000001111111111222222222233\ 01234567890123456789012345678901 01234567890123456789012345678901\ -------------------------------- --------------------------------\ "; int i; if (counter % 2) putc('\n'); counter = 0; for (i = 0; i < 4; i++, data += 79) printf("%.79s\n", data); } static void binary(char *label, uint value, int nbits) { uint mask = 1 << (nbits - 1); int i, second = (counter++ % 2); if (second) putc(' '); puts(label); for (i = 32 + 1; i != nbits; i--) putc(' '); while (mask != 0) { if (value & mask) putc('1'); else putc('0'); mask >>= 1; } if (second) putc('\n'); } #define PA_NBITS 16 #define PA_NB_ODR 8 #define PB_NBITS 18 #define PB_NB_ODR 16 #define PC_NBITS 12 #define PD_NBITS 13 static int do_iopinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; iop8xx_t __iomem *iop = &immap->im_ioport; ushort __iomem *l, *r; uint __iomem *R; counter = 0; header(); /* * Ports A & B */ l = &iop->iop_padir; R = &immap->im_cpm.cp_pbdir; binary("PA_DIR", in_be16(l++), PA_NBITS); binary("PB_DIR", in_be32(R++), PB_NBITS); binary("PA_PAR", in_be16(l++), PA_NBITS); binary("PB_PAR", in_be32(R++), PB_NBITS); binary("PA_ODR", in_be16(l++), PA_NB_ODR); binary("PB_ODR", in_be32(R++), PB_NB_ODR); binary("PA_DAT", in_be16(l++), PA_NBITS); binary("PB_DAT", in_be32(R++), PB_NBITS); header(); /* * Ports C & D */ l = &iop->iop_pcdir; r = &iop->iop_pddir; binary("PC_DIR", in_be16(l++), PC_NBITS); binary("PD_DIR", in_be16(r++), PD_NBITS); binary("PC_PAR", in_be16(l++), PC_NBITS); binary("PD_PAR", in_be16(r++), PD_NBITS); binary("PC_SO ", in_be16(l++), PC_NBITS); binary(" ", 0, 0); r++; binary("PC_DAT", in_be16(l++), PC_NBITS); binary("PD_DAT", in_be16(r++), PD_NBITS); binary("PC_INT", in_be16(l++), PC_NBITS); header(); return 0; } /* * set the io pins * this needs a clean up for smaller tighter code * use *uint and set the address based on cmd + port */ static int do_iopset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint rcode = 0; iopin_t iopin; static uint port; static uint pin; static uint value; static enum { DIR, PAR, SOR, ODR, DAT, INT } cmd = DAT; if (argc != 5) { puts("iopset PORT PIN CMD VALUE\n"); return 1; } port = argv[1][0] - 'A'; if (port > 3) port -= 0x20; if (port > 3) rcode = 1; pin = simple_strtol(argv[2], NULL, 10); if (pin > 31) rcode = 1; switch (argv[3][0]) { case 'd': if (argv[3][1] == 'a') cmd = DAT; else if (argv[3][1] == 'i') cmd = DIR; else rcode = 1; break; case 'p': cmd = PAR; break; case 'o': cmd = ODR; break; case 's': cmd = SOR; break; case 'i': cmd = INT; break; default: printf("iopset: unknown command %s\n", argv[3]); rcode = 1; } if (argv[4][0] == '1') value = 1; else if (argv[4][0] == '0') value = 0; else rcode = 1; if (rcode == 0) { iopin.port = port; iopin.pin = pin; iopin.flag = 0; switch (cmd) { case DIR: if (value) iopin_set_out(&iopin); else iopin_set_in(&iopin); break; case PAR: if (value) iopin_set_ded(&iopin); else iopin_set_gen(&iopin); break; case SOR: if (value) iopin_set_opt2(&iopin); else iopin_set_opt1(&iopin); break; case ODR: if (value) iopin_set_odr(&iopin); else iopin_set_act(&iopin); break; case DAT: if (value) iopin_set_high(&iopin); else iopin_set_low(&iopin); break; case INT: if (value) iopin_set_falledge(&iopin); else iopin_set_anyedge(&iopin); break; } } return rcode; } static void prbrg(int n, uint val) { uint extc = (val >> 14) & 3; uint cd = (val & CPM_BRG_CD_MASK) >> 1; uint div16 = (val & CPM_BRG_DIV16) != 0; ulong clock = gd->cpu_clk; printf("BRG%d:", n); if (val & CPM_BRG_RST) puts(" RESET"); else puts(" "); if (val & CPM_BRG_EN) puts(" ENABLED"); else puts(" DISABLED"); printf(" EXTC=%d", extc); if (val & CPM_BRG_ATB) puts(" ATB"); else puts(" "); printf(" DIVIDER=%4d", cd); if (extc == 0 && cd != 0) { uint baudrate; if (div16) baudrate = (clock / 16) / (cd + 1); else baudrate = clock / (cd + 1); printf("=%6d bps", baudrate); } else { puts(" "); } if (val & CPM_BRG_DIV16) puts(" DIV16"); else puts(" "); putc('\n'); } static int do_brginfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; cpm8xx_t __iomem *cp = &immap->im_cpm; uint __iomem *p = &cp->cp_brgc1; int i = 1; while (i <= 4) prbrg(i++, in_be32(p++)); return 0; } #ifdef CONFIG_CMD_REGINFO void print_reginfo(void) { immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; sit8xx_t __iomem *timers = &immap->im_sit; printf("\nSystem Configuration registers\n" "\tIMMR\t0x%08X\n", get_immr()); do_siuinfo(NULL, 0, 0, NULL); printf("Memory Controller Registers\n"); do_memcinfo(NULL, 0, 0, NULL); printf("\nSystem Integration Timers\n"); printf("\tTBSCR\t0x%04X\tRTCSC\t0x%04X\n", in_be16(&timers->sit_tbscr), in_be16(&timers->sit_rtcsc)); printf("\tPISCR\t0x%04X\n", in_be16(&timers->sit_piscr)); } #endif /***************************************************/ U_BOOT_CMD( siuinfo, 1, 1, do_siuinfo, "print System Interface Unit (SIU) registers", "" ); U_BOOT_CMD( memcinfo, 1, 1, do_memcinfo, "print Memory Controller registers", "" ); U_BOOT_CMD( carinfo, 1, 1, do_carinfo, "print Clocks and Reset registers", "" ); U_BOOT_CMD( iopinfo, 1, 1, do_iopinfo, "print I/O Port registers", "" ); U_BOOT_CMD( iopset, 5, 0, do_iopset, "set I/O Port registers", "PORT PIN CMD VALUE\nPORT: A-D, PIN: 0-31, CMD: [dat|dir|odr|sor], VALUE: 0|1" ); U_BOOT_CMD( brginfo, 1, 1, do_brginfo, "print Baud Rate Generator (BRG) registers", "" );