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