dnscrypto-proxy: Support files updated.
[tomato.git] / release / src / shared / sbsdram.S
blob9798219e3b8e0733ec03e56446569e8d7a785ae8
1 /*
2  * BCM47XX Sonics SiliconBackplane SDRAM/MEMC core initialization
3  *
4  * Copyright 2004, Broadcom Corporation
5  * All Rights Reserved.
6  * 
7  * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8  * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9  * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10  * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11  *
12  * $Id$
13  */
15 #include <sbconfig.h>
16 #include <sbsdram.h>
17 #include <sbmemc.h>
18 #include <sbsocram.h>
19 #include <sbchipc.h>
20 #include <bcmdevs.h>
21 #include <bcmnvram.h>
23 #include <mipsinc.h>
25 /* #define      DEBUG_SBSDRAM   1 */
26 #ifdef  DEBUG_SBSDRAM
27         /* Trace function
28          * Write to prog space so we can see it in
29          * the Logic Analizer
30          */
31 #define TRACE_INIT              \
32         li      k0,0xb8000120;  \
33         li      k1,0x11;        \
34         sw      k1,0(k0);       \
35         li      k1,0x01020108;  \
36         sw      k1,4(k0);       \
37         li      k0,0xbb000000
39 #define TRACE(num, reg) sw      reg,(num << 4)(k0)
40 #else
41 #define TRACE(num, reg)
42 #define TRACE_INIT
43 #endif
45  * Register usage within this file:
46  *
47  *              top     ncdlsearch      test_mem        Xdr_do_init     sb_reset_core
48  *      v0:     retval                  retval
49  *      v1:     corerev -               -               corerev         -
50  *      a0:     coreptr coreptr         -               coreptr         coreptr
51  *      a1:             x               x               x               sdr/ddr flag
52  *      a2:                             x
53  *      a3:                             x
54  *      t0:     -       -                               config
55  *      t1:     -       -                               mode
56  *      t2:     -       wr/strm         off             wr/strm
57  *      t3:     -       rd/strd                         rd/strd
58  *      t4:     -       g/clkd                          g/clkd
59  *      t5:                             x
60  *      t6:     retaddr -                               -               -
61  *      t7:     -       -                               retaddr         -
62  *      s0:             pass_count                      -               -
63  *      s1:             wrsum/clkdsum                   -               -
64  *      s2:             rdsum/pass_countmax             -               -
65  *      s3:             gsum/strmmax                    -               -
66  *      s4:             wrlim/stdmmax                   -               -
67  *      s5:             rdlim/clkdmax                   -               -
68  *      s6:             glim/clkdlim                    -               -
69  *      s7:             dll                             -               -
70  *      t8:     -       -                               x               tmp
71  *      t9:     -       -                               x               retaddr
72  *      k0:     trace   trace           trace           -               -
73  *      k1:     trace   trace           trace           -               -
74  *      gp:
75  *      sp:
76  *      s8:     -       step                            -               -
77  *      ra:
78  */
81         .text
82         .set    mips32
84         LEAF(board_draminit)
85         .set    noreorder
87         /* Save return address */
88         move    t6,ra
90         TRACE_INIT
92         /* Scan for an SDRAM controller (a0) */
93         li      a0,KSEG1ADDR(SB_ENUM_BASE)
94 1:      lw      v1,(SBCONFIGOFF + SBIDHIGH)(a0)
95         and     a1,v1,SBIDH_CC_MASK
96         srl     a1,a1,SBIDH_CC_SHIFT
97         beq     a1,SB_MEMC,foundctrl
98         nop
99         beq     a1,SB_SOCRAM,foundctrl
100         nop
101         beq     a1,SB_SDRAM,foundctrl
102         nop
103         addu    a0,SB_CORE_SIZE
104         bne     a1,(SBIDH_CC_MASK >> SBIDH_CC_SHIFT),1b
105         nop
107         /* No SDRAM controller */
108         jr      t6
109         li      v0, 0
111 foundctrl:
112         /* If we are already in RAM, just go and size it */
113         bal     1f
114         nop
115 1:      li      t0,PHYSADDR_MASK
116         and     t0,t0,ra
117         li      t1,SB_FLASH1
118         blt     t0,t1,memprio_szmem
119         nop
121         /* For socram we don't need any nvram parms, just do a core reset */
122         bne     a1,SB_SOCRAM,read_nvram
123         nop
124         bal     sb_core_reset
125         li      a2,0
126         /* and size memory */
127         b       memprio_szmem
128         nop
130 read_nvram:
131         /* Find NVRAM (a2) */
132         li      t0,KSEG1ADDR(SB_ENUM_BASE)      # Is there a chipcommon core?
133         lw      t1,(SBCONFIGOFF + SBIDHIGH)(t0)
134         and     t1,t1,SBIDH_CC_MASK
135         srl     t1,t1,SBIDH_CC_SHIFT
136         bne     t1,SB_CC,notcc
137         nop
139         /* It is a chipcommon core: */
140         /* 1: Isolate memc's corerev in v1 */
141         and     t2,v1,SBIDH_RCE_MASK
142         srl     t2,t2,SBIDH_RCE_SHIFT
143         and     v1,v1,SBIDH_RC_MASK
144         or      v1,t2
146         /* 1.5: 5365a0 lies about its revision, it is really 1 */
147         bnez    v1,1f
148         nop
150         lw      t1,CC_CHIPID(t0)                # Get chipid
151         andi    t1,CID_ID_MASK                  # Check chipid
152         bne     t1,BCM5365_CHIP_ID,1f
153         nop
154         li      v1,1
156         /* 2: use the 32MB window */
157 1:      li      t2,KSEG1ADDR(SB_FLASH2 - NVRAM_SPACE)
158         li      t4,SB_FLASH2_SZ
159         b       find_nvram
160         nop
162 notcc:
163         /* else use the 4MB window */
164         li      t2,KSEG1ADDR(SB_FLASH1 - NVRAM_SPACE)
165         li      t4,SB_FLASH1_SZ
167 find_nvram:
168         li      t3,FLASH_MIN 
169         li      t0,NVRAM_MAGIC
172         add     a2,t2,t3
173         lw      t1,0(a2)
174         beq     t0,t1,read_parms
175         nop
177         sll     t3,t3,1
178         ble     t3,t4,1b
179         nop
181         /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
182         li      a2,KSEG1ADDR(SB_FLASH1 + 0x1000)
183         lw      t1,0(a2)
184         beq     t0,t1,read_parms
185         nop
187         li      a2,KSEG1ADDR(SB_FLASH1 + 0x400)
188         lw      t1,0(a2)
189         beq     t0,t1,read_parms
190         nop
192         b       init                    # No NVRAM
193         li      a2, 0
195 read_parms:
196         /* Get SDRAM parameters (t0, t1, t2) from NVRAM (a2) */
197         lw      t0,8(a2)                # SDRAM init
198         srl     t0,16
199         lw      t2,12(a2)
200         andi    t1,t2,0xffff            # SDRAM config
201         srl     t2,16                   # SDRAM refresh
202         lw      t3,16(a2)               # SDRAM ncdl
204 init:
205         /* Initialize SDRAM controller:  sdram core */
206         beq     a1,SB_SDRAM,sdram_init
207         nop
208         /* else it is a memc core */
210 memc_init:
211         bnez    a2,1f                   # Already have the parms in
212         nop                             #  t0, t1, t2, t3
214         /* No nvram parms: assume DDRM16MX16X2 */
216         li      t0,MEMC_DDR_INIT
217         li      t1,MEMC_DDR_MODE
218         li      t3,MEMC_DDR1_NCDL       # If rev1 (4712):
219         beq     v1,1,1f
220         nop
221                                         # rev0, 2:
222         li      t3,MEMC_DDR_NCDL
225         andi    a3,t0,MEMC_CONFIG_DDR   # Is it ddr or sdr?
226         beqz    a3,memc_sdr_init
227         nop
229         /* Initialize DDR SDRAM */
230 memc_ddr_init:
231         beqz    t3,ddr_find_ncdl        # Do we have ncdl values? (0s)
232         nop
234         li      t4,-1                   # or ffs
235         bne     t3,t4,break_ddr_ncdl
236         nop
238 ddr_find_ncdl:
240 /* Register usage */
241 #define pass_count      s0
242 #define wrsum           s1
243 #define rdsum           s2
244 #define gsum            s3
245 #define wrlim           s4
246 #define rdlim           s5
247 #define glim            s6
248 #define dll             s7
249 #define step            s8
250 #define wr              t2
251 #define rd              t3
252 #define g               t4
254         /* Initialize counter & accumulators */
255         move    pass_count,zero
256         move    wrsum,zero
257         move    rdsum,zero
258         move    gsum,zero
260         /* Initialize with default values */
261         li      wr,5
262         li      rd,5
263         bal     ddr_do_init
264         li      g,10
266         /* Read dll value */
267         lw      dll,MEMC_NCDLCTL(a0)
268         TRACE(1, dll)
269         andi    dll,dll,0xfe
270         srl     dll,dll,1
271         beqz    dll,memprio_szmem               /* If zero, leave the default values */
272         nop
274         move    wrlim,dll               /* dll value is lim for wr, rd and g */
275         move    rdlim,dll
276         move    glim,dll
277         TRACE(2, wrlim)
278         TRACE(3, rdlim)
279         TRACE(4, glim)
281         addi    step,dll,15             /* step = (dll + 16 - 1) / 16 */
282         srl     step,step,4
283         TRACE(5, step)
285         sub     wr,zero,dll             /* Negate dll as initial value */
286         move    rd,wr
287         move    g,wr
289         /* Inner loop:  call ddr_do_init to re-initialize and the test mem */
290 loop:
291         TRACE(6, wr)
292         TRACE(7, rd)
293         TRACE(8, g)     
294         bal     ddr_do_init
295         nop
297         bal     test_mem
298         nop
300         TRACE(9, v0)
301         beqz    v0,nextg
302         nop
304         /* Memory is ok */
306         addi    pass_count,1
307         add     wrsum,wrsum,wr
308         add     rdsum,rdsum,rd
309         add     gsum,gsum,g
310         TRACE(0xa, pass_count)
311         TRACE(0xb, wrsum)
312         TRACE(0xc, rdsum)
313         TRACE(0xd, gsum)
315         bne     wr,dll,1f
316         nop
317         sll     wrlim,dll,1
318         TRACE(0xe, wrlim)
321         bne     rd,dll,2f
322         nop
323         sll     rdlim,dll,1
324         TRACE(0xf, rdlim)
327         bne     g,dll,nextg
328         nop
329         sll     glim,dll,1
330         TRACE(0x10, glim)
332 nextg:
333         add     g,g,step
334         ble     g,glim,loop
335         nop
336         sub     g,zero,dll
337         move    glim,dll
338         TRACE(0x11, g)
340         /* nextrd: */
341         add     rd,rd,step
342         ble     rd,rdlim,loop
343         nop
344         sub     rd,zero,dll
345         move    rdlim,dll
346         TRACE(0x12, rd)
348         /* nextwr: */
349         add     wr,wr,step
350         ble     wr,wrlim,loop
351         nop
353         /* All done, calculate average values and program them */
354         
355         TRACE(0x13, pass_count)
356         TRACE(0x14, wrsum)
357         TRACE(0x15, rdsum)
358         TRACE(0x16, gsum)
359         beqz    pass_count,1f
360         nop
362         div     zero,wrsum,pass_count
363         mflo    wr
365         div     zero,rdsum,pass_count
366         mflo    rd
368         div     zero,gsum,pass_count
369         mflo    g
371         b       ddr_got_ncdl
372         nop
374         /* No passing values, panic! (use defaults) */
376         li      t3,MEMC_DDR1_NCDL       # If rev1:
377         beq     v1,1,2f
378         nop
379                                         # rev0, 2:
380         li      t3,MEMC_DDR_NCDL
383 break_ddr_ncdl:
384         andi    t4,t3,0xff              # t4:   g
385         srl     t2,t3,16                # t2:   wr
386         andi    t2,t2,0xff
387         srl     t3,t3,8                 # t3:   rd
388         andi    t3,t3,0xff
390 ddr_got_ncdl:
391         TRACE(0x17, wr)
392         TRACE(0x18, rd)
393         TRACE(0x19, g)
394         bal     ddr_do_init
395         nop
397         b       memprio_szmem
398         nop
400 memc_sdr_init:
401         beqz    t3,sdr_find_ncdl        # Do we have ncdl values?
402         nop
404         li      t4,-1
405         bne     t3,t4,break_sdr_ncdl
406         nop
408 sdr_find_ncdl:
410 /* Register usage */
411 #define pass_count      s0
412 #define clkdsum         s1
413 #define pass_countmax   s2
414 #define strmmax         s3
415 #define strdmax         s4
416 #define clkdmax         s5
417 #define clkdlim         s6
418 #define strm            t2
419 #define strd            t3
420 #define clkd            t4
422 #define STRMLIM         4
423 #define STRDLIM         16
424 #define CLKDLIM         128
425 #define CLKDLIM_IC      256
427         /* Initialize counter & saved values */
428         move    pass_countmax,zero
429         move    strmmax,zero
430         move    strdmax,zero
431         li      clkdlim,CLKDLIM
433         and     strm,t0,0x2000          /* Test for internal clock (Using strm as a temp) */
434         beqz    strm,strmloop
435         nop
437         li      clkdlim,CLKDLIM_IC
439         move    strm,zero               /* strm loop */
440 strmloop:
441         move    strd,zero
442 strdloop:
443         move    pass_count,zero
444         move    clkdsum,zero
445         move    clkd,zero
447         /* Inner loop:  call sdr_do_init to re-initialize and the test mem */
448 clkdloop:
449         TRACE(0x1a, strm)
450         TRACE(0x1b, strd)
451         TRACE(0x1c, clkd)       
452         bal     sdr_do_init
453         nop
455         bal     test_mem
456         nop
458         TRACE(0x1d, v0)
459         beqz    v0,failclkd
460         nop
462         /* Memory is ok */
464         addi    pass_count,1
465         add     clkdsum,clkdsum,clkd
466         TRACE(0x1e, pass_count)
467         TRACE(0x1f, clkdsum)
468         b       nextclkd
469         nop
471 failclkd:
472         bnez    pass_count,clkdout      # End of passing range, leave clkd loop
473         nop
475 nextclkd:
476         addi    clkd,clkd,1
477         blt     clkd,clkdlim,clkdloop
478         nop
480 clkdout:
481         /* If no passing values, skip to next strm */
482         beqz    pass_count,nextstrm
483         nop
485         /* If this is a new max, Save the values */
486         ble     pass_count,pass_countmax,nextstrd
487         nop
489         move    pass_countmax,pass_count
490         div     zero,clkdsum,pass_count
491         mflo    clkdmax
492         move    strdmax,strd
493         move    strmmax,strm
494         TRACE(0x20, pass_count)
495         TRACE(0x21, clkdmax)
496         TRACE(0x22, strdmax)
497         TRACE(0x23, strmmax)
499 nextstrd:
500         addi    strd,strd,1
501         blt     strd,STRDLIM,strdloop
502         nop
504 nextstrm:
505         addi    strm,strm,1
506         blt     strm,STRMLIM,strmloop
507         nop
509         /* All done, program the new ncdl values */
510         
511         TRACE(0x24, pass_count)
512         TRACE(0x25, clkdmax)
513         TRACE(0x26, strdmax)
514         TRACE(0x27, strmmax)
516         beqz    pass_countmax,1f
517         nop
519         move    clkd,clkdmax
520         move    strd,strdmax
521         move    strm,strmmax
522         b       sdr_got_ncdl
523         nop
525         /* No passing values, panic! (use defaults) */
527         li      t3,MEMC_SDR1_NCDL       # If rev1:
528         beq     v1,1,2f
529         nop
530                                         # rev0, 2:
531         li      t3,MEMC_SDR_NCDL
534 break_sdr_ncdl:
535         andi    t4,t3,0xff              # t4:   cd
536         srl     t2,t3,16                # t2:   sm
537         andi    t2,t2,3                 #       sm is 2 bits only
538         srl     t3,t3,8                 # t3:   sd
539         andi    t3,t3,0xf               #       sd is 4 bits
541 sdr_got_ncdl:
542         bal     sdr_do_init
543         nop
545         b       memprio_szmem
546         nop
548 sdram_init:
549         bnez    a2,1f                   # Already have the parms in t0, t1, t2
550         nop
552         /* Use default SDRAM parameters */
553         li      t0, SDRAM_INIT
554         li      t1, SDRAM_CONFIG
555         li      t2, SDRAM_REFRESH
557         /* Initialize SDRAM */
559         bal     sb_core_reset
560         li      a2,0
562         sw      t1, 4(a0)               # SDRAM config
563         li      a1, 0x000a
564         sw      a1, 0(a0)
565         li      a1, 0x000c
566         sw      a1, 0(a0)
567         li      a1, 0x0009
568         sw      a1, 0(a0)               # 1st refresh of power up sequence
569         sw      a1, 0(a0)               # 2nd refresh of power up sequence
570         sw      a1, 0(a0)               # 3rd refresh of power up sequence
571         sw      a1, 0(a0)               # 4th refresh of power up sequence
572         sw      a1, 0(a0)               # 5th refresh of power up sequence
573         sw      a1, 0(a0)               # 6th refresh of power up sequence
574         sw      a1, 0(a0)               # 7th refresh of power up sequence
575         sw      a1, 0(a0)               # 8th refresh of power up sequence
576         sw      t0, 0(a0)               # SDRAM init
577         sw      t2, 8(a0)               # SDRAM refresh
580         /* Change the memory priority inversion counter value */
581         /* Determine memory size and return */
582 memprio_szmem:
584 #ifdef APPLE
585         lw      t0, MEMC_PRIORINV(a0) 
586         li      t1, 0xFFFF0000
587         and     t0, t0, t1
588         ori     t0, t0, 0x1
589         sw      t0, MEMC_PRIORINV(a0)
590 #else
591         li      t0,KSEG1ADDR(SB_ENUM_BASE)      # is there a chipcommon core?
592         lw      t1,(SBCONFIGOFF + SBIDHIGH)(t0)
593         and     t1,t1,SBIDH_CC_MASK
594         srl     t1,t1,SBIDH_CC_SHIFT
595         bne     t1,SB_CC,0f
596         nop
597         lw      t1,CC_CHIPID(t0)                # is this BCM4785 chip?
598         and     t1,t1,CID_ID_MASK
599         bne     t1,BCM4785_CHIP_ID,0f
600         nop
601         lw      t0,MEMC_PRIORINV(a0)            # change PriorInvTim to 2
602         and     t0,t0,0xFFFF0000
603         ori     t0,t0,0x02
604         sw      t0,MEMC_PRIORINV(a0)
605 #endif
606 0:      lw      t0,(SBCONFIGOFF + SBIDHIGH)(a0)
607         and     t1,t0,SBIDH_CC_MASK
608         srl     t1,t1,SBIDH_CC_SHIFT
609         bne     t1,SB_SOCRAM,szmem_alias
610         nop
612         /* The socram core tells us how much memory there is */
613         lw      t1,SR_COREINFO(a0)
614         and     t0,t0,SBIDH_RC_MASK             /* Find corerev */
615         beq     t0,zero,crev0
617         /* Its corerev >= 1 */
618         and     t2,t1,SRCI_SRNB_MASK            /* Find number of blocks */
619         srl     t2,t2,SRCI_SRNB_SHIFT
620         and     t1,t1,SRCI_SRBSZ_MASK           /* Find block size */
621         addi    t1,t1,SR_BSZ_BASE
622         li      t0,1
623         sll     t0,t0,t1
624         mul     v0,t0,t2
625         jr      t6
626         nop
628 crev0:
629         and     t1,t1,SRCI_MS0_MASK
630         add     t1,t1,SR_MS0_BASE
631         li      v0,1
632         sll     v0,v0,t1
633         jr      t6
634         nop
635         
636 szmem_alias:
637         li      t0,KSEG1
638         li      t2,0xaa55beef
639         sw      zero,0(t0)
640         li      v0,(1 << 20)
642 1:      or      t0,v0,KSEG1
643         sw      t2,0(t0)
644         li      t0,KSEG1
645         lw      t1,0(t0)
646         beq     t1,t2,done
647         nop
649         sll     v0,v0,1
650         bne     v0,(128 << 20),1b
651         nop
652         /* Didn't find an alias, must be 128MB */
654 done:
655         jr      t6      
656         nop
659         /*
660          * Test memory
661          *
662          * Uses arg in t2(wr/sd), t3(rd/sm) and t4(g/clkd)
663          * Returns success (1) or failure (0) in v0
664          * Uses a1, a2, a3 & t5
665          */
666 test_mem:
667         /* Use t4 to generate a semi-random address in the second KB */
668         li      a1,KSEG1
669         addi    a2,t4,255
670         sll     a2,a2,2
671         add     a1,a1,a2
673         /* First set: 0 & its negation */
674         li      a2,0
675         sw      a2,0(a1)
676         not     a3,a2
677         sw      a3,4(a1)
678         nop
679         lw      t5,0(a1)
680         bne     a2,t5,bad_mem
681         nop
683         lw      t5,4(a1)
684         bne     a3,t5,bad_mem
685         nop
687         /* Second set: 0xaaaaaaaa & its negation */
688         li      a2,0xaaaaaaaa
689         sw      a2,0(a1)
690         not     a3,a2
691         sw      a3,4(a1)
692         nop
693         lw      t5,0(a1)
694         bne     a2,t5,bad_mem
695         nop
697         lw      t5,4(a1)
698         bne     a3,t5,bad_mem
699         nop
701         /* Third set: 0x12345678 & its negation */
702         li      a2,0x12345678
703         sw      a2,0(a1)
704         not     a3,a2
705         sw      a3,4(a1)
706         nop
707         lw      t5,0(a1)
708         bne     a2,t5,bad_mem
709         nop
711         lw      t5,4(a1)
712         bne     a3,t5,bad_mem
713         nop
715         /* Fourth set: the ncdl & its negation */
716         sll     a2,t2,8
717         or      a2,t3
718         sll     a2,a2,8
719         or      a2,t4
720         sw      a2,0(a1)
721         not     a3,a2
722         sw      a3,4(a1)
723         nop
724         lw      t5,0(a1)
725         bne     a2,t5,bad_mem
726         nop
728         lw      t5,4(a1)
729         bne     a3,t5,bad_mem
730         nop
732         /* Fifth set: the CPU count register & its negation */
733         mfc0    a2,$9
734         sw      a2,0(a1)
735         not     a3,a2
736         sw      a3,4(a1)
737         nop
738         lw      t5,0(a1)
739         bne     a2,t5,bad_mem
740         nop
742         lw      t5,4(a1)
743         bne     a3,t5,bad_mem
744         nop
746         jr      ra
747         li      v0,1
749 bad_mem:
750         jr      ra
751         li      v0,0
754         /* Do an init of the memc core for ddr
755          *      a0:     memc core pointer
756          *      t0:     memc config value
757          *      t1:     memc mode value
758          *      t2:     memc wr ncdl value
759          *      t3:     memc rd ncdl value
760          *      t4:     memc g ncdl value
761          *
762          * Uses a1, a2, t7, t8, t9 (here and by calling sb_core_reset)
763          */
764 ddr_do_init:
766         /* Save return address */
767         move    t7,ra
769         bal     sb_core_reset
770         li      a1,0
772         li      a1,MEMC_CONFIG_INIT
773         or      a1,a1,t0
774         lui     a2, 0x8                 # set DQMGate for memc rev 4 or more
775         or      a1, a1, a2
776         sw      a1,MEMC_CONFIG(a0)
778         li      a1,MEMC_DRAMTIM25_INIT  # Assume CAS latency of 2.5
779         andi    t8,t1,0xf0              # Find out the CAS latency
780         bne     t8,0x20,1f
781         nop
782         li      a1,MEMC_DRAMTIM2_INIT   # CAS latency is 2
783 1:      
784         sw      a1,MEMC_DRAMTIM(a0)
786 #ifndef BCM_ATE
787         li      t8,KSEG1ADDR(SB_ENUM_BASE)      # Get package options
788         lw      a1,CC_CHIPID(t8)                # Get chipid
789         li      t9,CID_PKG_MASK                 # Check package options
790         and     a1,a1,t9
791         srl     a1,a1,CID_PKG_SHIFT
792         addi    t8,SBCONFIGOFF                  # Get corerev for chipcommon
793         lw      a2,SBIDHIGH(t8)
794         li      t8,SBIDH_RCE_MASK
795         and     t8,t8,a2
796         srl     t8,SBIDH_RCE_SHIFT
797         li      t9,SBIDH_RC_MASK
798         and     t9,t9,a2
799         or      t8,t8,t9
800         bge     t8,10,1f                        # If ccrev is >= 10 use 4bit pkg opt
801         nop
802         ori     a1,8                            #  else add a bit to the 3bit field
804         beq     a1,HDLSIM_PKG_ID,hdlsim         # Special case for hdl sim:
805         nop
807         li      t8,KSEG1ADDR(SB_ENUM_BASE)      # Get chipid again
808         lw      a2,CC_CHIPID(t8)
809         li      t9,BCM5350_CHIP_ID              # 5350 ChipID
810         li      t8,CID_ID_MASK
811         and     t8,t8,a2
812         bne     t8,t9,notsim                    # if not 5350keep going
813         nop
815         bne     a1,(8 | HDLSIM5350_PKG_ID),notsim       # If 5350, is it (3/4-bit) vsim?
816         nop
817 #endif  /* !BCM_ATE */
819 hdlsim:
820         li      a1,MEMC_RDNCDLCOR_SIMINIT       #  Fixed 0xf6 rdncdl and no inits
821         sw      a1,MEMC_RDNCDLCOR(a0)           #  of wrncdl, dqsgate and miscdly.
823 #ifndef BCM_ATE
824         b       simskip
825         nop
827 notsim: andi    t8,t3,0xff
828         sll     a1,t8,8                 # Replicate rd ncdl 4 times
829         or      a1,a1,t8
830         sll     t8,a1,16
831         or      t8,t8,a1
832         li      a1,MEMC_RDNCDLCOR_INIT
833         or      a1,a1,t8
834         sw      a1,MEMC_RDNCDLCOR(a0)
836         li      a1,MEMC_1_WRNCDLCOR_INIT # If rev1:
837         beq     v1,1,1f
838         nop
839                                         # rev0, 2
840         li      a1,MEMC_WRNCDLCOR_INIT
842         andi    t8,t2,0xff
843         or      a1,a1,t8
844         sw      a1,MEMC_WRNCDLCOR(a0)
846         li      a1,MEMC_DQSGATENCDL_INIT
847         andi    t8,t4,0xff
848         or      a1,a1,t8
849         sw      a1,MEMC_DQSGATENCDL(a0)
851         li      a1,MEMC_1_MISCDLYCTL_INIT # If rev1:
852         beq     v1,1,2f
853         nop
854                                         # rev0,2
855         li      a1,MEMC_MISCDLYCTL_INIT
857         sw      a1,MEMC_MISCDLYCTL(a0)
858 #endif  /* !BCM_ATE */
860 simskip:
861         li      a1,MEMC_NCDLCTL_INIT
862         sw      a1,MEMC_NCDLCTL(a0)
864         li      a1,MEMC_CONTROL_INIT0
865         sw      a1,MEMC_CONTROL(a0)
867         li      a1,MEMC_CONTROL_INIT1
868         sw      a1,MEMC_CONTROL(a0)
870         li      a1,MEMC_MODEBUF_INIT0
871         sw      a1,MEMC_MODEBUF(a0)
873         li      a1,MEMC_CONTROL_INIT2
874         sw      a1,MEMC_CONTROL(a0)
876         li      a1,MEMC_MODEBUF_INIT1
877         or      a1,a1,t1
878         sw      a1,MEMC_MODEBUF(a0)
880         li      a1,MEMC_CONTROL_INIT3
881         sw      a1,MEMC_CONTROL(a0)
883         li      a1,MEMC_CONTROL_INIT4
884         sw      a1,MEMC_CONTROL(a0)
886         li      a1,MEMC_CONTROL_INIT5
887         sw      a1,MEMC_CONTROL(a0)
888         lw      a1,MEMC_CONTROL(a0)
889         lw      a1,MEMC_CONTROL(a0)
890         lw      a1,MEMC_CONTROL(a0)
892         li      a1,MEMC_CONTROL_INIT5
893         sw      a1,MEMC_CONTROL(a0)
894         lw      a1,MEMC_CONTROL(a0)
895         lw      a1,MEMC_CONTROL(a0)
896         lw      a1,MEMC_CONTROL(a0)
898         li      a1,MEMC_REFRESH_INIT
899         sw      a1,MEMC_REFRESH(a0)
900         
901         li      a1,MEMC_MODEBUF_INIT2
902         or      a1,a1,t1
903         sw      a1,MEMC_MODEBUF(a0)
905         li      a1,MEMC_CONTROL_INIT6
906         sw      a1,MEMC_CONTROL(a0)
908         li      a1,MEMC_CONTROL_INIT7
909         sw      a1,MEMC_CONTROL(a0)
911         /* Wait for SDRAM controller to refresh.
912          * We want 8uS delay.
913          */
914         li      t8,50
915 1:      lw      a1,(SBCONFIGOFF + SBIDLOW)(a0)
916         lw      a1,(SBCONFIGOFF + SBIDHIGH)(a0)
918         bnez    t8,1b
919         subu    t8,1
921         jr      t7
922         nop
924         /* Do an init of the memc core for sdr
925          *      a0:     memc core pointer
926          *      t0:     memc config value
927          *      t1:     memc mode value
928          *      t2:     memc strobe mode ncdl value
929          *      t3:     memc strobe delay ncdl value
930          *      t4:     memc clock delay ncdl value
931          *
932          * Uses a1, t7, t8, t9 (here and by calling sb_core_reset)
933          */
934 sdr_do_init:
936         /* Save return address */
937         move    t7,ra
939         bal     sb_core_reset
940         li      a1,0x40
942         /* Initialize SDRAM */
943         li      a1,MEMC_SD_CONFIG_INIT
944         or      a1,a1,t0
945         sw      a1,MEMC_CONFIG(a0)
947         li      a1,MEMC_SD_DRAMTIM3_INIT # Assume CAS latency of 3
948         andi    t8,t1,0xf0              # Find out the CAS latency
949         bne     t8,0x20,1f
950         nop
951         li      a1,MEMC_SD_DRAMTIM2_INIT # CAS latency is 2
952 1:      
953         sw      a1,MEMC_DRAMTIM(a0)
955         andi    t8,t4,0xff
956         ble     t8,MEMC_CD_THRESHOLD,1f # if (cd <= MEMC_CD_THRESHOLD) rd = cd
957         nop
959         li      t8,MEMC_CD_THRESHOLD    # else rd = MEMC_CD_THRESHOLD
961 1:                                      # t8 is now rd
962         sll     a1,t8,8                 #  .. replicate it 4 times
963         or      a1,a1,t8
964         sll     t8,a1,16
965         or      t8,t8,a1
966         li      a1,MEMC_SD_RDNCDLCOR_INIT
967         or      a1,a1,t8
968         sw      a1,MEMC_RDNCDLCOR(a0)
970         li      a1,MEMC_SD1_WRNCDLCOR_INIT # rev1
971         beq     v1,1,1f
972         nop
974         li      a1,MEMC_SD_WRNCDLCOR_INIT # rev0, 2
976         li      t8,0
977         ble     t4,MEMC_CD_THRESHOLD,2f # if (cd <= MEMC_CD_THRESHOLD) wr = 0
978         nop
979         
980         andi    t8,t4,0xff              # else wr = cd - MEMC_CD_THRESHOLD
981         sub     t8,t8,MEMC_CD_THRESHOLD
982         andi    t8,t8,0xff
984 2:                                      # t8 is now wr, a0 is extra bits
985         or      a1,a1,t8
986         sw      a1,MEMC_WRNCDLCOR(a0)
988         andi    t8,t2,3
989         sll     a1,t8,28
990         andi    t8,t3,0xf
991         sll     t8,t8,24
992         or      t8,t8,a1
993         li      a1,MEMC_SD1_MISCDLYCTL_INIT
994         beq     v1,1,3f                 # If rev1:
995         nop
996                                         # rev0, 2:
997         li      a1,MEMC_SD_MISCDLYCTL_INIT
999         or      a1,a1,t8
1000         sw      a1,MEMC_MISCDLYCTL(a0)
1002         li      a1,MEMC_SD_CONTROL_INIT0
1003         sw      a1,MEMC_CONTROL(a0)
1005         li      a1,MEMC_SD_CONTROL_INIT1
1006         sw      a1,MEMC_CONTROL(a0)
1008         li      a1,MEMC_SD_CONTROL_INIT2
1009         sw      a1,MEMC_CONTROL(a0)
1010         lw      a1,MEMC_CONTROL(a0)
1011         lw      a1,MEMC_CONTROL(a0)
1012         lw      a1,MEMC_CONTROL(a0)
1014         li      a1,MEMC_SD_CONTROL_INIT2
1015         sw      a1,MEMC_CONTROL(a0)
1016         lw      a1,MEMC_CONTROL(a0)
1017         lw      a1,MEMC_CONTROL(a0)
1018         lw      a1,MEMC_CONTROL(a0)
1020         li      a1,MEMC_SD_CONTROL_INIT2
1021         sw      a1,MEMC_CONTROL(a0)
1022         lw      a1,MEMC_CONTROL(a0)
1023         lw      a1,MEMC_CONTROL(a0)
1024         lw      a1,MEMC_CONTROL(a0)
1026         li      a1,MEMC_SD_REFRESH_INIT
1027         sw      a1,MEMC_REFRESH(a0)
1029         li      a1,MEMC_SD_MODEBUF_INIT
1030         or      a1,a1,t1
1031         sw      a1,MEMC_MODEBUF(a0)
1033         li      a1,MEMC_SD_CONTROL_INIT3
1034         sw      a1,MEMC_CONTROL(a0)
1036         li      a1,MEMC_SD_CONTROL_INIT4
1037         sw      a1,MEMC_CONTROL(a0)
1039         li      t8,50
1040 1:      lw      a1,(SBCONFIGOFF + SBIDLOW)(a0)
1041         lw      a1,(SBCONFIGOFF + SBIDHIGH)(a0)
1042         bnez    t8,1b
1043         subu    t8,1
1045         jr      t7
1046         nop
1049         /* Special sb_core_reset that makes sure the first time
1050          * clock is enabled, address line 6 is in the state specified
1051          * by a1.
1052          *
1053          * a0:  Core pointer
1054          * a1:  0x40 if a6 needs to be 1, 0 otherwise
1055          * uses t8, t9
1056          */
1058         .align 6
1060 sb_core_reset:
1062         /* Save return address */
1063         move    t9,ra
1064         
1065         /* run uncached */
1066         bal     kseg1_switch
1067         nop                                
1069         /* Figure out our address */
1070         bal     h0
1071         nop
1072 h0:     add     t8,ra,24                # This is (h1 - h0)
1073         andi    t8,t8,0x40
1074         bne     t8,a1,alt_core_reset
1075         nop
1077         /* Set reset while enabling the clock */
1078         li      t8,(SBTML_FGC | SBTML_CLK | SBTML_RESET)
1079 h1:     sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1080         b       cont
1081         nop
1083         /* Now pad to 0x40: We want (h2 - h1) == 0x40 and there
1084          * are 5 instructions inbetween them.
1085          */
1086         .space  (0x40 - 20)
1088 alt_core_reset:
1089         /* Set reset while enabling the clock */
1090         li      t8,(SBTML_FGC | SBTML_CLK | SBTML_RESET)
1091 h2:     sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1093 cont:
1094         /* Read back and delay */
1095         lw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1096         lw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1097         lw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1099         /* Clear reset */
1100         li      t8, (SBTML_FGC | SBTML_CLK)
1101         sw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1103         /* Read back and delay */
1104         lw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1105         lw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1106         lw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1108         /* Leave clock enabled */
1109         li      t8, SBTML_CLK
1110         sw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1112         /* Read back and delay */
1113         lw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1114         lw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1115         lw      t8, (SBCONFIGOFF + SBTMSTATELOW)(a0)
1117         jr      t9
1118         nop
1120         
1121 kseg1_switch:
1122         and     ra,ra,PHYSADDR_MASK
1123         or      ra,ra,KSEG1
1124         jr      ra
1125         nop 
1126         
1127         .set    reorder
1128         END(board_draminit)