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