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