]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/mpl/pati/pati.c
951010a6a3d7bc40ad60843898a92800e7ef00dd
3 * Martin Winistoerfer, martinwinistoerfer@gmx.ch.
5 * Denis Peter, d.peter@mpl.ch
6 * SPDX-License-Identifier: GPL-2.0+
9 /***********************************************************************************
10 * Bits for the SDRAM controller
11 * -----------------------------
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 **********************************************************************************/
34 #include <stdio_dev.h>
40 #if defined(__APPLE__)
41 /* Leading underscore on symbols */
43 #else /* No leading character on symbols */
49 * Macros to generate global absolutes.
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))
58 /************************************************************************
59 * Early debug routines
61 void write_hex (unsigned char i
)
68 serial_putc (cc
+ 55);
70 serial_putc (cc
+ 48);
73 serial_putc (cc
+ 55);
75 serial_putc (cc
+ 48);
78 #if defined(SDRAM_DEBUG)
80 void write_4hex (unsigned long val
)
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
);
90 unsigned long in32(unsigned long addr
)
92 unsigned long *p
=(unsigned long *)addr
;
96 void out32(unsigned long addr
,unsigned long data
)
98 unsigned long *p
=(unsigned long *)addr
;
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 */
112 const 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 */
121 { 0xffff, /* terminator */
131 extern int mem_test (unsigned long start
, unsigned long ramsize
, int quiet
);
136 phys_size_t
initdram(void)
138 unsigned char board_rev
;
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
));
153 reg
=in32(PLD_CONFIG_BASE
+PLD_BOARD_TIMING
);
154 board_rev
=(unsigned char)(SYSCNTR_BREV(reg
));
157 if(sdram_table
[i
].boardtype
==0xffff) {
158 puts("ERROR, found no table for Board 0x");
159 write_hex(board_rev
);
162 if(sdram_table
[i
].boardtype
==(unsigned char)board_rev
)
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");
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
));
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
));
181 out32(PLD_CONFIG_BASE
+PLD_BOARD_TIMING
,reg
);
183 #if defined(SDRAM_DEBUG)
184 puts("step 2 set IIP\n");
187 reg
|= SET_REG_BIT(1,SDRAM_IIP
);
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)
197 /* wait for at least 8 refresh */
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 */
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 */
211 in32(CONFIG_SYS_SDRAM_BASE
+ lmr
);
212 /* ok, we're done, return SDRAM size */
213 return ((0x400000 << sdram_table
[i
].sz
)); /* log2 value of 4MByte */
217 void set_flash_vpp(int ext_vpp
, int ext_wp
, int int_vpp
)
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
));
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
);
233 void show_pld_regs(void)
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
));
263 /****************************************************************
267 * GPIO7 is Interrupt PLX (Output)
269 * GPIO2 is PLX USERi (Output)
270 * GPIO1 is PLX Interrupt (Input)
271 ****************************************************************/
274 volatile immap_t
* immr
= (immap_t
*) CONFIG_SYS_IMMR
;
275 volatile sysconf5xx_t
*sysconf
= &immr
->im_siu_conf
;
277 reg
=sysconf
->sc_sgpiocr
; /* Data direction register */
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 */
284 /* set IRQ and USERi to 1 */
286 sysconf
->sc_sgpiodt2
=reg
; /* Data register */
289 void user_led0(int led_on
)
291 volatile immap_t
* immr
= (immap_t
*) CONFIG_SYS_IMMR
;
292 volatile sysconf5xx_t
*sysconf
= &immr
->im_siu_conf
;
294 reg
=sysconf
->sc_sgpiodt2
; /* Data register */
295 if(led_on
) /* set output to 1 */
299 sysconf
->sc_sgpiodt2
=reg
; /* Data register */
302 void user_led1(int led_on
)
304 volatile immap_t
* immr
= (immap_t
*) CONFIG_SYS_IMMR
;
305 volatile sysconf5xx_t
*sysconf
= &immr
->im_siu_conf
;
307 reg
=sysconf
->sc_sgpiodt2
; /* Data register */
308 if(led_on
) /* set output to 1 */
312 sysconf
->sc_sgpiodt2
=reg
; /* Data register */
315 int board_early_init_f(void)
321 /****************************************************************
323 ****************************************************************/
324 int last_stage_init (void)
330 /****************************************************************
332 ****************************************************************/
334 #define BOARD_NAME "PATI"
336 int checkboard (void)
344 reg
=in32(PLD_CONFIG_BASE
+PLD_BOARD_TIMING
);
345 rev
=(char)(SYSCNTR_BREV(reg
)+'A');
346 i
= getenv_f("serial#", s
, 32);
348 puts ("### No HW ID - assuming " BOARD_NAME
);
349 printf(" Rev. %c\n",rev
);
352 s
[sizeof(BOARD_NAME
)-1] = 0;
353 printf ("%s-1 Rev %c SN: %s\n", s
,rev
,
354 &s
[sizeof(BOARD_NAME
)]);
356 set_flash_vpp(1,0,0); /* set Flash VPP */
361 #ifdef CONFIG_SYS_PCI_CON_DEVICE
362 /************************************************************************
367 * PCI Host sends message ALIVE, Local acknowledges with ALIVE
369 * PCI_CON console over PCI:
370 * -------------------------
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
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
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
389 * - get an interrupt via the PCICON_ACK_REG register message
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
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
404 #define PCI_CON_PRINTF(fmt,args...) serial_printf (fmt ,##args)
406 #define PCI_CON_PRINTF(fmt,args...)
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
423 #define PCIMSG_ALIVE 0x1
424 #define PCIMSG_CONN 0x2
425 #define PCIMSG_DISC 0x3
426 #define PCIMSG_CON_DATA 0x5
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
434 #define REC_BUFFER_SIZE 0x100
435 int recbuf
[REC_BUFFER_SIZE
];
436 static int r_ptr
= 0;
438 struct stdio_dev pci_con_dev
;
442 void pci_con_put_it(const char c
)
444 /* Test for completition */
447 reg
=PCICON_GET_REG(PCICON_TRANSMIT_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
);
454 void pci_con_putc(struct stdio_dev
*dev
, const char c
)
458 pci_con_put_it('\r');
462 int pci_con_getc(struct stdio_dev
*dev
)
466 while(r_ptr
==(volatile int)w_ptr
);
468 if(r_ptr
==REC_BUFFER_SIZE
)
471 diff
=r_ptr
+REC_BUFFER_SIZE
-w_ptr
;
474 if((diff
<(REC_BUFFER_SIZE
-4)) && buff_full
) {
477 PCICON_SET_REG(PCICON_RECEIVE_REG
,0L);
482 int pci_con_tstc(struct stdio_dev
*dev
)
484 if(r_ptr
==(volatile int)w_ptr
)
489 void pci_con_puts(struct stdio_dev
*dev
, const char *s
)
497 void pci_con_init (void)
501 PCICON_SET_REG(PCICON_RECEIVE_REG
,0L);
505 /*******************************************
507 ******************************************/
508 int pci_dorbell_irq(void)
510 unsigned long reg
,data
;
512 reg
=PCICON_GET_REG(PCI9056_INT_CTRL_STAT
);
513 PCI_CON_PRINTF(" PCI9056_INT_CTRL_STAT = %08lX\n",reg
);
516 reg
=PCICON_GET_REG(PCICON_ACK_REG
);
519 PCI_CON_PRINTF(" Alive\n");
520 PCICON_SET_REG(PCICON_DBELL_REG
,PCIMSG_ALIVE
);
523 PCI_CON_PRINTF(" Conn %d",conn
);
527 PCICON_SET_REG(PCICON_RECEIVE_REG
,0L);
529 PCI_CON_PRINTF(" ... %d\n",conn
);
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
)
539 diff
=r_ptr
+REC_BUFFER_SIZE
-w_ptr
;
542 if(diff
>(REC_BUFFER_SIZE
-4))
546 PCICON_SET_REG(PCICON_RECEIVE_REG
,0L);
549 serial_printf(" PCI9056_PCI_TO_LOC_DBELL = %08lX\n",reg
);
552 PCICON_SET_REG(PCICON_ACK_REG
,~0L);
557 void pci_con_connect(void)
561 reg
=PCICON_GET_REG(PCI9056_INT_CTRL_STAT
);
562 /* default 0x0f010180 */
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");
570 pci_con_dev
.flags
= DEV_FLAGS_OUTPUT
| DEV_FLAGS_INPUT
;
571 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
;
575 stdio_register (&pci_con_dev
);
576 printf("PATI ready for PCI connection, type ctrl-c for exit\n");
579 if((volatile int)conn
)
582 irq_free_handler(0x2);
586 console_assign(stdin
,"pci_con");
587 console_assign(stderr
,"pci_con");
588 console_assign(stdout
,"pci_con");
591 void pci_con_disc(void)
593 console_assign(stdin
,"serial");
594 console_assign(stderr
,"serial");
595 console_assign(stdout
,"serial");
596 PCICON_SET_REG(PCICON_DBELL_REG
,PCIMSG_DISC
);
598 irq_free_handler(0x02);
601 #endif /* #ifdef CONFIG_SYS_PCI_CON_DEVICE */
604 * Absolute environment address for linker file.
606 GEN_ABS(env_start
, CONFIG_ENV_OFFSET
+ CONFIG_SYS_FLASH_BASE
);