2 * (C) Copyright 2001 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.de>
5 * ELTEC ELPPC RAM initialization
7 * SPDX-License-Identifier: GPL-2.0+
11 #include <asm/processor.h>
15 #include <ppc_asm.tmpl>
22 * setup pointer to message block
24 mflr r13 /* save away link register */
25 bl get_lnk_reg /* r3=addr of next instruction */
26 subi r4, r3, 8 /* r4=board_asm_init addr */
27 addi r29, r4, (MessageBlock-board_asm_init)
54 ori r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
66 ori r3, r3, (HID0_ICE | HID0_ICFI)
72 * setup memory controller
74 lis r1, MPC106_REG_ADDR@h
75 ori r1, r1, MPC106_REG_ADDR@l
76 lis r2, MPC106_REG_DATA@h
77 ori r2, r2, MPC106_REG_DATA@l
97 /* Configure EUMBAR */
99 ori r3, r3, 0x0078 /* offest of EUMBAR in PCI config space */
101 lis r3, MPC107_EUMB_ADDR@h
105 /* Configure Address Map B Option Reg */
107 ori r3, r3, 0x00e0 /* offest of AMBOR in PCI config space */
113 /* Configure I2C Controller */
114 lis r14, MPC107_I2C_ADDR@h /* base of I2C controller */
115 ori r14, r14, MPC107_I2C_ADDR@l
116 lis r3, 0x2b10 /* I2C clock = 100MHz/1024 */
118 li r3, 0 /* clear arbitration */
122 /* Configure MCCR1 */
124 ori r3, r3, MPC106_MCCR1
126 addis r3, r0, 0x0660 /* don't set MEMGO now ! */
131 /* Configure MCCR2 */
133 ori r3, r3, MPC106_MCCR2
141 /* Configure MCCR3 */
143 ori r3, r3, MPC106_MCCR3
150 /* Configure MCCR4 */
152 ori r3, r3, MPC106_MCCR4
160 * configure memory interface (MICRs)
162 addis r3, r0, 0x8000 /* ADDR_80 */
163 ori r3, r3, 0x0080 /* SMEMADD1 */
170 addis r3, r0, 0x8000 /* ADDR_84 */
171 ori r3, r3, 0x0084 /* SMEMADD2 */
178 addis r3, r0, 0x8000 /* ADDR_88 */
179 ori r3, r3, 0x0088 /* EXTSMEM1 */
186 addis r3, r0, 0x8000 /* ADDR_8C */
187 ori r3, r3, 0x008c /* EXTSMEM2 */
194 addis r3, r0, 0x8000 /* ADDR_90 */
195 ori r3, r3, 0x0090 /* EMEMADD1 */
202 addis r3, r0, 0x8000 /* ADDR_94 */
203 ori r3, r3, 0x0094 /* EMEMADD2 */
210 addis r3, r0, 0x8000 /* ADDR_98 */
211 ori r3, r3, 0x0098 /* EXTEMEM1 */
218 addis r3, r0, 0x8000 /* ADDR_9C */
219 ori r3, r3, 0x009c /* EXTEMEM2 */
226 addis r3, r0, 0x8000 /* ADDR_A0 */
227 ori r3, r3, 0x00a0 /* MEMBNKEN */
235 * must wait at least 100us after HRESET to issue a MEMGO
243 * enable RAM Operations through MCCR1 (MEMGO)
256 * set LEDs first time
259 lis r30, CONFIG_SYS_USR_LED_BASE@h
264 * init COM1 for polled output
266 lis r8, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
267 ori r8, r8, CONFIG_SYS_NS16550_COM1@l
269 stb r9, 1(r8) /* int disabled */
272 stb r9, 4(r8) /* modem ctrl */
275 stb r9, 3(r8) /* link ctrl */
277 li r9, (CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE)
278 stb r9, 0(r8) /* baud rate (LSB)*/
280 li r9, ((CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE) >> 8)
281 stb r9, 1(r8) /* baud rate (MSB) */
284 stb r9, 3(r8) /* 8 data bits, 2 stop bit, no parity */
287 stb r9, 4(r8) /* enable the receiver and transmitter (modem ctrl) */
290 lbz r9, 5(r8) /* transmit empty */
294 stb r9, 3(r8) /* send break, 8 data bits, 2 stop bit, no parity */
300 lwz r0, 5(r8) /* load from port for delay */
304 lbz r9, 5(r8) /* transmit empty */
308 stb r9, 3(r8) /* 8 data bits, 2 stop bit, no parity */
312 * intro message from message block
314 addi r3, r29, (MnewLine-MessageBlock)
316 addi r3, r29, (MinitLogo-MessageBlock)
320 * memory cofiguration using SPD information stored on the SODIMMs
322 addi r3, r29, (Mspd01-MessageBlock)
327 li r3, 0x0002 /* get RAM type from spd for bank0/1 */
330 cmpi 0, 0, r3, -1 /* error ? */
333 addi r3, r29, (Mfail-MessageBlock)
336 li r6, 0xe /* error codes in r6 and r7 */
338 b toggleError /* fail - loop forever */
341 mr r15, r3 /* save r3 */
343 addi r3, r29, (Mok-MessageBlock)
346 cmpli 0, 0, r15, 0x0004 /* SDRAM ? */
349 addi r3, r29, (MramTyp-MessageBlock)
352 li r6, 0xd /* error codes in r6 and r7 */
354 b toggleError /* fail - loop forever */
357 li r3, 0x0012 /* get supported CAS latencies from byte 18 */
368 addi r3, r29, (MramTyp-MessageBlock)
371 li r6, 0xc /* error codes in r6 and r7 */
373 b toggleError /* fail - loop forever */
376 cmpli 0, 0, r3, 0xa1 /* cycle time must be 10ns max. */
379 addi r3, r29, (MramTyp-MessageBlock)
382 li r6, 0xb /* error codes in r6 and r7 */
384 b toggleError /* fail - loop forever */
386 lis r20, 0x06e8 /* preset MCR1 value */
388 li r3, 0x0011 /* get number of internal banks from spd for bank0/1 */
396 addi r3, r29, (MramConfErr-MessageBlock)
399 li r6, 0xa /* error codes in r6 and r7 */
401 b toggleError /* fail - loop forever */
404 li r3, 0x0003 /* get number of row bits from spd for bank0/1 */
414 li r3, 0x0003 /* get number of row bits from spd for bank0/1 */
432 /* get the size of bank 0-1 */
434 li r3, 0x001f /* get bank size from spd for bank0/1 */
437 rlwinm r16, r3, 2, 24, 29 /* calculate size in MByte (128 MB max.) */
439 li r3, 0x0005 /* get number of banks from spd for bank0/1 */
442 cmpi 0, 0, r3, 2 /* 2 banks ? */
448 li r3, 0x000c /* get refresh from spd for bank0/1 */
450 andi. r3, r3, 0x007f /* mask selfrefresh bit */
451 li r4, 0x1800 /* refesh cycle 1536 clocks left shifted 2 */
452 cmpli 0, 0, r3, 0x0000 /* 15.6 us ? */
455 li r4, 0x0c00 /* refesh cycle 768 clocks left shifted 2 */
456 cmpli 0, 0, r3, 0x0002 /* 7.8 us ? */
459 li r4, 0x3000 /* refesh cycle 3072 clocks left shifted 2 */
460 cmpli 0, 0, r3, 0x0003 /* 31.3 us ? */
463 li r4, 0x6000 /* refesh cycle 6144 clocks left shifted 2 */
464 cmpli 0, 0, r3, 0x0004 /* 62.5 us ? */
468 ori r4, r4, 0xc000 /* refesh cycle 8224 clocks left shifted 2 */
469 cmpli 0, 0, r3, 0x0005 /* 125 us ? */
475 lis r21, 0x0400 /* preset MCCR2 value */
478 /* Overwrite MCCR1 */
480 ori r3, r3, MPC106_MCCR1
485 /* Overwrite MCCR2 */
487 ori r3, r3, MPC106_MCCR2
492 /* set the memory boundary registers for bank 0-3 */
496 subi r21, r16, 1 /* calculate end address bank0 */
499 cmpi 0, 0, r17, 0 /* bank1 present ? */
502 andi. r3, r16, 0x00ff /* calculate start address of bank1 */
503 andi. r4, r16, 0x0300
504 rlwinm r3, r3, 8, 16, 23
508 add r16, r16, r17 /* add to total memory size */
510 subi r3, r16, 1 /* calculate end address of bank1 */
513 rlwinm r3, r3, 8, 16, 23
517 ori r22, r22, 2 /* enable bank1 */
520 ori r23, r23, 0x0300 /* set bank1 start to unused area */
521 ori r24, r24, 0x0300 /* set bank1 end to unused area */
523 addi r3, r29, (Mactivate-MessageBlock)
527 addi r3, r29, (Mact0123e-MessageBlock)
531 * overwrite MSAR1, MEAR1, EMSAR1, and EMEAR1
533 addis r3, r0, 0x8000 /* ADDR_80 */
534 ori r3, r3, 0x0080 /* MSAR1 */
539 addis r3, r0, 0x8000 /* ADDR_88 */
540 ori r3, r3, 0x0088 /* EMSAR1 */
545 addis r3, r0, 0x8000 /* ADDR_90 */
546 ori r3, r3, 0x0090 /* MEAR1 */
551 addis r3, r0, 0x8000 /* ADDR_98 */
552 ori r3, r3, 0x0098 /* EMEAR1 */
557 addis r3, r0, 0x8000 /* ADDR_A0 */
558 ori r3, r3, 0x00a0 /* MBER */
564 * delay to let SDRAM go through several initialization/refresh cycles
576 lis r30, CONFIG_SYS_USR_LED_BASE@h
581 blr /* EXIT board_asm_init ... */
583 /*----------------------------------------------------------------------------*/
585 * print a message to COM1 in polling mode (r10=COM1 port, r3=(char*)string)
589 lis r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
590 ori r10, r10, CONFIG_SYS_NS16550_COM1@l
592 lbz r0, 5(r10) /* read link status */
594 andi. r0, r0, 0x40 /* mask transmitter empty bit */
595 beq cr0, WaitChr /* wait till empty */
596 lbzx r0, r0, r3 /* get char */
597 stb r0, 0(r10) /* write to transmit reg */
599 addi r3, r3, 1 /* next char */
600 lbzx r0, r0, r3 /* get char */
601 cmpwi cr1, r0, 0 /* end of string ? */
606 * print a char to COM1 in polling mode (r10=COM1 port, r3=char)
609 lis r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
610 ori r10, r10, CONFIG_SYS_NS16550_COM1@l
612 lbz r0, 5(r10) /* read link status */
614 andi. r0, r0, 0x40 /* mask transmitter empty bit */
615 beq cr0, OutChr1 /* wait till empty */
616 stb r3, 0(r10) /* write to transmit reg */
621 * print 8/4/2 digits hex value to COM1 in polling mode (r10=COM1 port, r3=val)
624 li r9, 4 /* shift reg for 2 digits */
627 li r9, 12 /* shift reg for 4 digits */
630 li r9, 28 /* shift reg for 8 digits */
632 lis r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
633 ori r10, r10, CONFIG_SYS_NS16550_COM1@l
635 lbz r0, 0(r29) /* slow down dummy read */
636 lbz r0, 5(r10) /* read link status */
638 andi. r0, r0, 0x40 /* mask transmitter empty bit */
649 stb r0, 0(r10) /* write to transmit reg */
656 * print 3 digits hdec value to COM1 in polling mode
657 * (r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch)
661 divwu r0, r3, r6 /* r0 = r3 / 10, r9 = r3 mod 10 */
665 divwu r0, r3, r6 /* r0 = r3 / 10, r8 = r3 mod 10 */
669 divwu r0, r3, r6 /* r0 = r3 / 10, r7 = r3 mod 10 */
672 lis r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
673 ori r10, r10, CONFIG_SYS_NS16550_COM1@l
679 addi r3, r7, 48 /* convert to ASCII */
681 lbz r0, 0(r29) /* slow down dummy read */
682 lbz r0, 5(r10) /* read link status */
684 andi. r0, r0, 0x40 /* mask transmitter empty bit */
686 stb r3, 0(r10) /* x00 to transmit */
690 addi r3, r8, 48 /* convert to ASCII */
692 lbz r0, 0(r29) /* slow down dummy read */
693 lbz r0, 5(r10) /* read link status */
695 andi. r0, r0, 0x40 /* mask transmitter empty bit */
697 stb r3, 0(r10) /* x0 to transmit */
699 addi r3, r9, 48 /* convert to ASCII */
701 lbz r0, 0(r29) /* slow down dummy read */
702 lbz r0, 5(r10) /* read link status */
704 andi. r0, r0, 0x40 /* mask transmitter empty bit */
706 stb r3, 0(r10) /* x to transmit */
713 toggleError: /* fail type in r6, r7=0xff, toggle LEDs */
714 stb r7, 2(r30) /* r7 to LED */
721 ble cr1, toggleError1
722 stb r6, 2(r30) /* r6 to LED */
729 ble cr1, toggleError2
733 * routines to read from ram spd
736 lis r0, 0x1 /* timeout for about 100us */
740 andi. r10, r10, 0x20 /* mask and test MBB */
743 orc. r10, r0, r0 /* return -1 to caller */
745 bclr 20, 0 /* return to caller */
748 lis r0, 0x10 /* timeout for about 1.5ms */
753 cmpli 0, 0, r10, 0x82 /* test MCF and MIF set */
756 orc. r10, r0, r0 /* return -1 to caller */
757 bclr 20, 0 /* return to caller */
761 stb r10, 12(r14) /* clear status */
762 bclr 20, 0 /* return to caller */
767 * out: r3 val or -1 for error
768 * uses r10, assumes that r14 points to I2C controller
771 mfspr r25, 8 /* save link register */
776 li r10, 0x80 /* start with MEN */
780 li r10, 0xb0 /* start as master */
784 li r10, 0xa0 /* write device 0xA0 */
790 lbz r10, 12(r14) /* test ACK */
794 stb r3, 16(r14) /* data address */
800 li r10, 0xb4 /* switch to read - restart */
804 li r10, 0xa1 /* read device 0xA0 */
810 li r10, 0xa8 /* no ACK */
814 lbz r10, 16(r14) /* trigger read next byte */
819 li r10, 0x88 /* generate STOP condition */
823 lbz r3, 16(r14) /* return read byte */
825 mtspr 8, r25 /* restore link register */
829 li r10, 0x80 /* generate STOP condition */
833 orc r3, r0, r0 /* return -1 */
834 mtspr 8, r25 /* restore link register */
838 mflr r3 /* return link reg */
844 .ascii "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
845 .ascii "\015\012Initialising RAM\015\012\000"
847 .ascii " Reading SPD of SODIMM ...... \000"
849 .ascii "\015\012\SDRAM with CL=2 at 100 MHz required!\015\012\000"
851 .ascii "\015\012\Unsupported SODIMM Configuration!\015\012\000"
853 .ascii " Activating \000"
855 .ascii " MByte.\015\012\000"
857 .ascii "OK \015\012\000"
859 .ascii "FAILED \015\012\000"
861 .ascii "\015\012\000"