uboot/board/esd/pmc440/cmd_pmc440.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007-2008
   3 * Matthias Fuchs, esd Gmbh, matthias.fuchs@esd-electronics.com.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 *
  23 */
  24#include <common.h>
  25#include <command.h>
  26#include <asm/io.h>
  27#include <asm/cache.h>
  28#include <asm/processor.h>
  29#if defined(CONFIG_LOGBUFFER)
  30#include <logbuff.h>
  31#endif
  32
  33#include "pmc440.h"
  34
  35int is_monarch(void);
  36int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset,
  37                           uchar *buffer, unsigned cnt);
  38int eeprom_write_enable(unsigned dev_addr, int state);
  39
  40DECLARE_GLOBAL_DATA_PTR;
  41
  42#if defined(CONFIG_CMD_BSP)
  43
  44static int got_fifoirq;
  45static int got_hcirq;
  46
  47int fpga_interrupt(u32 arg)
  48{
  49        pmc440_fpga_t *fpga = (pmc440_fpga_t *)arg;
  50        int rc = -1; /* not for us */
  51        u32 status = FPGA_IN32(&fpga->status);
  52
  53        /* check for interrupt from fifo module */
  54        if (status & STATUS_FIFO_ISF) {
  55                /* disable this int source */
  56                FPGA_OUT32(&fpga->hostctrl, HOSTCTRL_FIFOIE_GATE);
  57                rc = 0;
  58                got_fifoirq = 1; /* trigger backend */
  59        }
  60
  61        if (status & STATUS_HOST_ISF) {
  62                FPGA_OUT32(&fpga->hostctrl, HOSTCTRL_HCINT_GATE);
  63                rc = 0;
  64                got_hcirq = 1;
  65        }
  66
  67        return rc;
  68}
  69
  70int do_waithci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  71{
  72        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
  73
  74        got_hcirq = 0;
  75
  76        FPGA_CLRBITS(&fpga->ctrla, CTRL_HOST_IE);
  77        FPGA_OUT32(&fpga->hostctrl, HOSTCTRL_HCINT_GATE);
  78
  79        irq_install_handler(IRQ0_FPGA,
  80                            (interrupt_handler_t *)fpga_interrupt,
  81                            fpga);
  82
  83        FPGA_SETBITS(&fpga->ctrla, CTRL_HOST_IE);
  84
  85        while (!got_hcirq) {
  86                /* Abort if ctrl-c was pressed */
  87                if (ctrlc()) {
  88                        puts("\nAbort\n");
  89                        break;
  90                }
  91        }
  92        if (got_hcirq)
  93                printf("Got interrupt!\n");
  94
  95        FPGA_CLRBITS(&fpga->ctrla, CTRL_HOST_IE);
  96        irq_free_handler(IRQ0_FPGA);
  97        return 0;
  98}
  99U_BOOT_CMD(
 100        waithci,        1,      1,      do_waithci,
 101        "waithci - Wait for host control interrupt\n",
 102        NULL
 103        );
 104
 105void dump_fifo(pmc440_fpga_t *fpga, int f, int *n)
 106{
 107        u32 ctrl;
 108
 109        while (!((ctrl = FPGA_IN32(&fpga->fifo[f].ctrl)) & FIFO_EMPTY)) {
 110                printf("%5d  %d    %3d  %08x",
 111                       (*n)++, f, ctrl & (FIFO_LEVEL_MASK | FIFO_FULL),
 112                       FPGA_IN32(&fpga->fifo[f].data));
 113                if (ctrl & FIFO_OVERFLOW) {
 114                        printf(" OVERFLOW\n");
 115                        FPGA_CLRBITS(&fpga->fifo[f].ctrl, FIFO_OVERFLOW);
 116                } else
 117                        printf("\n");
 118        }
 119}
 120
 121int do_fifo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 122{
 123        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
 124        int i;
 125        int n = 0;
 126        u32 ctrl, data, f;
 127        char str[] = "\\|/-";
 128        int abort = 0;
 129        int count = 0;
 130        int count2 = 0;
 131
 132        switch (argc) {
 133        case 1:
 134                /* print all fifos status information */
 135                printf("fifo level status\n");
 136                printf("______________________________\n");
 137                for (i=0; i<FIFO_COUNT; i++) {
 138                        ctrl = FPGA_IN32(&fpga->fifo[i].ctrl);
 139                        printf(" %d    %3d  %s%s%s %s\n",
 140                               i, ctrl & (FIFO_LEVEL_MASK | FIFO_FULL),
 141                               ctrl & FIFO_FULL ? "FULL     " : "",
 142                               ctrl & FIFO_EMPTY ? "EMPTY    " : "",
 143                               ctrl & (FIFO_FULL|FIFO_EMPTY) ? "" : "NOT EMPTY",
 144                               ctrl & FIFO_OVERFLOW ? "OVERFLOW" : "");
 145                }
 146                break;
 147
 148        case 2:
 149                /* completely read out fifo 'n' */
 150                if (!strcmp(argv[1],"read")) {
 151                        printf("  #   fifo level data\n");
 152                        printf("______________________________\n");
 153
 154                        for (i=0; i<FIFO_COUNT; i++)
 155                                dump_fifo(fpga, i, &n);
 156
 157                } else if (!strcmp(argv[1],"wait")) {
 158                        got_fifoirq = 0;
 159
 160                        irq_install_handler(IRQ0_FPGA,
 161                                            (interrupt_handler_t *)fpga_interrupt,
 162                                            fpga);
 163
 164                        printf("  #   fifo level data\n");
 165                        printf("______________________________\n");
 166
 167                        /* enable all fifo interrupts */
 168                        FPGA_OUT32(&fpga->hostctrl,
 169                                   HOSTCTRL_FIFOIE_GATE | HOSTCTRL_FIFOIE_FLAG);
 170                        for (i=0; i<FIFO_COUNT; i++) {
 171                                /* enable interrupts from all fifos */
 172                                FPGA_SETBITS(&fpga->fifo[i].ctrl, FIFO_IE);
 173                        }
 174
 175                        while (1) {
 176                                /* wait loop */
 177                                while (!got_fifoirq) {
 178                                        count++;
 179                                        if (!(count % 100)) {
 180                                                count2++;
 181                                                putc(0x08); /* backspace */
 182                                                putc(str[count2 % 4]);
 183                                        }
 184
 185                                        /* Abort if ctrl-c was pressed */
 186                                        if ((abort = ctrlc())) {
 187                                                puts("\nAbort\n");
 188                                                break;
 189                                        }
 190                                        udelay(1000);
 191                                }
 192                                if (abort)
 193                                        break;
 194
 195                                /* simple fifo backend */
 196                                if (got_fifoirq) {
 197                                        for (i=0; i<FIFO_COUNT; i++)
 198                                                dump_fifo(fpga, i, &n);
 199
 200                                        got_fifoirq = 0;
 201                                        /* unmask global fifo irq */
 202                                        FPGA_OUT32(&fpga->hostctrl,
 203                                                   HOSTCTRL_FIFOIE_GATE |
 204                                                   HOSTCTRL_FIFOIE_FLAG);
 205                                }
 206                        }
 207
 208                        /* disable all fifo interrupts */
 209                        FPGA_OUT32(&fpga->hostctrl, HOSTCTRL_FIFOIE_GATE);
 210                        for (i=0; i<FIFO_COUNT; i++)
 211                                FPGA_CLRBITS(&fpga->fifo[i].ctrl, FIFO_IE);
 212
 213                        irq_free_handler(IRQ0_FPGA);
 214
 215                } else {
 216                        printf("Usage:\nfifo %s\n", cmdtp->help);
 217                        return 1;
 218                }
 219                break;
 220
 221        case 4:
 222        case 5:
 223                if (!strcmp(argv[1],"write")) {
 224                        /* get fifo number or fifo address */
 225                        f = simple_strtoul(argv[2], NULL, 16);
 226
 227                        /* data paramter */
 228                        data = simple_strtoul(argv[3], NULL, 16);
 229
 230                        /* get optional count parameter */
 231                        n = 1;
 232                        if (argc >= 5)
 233                                n = (int)simple_strtoul(argv[4], NULL, 10);
 234
 235                        if (f < FIFO_COUNT) {
 236                                printf("writing %d x %08x to fifo %d\n",
 237                                       n, data, f);
 238                                for (i=0; i<n; i++)
 239                                        FPGA_OUT32(&fpga->fifo[f].data, data);
 240                        } else {
 241                                printf("writing %d x %08x to fifo port at "
 242                                       "address %08x\n",
 243                                       n, data, f);
 244                                for (i=0; i<n; i++)
 245                                        out32(f, data);
 246                        }
 247                } else {
 248                        printf("Usage:\nfifo %s\n", cmdtp->help);
 249                        return 1;
 250                }
 251                break;
 252
 253        default:
 254                printf("Usage:\nfifo %s\n", cmdtp->help);
 255                return 1;
 256        }
 257        return 0;
 258}
 259U_BOOT_CMD(
 260        fifo,   5,      1,      do_fifo,
 261        "fifo    - Fifo module operations\n",
 262        "wait\nfifo read\n"
 263        "fifo write fifo(0..3) data [cnt=1]\n"
 264        "fifo write address(>=4) data [cnt=1]\n"
 265        "  - without arguments: print all fifo's status\n"
 266        "  - with 'wait' argument: interrupt driven read from all fifos\n"
 267        "  - with 'read' argument: read current contents from all fifos\n"
 268        "  - with 'write' argument: write 'data' 'cnt' times to "
 269        "'fifo' or 'address'\n"
 270        );
 271
 272int do_setup_bootstrap_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 273{
 274        ulong sdsdp[5];
 275        ulong delay;
 276        int count=16;
 277
 278        if (argc < 2) {
 279                printf("Usage:\nsbe %s\n", cmdtp->help);
 280                return -1;
 281        }
 282
 283        if (argc > 1) {
 284                if (!strcmp(argv[1], "400")) {
 285                        /* PLB=133MHz, PLB/PCI=3 */
 286                        printf("Bootstrapping for 400MHz\n");
 287                        sdsdp[0]=0x8678624e;
 288                        sdsdp[1]=0x095fa030;
 289                        sdsdp[2]=0x40082350;
 290                        sdsdp[3]=0x0d050000;
 291                } else if (!strcmp(argv[1], "533")) {
 292                        /* PLB=133MHz, PLB/PCI=3 */
 293                        printf("Bootstrapping for 533MHz\n");
 294                        sdsdp[0]=0x87788252;
 295                        sdsdp[1]=0x095fa030;
 296                        sdsdp[2]=0x40082350;
 297                        sdsdp[3]=0x0d050000;
 298                } else if (!strcmp(argv[1], "667")) {
 299                        /* PLB=133MHz, PLB/PCI=3 */
 300                        printf("Bootstrapping for 667MHz\n");
 301                        sdsdp[0]=0x8778a256;
 302                        sdsdp[1]=0x095fa030;
 303                        sdsdp[2]=0x40082350;
 304                        sdsdp[3]=0x0d050000;
 305                } else {
 306                        printf("Usage:\nsbe %s\n", cmdtp->help);
 307                        return -1;
 308                }
 309        }
 310
 311        if (argc > 2) {
 312                sdsdp[4] = 0;
 313                if (argv[2][0]=='1')
 314                        sdsdp[4]=0x19750100;
 315                else if (argv[2][0]=='0')
 316                        sdsdp[4]=0x19750000;
 317                if (sdsdp[4])
 318                        count += 4;
 319        }
 320
 321        if (argc > 3) {
 322                delay = simple_strtoul(argv[3], NULL, 10);
 323                if (delay > 20)
 324                        delay = 20;
 325                sdsdp[4] |= delay;
 326        }
 327
 328        printf("Writing boot EEPROM ...\n");
 329        if (bootstrap_eeprom_write(CONFIG_SYS_I2C_BOOT_EEPROM_ADDR,
 330                                   0, (uchar*)sdsdp, count) != 0)
 331                printf("bootstrap_eeprom_write failed\n");
 332        else
 333                printf("done (dump via 'i2c md 52 0.1 14')\n");
 334
 335        return 0;
 336}
 337U_BOOT_CMD(
 338        sbe, 4, 0, do_setup_bootstrap_eeprom,
 339        "sbe     - setup bootstrap eeprom\n",
 340        "<cpufreq:400|533|667> [<console-uart:0|1> [<bringup delay (0..20s)>]]"
 341        );
 342
 343#if defined(CONFIG_PRAM)
 344#include <environment.h>
 345extern env_t *env_ptr;
 346
 347int do_painit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 348{
 349        u32 pram, nextbase, base;
 350        char *v;
 351        u32 param;
 352        ulong *lptr;
 353
 354        v = getenv("pram");
 355        if (v)
 356                pram = simple_strtoul(v, NULL, 10);
 357        else {
 358                printf("Error: pram undefined. Please define pram in KiB\n");
 359                return 1;
 360        }
 361
 362        base = gd->bd->bi_memsize;
 363#if defined(CONFIG_LOGBUFFER)
 364        base -= LOGBUFF_LEN + LOGBUFF_OVERHEAD;
 365#endif
 366        /*
 367         * gd->bd->bi_memsize == physical ram size - CONFIG_SYS_MEM_TOP_HIDE
 368         */
 369        param = base - (pram << 10);
 370        printf("PARAM: @%08x\n", param);
 371        debug("memsize=0x%08x, base=0x%08x\n", gd->bd->bi_memsize, base);
 372
 373        /* clear entire PA ram */
 374        memset((void*)param, 0, (pram << 10));
 375
 376        /* reserve 4k for pointer field */
 377        nextbase = base - 4096;
 378        lptr = (ulong*)(base);
 379
 380        /*
 381         * *(--lptr) = item_size;
 382         * *(--lptr) = base - item_base = distance from field top;
 383         */
 384
 385        /* env is first (4k aligned) */
 386        nextbase -= ((CONFIG_ENV_SIZE + 4096 - 1) & ~(4096 - 1));
 387        memcpy((void*)nextbase, env_ptr, CONFIG_ENV_SIZE);
 388        *(--lptr) = CONFIG_ENV_SIZE;     /* size */
 389        *(--lptr) = base - nextbase;  /* offset | type=0 */
 390
 391        /* free section */
 392        *(--lptr) = nextbase - param; /* size */
 393        *(--lptr) = (base - param) | 126; /* offset | type=126 */
 394
 395        /* terminate pointer field */
 396        *(--lptr) = crc32(0, (void*)(base - 0x10), 0x10);
 397        *(--lptr) = 0;                /* offset=0 -> terminator */
 398        return 0;
 399}
 400U_BOOT_CMD(
 401        painit, 1,      1,      do_painit,
 402        "painit  - prepare PciAccess system\n",
 403        NULL
 404        );
 405#endif /* CONFIG_PRAM */
 406
 407int do_selfreset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 408{
 409        in_be32((void*)CONFIG_SYS_RESET_BASE);
 410        return 0;
 411}
 412U_BOOT_CMD(
 413        selfreset,      1,      1,      do_selfreset,
 414        "selfreset- assert self-reset# signal\n",
 415        NULL
 416        );
 417
 418int do_resetout(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 419{
 420        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
 421
 422        /* requiers bootet FPGA and PLD_IOEN_N active */
 423        if (in_be32((void*)GPIO1_OR) & GPIO1_IOEN_N) {
 424                printf("Error: resetout requires a bootet FPGA\n");
 425                return -1;
 426        }
 427
 428        if (argc > 1) {
 429                if (argv[1][0] == '0') {
 430                        /* assert */
 431                        printf("PMC-RESETOUT# asserted\n");
 432                        FPGA_OUT32(&fpga->hostctrl,
 433                                   HOSTCTRL_PMCRSTOUT_GATE);
 434                } else {
 435                        /* deassert */
 436                        printf("PMC-RESETOUT# deasserted\n");
 437                        FPGA_OUT32(&fpga->hostctrl,
 438                                   HOSTCTRL_PMCRSTOUT_GATE |
 439                                   HOSTCTRL_PMCRSTOUT_FLAG);
 440                }
 441        } else {
 442                printf("PMC-RESETOUT# is %s\n",
 443                       FPGA_IN32(&fpga->hostctrl) & HOSTCTRL_PMCRSTOUT_FLAG ?
 444                       "inactive" : "active");
 445        }
 446
 447        return 0;
 448}
 449U_BOOT_CMD(
 450        resetout,       2,      1,      do_resetout,
 451        "resetout - assert PMC-RESETOUT# signal\n",
 452        NULL
 453        );
 454
 455int do_inta(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 456{
 457        if (is_monarch()) {
 458                printf("This command is only supported in non-monarch mode\n");
 459                return -1;
 460        }
 461
 462        if (argc > 1) {
 463                if (argv[1][0] == '0') {
 464                        /* assert */
 465                        printf("inta# asserted\n");
 466                        out_be32((void*)GPIO1_TCR,
 467                                 in_be32((void*)GPIO1_TCR) | GPIO1_INTA_FAKE);
 468                } else {
 469                        /* deassert */
 470                        printf("inta# deasserted\n");
 471                        out_be32((void*)GPIO1_TCR,
 472                                 in_be32((void*)GPIO1_TCR) & ~GPIO1_INTA_FAKE);
 473                }
 474        } else {
 475                printf("inta# is %s\n",
 476                       in_be32((void*)GPIO1_TCR) & GPIO1_INTA_FAKE ?
 477                       "active" : "inactive");
 478        }
 479        return 0;
 480}
 481U_BOOT_CMD(
 482        inta,   2,      1,      do_inta,
 483        "inta    - Assert/Deassert or query INTA# state in non-monarch mode\n",
 484        NULL
 485        );
 486
 487/* test-only */
 488int do_pmm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 489{
 490        ulong pciaddr;
 491
 492        if (argc > 1) {
 493                pciaddr = simple_strtoul(argv[1], NULL, 16);
 494
 495                pciaddr &= 0xf0000000;
 496
 497                /* map PCI address at 0xc0000000 in PLB space */
 498
 499                /* PMM1 Mask/Attribute - disabled b4 setting */
 500                out32r(PCIX0_PMM1MA, 0x00000000);
 501                /* PMM1 Local Address */
 502                out32r(PCIX0_PMM1LA, 0xc0000000);
 503                /* PMM1 PCI Low Address */
 504                out32r(PCIX0_PMM1PCILA, pciaddr);
 505                /* PMM1 PCI High Address */
 506                out32r(PCIX0_PMM1PCIHA, 0x00000000);
 507                /* 256MB + No prefetching, and enable region */
 508                out32r(PCIX0_PMM1MA, 0xf0000001);
 509        } else {
 510                printf("Usage:\npmm %s\n", cmdtp->help);
 511        }
 512        return 0;
 513}
 514U_BOOT_CMD(
 515        pmm,    2,      1,      do_pmm,
 516        "pmm     - Setup pmm[1] registers\n",
 517        "<pciaddr> (pciaddr will be aligned to 256MB)\n"
 518        );
 519
 520#if defined(CONFIG_SYS_EEPROM_WREN)
 521int do_eep_wren(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 522{
 523        int query = argc == 1;
 524        int state = 0;
 525
 526        if (query) {
 527                /* Query write access state. */
 528                state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR, -1);
 529                if (state < 0) {
 530                        puts("Query of write access state failed.\n");
 531                } else {
 532                        printf("Write access for device 0x%0x is %sabled.\n",
 533                               CONFIG_SYS_I2C_EEPROM_ADDR, state ? "en" : "dis");
 534                        state = 0;
 535                }
 536        } else {
 537                if ('0' == argv[1][0]) {
 538                        /* Disable write access. */
 539                        state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR, 0);
 540                } else {
 541                        /* Enable write access. */
 542                        state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR, 1);
 543                }
 544                if (state < 0) {
 545                        puts("Setup of write access state failed.\n");
 546                }
 547        }
 548
 549        return state;
 550}
 551U_BOOT_CMD(eepwren, 2, 0, do_eep_wren,
 552           "eepwren - Enable / disable / query EEPROM write access\n",
 553           NULL);
 554#endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */
 555
 556#endif /* CONFIG_CMD_BSP */
 557