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