blob: 7f1164a5c7acdced9b3c2b790eefea0d09ae8dab [file] [log] [blame]
wdenkb6e4c402004-01-02 16:05:07 +00001/*
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>
Jean-Christophe PLAGNIOL-VILLARD52cb4d42009-05-16 12:14:54 +020049#include <stdio_dev.h>
wdenkb6e4c402004-01-02 16:05:07 +000050#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);
wdenkb6e4c402004-01-02 16:05:07 +0000147
148/*
149 * Get RAM size.
150 */
Becky Bruce9973e3c2008-06-09 16:03:40 -0500151phys_size_t initdram(int board_type)
wdenkb6e4c402004-01-02 16:05:07 +0000152{
153 unsigned char board_rev;
154 unsigned long reg;
155 unsigned long lmr;
156 int i,timeout;
157
158#if defined(SDRAM_DEBUG)
159 reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
160 puts("\n\nSYSTEM part 0x"); write_4hex(SYSCNTR_PART(reg));
161 puts(" Vers 0x"); write_4hex(SYSCNTR_ID(reg));
162 puts("\nSDRAM part 0x"); write_4hex(SDRAM_PART(reg));
163 puts(" Vers 0x"); write_4hex(SDRAM_ID(reg));
164 reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
165 puts("\nBoard rev. 0x"); write_4hex(SYSCNTR_BREV(reg));
166 putc('\n');
167#endif
168 reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
169 board_rev=(unsigned char)(SYSCNTR_BREV(reg));
170 i=0;
171 while(1) {
172 if(sdram_table[i].boardtype==0xffff) {
173 puts("ERROR, found no table for Board 0x");
174 write_hex(board_rev);
175 while(1);
176 }
177 if(sdram_table[i].boardtype==(unsigned char)board_rev)
178 break;
179 i++;
180 }
181 /* Set CAL, RCD, WREQ, PR and RC Bits */
182#if defined(SDRAM_DEBUG)
183 puts("Set CAL, RCD, WREQ, PR and RC Bits\n");
184#endif
185 /* mask bits */
186 reg &= ~(SET_REG_BIT(1,SDRAM_CAL) | SET_REG_BIT(1,SDRAM_RCD) | SET_REG_BIT(1,SDRAM_WREQ) |
187 SET_REG_BIT(1,SDRAM_PR) | SET_REG_BIT(1,SDRAM_RC) | SET_REG_BIT(1,SDRAM_LMR) |
188 SET_REG_BIT(1,SDRAM_IIP) | SET_REG_BIT(1,SDRAM_RES0));
189 /* set bits */
190 reg |= (SET_REG_BIT(sdram_table[i].cal,SDRAM_CAL) |
191 SET_REG_BIT(sdram_table[i].rcd,SDRAM_RCD) |
192 SET_REG_BIT(sdram_table[i].wrec,SDRAM_WREQ) |
193 SET_REG_BIT(sdram_table[i].pr,SDRAM_PR) |
194 SET_REG_BIT(sdram_table[i].rc,SDRAM_RC));
195
196 out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
197 /* step 2 set IIP */
198#if defined(SDRAM_DEBUG)
199 puts("step 2 set IIP\n");
200#endif
201 /* step 2 set IIP */
202 reg |= SET_REG_BIT(1,SDRAM_IIP);
203 timeout=0;
204 while (timeout!=0xffff) {
205 __asm__ volatile("eieio");
206 reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
207 if((reg & SET_REG_BIT(1,SDRAM_IIP))==0)
208 break;
209 timeout++;
210 udelay(1);
211 }
212 /* wait for at least 8 refresh */
213 udelay(1000);
214 /* set LMR */
215 reg |= SET_REG_BIT(1,SDRAM_LMR);
216 out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
217 __asm__ volatile("eieio");
218 lmr=0x00000002; /* sequential burst 4 data */
219 if(sdram_table[i].cal==1)
220 lmr|=0x00000030; /* cal = 3 */
221 else
222 lmr|=0000000020; /* cal = 2 */
223 /* rest standard operation programmed write burst length */
224 /* we have a x32 bit bus to the SDRAM, so shift the addr with 2 */
225 lmr<<=2;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200226 in32(CONFIG_SYS_SDRAM_BASE + lmr);
wdenkb6e4c402004-01-02 16:05:07 +0000227 /* ok, we're done, return SDRAM size */
228 return ((0x400000 << sdram_table[i].sz)); /* log2 value of 4MByte */
229}
230
231
232void set_flash_vpp(int ext_vpp, int ext_wp, int int_vpp)
233{
234 unsigned long reg;
235 reg=in32(PLD_CONF_REG2+PLD_CONFIG_BASE);
236 reg &= ~(SET_REG_BIT(1,SYSCNTR_CPU_VPP) |
237 SET_REG_BIT(1,SYSCNTR_FL_VPP) |
238 SET_REG_BIT(1,SYSCNTR_FL_WP));
239
240 reg |= (SET_REG_BIT(int_vpp,SYSCNTR_CPU_VPP) |
241 SET_REG_BIT(ext_vpp,SYSCNTR_FL_VPP) |
242 SET_REG_BIT(ext_wp,SYSCNTR_FL_WP));
243 out32(PLD_CONF_REG2+PLD_CONFIG_BASE,reg);
244 udelay(100);
245}
246
247
248void show_pld_regs(void)
249{
250 unsigned long reg,reg1;
251 reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
252 printf("\nSYSTEM part %ld, Vers %ld\n",SYSCNTR_PART(reg),SYSCNTR_ID(reg));
253 printf("SDRAM part %ld, Vers %ld\n",SDRAM_PART(reg),SDRAM_ID(reg));
254 reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
255 printf("Board rev. %c\n",(char) (SYSCNTR_BREV(reg)+'A'));
256 printf("Waitstates %ld\n",GET_SYSCNTR_FLWAIT(reg));
257 printf("SDRAM: CAL=%ld RCD=%ld WREQ=%ld PR=%ld\n RC=%ld LMR=%ld IIP=%ld\n",
258 GET_REG_BIT(reg,SDRAM_CAL),GET_REG_BIT(reg,SDRAM_RCD),
259 GET_REG_BIT(reg,SDRAM_WREQ),GET_REG_BIT(reg,SDRAM_PR),
260 GET_REG_BIT(reg,SDRAM_RC),GET_REG_BIT(reg,SDRAM_LMR),
261 GET_REG_BIT(reg,SDRAM_IIP));
262 reg=in32(PLD_CONFIG_BASE+PLD_CONF_REG1);
263 reg1=in32(PLD_CONFIG_BASE+PLD_CONF_REG2);
264 printf("HW Config: FLAG=%ld IP=%ld index=%ld PRPM=%ld\n ICW=%ld ISB=%ld BDIS=%ld PCIM=%ld\n",
265 GET_REG_BIT(reg,SYSCNTR_FLAG),GET_REG_BIT(reg,SYSCNTR_IP),
266 GET_SYSCNTR_BOOTIND(reg),GET_REG_BIT(reg,SYSCNTR_PRM),
267 GET_REG_BIT(reg,SYSCNTR_ICW),GET_SYSCNTR_ISB(reg),
268 GET_REG_BIT(reg1,SYSCNTR_BDIS),GET_REG_BIT(reg1,SYSCNTR_PCIM));
269 printf("Switches: MUX=%ld PCI_DIS=%ld Boot_EN=%ld Config=%ld\n",GET_SDRAM_MUX(reg),
270 GET_REG_BIT(reg,SDRAM_PDIS),GET_REG_BIT(reg1,SYSCNTR_BOOTEN),
271 GET_SYSCNTR_CFG(reg1));
272 printf("Misc: RIP=%ld CPU_VPP=%ld FLSH_VPP=%ld FLSH_WP=%ld\n\n",
273 GET_REG_BIT(reg,SDRAM_RIP),GET_REG_BIT(reg1,SYSCNTR_CPU_VPP),
274 GET_REG_BIT(reg1,SYSCNTR_FL_VPP),GET_REG_BIT(reg1,SYSCNTR_FL_WP));
275}
276
277
278/****************************************************************
279 * Setting IOs
280 * -----------
281 * GPIO6 is User LED1
282 * GPIO7 is Interrupt PLX (Output)
283 * GPIO5 is User LED0
284 * GPIO2 is PLX USERi (Output)
285 * GPIO1 is PLX Interrupt (Input)
286 ****************************************************************/
287 void init_ios(void)
288 {
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200289 volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
wdenkb6e4c402004-01-02 16:05:07 +0000290 volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
291 unsigned long reg;
292 reg=sysconf->sc_sgpiocr; /* Data direction register */
293 reg &= ~0x67000000;
294 reg |= 0x27000000; /* set outpupts */
295 sysconf->sc_sgpiocr=reg; /* Data direction register */
296 reg=sysconf->sc_sgpiodt2; /* Data register */
297 /* set output to 0 */
298 reg &= ~0x27000000;
299 /* set IRQ and USERi to 1 */
300 reg |= 0x28000000;
301 sysconf->sc_sgpiodt2=reg; /* Data register */
302}
303
304void user_led0(int led_on)
305{
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200306 volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
wdenkb6e4c402004-01-02 16:05:07 +0000307 volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
308 unsigned long reg;
309 reg=sysconf->sc_sgpiodt2; /* Data register */
310 if(led_on) /* set output to 1 */
311 reg |= 0x04000000;
312 else
313 reg &= ~0x04000000;
314 sysconf->sc_sgpiodt2=reg; /* Data register */
315}
316
317void user_led1(int led_on)
318{
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200319 volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
wdenkb6e4c402004-01-02 16:05:07 +0000320 volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
321 unsigned long reg;
322 reg=sysconf->sc_sgpiodt2; /* Data register */
323 if(led_on) /* set output to 1 */
324 reg |= 0x02000000;
325 else
326 reg &= ~0x02000000;
327 sysconf->sc_sgpiodt2=reg; /* Data register */
328}
329
330
331/****************************************************************
332 * Last Stage Init
333 ****************************************************************/
334int last_stage_init (void)
335{
wdenkb6e4c402004-01-02 16:05:07 +0000336 init_ios();
337 return 0;
338}
339
340/****************************************************************
341 * Check the board
342 ****************************************************************/
343
344#define BOARD_NAME "PATI"
345
346int checkboard (void)
347{
Wolfgang Denkd39041f2009-07-19 01:15:52 +0200348 char s[50];
349 ulong reg;
wdenkb6e4c402004-01-02 16:05:07 +0000350 char rev;
351 int i;
352
353 puts ("\nBoard: ");
354 reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
355 rev=(char)(SYSCNTR_BREV(reg)+'A');
Wolfgang Denkcdb74972010-07-24 21:55:43 +0200356 i = getenv_f("serial#", s, 32);
wdenkb6e4c402004-01-02 16:05:07 +0000357 if ((i == -1)) {
358 puts ("### No HW ID - assuming " BOARD_NAME);
359 printf(" Rev. %c\n",rev);
360 }
361 else {
362 s[sizeof(BOARD_NAME)-1] = 0;
363 printf ("%s-1 Rev %c SN: %s\n", s,rev,
364 &s[sizeof(BOARD_NAME)]);
365 }
366 set_flash_vpp(1,0,0); /* set Flash VPP */
367 return 0;
368}
369
370
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200371#ifdef CONFIG_SYS_PCI_CON_DEVICE
wdenkb6e4c402004-01-02 16:05:07 +0000372/************************************************************************
373 * PCI Communication
374 *
375 * Alive (Pinging):
376 * ----------------
377 * PCI Host sends message ALIVE, Local acknowledges with ALIVE
378 *
379 * PCI_CON console over PCI:
380 * -------------------------
381 * Local side:
382 * - uses PCI9056_LOC_TO_PCI_DBELL register to signal that
383 * data is avaible (PCIMSG_CONN)
384 * - uses PCI9056_MAILBOX1 to send data
385 * - uses PCI9056_MAILBOX0 to receive data
386 * PCI side:
387 * - uses PCI9056_PCI_TO_LOC_DBELL register to signal that
388 * data is avaible (PCIMSG_CONN)
389 * - uses PCI9056_MAILBOX0 to send data
390 * - uses PCI9056_MAILBOX1 to receive data
391 *
392 * How it works:
393 * Send:
394 * - check if PCICON_TRANSMIT_REG is empty
395 * - write data or'ed with 0x80000000 into the PCICON_TRANSMIT_REG
396 * - write PCIMSG_CONN into the PCICON_DBELL_REG to signal a data
397 * is waiting
398 * Receive:
399 * - get an interrupt via the PCICON_ACK_REG register message
400 * PCIMSG_CONN
401 * - write the data from the PCICON_RECEIVE_REG into the receive
402 * buffer and if the receive buffer is not full, clear the
403 * PCICON_RECEIVE_REG (this allows the counterpart to write more data)
404 * - Clear the interrupt by writing 0xFFFFFFFF to the PCICON_ACK_REG
405 *
406 * The PCICON_RECEIVE_REG must be cleared by the routine which reads
407 * the receive buffer if the buffer is not full any more
408 *
409 */
410
411#undef PCI_CON_DEBUG
412
413#ifdef PCI_CON_DEBUG
414#define PCI_CON_PRINTF(fmt,args...) serial_printf (fmt ,##args)
415#else
416#define PCI_CON_PRINTF(fmt,args...)
417#endif
418
419
420/*********************************************************
421 * we work only with a receive buffer on eiter side.
422 * Transmit buffer is free, if mailbox is cleared.
423 * Transmit character is or'ed with 0x80000000
424 * PATI receive register MAILBOX0
425 * PATI transmit register MAILBOX1
426 *********************************************************/
427#define PCICON_RECEIVE_REG PCI9056_MAILBOX0
428#define PCICON_TRANSMIT_REG PCI9056_MAILBOX1
429#define PCICON_DBELL_REG PCI9056_LOC_TO_PCI_DBELL
430#define PCICON_ACK_REG PCI9056_PCI_TO_LOC_DBELL
431
432
433#define PCIMSG_ALIVE 0x1
434#define PCIMSG_CONN 0x2
435#define PCIMSG_DISC 0x3
436#define PCIMSG_CON_DATA 0x5
437
438
439#define PCICON_GET_REG(x) (in32(x + PCI_CONFIG_BASE))
440#define PCICON_SET_REG(x,y) (out32(x + PCI_CONFIG_BASE,y))
441#define PCICON_TX_FLAG 0x80000000
442
443
444#define REC_BUFFER_SIZE 0x100
445int recbuf[REC_BUFFER_SIZE];
446static int r_ptr = 0;
447int w_ptr;
Jean-Christophe PLAGNIOL-VILLARD52cb4d42009-05-16 12:14:54 +0200448struct stdio_dev pci_con_dev;
wdenkb6e4c402004-01-02 16:05:07 +0000449int conn=0;
450int buff_full=0;
451
452void pci_con_put_it(const char c)
453{
454 /* Test for completition */
455 unsigned long reg;
456 do {
457 reg=PCICON_GET_REG(PCICON_TRANSMIT_REG);
458 }while(reg);
459 reg=PCICON_TX_FLAG + c;
460 PCICON_SET_REG(PCICON_TRANSMIT_REG,reg);
461 PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_CON_DATA);
462}
463
464void pci_con_putc(const char c)
465{
466 pci_con_put_it(c);
467 if(c == '\n')
468 pci_con_put_it('\r');
469}
470
471
472int pci_con_getc(void)
473{
474 int res;
475 int diff;
476 while(r_ptr==(volatile int)w_ptr);
477 res=recbuf[r_ptr++];
478 if(r_ptr==REC_BUFFER_SIZE)
479 r_ptr=0;
480 if(w_ptr<r_ptr)
481 diff=r_ptr+REC_BUFFER_SIZE-w_ptr;
482 else
483 diff=r_ptr-w_ptr;
484 if((diff<(REC_BUFFER_SIZE-4)) && buff_full) {
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200485 /* clear Mail box */
wdenkb6e4c402004-01-02 16:05:07 +0000486 buff_full=0;
487 PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
488 }
489 return res;
490}
491
492int pci_con_tstc(void)
493{
494 if(r_ptr==(volatile int)w_ptr)
495 return 0;
496 return 1;
497}
498
499void pci_con_puts (const char *s)
500{
501 while (*s) {
502 pci_con_putc(*s);
503 ++s;
504 }
505}
506
507void pci_con_init (void)
508{
509 w_ptr = 0;
510 r_ptr = 0;
511 PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
512 conn=1;
513}
514
515/*******************************************
516 * IRQ routine
517 ******************************************/
518int pci_dorbell_irq(void)
519{
520 unsigned long reg,data;
521 int diff;
522 reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT);
523 PCI_CON_PRINTF(" PCI9056_INT_CTRL_STAT = %08lX\n",reg);
524 if(reg & (1<<20) ) {
525 /* read doorbell */
526 reg=PCICON_GET_REG(PCICON_ACK_REG);
527 switch(reg) {
528 case PCIMSG_ALIVE:
529 PCI_CON_PRINTF(" Alive\n");
530 PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_ALIVE);
531 break;
532 case PCIMSG_CONN:
533 PCI_CON_PRINTF(" Conn %d",conn);
534 w_ptr = 0;
535 r_ptr = 0;
536 buff_full=0;
537 PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
538 conn=1;
539 PCI_CON_PRINTF(" ... %d\n",conn);
540 break;
541 case PCIMSG_CON_DATA:
542 data=PCICON_GET_REG(PCICON_RECEIVE_REG);
543 recbuf[w_ptr++]=(int)(data&0xff);
544 PCI_CON_PRINTF(" Data Console %lX, %X %d %d %X\n",data,((int)(data&0xFF)),
545 r_ptr,w_ptr,recbuf[w_ptr-1]);
546 if(w_ptr==REC_BUFFER_SIZE)
547 w_ptr=0;
548 if(w_ptr<r_ptr)
549 diff=r_ptr+REC_BUFFER_SIZE-w_ptr;
550 else
551 diff=r_ptr-w_ptr;
552 if(diff>(REC_BUFFER_SIZE-4))
553 buff_full=1;
554 else
555 /* clear Mail box */
556 PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
557 break;
558 default:
559 serial_printf(" PCI9056_PCI_TO_LOC_DBELL = %08lX\n",reg);
560 }
561 /* clear IRQ */
562 PCICON_SET_REG(PCICON_ACK_REG,~0L);
563 }
564 return 0;
565}
566
567void pci_con_connect(void)
568{
569 unsigned long reg;
570 conn=0;
571 reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT);
572 /* default 0x0f010180 */
573 reg &= 0xff000000;
574 reg |= 0x00030000; /* enable local dorbell */
575 reg |= 0x00000300; /* enable PCI dorbell */
576 PCICON_SET_REG(PCI9056_INT_CTRL_STAT , reg);
577 irq_install_handler (0x2, (interrupt_handler_t *) pci_dorbell_irq,NULL);
578 memset (&pci_con_dev, 0, sizeof (pci_con_dev));
579 strcpy (pci_con_dev.name, "pci_con");
580 pci_con_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
581 pci_con_dev.putc = pci_con_putc;
582 pci_con_dev.puts = pci_con_puts;
583 pci_con_dev.getc = pci_con_getc;
584 pci_con_dev.tstc = pci_con_tstc;
Jean-Christophe PLAGNIOL-VILLARD52cb4d42009-05-16 12:14:54 +0200585 stdio_register (&pci_con_dev);
wdenkb6e4c402004-01-02 16:05:07 +0000586 printf("PATI ready for PCI connection, type ctrl-c for exit\n");
587 do {
588 udelay(10);
589 if((volatile int)conn)
590 break;
591 if(ctrlc()) {
592 irq_free_handler(0x2);
593 return;
594 }
595 }while(1);
596 console_assign(stdin,"pci_con");
597 console_assign(stderr,"pci_con");
598 console_assign(stdout,"pci_con");
599}
600
601void pci_con_disc(void)
602{
603 console_assign(stdin,"serial");
604 console_assign(stderr,"serial");
605 console_assign(stdout,"serial");
606 PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_DISC);
607 /* reconnection */
608 irq_free_handler(0x02);
609 pci_con_connect();
610}
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200611#endif /* #ifdef CONFIG_SYS_PCI_CON_DEVICE */
wdenkb6e4c402004-01-02 16:05:07 +0000612
613/*
614 * Absolute environment address for linker file.
615 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200616GEN_ABS(env_start, CONFIG_ENV_OFFSET + CONFIG_SYS_FLASH_BASE);