uboot/board/esd/pci405/pci405.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001-2004
   3 * Stefan Roese, esd gmbh germany, stefan.roese@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 <asm/processor.h>
  26#include <command.h>
  27#include <malloc.h>
  28#include <pci.h>
  29#include <asm/4xx_pci.h>
  30#include <asm/io.h>
  31
  32#include "pci405.h"
  33
  34DECLARE_GLOBAL_DATA_PTR;
  35
  36/* Prototypes */
  37int gunzip(void *, int, unsigned char *, unsigned long *);
  38int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  39unsigned long fpga_done_state(void);
  40unsigned long fpga_init_state(void);
  41
  42#if 0
  43#define FPGA_DEBUG
  44#endif
  45
  46/* predefine these here */
  47#define FPGA_DONE_STATE (fpga_done_state())
  48#define FPGA_INIT_STATE (fpga_init_state())
  49
  50/* fpga configuration data - generated by bin2cc */
  51const unsigned char fpgadata[] =
  52{
  53#include "fpgadata.c"
  54};
  55
  56/*
  57 * include common fpga code (for esd boards)
  58 */
  59#include "../common/fpga.c"
  60
  61#define FPGA_DONE_STATE_V11 (in_be32((void*)GPIO0_IR) & CONFIG_SYS_FPGA_DONE)
  62#define FPGA_DONE_STATE_V12 (in_be32((void*)GPIO0_IR) & CONFIG_SYS_FPGA_DONE_V12)
  63
  64#define FPGA_INIT_STATE_V11 (in_be32((void*)GPIO0_IR) & CONFIG_SYS_FPGA_INIT)
  65#define FPGA_INIT_STATE_V12 (in_be32((void*)GPIO0_IR) & CONFIG_SYS_FPGA_INIT_V12)
  66
  67
  68int board_revision(void)
  69{
  70        unsigned long cntrl0Reg;
  71        unsigned long value;
  72
  73        /*
  74         * Get version of PCI405 board from GPIO's
  75         */
  76
  77        /*
  78         * Setup GPIO pins (CS2/GPIO11 and CS3/GPIO12 as GPIO)
  79         */
  80        cntrl0Reg = mfdcr(cntrl0);
  81        mtdcr(cntrl0, cntrl0Reg | 0x03000000);
  82        out_be32((void*)GPIO0_ODR, in_be32((void*)GPIO0_ODR) & ~0x00100200);
  83        out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) & ~0x00100200);
  84        udelay(1000);                   /* wait some time before reading input */
  85        value = in_be32((void*)GPIO0_IR) & 0x00100200;       /* get config bits */
  86
  87        /*
  88         * Restore GPIO settings
  89         */
  90        mtdcr(cntrl0, cntrl0Reg);
  91
  92        switch (value) {
  93        case 0x00100200:
  94                /* CS2==1 && IRQ5==1 -> version 1.0 and 1.1 */
  95                return 1;
  96        case 0x00000200:
  97                /* CS2==0 && IRQ5==1 -> version 1.2 */
  98                return 2;
  99        case 0x00000000:
 100                /* CS2==0 && IRQ5==0 -> version 1.3 */
 101                return 3;
 102#if 0 /* not yet manufactured ! */
 103        case 0x00100000:
 104                /* CS2==1 && IRQ5==0 -> version 1.4 */
 105                return 4;
 106#endif
 107        default:
 108                /* should not be reached! */
 109                return 0;
 110        }
 111}
 112
 113
 114unsigned long fpga_done_state(void)
 115{
 116        if (gd->board_type < 2) {
 117                return FPGA_DONE_STATE_V11;
 118        } else {
 119                return FPGA_DONE_STATE_V12;
 120        }
 121}
 122
 123
 124unsigned long fpga_init_state(void)
 125{
 126        if (gd->board_type < 2) {
 127                return FPGA_INIT_STATE_V11;
 128        } else {
 129                return FPGA_INIT_STATE_V12;
 130        }
 131}
 132
 133
 134int board_early_init_f (void)
 135{
 136        unsigned long cntrl0Reg;
 137
 138        /*
 139         * First pull fpga-prg pin low, to disable fpga logic (on version 1.2 board)
 140         */
 141        out_be32((void*)GPIO0_ODR, 0x00000000);        /* no open drain pins      */
 142        out_be32((void*)GPIO0_TCR, CONFIG_SYS_FPGA_PRG);      /* setup for output        */
 143        out_be32((void*)GPIO0_OR,  CONFIG_SYS_FPGA_PRG);      /* set output pins to high */
 144        out_be32((void*)GPIO0_OR, 0);                  /* pull prg low            */
 145
 146        /*
 147         * IRQ 0-15  405GP internally generated; active high; level sensitive
 148         * IRQ 16    405GP internally generated; active low; level sensitive
 149         * IRQ 17-24 RESERVED
 150         * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
 151         * IRQ 26 (EXT IRQ 1) CAN1; active low; level sensitive
 152         * IRQ 27 (EXT IRQ 2) CAN2; active low; level sensitive
 153         * IRQ 28 (EXT IRQ 3) CAN3; active low; level sensitive
 154         * IRQ 29 (EXT IRQ 4) unused; active low; level sensitive
 155         * IRQ 30 (EXT IRQ 5) FPGA Timestamp; active low; level sensitive
 156         * IRQ 31 (EXT IRQ 6) PCI Reset; active low; level sensitive
 157         */
 158        mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
 159        mtdcr(uicer, 0x00000000);        /* disable all ints */
 160        mtdcr(uiccr, 0x00000000);        /* set all to be non-critical*/
 161        mtdcr(uicpr, 0xFFFFFF80);        /* set int polarities */
 162        mtdcr(uictr, 0x10000000);        /* set int trigger levels */
 163        mtdcr(uicvcr, 0x00000001);       /* set vect base=0,INT0 highest priority*/
 164        mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
 165
 166        /*
 167         * Setup GPIO pins (IRQ4/GPIO21 as GPIO)
 168         */
 169        cntrl0Reg = mfdcr(cntrl0);
 170        mtdcr(cntrl0, cntrl0Reg | 0x00008000);
 171
 172        /*
 173         * Setup GPIO pins (CS6+CS7 as GPIO)
 174         */
 175        mtdcr(cntrl0, cntrl0Reg | 0x00300000);
 176
 177        /*
 178         * EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 25 us
 179         */
 180        mtebc (epcr, 0xa8400000); /* ebc always driven */
 181
 182        return 0;
 183}
 184
 185int misc_init_r (void)
 186{
 187        unsigned char *dst;
 188        ulong len = sizeof(fpgadata);
 189        int status;
 190        int index;
 191        int i;
 192        unsigned int *ptr;
 193        unsigned int *magic;
 194
 195        /*
 196         * On PCI-405 the environment is saved in eeprom!
 197         * FPGA can be gzip compressed (malloc) and booted this late.
 198         */
 199
 200        dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE);
 201        if (gunzip (dst, CONFIG_SYS_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) {
 202                printf ("GUNZIP ERROR - must RESET board to recover\n");
 203                do_reset (NULL, 0, 0, NULL);
 204        }
 205
 206        status = fpga_boot(dst, len);
 207        if (status != 0) {
 208                printf("\nFPGA: Booting failed ");
 209                switch (status) {
 210                case ERROR_FPGA_PRG_INIT_LOW:
 211                        printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
 212                        break;
 213                case ERROR_FPGA_PRG_INIT_HIGH:
 214                        printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
 215                        break;
 216                case ERROR_FPGA_PRG_DONE:
 217                        printf("(Timeout: DONE not high after programming FPGA)\n ");
 218                        break;
 219                }
 220
 221                /* display infos on fpgaimage */
 222                index = 15;
 223                for (i=0; i<4; i++) {
 224                        len = dst[index];
 225                        printf("FPGA: %s\n", &(dst[index+1]));
 226                        index += len+3;
 227                }
 228                putc ('\n');
 229                /* delayed reboot */
 230                for (i=20; i>0; i--) {
 231                        printf("Rebooting in %2d seconds \r",i);
 232                        for (index=0;index<1000;index++)
 233                                udelay(1000);
 234                }
 235                putc ('\n');
 236                do_reset(NULL, 0, 0, NULL);
 237        }
 238
 239        puts("FPGA:  ");
 240
 241        /* display infos on fpgaimage */
 242        index = 15;
 243        for (i=0; i<4; i++) {
 244                len = dst[index];
 245                printf("%s ", &(dst[index+1]));
 246                index += len+3;
 247        }
 248        putc ('\n');
 249
 250        /*
 251         * Reset FPGA via FPGA_DATA pin
 252         */
 253        SET_FPGA(FPGA_PRG | FPGA_CLK);
 254        udelay(1000); /* wait 1ms */
 255        SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
 256        udelay(1000); /* wait 1ms */
 257
 258        /*
 259         * Check if magic for pci reconfig is written
 260         */
 261        magic = (unsigned int *)0x00000004;
 262        if (*magic == PCI_RECONFIG_MAGIC) {
 263                /*
 264                 * Rewrite pci config regs (only after soft-reset with magic set)
 265                 */
 266                ptr = (unsigned int *)PCI_REGS_ADDR;
 267                if (crc32(0, (uchar *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4) == *ptr) {
 268                        puts("Restoring PCI Configurations Regs!\n");
 269                        ptr = (unsigned int *)PCI_REGS_ADDR + 1;
 270                        for (i=0; i<0x40; i+=4) {
 271                                pci_write_config_dword(PCIDEVID_405GP, i, *ptr++);
 272                        }
 273                }
 274                mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
 275
 276                *magic = 0;      /* clear pci reconfig magic again */
 277        }
 278
 279        /*
 280         * Decrease PLB latency timeout and reduce priority of the PCI bridge master
 281         */
 282#define PCI0_BRDGOPT1 0x4a
 283        pci_write_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, 0x3f20);
 284
 285#define plb0_acr      0x87
 286        /*
 287         * Enable fairness and high bus utilization
 288         */
 289        mtdcr(plb0_acr, 0x98000000);
 290
 291        free(dst);
 292        return (0);
 293}
 294
 295
 296/*
 297 * Check Board Identity:
 298 */
 299int checkboard (void)
 300{
 301        char str[64];
 302        int i = getenv_r ("serial#", str, sizeof(str));
 303
 304        puts ("Board: ");
 305
 306        if (i == -1) {
 307                puts ("### No HW ID - assuming PCI405");
 308        } else {
 309                puts (str);
 310        }
 311
 312        gd->board_type = board_revision();
 313        printf(" (Rev 1.%ld", gd->board_type);
 314
 315        if (gd->board_type >= 2) {
 316                unsigned long cntrl0Reg;
 317                unsigned long value;
 318
 319                /*
 320                 * Setup GPIO pins (Trace/GPIO1 to GPIO)
 321                 */
 322                cntrl0Reg = mfdcr(cntrl0);
 323                mtdcr(cntrl0, cntrl0Reg & ~0x08000000);
 324                out_be32((void*)GPIO0_ODR, in_be32((void*)GPIO0_ODR) & ~0x40000000);
 325                out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) & ~0x40000000);
 326                udelay(1000);                   /* wait some time before reading input */
 327                value = in_be32((void*)GPIO0_IR) & 0x40000000;       /* get config bits */
 328                if (value) {
 329                        puts(", 33 MHz PCI");
 330                } else {
 331                        puts(", 66 MHz PCI");
 332                }
 333        }
 334
 335        puts(")\n");
 336
 337        return 0;
 338}
 339
 340/* ------------------------------------------------------------------------- */
 341int wpeeprom(int wp)
 342{
 343        int wp_state = wp;
 344        volatile unsigned char *uart1_mcr = (volatile unsigned char *)0xef600404;
 345
 346        if (wp == 1) {
 347                *uart1_mcr &= ~0x02;
 348        } else if (wp == 0) {
 349                *uart1_mcr |= 0x02;
 350        } else {
 351                if (*uart1_mcr & 0x02) {
 352                        wp_state = 0;
 353                } else {
 354                        wp_state = 1;
 355                }
 356        }
 357        return wp_state;
 358}
 359
 360int do_wpeeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 361{
 362        int wp = -1;
 363        if (argc >= 2) {
 364                if (argv[1][0] == '1') {
 365                        wp = 1;
 366                } else if (argv[1][0] == '0') {
 367                        wp = 0;
 368                }
 369        }
 370
 371        wp = wpeeprom(wp);
 372        printf("EEPROM write protection %s\n", wp ? "ENABLED" : "DISABLED");
 373        return 0;
 374}
 375
 376U_BOOT_CMD(
 377        wpeeprom,       2,      1,      do_wpeeprom,
 378        "wpeeprom - Check/Enable/Disable I2C EEPROM write protection\n",
 379        "wpeeprom\n"
 380        "    - check I2C EEPROM write protection state\n"
 381        "wpeeprom 1\n"
 382        "    - enable I2C EEPROM write protection\n"
 383        "wpeeprom 0\n"
 384        "    - disable I2C EEPROM write protection\n"
 385        );
 386