]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/mpl/pati/pati.c
imported Freescale specific U-Boot additions for i.MX28,... release L2.6.31_10.08.01
[karo-tx-uboot.git] / 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  * 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  */
76 void 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
95 void 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
105 unsigned long in32(unsigned long addr)
106 {
107         unsigned long *p=(unsigned long *)addr;
108         return *p;
109 }
110
111 void out32(unsigned long addr,unsigned long data)
112 {
113         unsigned long *p=(unsigned long *)addr;
114         *p=data;
115 }
116
117 typedef 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
127 const 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
146 extern int mem_test (unsigned long start, unsigned long ramsize, int quiet);
147 extern void mem_test_reloc(void);
148
149 /*
150  * Get RAM size.
151  */
152 phys_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
233 void 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
249 void 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
305 void 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
318 void 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  ****************************************************************/
335 int 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
348 int 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
447 int recbuf[REC_BUFFER_SIZE];
448 static int r_ptr = 0;
449 int w_ptr;
450 struct stdio_dev pci_con_dev;
451 int conn=0;
452 int buff_full=0;
453
454 void 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
466 void 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
474 int 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
494 int pci_con_tstc(void)
495 {
496         if(r_ptr==(volatile int)w_ptr)
497                 return 0;
498         return 1;
499 }
500
501 void pci_con_puts (const char *s)
502 {
503         while (*s) {
504                 pci_con_putc(*s);
505                 ++s;
506         }
507 }
508
509 void 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  ******************************************/
520 int 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
569 void 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
603 void 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  */
618 GEN_ABS(env_start, CONFIG_ENV_OFFSET + CONFIG_SYS_FLASH_BASE);