uboot/board/mpl/pati/pati.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003
   3 * Martin Winistoerfer, martinwinistoerfer@gmx.ch.
   4 * Atapted for PATI
   5 * Denis Peter, d.peter@mpl.ch
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9/***********************************************************************************
  10 * Bits for the SDRAM controller
  11 * -----------------------------
  12 *
  13 * CAL: CAS Latency. If cleared to 0 (default) the SDRAM controller asserts TA# on
  14 *      the 2nd Clock after ACTIVE command (CAS Latency = 2). If set to 1 the SDRAM
  15 *      controller asserts TA# on the 3rd Clock after ACTIVE command (CAS Latency = 3).
  16 * RCD: RCD ACTIVE to READ or WRITE Delay (Ras to Cas Delay). If cleared 0 (default)
  17 *      tRCD of the SDRAM must equal or less 25ns. If set to 1 tRCD must be equal or less 50ns.
  18 * WREC:Write Recovery. If cleared 0 (default) tWR of the SDRAM must equal or less 25ns.
  19 *      If set to 1 tWR must be equal or less 50ns.
  20 * RP:  Precharge Command Time. If cleared 0 (default) tRP of the SDRAM must equal or less
  21 *      25ns. If set to 1 tRP must be equal or less 50ns.
  22 * RC:  Auto Refresh to Active Time. If cleared 0 (default) tRC of the SDRAM must equal
  23 *      or less 75ns. If set to 1 tRC must be equal or less 100ns.
  24 * LMR: Bit to set the Mode Register of the SDRAM. If set, the next access to the SDRAM
  25 *      is the Load Mode Register Command.
  26 * IIP: Init in progress. Set to 1 for starting the init sequence
  27 *      (Precharge All). As long this bit is set, the Precharge All is still in progress.
  28 *      After command has completed, wait at least for 8 refresh (200usec) before proceed.
  29 **********************************************************************************/
  30
  31#include <common.h>
  32#include <console.h>
  33#include <mpc5xx.h>
  34#include <stdio_dev.h>
  35#include <pci_ids.h>
  36#define PLX9056_LOC
  37#include "plx9056.h"
  38#include "pati.h"
  39
  40#if defined(__APPLE__)
  41/* Leading underscore on symbols */
  42#  define SYM_CHAR "_"
  43#else /* No leading character on symbols */
  44#  define SYM_CHAR
  45#endif
  46
  47#undef SDRAM_DEBUG
  48/*
  49 * Macros to generate global absolutes.
  50 */
  51#define GEN_SYMNAME(str) SYM_CHAR #str
  52#define GEN_VALUE(str) #str
  53#define GEN_ABS(name, value) \
  54                asm (".globl " GEN_SYMNAME(name)); \
  55                asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))
  56
  57
  58/************************************************************************
  59 * Early debug routines
  60 */
  61void write_hex (unsigned char i)
  62{
  63        char cc;
  64
  65        cc = i >> 4;
  66        cc &= 0xf;
  67        if (cc > 9)
  68                serial_putc (cc + 55);
  69        else
  70                serial_putc (cc + 48);
  71        cc = i & 0xf;
  72        if (cc > 9)
  73                serial_putc (cc + 55);
  74        else
  75                serial_putc (cc + 48);
  76}
  77
  78#if defined(SDRAM_DEBUG)
  79
  80void write_4hex (unsigned long val)
  81{
  82        write_hex ((unsigned char) (val >> 24));
  83        write_hex ((unsigned char) (val >> 16));
  84        write_hex ((unsigned char) (val >> 8));
  85        write_hex ((unsigned char) val);
  86}
  87
  88#endif
  89
  90unsigned long in32(unsigned long addr)
  91{
  92        unsigned long *p=(unsigned long *)addr;
  93        return *p;
  94}
  95
  96void out32(unsigned long addr,unsigned long data)
  97{
  98        unsigned long *p=(unsigned long *)addr;
  99        *p=data;
 100}
 101
 102typedef struct {
 103        unsigned short boardtype; /* Board revision and Population Options */
 104        unsigned char cal;              /* cas Latency  0:CAL=2 1:CAL=3 */
 105        unsigned char rcd;              /* ras to cas delay  0:<25ns 1:<50ns*/
 106        unsigned char wrec;             /* write recovery 0:<25ns 1:<50ns */
 107        unsigned char pr;               /* Precharge Command Time 0:<25ns 1:<50ns */
 108        unsigned char rc;               /* Auto Refresh to Active Time 0:<75ns 1:<100ns */
 109        unsigned char sz;               /* log binary => Size = (4MByte<<sz) 5 = 128, 4 = 64, 3 = 32, 2 = 16, 1=8 */
 110} sdram_t;
 111
 112const sdram_t sdram_table[] = {
 113        { 0x0000,       /* PATI Rev A, 16MByte -1 Board */
 114                1,      /* Case Latenty = 3 */
 115                0,      /* ras to cas delay  0 (20ns) */
 116                0,      /* write recovery 0:<25ns 1:<50ns*/
 117                0,      /* Precharge Command Time 0 (20ns) */
 118                0,      /* Auto Refresh to Active Time 0 (68) */
 119                2       /* log binary => Size 2 = 16MByte, 1=8 */
 120        },
 121        { 0xffff, /* terminator */
 122          0xff,
 123          0xff,
 124          0xff,
 125          0xff,
 126          0xff,
 127          0xff }
 128};
 129
 130
 131extern int mem_test (unsigned long start, unsigned long ramsize, int quiet);
 132
 133/*
 134 * Get RAM size.
 135 */
 136phys_size_t initdram(int board_type)
 137{
 138        unsigned char board_rev;
 139        unsigned long reg;
 140        unsigned long lmr;
 141        int i,timeout;
 142
 143#if defined(SDRAM_DEBUG)
 144        reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
 145        puts("\n\nSYSTEM part 0x"); write_4hex(SYSCNTR_PART(reg));
 146        puts(" Vers 0x"); write_4hex(SYSCNTR_ID(reg));
 147        puts("\nSDRAM  part  0x"); write_4hex(SDRAM_PART(reg));
 148        puts(" Vers 0x"); write_4hex(SDRAM_ID(reg));
 149        reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
 150        puts("\nBoard rev.   0x"); write_4hex(SYSCNTR_BREV(reg));
 151   putc('\n');
 152#endif
 153        reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
 154        board_rev=(unsigned char)(SYSCNTR_BREV(reg));
 155        i=0;
 156        while(1) {
 157                if(sdram_table[i].boardtype==0xffff) {
 158                        puts("ERROR, found no table for Board 0x");
 159                        write_hex(board_rev);
 160                        while(1);
 161                }
 162                if(sdram_table[i].boardtype==(unsigned char)board_rev)
 163                        break;
 164                i++;
 165        }
 166        /* Set CAL, RCD, WREQ, PR and RC Bits */
 167#if defined(SDRAM_DEBUG)
 168        puts("Set CAL, RCD, WREQ, PR and RC Bits\n");
 169#endif
 170        /* mask bits */
 171        reg &= ~(SET_REG_BIT(1,SDRAM_CAL) | SET_REG_BIT(1,SDRAM_RCD) | SET_REG_BIT(1,SDRAM_WREQ) |
 172                                SET_REG_BIT(1,SDRAM_PR)  |  SET_REG_BIT(1,SDRAM_RC) | SET_REG_BIT(1,SDRAM_LMR)  |
 173                                SET_REG_BIT(1,SDRAM_IIP) | SET_REG_BIT(1,SDRAM_RES0));
 174        /* set bits */
 175        reg |= (SET_REG_BIT(sdram_table[i].cal,SDRAM_CAL) |
 176                          SET_REG_BIT(sdram_table[i].rcd,SDRAM_RCD) |
 177                          SET_REG_BIT(sdram_table[i].wrec,SDRAM_WREQ) |
 178                          SET_REG_BIT(sdram_table[i].pr,SDRAM_PR) |
 179                          SET_REG_BIT(sdram_table[i].rc,SDRAM_RC));
 180
 181        out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
 182        /* step 2 set IIP */
 183#if defined(SDRAM_DEBUG)
 184        puts("step 2 set IIP\n");
 185#endif
 186        /* step 2 set IIP */
 187        reg |= SET_REG_BIT(1,SDRAM_IIP);
 188        timeout=0;
 189        while (timeout!=0xffff) {
 190                __asm__ volatile("eieio");
 191                reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
 192                if((reg & SET_REG_BIT(1,SDRAM_IIP))==0)
 193                        break;
 194                timeout++;
 195                udelay(1);
 196        }
 197        /* wait for at least 8 refresh */
 198        udelay(1000);
 199        /* set LMR */
 200        reg |= SET_REG_BIT(1,SDRAM_LMR);
 201        out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
 202        __asm__ volatile("eieio");
 203        lmr=0x00000002; /* sequential burst 4 data */
 204        if(sdram_table[i].cal==1)
 205                lmr|=0x00000030; /* cal = 3 */
 206        else
 207                lmr|=0000000020; /* cal = 2 */
 208        /* rest standard operation programmed write burst length */
 209        /* we have a x32 bit bus to the SDRAM, so shift the addr with 2 */
 210        lmr<<=2;
 211        in32(CONFIG_SYS_SDRAM_BASE + lmr);
 212        /* ok, we're done, return SDRAM size */
 213        return ((0x400000 << sdram_table[i].sz));               /* log2 value of 4MByte  */
 214}
 215
 216
 217void set_flash_vpp(int ext_vpp, int ext_wp, int int_vpp)
 218{
 219        unsigned long reg;
 220        reg=in32(PLD_CONF_REG2+PLD_CONFIG_BASE);
 221        reg &= ~(SET_REG_BIT(1,SYSCNTR_CPU_VPP) |
 222                           SET_REG_BIT(1,SYSCNTR_FL_VPP) |
 223                                SET_REG_BIT(1,SYSCNTR_FL_WP));
 224
 225        reg |= (SET_REG_BIT(int_vpp,SYSCNTR_CPU_VPP) |
 226                           SET_REG_BIT(ext_vpp,SYSCNTR_FL_VPP) |
 227                                SET_REG_BIT(ext_wp,SYSCNTR_FL_WP));
 228        out32(PLD_CONF_REG2+PLD_CONFIG_BASE,reg);
 229        udelay(100);
 230}
 231
 232
 233void show_pld_regs(void)
 234{
 235        unsigned long reg,reg1;
 236        reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
 237        printf("\nSYSTEM part %ld, Vers %ld\n",SYSCNTR_PART(reg),SYSCNTR_ID(reg));
 238        printf("SDRAM  part %ld, Vers %ld\n",SDRAM_PART(reg),SDRAM_ID(reg));
 239        reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
 240        printf("Board rev.  %c\n",(char) (SYSCNTR_BREV(reg)+'A'));
 241        printf("Waitstates  %ld\n",GET_SYSCNTR_FLWAIT(reg));
 242        printf("SDRAM:      CAL=%ld RCD=%ld WREQ=%ld PR=%ld\n            RC=%ld  LMR=%ld IIP=%ld\n",
 243                GET_REG_BIT(reg,SDRAM_CAL),GET_REG_BIT(reg,SDRAM_RCD),
 244                GET_REG_BIT(reg,SDRAM_WREQ),GET_REG_BIT(reg,SDRAM_PR),
 245                GET_REG_BIT(reg,SDRAM_RC),GET_REG_BIT(reg,SDRAM_LMR),
 246                GET_REG_BIT(reg,SDRAM_IIP));
 247        reg=in32(PLD_CONFIG_BASE+PLD_CONF_REG1);
 248        reg1=in32(PLD_CONFIG_BASE+PLD_CONF_REG2);
 249        printf("HW Config:  FLAG=%ld IP=%ld  index=%ld PRPM=%ld\n            ICW=%ld  ISB=%ld BDIS=%ld  PCIM=%ld\n",
 250                GET_REG_BIT(reg,SYSCNTR_FLAG),GET_REG_BIT(reg,SYSCNTR_IP),
 251                GET_SYSCNTR_BOOTIND(reg),GET_REG_BIT(reg,SYSCNTR_PRM),
 252                GET_REG_BIT(reg,SYSCNTR_ICW),GET_SYSCNTR_ISB(reg),
 253                GET_REG_BIT(reg1,SYSCNTR_BDIS),GET_REG_BIT(reg1,SYSCNTR_PCIM));
 254        printf("Switches:   MUX=%ld PCI_DIS=%ld Boot_EN=%ld  Config=%ld\n",GET_SDRAM_MUX(reg),
 255                GET_REG_BIT(reg,SDRAM_PDIS),GET_REG_BIT(reg1,SYSCNTR_BOOTEN),
 256                GET_SYSCNTR_CFG(reg1));
 257        printf("Misc:       RIP=%ld CPU_VPP=%ld FLSH_VPP=%ld FLSH_WP=%ld\n\n",
 258                GET_REG_BIT(reg,SDRAM_RIP),GET_REG_BIT(reg1,SYSCNTR_CPU_VPP),
 259                GET_REG_BIT(reg1,SYSCNTR_FL_VPP),GET_REG_BIT(reg1,SYSCNTR_FL_WP));
 260}
 261
 262
 263/****************************************************************
 264 * Setting IOs
 265 * -----------
 266 * GPIO6 is User LED1
 267 * GPIO7 is Interrupt PLX (Output)
 268 * GPIO5 is User LED0
 269 * GPIO2 is PLX USERi (Output)
 270 * GPIO1 is PLX Interrupt (Input)
 271 ****************************************************************/
 272 void init_ios(void)
 273 {
 274        volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
 275        volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
 276        unsigned long reg;
 277        reg=sysconf->sc_sgpiocr; /* Data direction register */
 278        reg &= ~0x67000000;
 279        reg |= 0x27000000; /* set outpupts */
 280        sysconf->sc_sgpiocr=reg; /* Data direction register */
 281        reg=sysconf->sc_sgpiodt2; /* Data register */
 282        /* set output to 0 */
 283        reg &= ~0x27000000;
 284        /* set IRQ and USERi to 1 */
 285        reg |= 0x28000000;
 286        sysconf->sc_sgpiodt2=reg; /* Data register */
 287}
 288
 289void user_led0(int led_on)
 290{
 291        volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
 292        volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
 293        unsigned long reg;
 294        reg=sysconf->sc_sgpiodt2; /* Data register */
 295        if(led_on)      /* set output to 1 */
 296                reg |= 0x04000000;
 297        else
 298                reg &= ~0x04000000;
 299        sysconf->sc_sgpiodt2=reg; /* Data register */
 300}
 301
 302void user_led1(int led_on)
 303{
 304        volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
 305        volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
 306        unsigned long reg;
 307        reg=sysconf->sc_sgpiodt2; /* Data register */
 308        if(led_on)      /* set output to 1 */
 309                reg |= 0x02000000;
 310        else
 311                reg &= ~0x02000000;
 312        sysconf->sc_sgpiodt2=reg; /* Data register */
 313}
 314
 315int board_early_init_f(void)
 316{
 317        spi_init_f();
 318        return 0;
 319}
 320
 321/****************************************************************
 322 * Last Stage Init
 323 ****************************************************************/
 324int last_stage_init (void)
 325{
 326        init_ios();
 327        return 0;
 328}
 329
 330/****************************************************************
 331 * Check the board
 332 ****************************************************************/
 333
 334#define BOARD_NAME      "PATI"
 335
 336int checkboard (void)
 337{
 338        char s[50];
 339        ulong reg;
 340        char rev;
 341        int i;
 342
 343        puts ("\nBoard: ");
 344        reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
 345        rev=(char)(SYSCNTR_BREV(reg)+'A');
 346        i = getenv_f("serial#", s, 32);
 347        if ((i == -1)) {
 348                puts ("### No HW ID - assuming " BOARD_NAME);
 349                printf(" Rev. %c\n",rev);
 350        }
 351        else {
 352                s[sizeof(BOARD_NAME)-1] = 0;
 353                printf ("%s-1 Rev %c SN: %s\n", s,rev,
 354                                &s[sizeof(BOARD_NAME)]);
 355        }
 356        set_flash_vpp(1,0,0); /* set Flash VPP */
 357        return 0;
 358}
 359
 360
 361#ifdef CONFIG_SYS_PCI_CON_DEVICE
 362/************************************************************************
 363 * PCI Communication
 364 *
 365 * Alive (Pinging):
 366 * ----------------
 367 * PCI Host sends message ALIVE, Local acknowledges with ALIVE
 368 *
 369 * PCI_CON console over PCI:
 370 * -------------------------
 371 * Local side:
 372 *     - uses PCI9056_LOC_TO_PCI_DBELL register to signal that
 373 *       data is avaible (PCIMSG_CONN)
 374 *     - uses PCI9056_MAILBOX1 to send data
 375 *     - uses PCI9056_MAILBOX0 to receive data
 376 * PCI side:
 377 *     - uses PCI9056_PCI_TO_LOC_DBELL register to signal that
 378 *       data is avaible (PCIMSG_CONN)
 379 *     - uses PCI9056_MAILBOX0 to send data
 380 *     - uses PCI9056_MAILBOX1 to receive data
 381 *
 382 * How it works:
 383 *     Send:
 384 *     - check if PCICON_TRANSMIT_REG is empty
 385 *     - write data or'ed with 0x80000000 into the PCICON_TRANSMIT_REG
 386 *     - write PCIMSG_CONN into the PCICON_DBELL_REG to signal a data
 387 *       is waiting
 388 *     Receive:
 389 *     - get an interrupt via the PCICON_ACK_REG register message
 390 *       PCIMSG_CONN
 391 *     - write the data from the PCICON_RECEIVE_REG into the receive
 392 *       buffer and if the receive buffer is not full, clear the
 393 *       PCICON_RECEIVE_REG (this allows the counterpart to write more data)
 394 *     - Clear the interrupt by writing 0xFFFFFFFF to the PCICON_ACK_REG
 395 *
 396 *     The PCICON_RECEIVE_REG must be cleared by the routine which reads
 397 *     the receive buffer if the buffer is not full any more
 398 *
 399 */
 400
 401#undef PCI_CON_DEBUG
 402
 403#ifdef  PCI_CON_DEBUG
 404#define PCI_CON_PRINTF(fmt,args...)     serial_printf (fmt ,##args)
 405#else
 406#define PCI_CON_PRINTF(fmt,args...)
 407#endif
 408
 409
 410/*********************************************************
 411 * we work only with a receive buffer on eiter side.
 412 * Transmit buffer is free, if mailbox is cleared.
 413 * Transmit character is or'ed with 0x80000000
 414 * PATI receive register MAILBOX0
 415 * PATI transmit register MAILBOX1
 416 *********************************************************/
 417#define PCICON_RECEIVE_REG      PCI9056_MAILBOX0
 418#define PCICON_TRANSMIT_REG     PCI9056_MAILBOX1
 419#define PCICON_DBELL_REG        PCI9056_LOC_TO_PCI_DBELL
 420#define PCICON_ACK_REG          PCI9056_PCI_TO_LOC_DBELL
 421
 422
 423#define PCIMSG_ALIVE            0x1
 424#define PCIMSG_CONN             0x2
 425#define PCIMSG_DISC             0x3
 426#define PCIMSG_CON_DATA 0x5
 427
 428
 429#define PCICON_GET_REG(x)       (in32(x + PCI_CONFIG_BASE))
 430#define PCICON_SET_REG(x,y)     (out32(x + PCI_CONFIG_BASE,y))
 431#define PCICON_TX_FLAG          0x80000000
 432
 433
 434#define REC_BUFFER_SIZE 0x100
 435int recbuf[REC_BUFFER_SIZE];
 436static int r_ptr = 0;
 437int w_ptr;
 438struct stdio_dev pci_con_dev;
 439int conn=0;
 440int buff_full=0;
 441
 442void pci_con_put_it(const char c)
 443{
 444        /* Test for completition */
 445        unsigned long reg;
 446        do {
 447                reg=PCICON_GET_REG(PCICON_TRANSMIT_REG);
 448        }while(reg);
 449        reg=PCICON_TX_FLAG + c;
 450        PCICON_SET_REG(PCICON_TRANSMIT_REG,reg);
 451        PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_CON_DATA);
 452}
 453
 454void pci_con_putc(struct stdio_dev *dev, const char c)
 455{
 456        pci_con_put_it(c);
 457        if(c == '\n')
 458                pci_con_put_it('\r');
 459}
 460
 461
 462int pci_con_getc(struct stdio_dev *dev)
 463{
 464        int res;
 465        int diff;
 466        while(r_ptr==(volatile int)w_ptr);
 467        res=recbuf[r_ptr++];
 468        if(r_ptr==REC_BUFFER_SIZE)
 469                r_ptr=0;
 470        if(w_ptr<r_ptr)
 471                diff=r_ptr+REC_BUFFER_SIZE-w_ptr;
 472        else
 473                diff=r_ptr-w_ptr;
 474        if((diff<(REC_BUFFER_SIZE-4)) && buff_full) {
 475                /* clear Mail box */
 476                        buff_full=0;
 477                        PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
 478        }
 479        return res;
 480}
 481
 482int pci_con_tstc(struct stdio_dev *dev)
 483{
 484        if(r_ptr==(volatile int)w_ptr)
 485                return 0;
 486        return 1;
 487}
 488
 489void pci_con_puts(struct stdio_dev *dev, const char *s)
 490{
 491        while (*s) {
 492                pci_con_putc(*s);
 493                ++s;
 494        }
 495}
 496
 497void pci_con_init (void)
 498{
 499        w_ptr = 0;
 500        r_ptr = 0;
 501        PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
 502        conn=1;
 503}
 504
 505/*******************************************
 506 * IRQ routine
 507 ******************************************/
 508int pci_dorbell_irq(void)
 509{
 510        unsigned long reg,data;
 511        int diff;
 512        reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT);
 513        PCI_CON_PRINTF(" PCI9056_INT_CTRL_STAT = %08lX\n",reg);
 514        if(reg & (1<<20) ) {
 515                /* read doorbell */
 516                reg=PCICON_GET_REG(PCICON_ACK_REG);
 517                switch(reg) {
 518                        case PCIMSG_ALIVE:
 519                                PCI_CON_PRINTF(" Alive\n");
 520                                PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_ALIVE);
 521                                break;
 522                        case PCIMSG_CONN:
 523                                PCI_CON_PRINTF(" Conn %d",conn);
 524                                w_ptr = 0;
 525                                r_ptr = 0;
 526                                buff_full=0;
 527                                PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
 528                                conn=1;
 529                                PCI_CON_PRINTF(" ... %d\n",conn);
 530                                break;
 531                        case PCIMSG_CON_DATA:
 532                                data=PCICON_GET_REG(PCICON_RECEIVE_REG);
 533                                recbuf[w_ptr++]=(int)(data&0xff);
 534                                PCI_CON_PRINTF(" Data Console %lX, %X %d %d %X\n",data,((int)(data&0xFF)),
 535                                        r_ptr,w_ptr,recbuf[w_ptr-1]);
 536                                if(w_ptr==REC_BUFFER_SIZE)
 537                                        w_ptr=0;
 538                                if(w_ptr<r_ptr)
 539                                        diff=r_ptr+REC_BUFFER_SIZE-w_ptr;
 540                                else
 541                                        diff=r_ptr-w_ptr;
 542                                if(diff>(REC_BUFFER_SIZE-4))
 543                                        buff_full=1;
 544                                else
 545                                        /* clear Mail box */
 546                                        PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
 547                                break;
 548                        default:
 549                                serial_printf(" PCI9056_PCI_TO_LOC_DBELL = %08lX\n",reg);
 550                }
 551                /* clear IRQ */
 552                PCICON_SET_REG(PCICON_ACK_REG,~0L);
 553        }
 554        return 0;
 555}
 556
 557void pci_con_connect(void)
 558{
 559        unsigned long reg;
 560        conn=0;
 561        reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT);
 562        /* default 0x0f010180 */
 563        reg &= 0xff000000;
 564        reg |= 0x00030000; /* enable local dorbell */
 565        reg |= 0x00000300; /* enable PCI dorbell */
 566        PCICON_SET_REG(PCI9056_INT_CTRL_STAT , reg);
 567        irq_install_handler (0x2, (interrupt_handler_t *) pci_dorbell_irq,NULL);
 568        memset (&pci_con_dev, 0, sizeof (pci_con_dev));
 569        strcpy (pci_con_dev.name, "pci_con");
 570        pci_con_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
 571        pci_con_dev.putc = pci_con_putc;
 572        pci_con_dev.puts = pci_con_puts;
 573        pci_con_dev.getc = pci_con_getc;
 574        pci_con_dev.tstc = pci_con_tstc;
 575        stdio_register (&pci_con_dev);
 576        printf("PATI ready for PCI connection, type ctrl-c for exit\n");
 577        do {
 578                udelay(10);
 579                if((volatile int)conn)
 580                        break;
 581                if(ctrlc()) {
 582                        irq_free_handler(0x2);
 583                        return;
 584                }
 585        }while(1);
 586        console_assign(stdin,"pci_con");
 587        console_assign(stderr,"pci_con");
 588        console_assign(stdout,"pci_con");
 589}
 590
 591void pci_con_disc(void)
 592{
 593        console_assign(stdin,"serial");
 594        console_assign(stderr,"serial");
 595        console_assign(stdout,"serial");
 596        PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_DISC);
 597        /* reconnection */
 598        irq_free_handler(0x02);
 599        pci_con_connect();
 600}
 601#endif /* #ifdef CONFIG_SYS_PCI_CON_DEVICE */
 602
 603/*
 604 * Absolute environment address for linker file.
 605 */
 606GEN_ABS(env_start, CONFIG_ENV_OFFSET + CONFIG_SYS_FLASH_BASE);
 607