2 * (C) Copyright 2001 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.de>
5 * ELTEC ELPPC RAM initialization
7 * See file CREDITS for list of people who contributed to this
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 #include <asm/processor.h>
31 #include <ppc_asm.tmpl>
38 * setup pointer to message block
40 mflr r13 /* save away link register */
41 bl get_lnk_reg /* r3=addr of next instruction */
42 subi r4, r3, 8 /* r4=board_asm_init addr */
43 addi r29, r4, (MessageBlock-board_asm_init)
70 ori r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
82 ori r3, r3, (HID0_ICE | HID0_ICFI)
88 * setup memory controller
90 lis r1, MPC106_REG_ADDR@h
91 ori r1, r1, MPC106_REG_ADDR@l
92 lis r2, MPC106_REG_DATA@h
93 ori r2, r2, MPC106_REG_DATA@l
104 /* Configure PICR2 */
106 ori r3, r3, PCI_PICR2
113 /* Configure EUMBAR */
115 ori r3, r3, 0x0078 /* offest of EUMBAR in PCI config space */
117 lis r3, MPC107_EUMB_ADDR@h
121 /* Configure Address Map B Option Reg */
123 ori r3, r3, 0x00e0 /* offest of AMBOR in PCI config space */
129 /* Configure I2C Controller */
130 lis r14, MPC107_I2C_ADDR@h /* base of I2C controller */
131 ori r14, r14, MPC107_I2C_ADDR@l
132 lis r3, 0x2b10 /* I2C clock = 100MHz/1024 */
134 li r3, 0 /* clear arbitration */
138 /* Configure MCCR1 */
140 ori r3, r3, MPC106_MCCR1
142 addis r3, r0, 0x0660 /* don't set MEMGO now ! */
147 /* Configure MCCR2 */
149 ori r3, r3, MPC106_MCCR2
157 /* Configure MCCR3 */
159 ori r3, r3, MPC106_MCCR3
166 /* Configure MCCR4 */
168 ori r3, r3, MPC106_MCCR4
176 * configure memory interface (MICRs)
178 addis r3, r0, 0x8000 /* ADDR_80 */
179 ori r3, r3, 0x0080 /* SMEMADD1 */
186 addis r3, r0, 0x8000 /* ADDR_84 */
187 ori r3, r3, 0x0084 /* SMEMADD2 */
194 addis r3, r0, 0x8000 /* ADDR_88 */
195 ori r3, r3, 0x0088 /* EXTSMEM1 */
202 addis r3, r0, 0x8000 /* ADDR_8C */
203 ori r3, r3, 0x008c /* EXTSMEM2 */
210 addis r3, r0, 0x8000 /* ADDR_90 */
211 ori r3, r3, 0x0090 /* EMEMADD1 */
218 addis r3, r0, 0x8000 /* ADDR_94 */
219 ori r3, r3, 0x0094 /* EMEMADD2 */
226 addis r3, r0, 0x8000 /* ADDR_98 */
227 ori r3, r3, 0x0098 /* EXTEMEM1 */
234 addis r3, r0, 0x8000 /* ADDR_9C */
235 ori r3, r3, 0x009c /* EXTEMEM2 */
242 addis r3, r0, 0x8000 /* ADDR_A0 */
243 ori r3, r3, 0x00a0 /* MEMBNKEN */
251 * must wait at least 100us after HRESET to issue a MEMGO
259 * enable RAM Operations through MCCR1 (MEMGO)
272 * set LEDs first time
275 lis r30, CONFIG_SYS_USR_LED_BASE@h
280 * init COM1 for polled output
282 lis r8, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
283 ori r8, r8, CONFIG_SYS_NS16550_COM1@l
285 stb r9, 1(r8) /* int disabled */
288 stb r9, 4(r8) /* modem ctrl */
291 stb r9, 3(r8) /* link ctrl */
293 li r9, (CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE)
294 stb r9, 0(r8) /* baud rate (LSB)*/
296 li r9, ((CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE) >> 8)
297 stb r9, 1(r8) /* baud rate (MSB) */
300 stb r9, 3(r8) /* 8 data bits, 2 stop bit, no parity */
303 stb r9, 4(r8) /* enable the receiver and transmitter (modem ctrl) */
306 lbz r9, 5(r8) /* transmit empty */
310 stb r9, 3(r8) /* send break, 8 data bits, 2 stop bit, no parity */
316 lwz r0, 5(r8) /* load from port for delay */
320 lbz r9, 5(r8) /* transmit empty */
324 stb r9, 3(r8) /* 8 data bits, 2 stop bit, no parity */
328 * intro message from message block
330 addi r3, r29, (MnewLine-MessageBlock)
332 addi r3, r29, (MinitLogo-MessageBlock)
336 * memory cofiguration using SPD information stored on the SODIMMs
338 addi r3, r29, (Mspd01-MessageBlock)
343 li r3, 0x0002 /* get RAM type from spd for bank0/1 */
346 cmpi 0, 0, r3, -1 /* error ? */
349 addi r3, r29, (Mfail-MessageBlock)
352 li r6, 0xe /* error codes in r6 and r7 */
354 b toggleError /* fail - loop forever */
357 mr r15, r3 /* save r3 */
359 addi r3, r29, (Mok-MessageBlock)
362 cmpli 0, 0, r15, 0x0004 /* SDRAM ? */
365 addi r3, r29, (MramTyp-MessageBlock)
368 li r6, 0xd /* error codes in r6 and r7 */
370 b toggleError /* fail - loop forever */
373 li r3, 0x0012 /* get supported CAS latencies from byte 18 */
384 addi r3, r29, (MramTyp-MessageBlock)
387 li r6, 0xc /* error codes in r6 and r7 */
389 b toggleError /* fail - loop forever */
392 cmpli 0, 0, r3, 0xa1 /* cycle time must be 10ns max. */
395 addi r3, r29, (MramTyp-MessageBlock)
398 li r6, 0xb /* error codes in r6 and r7 */
400 b toggleError /* fail - loop forever */
402 lis r20, 0x06e8 /* preset MCR1 value */
404 li r3, 0x0011 /* get number of internal banks from spd for bank0/1 */
412 addi r3, r29, (MramConfErr-MessageBlock)
415 li r6, 0xa /* error codes in r6 and r7 */
417 b toggleError /* fail - loop forever */
420 li r3, 0x0003 /* get number of row bits from spd for bank0/1 */
430 li r3, 0x0003 /* get number of row bits from spd for bank0/1 */
448 /* get the size of bank 0-1 */
450 li r3, 0x001f /* get bank size from spd for bank0/1 */
453 rlwinm r16, r3, 2, 24, 29 /* calculate size in MByte (128 MB max.) */
455 li r3, 0x0005 /* get number of banks from spd for bank0/1 */
458 cmpi 0, 0, r3, 2 /* 2 banks ? */
464 li r3, 0x000c /* get refresh from spd for bank0/1 */
466 andi. r3, r3, 0x007f /* mask selfrefresh bit */
467 li r4, 0x1800 /* refesh cycle 1536 clocks left shifted 2 */
468 cmpli 0, 0, r3, 0x0000 /* 15.6 us ? */
471 li r4, 0x0c00 /* refesh cycle 768 clocks left shifted 2 */
472 cmpli 0, 0, r3, 0x0002 /* 7.8 us ? */
475 li r4, 0x3000 /* refesh cycle 3072 clocks left shifted 2 */
476 cmpli 0, 0, r3, 0x0003 /* 31.3 us ? */
479 li r4, 0x6000 /* refesh cycle 6144 clocks left shifted 2 */
480 cmpli 0, 0, r3, 0x0004 /* 62.5 us ? */
484 ori r4, r4, 0xc000 /* refesh cycle 8224 clocks left shifted 2 */
485 cmpli 0, 0, r3, 0x0005 /* 125 us ? */
491 lis r21, 0x0400 /* preset MCCR2 value */
494 /* Overwrite MCCR1 */
496 ori r3, r3, MPC106_MCCR1
501 /* Overwrite MCCR2 */
503 ori r3, r3, MPC106_MCCR2
508 /* set the memory boundary registers for bank 0-3 */
512 subi r21, r16, 1 /* calculate end address bank0 */
515 cmpi 0, 0, r17, 0 /* bank1 present ? */
518 andi. r3, r16, 0x00ff /* calculate start address of bank1 */
519 andi. r4, r16, 0x0300
520 rlwinm r3, r3, 8, 16, 23
524 add r16, r16, r17 /* add to total memory size */
526 subi r3, r16, 1 /* calculate end address of bank1 */
529 rlwinm r3, r3, 8, 16, 23
533 ori r22, r22, 2 /* enable bank1 */
536 ori r23, r23, 0x0300 /* set bank1 start to unused area */
537 ori r24, r24, 0x0300 /* set bank1 end to unused area */
539 addi r3, r29, (Mactivate-MessageBlock)
543 addi r3, r29, (Mact0123e-MessageBlock)
547 * overwrite MSAR1, MEAR1, EMSAR1, and EMEAR1
549 addis r3, r0, 0x8000 /* ADDR_80 */
550 ori r3, r3, 0x0080 /* MSAR1 */
555 addis r3, r0, 0x8000 /* ADDR_88 */
556 ori r3, r3, 0x0088 /* EMSAR1 */
561 addis r3, r0, 0x8000 /* ADDR_90 */
562 ori r3, r3, 0x0090 /* MEAR1 */
567 addis r3, r0, 0x8000 /* ADDR_98 */
568 ori r3, r3, 0x0098 /* EMEAR1 */
573 addis r3, r0, 0x8000 /* ADDR_A0 */
574 ori r3, r3, 0x00a0 /* MBER */
580 * delay to let SDRAM go through several initialization/refresh cycles
592 lis r30, CONFIG_SYS_USR_LED_BASE@h
597 blr /* EXIT board_asm_init ... */
599 /*----------------------------------------------------------------------------*/
601 * print a message to COM1 in polling mode (r10=COM1 port, r3=(char*)string)
605 lis r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
606 ori r10, r10, CONFIG_SYS_NS16550_COM1@l
608 lbz r0, 5(r10) /* read link status */
610 andi. r0, r0, 0x40 /* mask transmitter empty bit */
611 beq cr0, WaitChr /* wait till empty */
612 lbzx r0, r0, r3 /* get char */
613 stb r0, 0(r10) /* write to transmit reg */
615 addi r3, r3, 1 /* next char */
616 lbzx r0, r0, r3 /* get char */
617 cmpwi cr1, r0, 0 /* end of string ? */
622 * print a char to COM1 in polling mode (r10=COM1 port, r3=char)
625 lis r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
626 ori r10, r10, CONFIG_SYS_NS16550_COM1@l
628 lbz r0, 5(r10) /* read link status */
630 andi. r0, r0, 0x40 /* mask transmitter empty bit */
631 beq cr0, OutChr1 /* wait till empty */
632 stb r3, 0(r10) /* write to transmit reg */
637 * print 8/4/2 digits hex value to COM1 in polling mode (r10=COM1 port, r3=val)
640 li r9, 4 /* shift reg for 2 digits */
643 li r9, 12 /* shift reg for 4 digits */
646 li r9, 28 /* shift reg for 8 digits */
648 lis r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
649 ori r10, r10, CONFIG_SYS_NS16550_COM1@l
651 lbz r0, 0(r29) /* slow down dummy read */
652 lbz r0, 5(r10) /* read link status */
654 andi. r0, r0, 0x40 /* mask transmitter empty bit */
665 stb r0, 0(r10) /* write to transmit reg */
672 * print 3 digits hdec value to COM1 in polling mode
673 * (r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch)
677 divwu r0, r3, r6 /* r0 = r3 / 10, r9 = r3 mod 10 */
681 divwu r0, r3, r6 /* r0 = r3 / 10, r8 = r3 mod 10 */
685 divwu r0, r3, r6 /* r0 = r3 / 10, r7 = r3 mod 10 */
688 lis r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
689 ori r10, r10, CONFIG_SYS_NS16550_COM1@l
695 addi r3, r7, 48 /* convert to ASCII */
697 lbz r0, 0(r29) /* slow down dummy read */
698 lbz r0, 5(r10) /* read link status */
700 andi. r0, r0, 0x40 /* mask transmitter empty bit */
702 stb r3, 0(r10) /* x00 to transmit */
706 addi r3, r8, 48 /* convert to ASCII */
708 lbz r0, 0(r29) /* slow down dummy read */
709 lbz r0, 5(r10) /* read link status */
711 andi. r0, r0, 0x40 /* mask transmitter empty bit */
713 stb r3, 0(r10) /* x0 to transmit */
715 addi r3, r9, 48 /* convert to ASCII */
717 lbz r0, 0(r29) /* slow down dummy read */
718 lbz r0, 5(r10) /* read link status */
720 andi. r0, r0, 0x40 /* mask transmitter empty bit */
722 stb r3, 0(r10) /* x to transmit */
729 toggleError: /* fail type in r6, r7=0xff, toggle LEDs */
730 stb r7, 2(r30) /* r7 to LED */
737 ble cr1, toggleError1
738 stb r6, 2(r30) /* r6 to LED */
745 ble cr1, toggleError2
749 * routines to read from ram spd
752 lis r0, 0x1 /* timeout for about 100us */
756 andi. r10, r10, 0x20 /* mask and test MBB */
759 orc. r10, r0, r0 /* return -1 to caller */
761 bclr 20, 0 /* return to caller */
764 lis r0, 0x10 /* timeout for about 1.5ms */
769 cmpli 0, 0, r10, 0x82 /* test MCF and MIF set */
772 orc. r10, r0, r0 /* return -1 to caller */
773 bclr 20, 0 /* return to caller */
777 stb r10, 12(r14) /* clear status */
778 bclr 20, 0 /* return to caller */
783 * out: r3 val or -1 for error
784 * uses r10, assumes that r14 points to I2C controller
787 mfspr r25, 8 /* save link register */
792 li r10, 0x80 /* start with MEN */
796 li r10, 0xb0 /* start as master */
800 li r10, 0xa0 /* write device 0xA0 */
806 lbz r10, 12(r14) /* test ACK */
810 stb r3, 16(r14) /* data address */
816 li r10, 0xb4 /* switch to read - restart */
820 li r10, 0xa1 /* read device 0xA0 */
826 li r10, 0xa8 /* no ACK */
830 lbz r10, 16(r14) /* trigger read next byte */
835 li r10, 0x88 /* generate STOP condition */
839 lbz r3, 16(r14) /* return read byte */
841 mtspr 8, r25 /* restore link register */
845 li r10, 0x80 /* generate STOP condition */
849 orc r3, r0, r0 /* return -1 */
850 mtspr 8, r25 /* restore link register */
854 mflr r3 /* return link reg */
860 .ascii "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
861 .ascii "\015\012Initialising RAM\015\012\000"
863 .ascii " Reading SPD of SODIMM ...... \000"
865 .ascii "\015\012\SDRAM with CL=2 at 100 MHz required!\015\012\000"
867 .ascii "\015\012\Unsupported SODIMM Configuration!\015\012\000"
869 .ascii " Activating \000"
871 .ascii " MByte.\015\012\000"
873 .ascii "OK \015\012\000"
875 .ascii "FAILED \015\012\000"
877 .ascii "\015\012\000"