blob: 5d701a7931d063f77826645c989f7b8d869c97eb [file] [log] [blame]
wdenkbc01dd52004-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
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenkbc01dd52004-01-02 16:05:07 +00007 */
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>
Jean-Christophe PLAGNIOL-VILLARD2a7a0312009-05-16 12:14:54 +020033#include <stdio_dev.h>
wdenkbc01dd52004-01-02 16:05:07 +000034#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 */
60void 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
79void 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
89unsigned long in32(unsigned long addr)
90{
91 unsigned long *p=(unsigned long *)addr;
92 return *p;
93}
94
95void out32(unsigned long addr,unsigned long data)
96{
97 unsigned long *p=(unsigned long *)addr;
98 *p=data;
99}
100
101typedef 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
111const 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
130extern int mem_test (unsigned long start, unsigned long ramsize, int quiet);
wdenkbc01dd52004-01-02 16:05:07 +0000131
132/*
133 * Get RAM size.
134 */
Becky Brucebd99ae72008-06-09 16:03:40 -0500135phys_size_t initdram(int board_type)
wdenkbc01dd52004-01-02 16:05:07 +0000136{
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;
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200210 in32(CONFIG_SYS_SDRAM_BASE + lmr);
wdenkbc01dd52004-01-02 16:05:07 +0000211 /* ok, we're done, return SDRAM size */
212 return ((0x400000 << sdram_table[i].sz)); /* log2 value of 4MByte */
213}
214
215
216void 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
232void 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 {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200273 volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
wdenkbc01dd52004-01-02 16:05:07 +0000274 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
288void user_led0(int led_on)
289{
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200290 volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
wdenkbc01dd52004-01-02 16:05:07 +0000291 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
301void user_led1(int led_on)
302{
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200303 volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
wdenkbc01dd52004-01-02 16:05:07 +0000304 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 ****************************************************************/
318int last_stage_init (void)
319{
wdenkbc01dd52004-01-02 16:05:07 +0000320 init_ios();
321 return 0;
322}
323
324/****************************************************************
325 * Check the board
326 ****************************************************************/
327
328#define BOARD_NAME "PATI"
329
330int checkboard (void)
331{
Wolfgang Denkc00ae012009-07-19 01:15:52 +0200332 char s[50];
333 ulong reg;
wdenkbc01dd52004-01-02 16:05:07 +0000334 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');
Wolfgang Denk76af2782010-07-24 21:55:43 +0200340 i = getenv_f("serial#", s, 32);
wdenkbc01dd52004-01-02 16:05:07 +0000341 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
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200355#ifdef CONFIG_SYS_PCI_CON_DEVICE
wdenkbc01dd52004-01-02 16:05:07 +0000356/************************************************************************
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
429int recbuf[REC_BUFFER_SIZE];
430static int r_ptr = 0;
431int w_ptr;
Jean-Christophe PLAGNIOL-VILLARD2a7a0312009-05-16 12:14:54 +0200432struct stdio_dev pci_con_dev;
wdenkbc01dd52004-01-02 16:05:07 +0000433int conn=0;
434int buff_full=0;
435
436void 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
Simon Glass0d1e1f72014-07-23 06:54:59 -0600448void pci_con_putc(struct stdio_dev *dev, const char c)
wdenkbc01dd52004-01-02 16:05:07 +0000449{
450 pci_con_put_it(c);
451 if(c == '\n')
452 pci_con_put_it('\r');
453}
454
455
Simon Glass0d1e1f72014-07-23 06:54:59 -0600456int pci_con_getc(struct stdio_dev *dev)
wdenkbc01dd52004-01-02 16:05:07 +0000457{
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) {
Wolfgang Denka1be4762008-05-20 16:00:29 +0200469 /* clear Mail box */
wdenkbc01dd52004-01-02 16:05:07 +0000470 buff_full=0;
471 PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
472 }
473 return res;
474}
475
Simon Glass0d1e1f72014-07-23 06:54:59 -0600476int pci_con_tstc(struct stdio_dev *dev)
wdenkbc01dd52004-01-02 16:05:07 +0000477{
478 if(r_ptr==(volatile int)w_ptr)
479 return 0;
480 return 1;
481}
482
Simon Glass0d1e1f72014-07-23 06:54:59 -0600483void pci_con_puts(struct stdio_dev *dev, const char *s)
wdenkbc01dd52004-01-02 16:05:07 +0000484{
485 while (*s) {
486 pci_con_putc(*s);
487 ++s;
488 }
489}
490
491void 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 ******************************************/
502int 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
551void 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;
Jean-Christophe PLAGNIOL-VILLARD2a7a0312009-05-16 12:14:54 +0200569 stdio_register (&pci_con_dev);
wdenkbc01dd52004-01-02 16:05:07 +0000570 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
585void 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}
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200595#endif /* #ifdef CONFIG_SYS_PCI_CON_DEVICE */
wdenkbc01dd52004-01-02 16:05:07 +0000596
597/*
598 * Absolute environment address for linker file.
599 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200600GEN_ABS(env_start, CONFIG_ENV_OFFSET + CONFIG_SYS_FLASH_BASE);