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