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