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,
30 #include <ppc_asm.tmpl>
37 * setup pointer to message block
39 mflr r13 /* save away link register */
40 bl get_lnk_reg /* r3=addr of next instruction */
41 subi r4, r3, 8 /* r4=board_asm_init addr */
42 addi r29, r4, (MessageBlock-board_asm_init)
69 ori r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
81 ori r3, r3, (HID0_ICE | HID0_ICFI)
87 * setup memory controller
89 lis r1, MPC106_REG_ADDR@h
90 ori r1, r1, MPC106_REG_ADDR@l
91 lis r2, MPC106_REG_DATA@h
92 ori r2, r2, MPC106_REG_DATA@l
103 /* Configure PICR2 */
105 ori r3, r3, PCI_PICR2
112 /* Configure EUMBAR */
114 ori r3, r3, 0x0078 /* offest of EUMBAR in PCI config space */
116 lis r3, MPC107_EUMB_ADDR@h
120 /* Configure Address Map B Option Reg */
122 ori r3, r3, 0x00e0 /* offest of AMBOR in PCI config space */
128 /* Configure I2C Controller */
129 lis r14, MPC107_I2C_ADDR@h /* base of I2C controller */
130 ori r14, r14, MPC107_I2C_ADDR@l
131 lis r3, 0x2b10 /* I2C clock = 100MHz/1024 */
133 li r3, 0 /* clear arbitration */
137 /* Configure MCCR1 */
139 ori r3, r3, MPC106_MCCR1
141 addis r3, r0, 0x0660 /* don't set MEMGO now ! */
146 /* Configure MCCR2 */
148 ori r3, r3, MPC106_MCCR2
156 /* Configure MCCR3 */
158 ori r3, r3, MPC106_MCCR3
165 /* Configure MCCR4 */
167 ori r3, r3, MPC106_MCCR4
175 * configure memory interface (MICRs)
177 addis r3, r0, 0x8000 /* ADDR_80 */
178 ori r3, r3, 0x0080 /* SMEMADD1 */
185 addis r3, r0, 0x8000 /* ADDR_84 */
186 ori r3, r3, 0x0084 /* SMEMADD2 */
193 addis r3, r0, 0x8000 /* ADDR_88 */
194 ori r3, r3, 0x0088 /* EXTSMEM1 */
201 addis r3, r0, 0x8000 /* ADDR_8C */
202 ori r3, r3, 0x008c /* EXTSMEM2 */
209 addis r3, r0, 0x8000 /* ADDR_90 */
210 ori r3, r3, 0x0090 /* EMEMADD1 */
217 addis r3, r0, 0x8000 /* ADDR_94 */
218 ori r3, r3, 0x0094 /* EMEMADD2 */
225 addis r3, r0, 0x8000 /* ADDR_98 */
226 ori r3, r3, 0x0098 /* EXTEMEM1 */
233 addis r3, r0, 0x8000 /* ADDR_9C */
234 ori r3, r3, 0x009c /* EXTEMEM2 */
241 addis r3, r0, 0x8000 /* ADDR_A0 */
242 ori r3, r3, 0x00a0 /* MEMBNKEN */
250 * must wait at least 100us after HRESET to issue a MEMGO
258 * enable RAM Operations through MCCR1 (MEMGO)
271 * set LEDs first time
274 lis r30, CFG_USR_LED_BASE@h
279 * init COM1 for polled output
281 lis r8, CFG_NS16550_COM1@h /* COM1 base address*/
282 ori r8, r8, CFG_NS16550_COM1@l
284 stb r9, 1(r8) /* int disabled */
287 stb r9, 4(r8) /* modem ctrl */
290 stb r9, 3(r8) /* link ctrl */
292 li r9, (CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE)
293 stb r9, 0(r8) /* baud rate (LSB)*/
295 li r9, ((CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE) >> 8)
296 stb r9, 1(r8) /* baud rate (MSB) */
299 stb r9, 3(r8) /* 8 data bits, 2 stop bit, no parity */
302 stb r9, 4(r8) /* enable the receiver and transmitter (modem ctrl) */
305 lbz r9, 5(r8) /* transmit empty */
309 stb r9, 3(r8) /* send break, 8 data bits, 2 stop bit, no parity */
315 lwz r0, 5(r8) /* load from port for delay */
319 lbz r9, 5(r8) /* transmit empty */
323 stb r9, 3(r8) /* 8 data bits, 2 stop bit, no parity */
327 * intro message from message block
329 addi r3, r29, (MnewLine-MessageBlock)
331 addi r3, r29, (MinitLogo-MessageBlock)
335 * memory cofiguration using SPD information stored on the SODIMMs
337 addi r3, r29, (Mspd01-MessageBlock)
342 li r3, 0x0002 /* get RAM type from spd for bank0/1 */
345 cmpi 0, 0, r3, -1 /* error ? */
348 addi r3, r29, (Mfail-MessageBlock)
351 li r6, 0xe /* error codes in r6 and r7 */
353 b toggleError /* fail - loop forever */
356 mr r15, r3 /* save r3 */
358 addi r3, r29, (Mok-MessageBlock)
361 cmpli 0, 0, r15, 0x0004 /* SDRAM ? */
364 addi r3, r29, (MramTyp-MessageBlock)
367 li r6, 0xd /* error codes in r6 and r7 */
369 b toggleError /* fail - loop forever */
372 li r3, 0x0012 /* get supported CAS latencies from byte 18 */
383 addi r3, r29, (MramTyp-MessageBlock)
386 li r6, 0xc /* error codes in r6 and r7 */
388 b toggleError /* fail - loop forever */
391 cmpli 0, 0, r3, 0xa1 /* cycle time must be 10ns max. */
394 addi r3, r29, (MramTyp-MessageBlock)
397 li r6, 0xb /* error codes in r6 and r7 */
399 b toggleError /* fail - loop forever */
401 lis r20, 0x06e8 /* preset MCR1 value */
403 li r3, 0x0011 /* get number of internal banks from spd for bank0/1 */
411 addi r3, r29, (MramConfErr-MessageBlock)
414 li r6, 0xa /* error codes in r6 and r7 */
416 b toggleError /* fail - loop forever */
419 li r3, 0x0003 /* get number of row bits from spd for bank0/1 */
429 li r3, 0x0003 /* get number of row bits from spd for bank0/1 */
447 /* get the size of bank 0-1 */
449 li r3, 0x001f /* get bank size from spd for bank0/1 */
452 rlwinm r16, r3, 2, 24, 29 /* calculate size in MByte (128 MB max.) */
454 li r3, 0x0005 /* get number of banks from spd for bank0/1 */
457 cmpi 0, 0, r3, 2 /* 2 banks ? */
463 li r3, 0x000c /* get refresh from spd for bank0/1 */
465 andi. r3, r3, 0x007f /* mask selfrefresh bit */
466 li r4, 0x1800 /* refesh cycle 1536 clocks left shifted 2 */
467 cmpli 0, 0, r3, 0x0000 /* 15.6 us ? */
470 li r4, 0x0c00 /* refesh cycle 768 clocks left shifted 2 */
471 cmpli 0, 0, r3, 0x0002 /* 7.8 us ? */
474 li r4, 0x3000 /* refesh cycle 3072 clocks left shifted 2 */
475 cmpli 0, 0, r3, 0x0003 /* 31.3 us ? */
478 li r4, 0x6000 /* refesh cycle 6144 clocks left shifted 2 */
479 cmpli 0, 0, r3, 0x0004 /* 62.5 us ? */
483 ori r4, r4, 0xc000 /* refesh cycle 8224 clocks left shifted 2 */
484 cmpli 0, 0, r3, 0x0005 /* 125 us ? */
490 lis r21, 0x0400 /* preset MCCR2 value */
493 /* Overwrite MCCR1 */
495 ori r3, r3, MPC106_MCCR1
500 /* Overwrite MCCR2 */
502 ori r3, r3, MPC106_MCCR2
507 /* set the memory boundary registers for bank 0-3 */
511 subi r21, r16, 1 /* calculate end address bank0 */
514 cmpi 0, 0, r17, 0 /* bank1 present ? */
517 andi. r3, r16, 0x00ff /* calculate start address of bank1 */
518 andi. r4, r16, 0x0300
519 rlwinm r3, r3, 8, 16, 23
523 add r16, r16, r17 /* add to total memory size */
525 subi r3, r16, 1 /* calculate end address of bank1 */
528 rlwinm r3, r3, 8, 16, 23
532 ori r22, r22, 2 /* enable bank1 */
535 ori r23, r23, 0x0300 /* set bank1 start to unused area */
536 ori r24, r24, 0x0300 /* set bank1 end to unused area */
538 addi r3, r29, (Mactivate-MessageBlock)
542 addi r3, r29, (Mact0123e-MessageBlock)
546 * overwrite MSAR1, MEAR1, EMSAR1, and EMEAR1
548 addis r3, r0, 0x8000 /* ADDR_80 */
549 ori r3, r3, 0x0080 /* MSAR1 */
554 addis r3, r0, 0x8000 /* ADDR_88 */
555 ori r3, r3, 0x0088 /* EMSAR1 */
560 addis r3, r0, 0x8000 /* ADDR_90 */
561 ori r3, r3, 0x0090 /* MEAR1 */
566 addis r3, r0, 0x8000 /* ADDR_98 */
567 ori r3, r3, 0x0098 /* EMEAR1 */
572 addis r3, r0, 0x8000 /* ADDR_A0 */
573 ori r3, r3, 0x00a0 /* MBER */
579 * delay to let SDRAM go through several initialization/refresh cycles
591 lis r30, CFG_USR_LED_BASE@h
596 blr /* EXIT board_asm_init ... */
598 /*----------------------------------------------------------------------------*/
600 * print a message to COM1 in polling mode (r10=COM1 port, r3=(char*)string)
604 lis r10, CFG_NS16550_COM1@h /* COM1 base address*/
605 ori r10, r10, CFG_NS16550_COM1@l
607 lbz r0, 5(r10) /* read link status */
609 andi. r0, r0, 0x40 /* mask transmitter empty bit */
610 beq cr0, WaitChr /* wait till empty */
611 lbzx r0, r0, r3 /* get char */
612 stb r0, 0(r10) /* write to transmit reg */
614 addi r3, r3, 1 /* next char */
615 lbzx r0, r0, r3 /* get char */
616 cmpwi cr1, r0, 0 /* end of string ? */
621 * print a char to COM1 in polling mode (r10=COM1 port, r3=char)
624 lis r10, CFG_NS16550_COM1@h /* COM1 base address*/
625 ori r10, r10, CFG_NS16550_COM1@l
627 lbz r0, 5(r10) /* read link status */
629 andi. r0, r0, 0x40 /* mask transmitter empty bit */
630 beq cr0, OutChr1 /* wait till empty */
631 stb r3, 0(r10) /* write to transmit reg */
636 * print 8/4/2 digits hex value to COM1 in polling mode (r10=COM1 port, r3=val)
639 li r9, 4 /* shift reg for 2 digits */
642 li r9, 12 /* shift reg for 4 digits */
645 li r9, 28 /* shift reg for 8 digits */
647 lis r10, CFG_NS16550_COM1@h /* COM1 base address*/
648 ori r10, r10, CFG_NS16550_COM1@l
650 lbz r0, 0(r29) /* slow down dummy read */
651 lbz r0, 5(r10) /* read link status */
653 andi. r0, r0, 0x40 /* mask transmitter empty bit */
664 stb r0, 0(r10) /* write to transmit reg */
671 * print 3 digits hdec value to COM1 in polling mode
672 * (r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch)
676 divwu r0, r3, r6 /* r0 = r3 / 10, r9 = r3 mod 10 */
680 divwu r0, r3, r6 /* r0 = r3 / 10, r8 = r3 mod 10 */
684 divwu r0, r3, r6 /* r0 = r3 / 10, r7 = r3 mod 10 */
687 lis r10, CFG_NS16550_COM1@h /* COM1 base address*/
688 ori r10, r10, CFG_NS16550_COM1@l
694 addi r3, r7, 48 /* convert to ASCII */
696 lbz r0, 0(r29) /* slow down dummy read */
697 lbz r0, 5(r10) /* read link status */
699 andi. r0, r0, 0x40 /* mask transmitter empty bit */
701 stb r3, 0(r10) /* x00 to transmit */
705 addi r3, r8, 48 /* convert to ASCII */
707 lbz r0, 0(r29) /* slow down dummy read */
708 lbz r0, 5(r10) /* read link status */
710 andi. r0, r0, 0x40 /* mask transmitter empty bit */
712 stb r3, 0(r10) /* x0 to transmit */
714 addi r3, r9, 48 /* convert to ASCII */
716 lbz r0, 0(r29) /* slow down dummy read */
717 lbz r0, 5(r10) /* read link status */
719 andi. r0, r0, 0x40 /* mask transmitter empty bit */
721 stb r3, 0(r10) /* x to transmit */
728 toggleError: /* fail type in r6, r7=0xff, toggle LEDs */
729 stb r7, 2(r30) /* r7 to LED */
736 ble cr1, toggleError1
737 stb r6, 2(r30) /* r6 to LED */
744 ble cr1, toggleError2
748 * routines to read from ram spd
751 lis r0, 0x1 /* timeout for about 100us */
755 andi. r10, r10, 0x20 /* mask and test MBB */
758 orc. r10, r0, r0 /* return -1 to caller */
760 bclr 20, 0 /* return to caller */
763 lis r0, 0x10 /* timeout for about 1.5ms */
768 cmpli 0, 0, r10, 0x82 /* test MCF and MIF set */
771 orc. r10, r0, r0 /* return -1 to caller */
772 bclr 20, 0 /* return to caller */
776 stb r10, 12(r14) /* clear status */
777 bclr 20, 0 /* return to caller */
782 * out: r3 val or -1 for error
783 * uses r10, assumes that r14 points to I2C controller
786 mfspr r25, 8 /* save link register */
791 li r10, 0x80 /* start with MEN */
795 li r10, 0xb0 /* start as master */
799 li r10, 0xa0 /* write device 0xA0 */
805 lbz r10, 12(r14) /* test ACK */
809 stb r3, 16(r14) /* data address */
815 li r10, 0xb4 /* switch to read - restart */
819 li r10, 0xa1 /* read device 0xA0 */
825 li r10, 0xa8 /* no ACK */
829 lbz r10, 16(r14) /* trigger read next byte */
834 li r10, 0x88 /* generate STOP condition */
838 lbz r3, 16(r14) /* return read byte */
840 mtspr 8, r25 /* restore link register */
844 li r10, 0x80 /* generate STOP condition */
848 orc r3, r0, r0 /* return -1 */
849 mtspr 8, r25 /* restore link register */
853 mflr r3 /* return link reg */
859 .ascii "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
860 .ascii "\015\012Initialising RAM\015\012\000"
862 .ascii " Reading SPD of SODIMM ...... \000"
864 .ascii "\015\012\SDRAM with CL=2 at 100 MHz required!\015\012\000"
866 .ascii "\015\012\Unsupported SODIMM Configuration!\015\012\000"
868 .ascii " Activating \000"
870 .ascii " MByte.\015\012\000"
872 .ascii "OK \015\012\000"
874 .ascii "FAILED \015\012\000"
876 .ascii "\015\012\000"