uboot/board/esd/du440/du440.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2008
   3 * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <asm/processor.h>
  10#include <asm/io.h>
  11#include <asm/bitops.h>
  12#include <command.h>
  13#include <i2c.h>
  14#include <asm/ppc440.h>
  15#include "du440.h"
  16
  17DECLARE_GLOBAL_DATA_PTR;
  18
  19extern flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  20extern ulong flash_get_size (ulong base, int banknum);
  21
  22int usbhub_init(void);
  23int dvi_init(void);
  24int eeprom_write_enable (unsigned dev_addr, int state);
  25int board_revision(void);
  26
  27static int du440_post_errors;
  28
  29int board_early_init_f(void)
  30{
  31        u32 sdr0_cust0;
  32        u32 sdr0_pfc1, sdr0_pfc2;
  33        u32 reg;
  34
  35        mtdcr(EBC0_CFGADDR, EBC0_CFG);
  36        mtdcr(EBC0_CFGDATA, 0xb8400000);
  37
  38        /*
  39         * Setup the GPIO pins
  40         */
  41        out_be32((void*)GPIO0_OR, 0x00000000 | CONFIG_SYS_GPIO0_EP_EEP);
  42        out_be32((void*)GPIO0_TCR, 0x0000001f | CONFIG_SYS_GPIO0_EP_EEP);
  43        out_be32((void*)GPIO0_OSRL, 0x50055400);
  44        out_be32((void*)GPIO0_OSRH, 0x55005000);
  45        out_be32((void*)GPIO0_TSRL, 0x50055400);
  46        out_be32((void*)GPIO0_TSRH, 0x55005000);
  47        out_be32((void*)GPIO0_ISR1L, 0x50000000);
  48        out_be32((void*)GPIO0_ISR1H, 0x00000000);
  49        out_be32((void*)GPIO0_ISR2L, 0x00000000);
  50        out_be32((void*)GPIO0_ISR2H, 0x00000000);
  51        out_be32((void*)GPIO0_ISR3L, 0x00000000);
  52        out_be32((void*)GPIO0_ISR3H, 0x00000000);
  53
  54        out_be32((void*)GPIO1_OR, 0x00000000);
  55        out_be32((void*)GPIO1_TCR, 0xc2000000 |
  56                 CONFIG_SYS_GPIO1_IORSTN |
  57                 CONFIG_SYS_GPIO1_IORST2N |
  58                 CONFIG_SYS_GPIO1_LEDUSR1 |
  59                 CONFIG_SYS_GPIO1_LEDUSR2 |
  60                 CONFIG_SYS_GPIO1_LEDPOST |
  61                 CONFIG_SYS_GPIO1_LEDDU);
  62        out_be32((void*)GPIO1_ODR, CONFIG_SYS_GPIO1_LEDDU);
  63        out_be32((void*)GPIO1_OSRL, 0x0c280000);
  64        out_be32((void*)GPIO1_OSRH, 0x00000000);
  65        out_be32((void*)GPIO1_TSRL, 0xcc000000);
  66        out_be32((void*)GPIO1_TSRH, 0x00000000);
  67        out_be32((void*)GPIO1_ISR1L, 0x00005550);
  68        out_be32((void*)GPIO1_ISR1H, 0x00000000);
  69        out_be32((void*)GPIO1_ISR2L, 0x00050000);
  70        out_be32((void*)GPIO1_ISR2H, 0x00000000);
  71        out_be32((void*)GPIO1_ISR3L, 0x01400000);
  72        out_be32((void*)GPIO1_ISR3H, 0x00000000);
  73
  74        /*
  75         * Setup the interrupt controller polarities, triggers, etc.
  76         */
  77        mtdcr(UIC0SR, 0xffffffff);      /* clear all */
  78        mtdcr(UIC0ER, 0x00000000);      /* disable all */
  79        mtdcr(UIC0CR, 0x00000005);      /* ATI & UIC1 crit are critical */
  80        mtdcr(UIC0PR, 0xfffff7ff);      /* per ref-board manual */
  81        mtdcr(UIC0TR, 0x00000000);      /* per ref-board manual */
  82        mtdcr(UIC0VR, 0x00000000);      /* int31 highest, base=0x000 */
  83        mtdcr(UIC0SR, 0xffffffff);      /* clear all */
  84
  85        /*
  86         * UIC1:
  87         *  bit30: ext. Irq 1: PLD : int 32+30
  88         */
  89        mtdcr(UIC1SR, 0xffffffff);      /* clear all */
  90        mtdcr(UIC1ER, 0x00000000);      /* disable all */
  91        mtdcr(UIC1CR, 0x00000000);      /* all non-critical */
  92        mtdcr(UIC1PR, 0xfffffffd);
  93        mtdcr(UIC1TR, 0x00000000);
  94        mtdcr(UIC1VR, 0x00000000);      /* int31 highest, base=0x000 */
  95        mtdcr(UIC1SR, 0xffffffff);      /* clear all */
  96
  97        /*
  98         * UIC2
  99         *  bit3: ext. Irq 2: DCF77 : int 64+3
 100         */
 101        mtdcr(UIC2SR, 0xffffffff);      /* clear all */
 102        mtdcr(UIC2ER, 0x00000000);      /* disable all */
 103        mtdcr(UIC2CR, 0x00000000);      /* all non-critical */
 104        mtdcr(UIC2PR, 0xffffffff);      /* per ref-board manual */
 105        mtdcr(UIC2TR, 0x00000000);      /* per ref-board manual */
 106        mtdcr(UIC2VR, 0x00000000);      /* int31 highest, base=0x000 */
 107        mtdcr(UIC2SR, 0xffffffff);      /* clear all */
 108
 109        /* select Ethernet pins */
 110        mfsdr(SDR0_PFC1, sdr0_pfc1);
 111        mfsdr(SDR0_PFC2, sdr0_pfc2);
 112
 113        /* setup EMAC bridge interface */
 114        if (board_revision() == 0) {
 115                /* 1 x MII */
 116                sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SELECT_MASK) |
 117                        SDR0_PFC1_SELECT_CONFIG_1_2;
 118                sdr0_pfc2 = (sdr0_pfc2 & ~SDR0_PFC2_SELECT_MASK) |
 119                        SDR0_PFC2_SELECT_CONFIG_1_2;
 120        } else {
 121                /* 2 x SMII */
 122                sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SELECT_MASK) |
 123                        SDR0_PFC1_SELECT_CONFIG_6;
 124                sdr0_pfc2 = (sdr0_pfc2 & ~SDR0_PFC2_SELECT_MASK) |
 125                        SDR0_PFC2_SELECT_CONFIG_6;
 126        }
 127
 128        /* enable 2nd IIC */
 129        sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SIS_MASK) | SDR0_PFC1_SIS_IIC1_SEL;
 130
 131        mtsdr(SDR0_PFC2, sdr0_pfc2);
 132        mtsdr(SDR0_PFC1, sdr0_pfc1);
 133
 134        /* PCI arbiter enabled */
 135        mfsdr(SDR0_PCI0, reg);
 136        mtsdr(SDR0_PCI0, 0x80000000 | reg);
 137
 138        /* setup NAND FLASH */
 139        mfsdr(SDR0_CUST0, sdr0_cust0);
 140        sdr0_cust0 = SDR0_CUST0_MUX_NDFC_SEL    |
 141                SDR0_CUST0_NDFC_ENABLE          |
 142                SDR0_CUST0_NDFC_BW_8_BIT        |
 143                SDR0_CUST0_NDFC_ARE_MASK        |
 144                (0x80000000 >> (28 + CONFIG_SYS_NAND0_CS)) |
 145                (0x80000000 >> (28 + CONFIG_SYS_NAND1_CS));
 146        mtsdr(SDR0_CUST0, sdr0_cust0);
 147
 148        return 0;
 149}
 150
 151int misc_init_r(void)
 152{
 153        uint pbcr;
 154        int size_val = 0;
 155        u32 reg;
 156        unsigned long usb2d0cr = 0;
 157        unsigned long usb2phy0cr, usb2h0cr = 0;
 158        unsigned long sdr0_pfc1;
 159        unsigned long sdr0_srst0, sdr0_srst1;
 160        int i, j;
 161
 162        /* adjust flash start and offset */
 163        gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
 164        gd->bd->bi_flashoffset = 0;
 165
 166        mtdcr(EBC0_CFGADDR, PB0CR);
 167        pbcr = mfdcr(EBC0_CFGDATA);
 168        size_val = ffs(gd->bd->bi_flashsize) - 21;
 169        pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17);
 170        mtdcr(EBC0_CFGADDR, PB0CR);
 171        mtdcr(EBC0_CFGDATA, pbcr);
 172
 173        /*
 174         * Re-check to get correct base address
 175         */
 176        flash_get_size(gd->bd->bi_flashstart, 0);
 177
 178        /*
 179         * USB suff...
 180         */
 181        /* SDR Setting */
 182        mfsdr(SDR0_PFC1, sdr0_pfc1);
 183        mfsdr(SDR0_USB0, usb2d0cr);
 184        mfsdr(SDR0_USB2PHY0CR, usb2phy0cr);
 185        mfsdr(SDR0_USB2H0CR, usb2h0cr);
 186
 187        usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_XOCLK_MASK;
 188        usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_XOCLK_EXTERNAL;
 189        usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_WDINT_MASK;
 190        usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_WDINT_16BIT_30MHZ;
 191        usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DVBUS_MASK;
 192        usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DVBUS_PURDIS;
 193        usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DWNSTR_MASK;
 194        usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DWNSTR_HOST;
 195        usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_UTMICN_MASK;
 196        usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_UTMICN_HOST;
 197
 198        /* An 8-bit/60MHz interface is the only possible alternative
 199           when connecting the Device to the PHY */
 200        usb2h0cr   = usb2h0cr &~SDR0_USB2H0CR_WDINT_MASK;
 201        usb2h0cr   = usb2h0cr | SDR0_USB2H0CR_WDINT_16BIT_30MHZ;
 202
 203        /* To enable the USB 2.0 Device function through the UTMI interface */
 204        usb2d0cr = usb2d0cr &~SDR0_USB2D0CR_USB2DEV_EBC_SEL_MASK;
 205
 206        sdr0_pfc1 = sdr0_pfc1 &~SDR0_PFC1_UES_MASK;
 207        sdr0_pfc1 = sdr0_pfc1 | SDR0_PFC1_UES_EBCHR_SEL;
 208
 209        mtsdr(SDR0_PFC1, sdr0_pfc1);
 210        mtsdr(SDR0_USB0, usb2d0cr);
 211        mtsdr(SDR0_USB2PHY0CR, usb2phy0cr);
 212        mtsdr(SDR0_USB2H0CR, usb2h0cr);
 213
 214        /*
 215         * Take USB out of reset:
 216         * -Initial status = all cores are in reset
 217         * -deassert reset to OPB1, P4OPB0, OPB2, PLB42OPB1 OPB2PLB40 cores
 218         * -wait 1 ms
 219         * -deassert reset to PHY
 220         * -wait 1 ms
 221         * -deassert  reset to HOST
 222         * -wait 4 ms
 223         * -deassert all other resets
 224         */
 225        mfsdr(SDR0_SRST1, sdr0_srst1);
 226        sdr0_srst1 &= ~(SDR0_SRST1_OPBA1 |              \
 227                        SDR0_SRST1_P4OPB0 |             \
 228                        SDR0_SRST1_OPBA2 |              \
 229                        SDR0_SRST1_PLB42OPB1 |          \
 230                        SDR0_SRST1_OPB2PLB40);
 231        mtsdr(SDR0_SRST1, sdr0_srst1);
 232        udelay(1000);
 233
 234        mfsdr(SDR0_SRST1, sdr0_srst1);
 235        sdr0_srst1 &= ~SDR0_SRST1_USB20PHY;
 236        mtsdr(SDR0_SRST1, sdr0_srst1);
 237        udelay(1000);
 238
 239        mfsdr(SDR0_SRST0, sdr0_srst0);
 240        sdr0_srst0 &= ~SDR0_SRST0_USB2H;
 241        mtsdr(SDR0_SRST0, sdr0_srst0);
 242        udelay(4000);
 243
 244        /* finally all the other resets */
 245        mtsdr(SDR0_SRST1, 0x00000000);
 246        mtsdr(SDR0_SRST0, 0x00000000);
 247
 248        printf("USB:   Host(int phy)\n");
 249
 250        /*
 251         * Clear PLB4A0_ACR[WRP]
 252         * This fix will make the MAL burst disabling patch for the Linux
 253         * EMAC driver obsolete.
 254         */
 255        reg = mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_WRP_MASK;
 256        mtdcr(PLB4A0_ACR, reg);
 257
 258        /*
 259         * release IO-RST#
 260         * We have to wait at least 560ms until we may call usbhub_init
 261         */
 262        out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) |
 263                 CONFIG_SYS_GPIO1_IORSTN | CONFIG_SYS_GPIO1_IORST2N);
 264
 265        /*
 266         * flash USR1/2 LEDs (600ms)
 267         * This results in the necessary delay from IORST# until
 268         * calling usbhub_init will succeed
 269         */
 270        for (j = 0; j < 3; j++) {
 271                out_be32((void*)GPIO1_OR,
 272                         (in_be32((void*)GPIO1_OR) & ~CONFIG_SYS_GPIO1_LEDUSR2) |
 273                         CONFIG_SYS_GPIO1_LEDUSR1);
 274
 275                for (i = 0; i < 100; i++)
 276                        udelay(1000);
 277
 278                out_be32((void*)GPIO1_OR,
 279                         (in_be32((void*)GPIO1_OR) & ~CONFIG_SYS_GPIO1_LEDUSR1) |
 280                         CONFIG_SYS_GPIO1_LEDUSR2);
 281
 282                for (i = 0; i < 100; i++)
 283                        udelay(1000);
 284        }
 285
 286        out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) &
 287                 ~(CONFIG_SYS_GPIO1_LEDUSR1 | CONFIG_SYS_GPIO1_LEDUSR2));
 288
 289        if (usbhub_init())
 290                du440_post_errors++;
 291
 292        if (dvi_init())
 293                du440_post_errors++;
 294
 295        return 0;
 296}
 297
 298int pld_revision(void)
 299{
 300        out_8((void *)CONFIG_SYS_CPLD_BASE, 0x00);
 301        return (int)(in_8((void *)CONFIG_SYS_CPLD_BASE) & CPLD_VERSION_MASK);
 302}
 303
 304int board_revision(void)
 305{
 306        int rpins = (int)((in_be32((void*)GPIO1_IR) & CONFIG_SYS_GPIO1_HWVER_MASK)
 307                          >> CONFIG_SYS_GPIO1_HWVER_SHIFT);
 308
 309        return ((rpins & 1) << 3) | ((rpins & 2) << 1) |
 310                ((rpins & 4) >> 1) | ((rpins & 8) >> 3);
 311}
 312
 313#if defined(CONFIG_SHOW_ACTIVITY)
 314void board_show_activity (ulong timestamp)
 315{
 316        if ((timestamp % 100) == 0)
 317                out_be32((void*)GPIO1_OR,
 318                         in_be32((void*)GPIO1_OR) ^ CONFIG_SYS_GPIO1_LEDUSR1);
 319}
 320
 321void show_activity(int arg)
 322{
 323}
 324#endif /* CONFIG_SHOW_ACTIVITY */
 325
 326int du440_phy_addr(int devnum)
 327{
 328        if (board_revision() == 0)
 329                return devnum;
 330
 331        return devnum + 1;
 332}
 333
 334int checkboard(void)
 335{
 336        char serno[32];
 337
 338        puts("Board: DU440");
 339
 340        if (getenv_f("serial#", serno, sizeof(serno)) > 0) {
 341                puts(", serial# ");
 342                puts(serno);
 343        }
 344
 345        printf(", HW-Rev. 1.%d, CPLD-Rev. 1.%d\n",
 346               board_revision(), pld_revision());
 347        return (0);
 348}
 349
 350int last_stage_init(void)
 351{
 352        int e, i;
 353
 354        /* everyting is ok: turn on POST-LED */
 355        out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | CONFIG_SYS_GPIO1_LEDPOST);
 356
 357        /* slowly blink on errors and finally keep LED off */
 358        for (e = 0; e < du440_post_errors; e++) {
 359                out_be32((void*)GPIO1_OR,
 360                         in_be32((void*)GPIO1_OR) | CONFIG_SYS_GPIO1_LEDPOST);
 361
 362                for (i = 0; i < 500; i++)
 363                        udelay(1000);
 364
 365                out_be32((void*)GPIO1_OR,
 366                         in_be32((void*)GPIO1_OR) & ~CONFIG_SYS_GPIO1_LEDPOST);
 367
 368                for (i = 0; i < 500; i++)
 369                        udelay(1000);
 370        }
 371
 372        return 0;
 373}
 374
 375/*
 376 * read field strength from I2C ADC
 377 */
 378int dcf77_status(void)
 379{
 380        unsigned int oldbus;
 381        uchar u[2];
 382        int mv;
 383
 384        oldbus = I2C_GET_BUS();
 385        I2C_SET_BUS(1);
 386
 387        if (i2c_read (IIC1_MCP3021_ADDR, 0, 0, u, 2)) {
 388                I2C_SET_BUS(oldbus);
 389                return -1;
 390        }
 391
 392        mv = (int)(((u[0] << 8) | u[1]) >> 2) * 3300 / 1024;
 393
 394        I2C_SET_BUS(oldbus);
 395        return mv;
 396}
 397
 398int do_dcf77(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 399{
 400        int mv;
 401        u32 pin, pinold;
 402        unsigned long long t1, t2;
 403        bd_t *bd = gd->bd;
 404
 405        printf("DCF77: ");
 406        mv = dcf77_status();
 407        if (mv > 0)
 408                printf("signal=%d mV\n", mv);
 409        else
 410                printf("ERROR - no signal\n");
 411
 412        t1 = t2 = 0;
 413        pinold = in_be32((void*)GPIO1_IR) & CONFIG_SYS_GPIO1_DCF77;
 414        while (!ctrlc()) {
 415                pin = in_be32((void*)GPIO1_IR) & CONFIG_SYS_GPIO1_DCF77;
 416                if (pin && !pinold) { /* bit start */
 417                        t1 = get_ticks();
 418                        if (t2 && ((unsigned int)(t1 - t2) /
 419                                   (bd->bi_procfreq / 1000) >= 1800))
 420                                printf("Start of minute\n");
 421
 422                        t2 = t1;
 423                }
 424                if (t1 && !pin && pinold) { /* bit end */
 425                        printf("%5d\n", (unsigned int)(get_ticks() - t1) /
 426                               (bd->bi_procfreq / 1000));
 427                }
 428                pinold = pin;
 429        }
 430
 431        printf("Abort\n");
 432        return 0;
 433}
 434U_BOOT_CMD(
 435        dcf77, 1, 1, do_dcf77,
 436        "Check DCF77 receiver",
 437        ""
 438);
 439
 440/*
 441 * initialize USB hub via I2C1
 442 */
 443int usbhub_init(void)
 444{
 445        int reg;
 446        int ret = 0;
 447        unsigned int oldbus;
 448        uchar u[] = {0x04, 0x24, 0x04, 0x07, 0x25, 0x00, 0x00, 0xd3,
 449                     0x18, 0xe0, 0x00, 0x00, 0x01, 0x64, 0x01, 0x64,
 450                     0x32};
 451        uchar stcd;
 452
 453        printf("Hub:   ");
 454
 455        oldbus = I2C_GET_BUS();
 456        I2C_SET_BUS(1);
 457
 458        for (reg = 0; reg < sizeof(u); reg++)
 459                if (i2c_write (IIC1_USB2507_ADDR, reg, 1, &u[reg], 1)) {
 460                        ret = -1;
 461                        break;
 462                }
 463
 464        if (ret == 0) {
 465                stcd = 0x03;
 466                if (i2c_write (IIC1_USB2507_ADDR, 0, 1, &stcd, 1))
 467                        ret = -1;
 468        }
 469
 470        if (ret == 0)
 471                printf("initialized\n");
 472        else
 473                printf("failed - cannot initialize USB hub\n");
 474
 475        I2C_SET_BUS(oldbus);
 476        return ret;
 477}
 478
 479int do_hubinit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 480{
 481        usbhub_init();
 482        return 0;
 483}
 484U_BOOT_CMD(
 485        hubinit, 1, 1, do_hubinit,
 486        "Initialize USB hub",
 487        ""
 488);
 489
 490#define CONFIG_SYS_BOOT_EEPROM_PAGE_WRITE_BITS 3
 491int boot_eeprom_write (unsigned dev_addr,
 492                       unsigned offset,
 493                       uchar *buffer,
 494                       unsigned cnt)
 495{
 496        unsigned end = offset + cnt;
 497        unsigned blk_off;
 498        int rcode = 0;
 499
 500#if defined(CONFIG_SYS_EEPROM_WREN)
 501        eeprom_write_enable(dev_addr, 1);
 502#endif
 503        /*
 504         * Write data until done or would cross a write page boundary.
 505         * We must write the address again when changing pages
 506         * because the address counter only increments within a page.
 507         */
 508
 509        while (offset < end) {
 510                unsigned alen, len;
 511                unsigned maxlen;
 512
 513                uchar addr[2];
 514
 515                blk_off = offset & 0xFF;        /* block offset */
 516
 517                addr[0] = offset >> 8;          /* block number */
 518                addr[1] = blk_off;              /* block offset */
 519                alen = 2;
 520                addr[0] |= dev_addr;            /* insert device address */
 521
 522                len = end - offset;
 523
 524                /*
 525                 * For a FRAM device there is no limit on the number of the
 526                 * bytes that can be ccessed with the single read or write
 527                 * operation.
 528                 */
 529#if defined(CONFIG_SYS_BOOT_EEPROM_PAGE_WRITE_BITS)
 530
 531#define BOOT_EEPROM_PAGE_SIZE (1 << CONFIG_SYS_BOOT_EEPROM_PAGE_WRITE_BITS)
 532#define BOOT_EEPROM_PAGE_OFFSET(x) ((x) & (BOOT_EEPROM_PAGE_SIZE - 1))
 533
 534                maxlen = BOOT_EEPROM_PAGE_SIZE -
 535                        BOOT_EEPROM_PAGE_OFFSET(blk_off);
 536#else
 537                maxlen = 0x100 - blk_off;
 538#endif
 539                if (maxlen > I2C_RXTX_LEN)
 540                        maxlen = I2C_RXTX_LEN;
 541
 542                if (len > maxlen)
 543                        len = maxlen;
 544
 545                if (i2c_write (addr[0], offset, alen - 1, buffer, len) != 0)
 546                        rcode = 1;
 547
 548                buffer += len;
 549                offset += len;
 550
 551#if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS)
 552                udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
 553#endif
 554        }
 555#if defined(CONFIG_SYS_EEPROM_WREN)
 556        eeprom_write_enable(dev_addr, 0);
 557#endif
 558        return rcode;
 559}
 560
 561int do_setup_boot_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 562{
 563        ulong sdsdp[4];
 564
 565        if (argc > 1) {
 566                if (!strcmp(argv[1], "533")) {
 567                        printf("Bootstrapping for 533MHz\n");
 568                        sdsdp[0] = 0x87788252;
 569                        /* PLB-PCI-divider = 3 : sync PCI clock=44MHz */
 570                        sdsdp[1] = 0x095fa030;
 571                        sdsdp[2] = 0x40082350;
 572                        sdsdp[3] = 0x0d050000;
 573                } else if (!strcmp(argv[1], "533-66")) {
 574                        printf("Bootstrapping for 533MHz (66MHz PCI)\n");
 575                        sdsdp[0] = 0x87788252;
 576                        /* PLB-PCI-divider = 2 : sync PCI clock=66MHz */
 577                        sdsdp[1] = 0x0957a030;
 578                        sdsdp[2] = 0x40082350;
 579                        sdsdp[3] = 0x0d050000;
 580                } else if (!strcmp(argv[1], "667")) {
 581                        printf("Bootstrapping for 667MHz\n");
 582                        sdsdp[0] = 0x8778a256;
 583                        /* PLB-PCI-divider = 4 : sync PCI clock=33MHz */
 584                        sdsdp[1] = 0x0947a030;
 585                        /* PLB-PCI-divider = 3 : sync PCI clock=44MHz
 586                         * -> not working when overclocking 533MHz chips
 587                         * -> untested on 667MHz chips */
 588                        /* sdsdp[1]=0x095fa030; */
 589                        sdsdp[2] = 0x40082350;
 590                        sdsdp[3] = 0x0d050000;
 591                } else if (!strcmp(argv[1], "667-166")) {
 592                        printf("Bootstrapping for 667-166MHz\n");
 593                        sdsdp[0] = 0x8778a252;
 594                        sdsdp[1] = 0x09d7a030;
 595                        sdsdp[2] = 0x40082350;
 596                        sdsdp[3] = 0x0d050000;
 597                }
 598        } else {
 599                printf("Bootstrapping for 533MHz (default)\n");
 600                sdsdp[0] = 0x87788252;
 601                /* PLB-PCI-divider = 3 : sync PCI clock=44MHz */
 602                sdsdp[1] = 0x095fa030;
 603                sdsdp[2] = 0x40082350;
 604                sdsdp[3] = 0x0d050000;
 605        }
 606
 607        printf("Writing boot EEPROM ...\n");
 608        if (boot_eeprom_write(CONFIG_SYS_I2C_BOOT_EEPROM_ADDR,
 609                              0, (uchar*)sdsdp, 16) != 0)
 610                printf("boot_eeprom_write failed\n");
 611        else
 612                printf("done (dump via 'i2c md 52 0.1 10')\n");
 613
 614        return 0;
 615}
 616U_BOOT_CMD(
 617        sbe, 2, 0, do_setup_boot_eeprom,
 618        "setup boot eeprom",
 619        ""
 620);
 621
 622#if defined(CONFIG_SYS_EEPROM_WREN)
 623/*
 624 * Input: <dev_addr>  I2C address of EEPROM device to enable.
 625 *         <state>     -1: deliver current state
 626 *                      0: disable write
 627 *                      1: enable write
 628 * Returns:            -1: wrong device address
 629 *                      0: dis-/en- able done
 630 *                    0/1: current state if <state> was -1.
 631 */
 632int eeprom_write_enable (unsigned dev_addr, int state)
 633{
 634        if ((CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) &&
 635            (CONFIG_SYS_I2C_BOOT_EEPROM_ADDR != dev_addr))
 636                return -1;
 637        else {
 638                switch (state) {
 639                case 1:
 640                        /* Enable write access, clear bit GPIO_SINT2. */
 641                        out_be32((void*)GPIO0_OR,
 642                                 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_GPIO0_EP_EEP);
 643                        state = 0;
 644                        break;
 645                case 0:
 646                        /* Disable write access, set bit GPIO_SINT2. */
 647                        out_be32((void*)GPIO0_OR,
 648                                 in_be32((void*)GPIO0_OR) | CONFIG_SYS_GPIO0_EP_EEP);
 649                        state = 0;
 650                        break;
 651                default:
 652                        /* Read current status back. */
 653                        state = (0 == (in_be32((void*)GPIO0_OR) &
 654                                       CONFIG_SYS_GPIO0_EP_EEP));
 655                        break;
 656                }
 657        }
 658        return state;
 659}
 660
 661int do_eep_wren (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 662{
 663        int query = argc == 1;
 664        int state = 0;
 665
 666        if (query) {
 667                /* Query write access state. */
 668                state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR, -1);
 669                if (state < 0)
 670                        puts ("Query of write access state failed.\n");
 671                else {
 672                        printf ("Write access for device 0x%0x is %sabled.\n",
 673                                CONFIG_SYS_I2C_EEPROM_ADDR, state ? "en" : "dis");
 674                        state = 0;
 675                }
 676        } else {
 677                if ('0' == argv[1][0]) {
 678                        /* Disable write access. */
 679                        state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR, 0);
 680                } else {
 681                        /* Enable write access. */
 682                        state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR, 1);
 683                }
 684                if (state < 0)
 685                        puts ("Setup of write access state failed.\n");
 686        }
 687
 688        return state;
 689}
 690
 691U_BOOT_CMD(eepwren, 2, 0, do_eep_wren,
 692        "Enable / disable / query EEPROM write access",
 693        ""
 694);
 695#endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */
 696
 697static int got_pldirq;
 698
 699static int pld_interrupt(u32 arg)
 700{
 701        int rc = -1; /* not for us */
 702        u8 status = in_8((void *)CONFIG_SYS_CPLD_BASE);
 703
 704        /* check for PLD interrupt */
 705        if (status & PWR_INT_FLAG) {
 706                /* reset this int */
 707                out_8((void *)CONFIG_SYS_CPLD_BASE, 0);
 708                rc = 0;
 709                got_pldirq = 1; /* trigger backend */
 710        }
 711
 712        return rc;
 713}
 714
 715int do_waitpwrirq(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 716{
 717        got_pldirq = 0;
 718
 719        /* clear any pending interrupt */
 720        out_8((void *)CONFIG_SYS_CPLD_BASE, 0);
 721
 722        irq_install_handler(CPLD_IRQ,
 723                            (interrupt_handler_t *)pld_interrupt, 0);
 724
 725        printf("Waiting ...\n");
 726        while(!got_pldirq) {
 727                /* Abort if ctrl-c was pressed */
 728                if (ctrlc()) {
 729                        puts("\nAbort\n");
 730                        break;
 731                }
 732        }
 733        if (got_pldirq) {
 734                printf("Got interrupt!\n");
 735                printf("Power %sready!\n",
 736                       in_8((void *)CONFIG_SYS_CPLD_BASE) &
 737                       PWR_RDY ? "":"NOT ");
 738        }
 739
 740        irq_free_handler(CPLD_IRQ);
 741        return 0;
 742}
 743U_BOOT_CMD(
 744        wpi,    1,      1,      do_waitpwrirq,
 745        "Wait for power change interrupt",
 746        ""
 747);
 748
 749/*
 750 * initialize DVI panellink transmitter
 751 */
 752int dvi_init(void)
 753{
 754        int i;
 755        int ret = 0;
 756        unsigned int oldbus;
 757        uchar u[] = {0x08, 0x34,
 758                     0x09, 0x20,
 759                     0x0a, 0x90,
 760                     0x0c, 0x89,
 761                     0x08, 0x35};
 762
 763        printf("DVI:   ");
 764
 765        oldbus = I2C_GET_BUS();
 766        I2C_SET_BUS(0);
 767
 768        for (i = 0; i < sizeof(u); i += 2)
 769                if (i2c_write (0x38, u[i], 1, &u[i + 1], 1)) {
 770                        ret = -1;
 771                        break;
 772                }
 773
 774        if (ret == 0)
 775                printf("initialized\n");
 776        else
 777                printf("failed - cannot initialize DVI transmitter\n");
 778
 779        I2C_SET_BUS(oldbus);
 780        return ret;
 781}
 782
 783int do_dviinit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 784{
 785        dvi_init();
 786        return 0;
 787}
 788U_BOOT_CMD(
 789        dviinit, 1, 1, do_dviinit,
 790        "Initialize DVI Panellink transmitter",
 791        ""
 792);
 793
 794/*
 795 * TODO: 'time' command might be useful for others as well.
 796 *       Move to 'common' directory.
 797 */
 798int do_time(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 799{
 800        unsigned long long start, end;
 801        char c, cmd[CONFIG_SYS_CBSIZE];
 802        char *p, *d = cmd;
 803        int ret, i;
 804        ulong us;
 805
 806        for (i = 1; i < argc; i++) {
 807                p = argv[i];
 808
 809                if (i > 1)
 810                        *d++ = ' ';
 811
 812                while ((c = *p++) != '\0') {
 813                        *d++ = c;
 814                }
 815        }
 816        *d = '\0';
 817
 818        start = get_ticks();
 819        ret = run_command(cmd, 0);
 820        end = get_ticks();
 821
 822        printf("ticks=%ld\n", (ulong)(end - start));
 823        us = (ulong)((1000L * (end - start)) / (get_tbclk() / 1000));
 824        printf("usec=%ld\n", us);
 825
 826        return ret;
 827}
 828U_BOOT_CMD(
 829        time,   CONFIG_SYS_MAXARGS,     1,      do_time,
 830        "run command and output execution time",
 831        ""
 832);
 833
 834extern void video_hw_rectfill (
 835        unsigned int bpp,               /* bytes per pixel */
 836        unsigned int dst_x,             /* dest pos x */
 837        unsigned int dst_y,             /* dest pos y */
 838        unsigned int dim_x,             /* frame width */
 839        unsigned int dim_y,             /* frame height */
 840        unsigned int color              /* fill color */
 841        );
 842
 843/*
 844 * graphics demo
 845 * draw rectangles using pseudorandom number generator
 846 * (see http://www.embedded.com/columns/technicalinsights/20900500)
 847 */
 848unsigned int rprime = 9972;
 849static unsigned int r;
 850static unsigned int Y;
 851
 852unsigned int prng(unsigned int max)
 853{
 854        if (r == 0 || r == 1 || r == -1)
 855                r = rprime; /* keep from getting stuck */
 856
 857        r = (9973 * ~r) + ((Y) % 701); /* the actual algorithm */
 858        Y = (r >> 16) % max; /* choose upper bits and reduce */
 859        return Y;
 860}
 861
 862int do_gfxdemo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 863{
 864        unsigned int color;
 865        unsigned int x, y, dx, dy;
 866
 867        while (!ctrlc()) {
 868                x = prng(1280 - 1);
 869                y = prng(1024 - 1);
 870                dx = prng(1280- x - 1);
 871                dy = prng(1024 - y - 1);
 872                color = prng(0x10000);
 873                video_hw_rectfill(2, x, y, dx, dy, color);
 874        }
 875
 876        return 0;
 877}
 878U_BOOT_CMD(
 879        gfxdemo,        CONFIG_SYS_MAXARGS,     1,      do_gfxdemo,
 880        "demo",
 881        ""
 882);
 883