Broadcom SDK and wireless driver: another attempt to update to ver. 5.10.147.0
[tomato.git] / release / src-rt / shared / sbsdram.S
blob5584b419efe0dc027977d8fb17ff3c5cde92a7a0
1 /*
2  * BCM47XX Sonics SiliconBackplane SDRAM/MEMC core initialization
3  *
4  * Copyright (C) 2009, 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: sbsdram.S,v 1.43.2.2 2008/11/14 18:18:20 Exp $
13  */
15 #include <hndsoc.h>
16 #include <sbmemc.h>
17 #include <sbsocram.h>
18 #include <sbchipc.h>
19 #include <bcmdevs.h>
20 #include <bcmnvram.h>
22 #include <mipsinc.h>
24 /* #define      DEBUG_SBSDRAM   1 */
25 #ifdef  DEBUG_SBSDRAM
26         /* Trace function
27          * Write to prog space so we can see it in
28          * the Logic Analizer
29          */
30 #define LATRACEINIT             \
31         li      k0,0xb8000120;  \
32         li      k1,0x11;        \
33         sw      k1,0(k0);       \
34         li      k1,0x01020108;  \
35         sw      k1,4(k0);       \
36         li      k0,0xbb000000
38 #define LATRACE(num, reg)       \
39         sw      reg,((num & 0xff) << 4)(k0)
41 #else
42 #define LATRACEINIT
43 #define LATRACE(num, reg)
44 #endif  /* DEBUG_SBSDRAM */
45 /* Debug macro - write a number to a chipc reg - use it with caution,
46  *  it changes k0 and k1 registers.
47  */
48 #define TRACEINIT(x)
49 #define TRACE(x)
50 #define TRACE2(x)
53  * Register usage within this file:
54  *
55  *              top     ncdlsearch      test_mem        Xdr_do_init     sb_reset_core
56  *      v0:     retval                  retval
57  *      v1:     corerev -               -               corerev         -
58  *      a0:     coreptr coreptr         -               coreptr         coreptr
59  *      a1:             x               x               x               sdr/ddr flag
60  *      a2:     NVRAM                   x               x
61  *      a3:                             x
62  *      t0:     -       -                               config
63  *      t1:     -       -                               mode
64  *      t2:     -       wr/strm         off             wr/strm
65  *      t3:     -       rd/strd                         rd/strd
66  *      t4:     -       g/clkd                          g/clkd
67  *      t5:                             x
68  *      t6:     retaddr -                               -               -
69  *      t7:     -       -                               retaddr         -
70  *      s0:             pass_count                      -               -
71  *      s1:             wrsum/clkdsum                   -               -
72  *      s2:             rdsum/pass_countmax             -               -
73  *      s3:             gsum/strmmax                    -               -
74  *      s4:             wrlim/stdmmax                   -               -
75  *      s5:             rdlim/clkdmax                   -               -
76  *      s6:             glim/clkdlim                    -               -
77  *      s7:             dll                             -               -
78  *      t8:     -       -                               x               tmp
79  *      t9:     -       -                               x               retaddr
80  *      k0:     trace   trace           trace           -               -
81  *      k1:     trace   trace           trace           -               -
82  *      gp:     PRESERVED
83  *      sp:
84  *      s8:     -       step                            -               -
85  *      ra:
86  */
89         .text
90         .set    mips32
92         LEAF(sb_draminit)
93         .set    noreorder
95         LATRACEINIT
96         TRACEINIT(0x425300)
98         /* Save return address */
99         move    t6,ra
101         /* Scan for a memory controller */
102         move    a0,s2
103 1:      lw      v1,(SBCONFIGOFF + SBIDHIGH)(a0)
104         and     a1,v1,SBIDH_CC_MASK
105         srl     a1,a1,SBIDH_CC_SHIFT
106         beq     a1,MEMC_CORE_ID,foundctrl
107         nop
108         beq     a1,SOCRAM_CORE_ID,foundctrl
109         nop
110         addu    a0,SI_CORE_SIZE
111         bne     a1,(SBIDH_CC_MASK >> SBIDH_CC_SHIFT),1b
112         nop
114         /* No memory controller */
115         li      v0,-1
116         jr      t6
117         nop
119 foundctrl:
120         TRACE(0x425301)
121         /* If we are already in RAM, just go and size it */
122         bal     1f
123         nop
124 1:      li      t0,PHYSADDR_MASK
125         and     t0,t0,ra
126         li      t1,SI_FLASH1
127         blt     t0,t1,memprio_szmem
128         nop
130         /* For socram we don't need any nvram parms, just do a core reset */
131 socram_init:
132         bne     a1,SOCRAM_CORE_ID,read_nvram
133         nop
134         TRACE(0x425302)
135         bal     sb_core_reset
136         li      a2,0
137         /* and size memory */
138         b       memprio_szmem
139         nop
141 read_nvram:
142         TRACE(0x425303)
143         /* Find NVRAM (a2) */
144         /* 1: Isolate memc's corerev in v1 */
145         and     t2,v1,SBIDH_RCE_MASK
146         srl     t2,t2,SBIDH_RCE_SHIFT
147         and     v1,v1,SBIDH_RC_MASK
148         or      v1,t2
150         /* 1.5: 5365a0 lies about its revision, it is really 1 */
151         bnez    v1,1f
152         nop
154         TRACE(0x425304)
155         li      t0,KSEG1ADDR(SI_ENUM_BASE)      # Is there a chipcommon core?
156         lw      t1,CC_CHIPID(t0)                # Get chipid
157         andi    t1,CID_ID_MASK                  # Check chipid
158         bne     t1,BCM5365_CHIP_ID,1f
159         nop
160         li      v1,1
162         /* 2: find_nvram, use the 32MB window */
163 1:      li      t2,KSEG1ADDR(SI_FLASH2 - NVRAM_SPACE)
164         li      t4,SI_FLASH2_SZ
165         li      t3,FLASH_MIN 
166         li      t0,NVRAM_MAGIC
168 2:      add     a2,t2,t3
169         lw      t1,0(a2)
170         beq     t0,t1,read_parms
171         nop
173         TRACE(0x425306)
174         sll     t3,t3,1
175         ble     t3,t4,2b
176         nop
178         /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
179         li      a2,KSEG1ADDR(SI_FLASH1 + 0x1000)
180         lw      t1,0(a2)
181         beq     t0,t1,read_parms
182         nop
184         TRACE(0x425307)
185         li      a2,KSEG1ADDR(SI_FLASH1 + 0x400)
186         lw      t1,0(a2)
187         beq     t0,t1,read_parms
188         nop
190         TRACE(0x425308)
191         b       memc_init                       # No NVRAM
192         li      a2, 0
194 read_parms:
195         /* Get SDRAM parameters (t0, t1, t2) from NVRAM (a2) */
196         TRACE(0x425309)
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 memc_init:
205         /* Initialize memc core */
206         TRACE(0x425309)
207         bnez    a2,1f                   # Already have the parms in
208         nop                             #  t0, t1, t2, t3
210         /* No nvram parms: assume DDRM16MX16X2 */
212         li      t0,MEMC_DDR_INIT
213         li      t1,MEMC_DDR_MODE
214         li      t3,MEMC_DDR1_NCDL       # If rev1 (4712):
215         beq     v1,1,1f
216         nop
217                                         # rev0, 2:
218         li      t3,MEMC_DDR_NCDL
221         andi    a3,t0,MEMC_CONFIG_DDR   # Is it ddr or sdr?
222         TRACE(0x42530a)
223         beqz    a3,memc_sdr_init
224         nop
226         /* Initialize DDR SDRAM */
227 memc_ddr_init:
228         beqz    t3,ddr_find_ncdl        # Do we have ncdl values? (0s)
229         nop
231         li      t4,-1                   # or ffs
232         bne     t3,t4,break_ddr_ncdl
233         nop
235 ddr_find_ncdl:
236         TRACE(0x42530b)
238 /* Register usage */
239 #define pass_count      s0
240 #define wrsum           s1
241 #define rdsum           s2
242 #define gsum            s3
243 #define wrlim           s4
244 #define rdlim           s5
245 #define glim            s6
246 #define dll             s7
247 #define step            s8
248 #define wr              t2
249 #define rd              t3
250 #define g               t4
252         /* Initialize counter & accumulators */
253         move    pass_count,zero
254         move    wrsum,zero
255         move    rdsum,zero
256         move    gsum,zero
258         /* Initialize with default values */
259         li      wr,5
260         li      rd,5
261         bal     ddr_do_init
262         li      g,10
264         /* Read dll value */
265         lw      dll,MEMC_NCDLCTL(a0)
266         LATRACE(0xc, dll)
267         andi    dll,dll,0xfe
268         srl     dll,dll,1
269         beqz    dll,memprio_szmem               /* If zero, leave the default values */
270         nop
272         move    wrlim,dll               /* dll value is lim for wr, rd and g */
273         move    rdlim,dll
274         move    glim,dll
275         LATRACE(0xd, wrlim)
276         LATRACE(0xe, rdlim)
277         LATRACE(0xf, glim)
279         addi    step,dll,15             /* step = (dll + 16 - 1) / 16 */
280         srl     step,step,4
281         LATRACE(0x10, step)
283         sub     wr,zero,dll             /* Negate dll as initial value */
284         move    rd,wr
285         move    g,wr
287         /* Inner loop:  call ddr_do_init to re-initialize and the test mem */
288 loop:
289         LATRACE(0x11, wr)
290         LATRACE(0x12, rd)
291         LATRACE(0x13, g)        
292         bal     ddr_do_init
293         nop
295         bal     test_mem
296         nop
298         LATRACE(0x14, v0)
299         beqz    v0,nextg
300         nop
302         /* Memory is ok */
304         addi    pass_count,1
305         add     wrsum,wrsum,wr
306         add     rdsum,rdsum,rd
307         add     gsum,gsum,g
308         LATRACE(0x15, pass_count)
309         LATRACE(0x16, wrsum)
310         LATRACE(0x17, rdsum)
311         LATRACE(0x18, gsum)
313         bne     wr,dll,1f
314         nop
315         sll     wrlim,dll,1
316         LATRACE(0x19, wrlim)
319         bne     rd,dll,2f
320         nop
321         sll     rdlim,dll,1
322         LATRACE(0x1a, rdlim)
325         bne     g,dll,nextg
326         nop
327         sll     glim,dll,1
328         LATRACE(0x1b, glim)
330 nextg:
331         add     g,g,step
332         ble     g,glim,loop
333         nop
334         sub     g,zero,dll
335         move    glim,dll
336         LATRACE(0x1c, g)
338         /* nextrd: */
339         add     rd,rd,step
340         ble     rd,rdlim,loop
341         nop
342         sub     rd,zero,dll
343         move    rdlim,dll
344         LATRACE(0x1d, rd)
346         /* nextwr: */
347         add     wr,wr,step
348         ble     wr,wrlim,loop
349         nop
351         /* All done, calculate average values and program them */
352         
353         LATRACE(0x1e, pass_count)
354         LATRACE(0x1f, wrsum)
355         LATRACE(0x20, rdsum)
356         LATRACE(0x21, gsum)
357         beqz    pass_count,1f
358         nop
360         div     zero,wrsum,pass_count
361         mflo    wr
363         div     zero,rdsum,pass_count
364         mflo    rd
366         div     zero,gsum,pass_count
367         mflo    g
369         b       ddr_got_ncdl
370         nop
372         /* No passing values, panic! (use defaults) */
374         li      t3,MEMC_DDR1_NCDL       # If rev1:
375         beq     v1,1,2f
376         nop
377                                         # rev0, 2:
378         li      t3,MEMC_DDR_NCDL
381 break_ddr_ncdl:
382         TRACE(0x425322)
383         andi    t4,t3,0xff              # t4:   g
384         srl     t2,t3,16                # t2:   wr
385         andi    t2,t2,0xff
386         srl     t3,t3,8                 # t3:   rd
387         andi    t3,t3,0xff
389 ddr_got_ncdl:
390         LATRACE(0x23, wr)
391         LATRACE(0x24, rd)
392         LATRACE(0x25, g)
393         bal     ddr_do_init
394         nop
396         b       memprio_szmem
397         nop
399 memc_sdr_init:
400         beqz    t3,sdr_find_ncdl        # Do we have ncdl values?
401         nop
403         li      t4,-1
404         bne     t3,t4,break_sdr_ncdl
405         nop
407 sdr_find_ncdl:
408         TRACE(0x425326)
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         LATRACE(0x27, strm)
450         LATRACE(0x28, strd)
451         LATRACE(0x29, clkd)     
452         bal     sdr_do_init
453         nop
455         bal     test_mem
456         nop
458         LATRACE(0x2a, v0)
459         beqz    v0,failclkd
460         nop
462         /* Memory is ok */
464         addi    pass_count,1
465         add     clkdsum,clkdsum,clkd
466         LATRACE(0x2b, pass_count)
467         LATRACE(0x2c, 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         LATRACE(0x2d, pass_count)
495         LATRACE(0x2e, clkdmax)
496         LATRACE(0x2f, strdmax)
497         LATRACE(0x30, 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         LATRACE(0x31, pass_count)
512         LATRACE(0x32, clkdmax)
513         LATRACE(0x33, strdmax)
514         LATRACE(0x34, 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         TRACE(0x425335)
536         andi    t4,t3,0xff              # t4:   cd
537         srl     t2,t3,16                # t2:   sm
538         andi    t2,t2,3                 #       sm is 2 bits only
539         srl     t3,t3,8                 # t3:   sd
540         andi    t3,t3,0xf               #       sd is 4 bits
542 sdr_got_ncdl:
543         bal     sdr_do_init
544         nop
546         /* Change the memory priority inversion counter value */
547         /* If an SOCRAM, determine memory size and return */
548 memprio_szmem:
549         TRACE(0x425337)
551 #ifdef APPLE
552         lw      t0, MEMC_PRIORINV(a0) 
553         li      t1, 0xFFFF0000
554         and     t0, t0, t1
555         ori     t0, t0, 0x1
556         sw      t0, MEMC_PRIORINV(a0)
557 #else
558         li      t0,KSEG1ADDR(SI_ENUM_BASE)      # is there a chipcommon core?
559         lw      t1,(SBCONFIGOFF + SBIDHIGH)(t0)
560         and     t1,t1,SBIDH_CC_MASK
561         srl     t1,t1,SBIDH_CC_SHIFT
562         bne     t1,CC_CORE_ID,0f
563         nop
564         lw      t1,CC_CHIPID(t0)                # is this BCM4785 chip?
565         and     t1,t1,CID_ID_MASK
566         bne     t1,BCM4785_CHIP_ID,0f
567         nop
568         lw      t0,MEMC_PRIORINV(a0)            # change PriorInvTim to 2
569         and     t0,t0,0xFFFF0000
570         ori     t0,t0,0x02
571         sw      t0,MEMC_PRIORINV(a0)
572 #endif
573 0:      TRACE(0x425338)
574         lw      t0,(SBCONFIGOFF + SBIDHIGH)(a0)
575         and     t1,t0,SBIDH_CC_MASK
576         srl     t1,t1,SBIDH_CC_SHIFT
577         beq     t1,SOCRAM_CORE_ID,1f
578         nop
579         jr      t6
580         li      v0,0
582         /* The socram core tells us how much memory there is */
583 1:      TRACE(0x425339)
584         lw      t1,SR_COREINFO(a0)
585         and     t0,t0,SBIDH_RC_MASK             /* Find corerev */
586         beq     t0,zero,crev0
588         /* Its corerev >= 1 */
589         and     t2,t1,SRCI_SRNB_MASK            /* Find number of blocks */
590         srl     t2,t2,SRCI_SRNB_SHIFT
591         and     t1,t1,SRCI_SRBSZ_MASK           /* Find block size */
592         addi    t1,t1,SR_BSZ_BASE
593         li      t0,1
594         sll     t0,t0,t1
595         mul     v0,t0,t2
596         jr      t6
597         nop
599 crev0:
600         and     t1,t1,SRCI_MS0_MASK
601         add     t1,t1,SR_MS0_BASE
602         li      v0,1
603         sll     v0,v0,t1
604         jr      t6
605         nop
607         /*
608          * Test memory
609          *
610          * Uses arg in t2(wr/sd), t3(rd/sm) and t4(g/clkd)
611          * Returns success (1) or failure (0) in v0
612          * Uses a1, a2, a3 & t5
613          */
614 test_mem:
615         /* Use t4 to generate a semi-random address in the second KB */
616         li      a1,KSEG1
617         addi    a2,t4,255
618         sll     a2,a2,2
619         add     a1,a1,a2
621         /* First set: 0 & its negation */
622         li      a2,0
623         sw      a2,0(a1)
624         not     a3,a2
625         sw      a3,4(a1)
626         nop
627         lw      t5,0(a1)
628         bne     a2,t5,bad_mem
629         nop
631         lw      t5,4(a1)
632         bne     a3,t5,bad_mem
633         nop
635         /* Second set: 0xaaaaaaaa & its negation */
636         li      a2,0xaaaaaaaa
637         sw      a2,0(a1)
638         not     a3,a2
639         sw      a3,4(a1)
640         nop
641         lw      t5,0(a1)
642         bne     a2,t5,bad_mem
643         nop
645         lw      t5,4(a1)
646         bne     a3,t5,bad_mem
647         nop
649         /* Third set: 0x12345678 & its negation */
650         li      a2,0x12345678
651         sw      a2,0(a1)
652         not     a3,a2
653         sw      a3,4(a1)
654         nop
655         lw      t5,0(a1)
656         bne     a2,t5,bad_mem
657         nop
659         lw      t5,4(a1)
660         bne     a3,t5,bad_mem
661         nop
663         /* Fourth set: the ncdl & its negation */
664         sll     a2,t2,8
665         or      a2,t3
666         sll     a2,a2,8
667         or      a2,t4
668         sw      a2,0(a1)
669         not     a3,a2
670         sw      a3,4(a1)
671         nop
672         lw      t5,0(a1)
673         bne     a2,t5,bad_mem
674         nop
676         lw      t5,4(a1)
677         bne     a3,t5,bad_mem
678         nop
680         /* Fifth set: the CPU count register & its negation */
681         mfc0    a2,$9
682         sw      a2,0(a1)
683         not     a3,a2
684         sw      a3,4(a1)
685         nop
686         lw      t5,0(a1)
687         bne     a2,t5,bad_mem
688         nop
690         lw      t5,4(a1)
691         bne     a3,t5,bad_mem
692         nop
694         jr      ra
695         li      v0,1
697 bad_mem:
698         jr      ra
699         li      v0,0
702         /* Do an init of the memc core for ddr
703          *      a0:     memc core pointer
704          *      t0:     memc config value
705          *      t1:     memc mode value
706          *      t2:     memc wr ncdl value
707          *      t3:     memc rd ncdl value
708          *      t4:     memc g ncdl value
709          *
710          * Uses a1, a2, t7, t8, t9 (here and by calling sb_core_reset)
711          */
712 ddr_do_init:
713         TRACE(0x42533a)
715         /* Save return address */
716         move    t7,ra
718         bal     sb_core_reset
719         li      a1,0
721         li      a1,MEMC_CONFIG_INIT
722         or      a1,a1,t0
723         lui     a2, 0x8                 # set DQMGate for memc rev 4 or more
724         or      a1, a1, a2
725         sw      a1,MEMC_CONFIG(a0)
727         li      a1,MEMC_DRAMTIM25_INIT          # Assume CAS latency of 2.5
728         andi    t8,t1,0xf0                      # Find out the CAS latency
729         bne     t8,0x20,1f
730         nop
731         li      a1,MEMC_DRAMTIM2_INIT           # CAS latency is 2
732 1:      
733         sw      a1,MEMC_DRAMTIM(a0)
735 #ifndef BCM_ATE
736         li      t8,KSEG1ADDR(SI_ENUM_BASE)      # Get package options
737         lw      a1,CC_CHIPID(t8)                # Get chipid
738         li      t9,CID_PKG_MASK                 # Check package options
739         and     a1,a1,t9
740         srl     a1,a1,CID_PKG_SHIFT
741         addi    t8,SBCONFIGOFF                  # Get corerev for chipcommon
742         lw      a2,SBIDHIGH(t8)
743         li      t8,SBIDH_RCE_MASK
744         and     t8,t8,a2
745         srl     t8,SBIDH_RCE_SHIFT
746         li      t9,SBIDH_RC_MASK
747         and     t9,t9,a2
748         or      t8,t8,t9
749         bge     t8,10,1f                        # If ccrev is >= 10 use 4bit pkg opt
750         nop
751         ori     a1,8                            #  else add a bit to the 3bit field
753         beq     a1,HDLSIM_PKG_ID,hdlsim         # Special case for hdl sim:
754         nop
756         li      t8,KSEG1ADDR(SI_ENUM_BASE)      # Get chipid again
757         lw      a2,CC_CHIPID(t8)
758         li      t9,BCM5350_CHIP_ID              # 5350 ChipID
759         li      t8,CID_ID_MASK
760         and     t8,t8,a2
761         bne     t8,t9,notsim                    # if not 5350keep going
762         nop
764         bne     a1,(8 | HDLSIM5350_PKG_ID),notsim       # If 5350, is it (3/4-bit) vsim?
765         nop
766 #endif  /* !BCM_ATE */
768 hdlsim:
769         li      a1,MEMC_RDNCDLCOR_SIMINIT       #  Fixed 0xf6 rdncdl and no inits
770         sw      a1,MEMC_RDNCDLCOR(a0)           #  of wrncdl, dqsgate and miscdly.
772 #ifndef BCM_ATE
773         b       simskip
774         nop
776 notsim: andi    t8,t3,0xff
777         sll     a1,t8,8                         # Replicate rd ncdl 4 times
778         or      a1,a1,t8
779         sll     t8,a1,16
780         or      t8,t8,a1
781         li      a1,MEMC_RDNCDLCOR_INIT
782         or      a1,a1,t8
783         sw      a1,MEMC_RDNCDLCOR(a0)
785         li      a1,MEMC_1_WRNCDLCOR_INIT # If rev1:
786         beq     v1,1,1f
787         nop
788                                         # rev0, 2
789         li      a1,MEMC_WRNCDLCOR_INIT
791         andi    t8,t2,0xff
792         or      a1,a1,t8
793         sw      a1,MEMC_WRNCDLCOR(a0)
795         li      a1,MEMC_DQSGATENCDL_INIT
796         andi    t8,t4,0xff
797         or      a1,a1,t8
798         sw      a1,MEMC_DQSGATENCDL(a0)
800         li      a1,MEMC_1_MISCDLYCTL_INIT # If rev1:
801         beq     v1,1,2f
802         nop
803                                         # rev0,2
804         li      a1,MEMC_MISCDLYCTL_INIT
806         sw      a1,MEMC_MISCDLYCTL(a0)
807 #endif  /* !BCM_ATE */
809 simskip:
810         li      a1,MEMC_NCDLCTL_INIT
811         sw      a1,MEMC_NCDLCTL(a0)
813         li      a1,MEMC_CONTROL_INIT0
814         sw      a1,MEMC_CONTROL(a0)
816         li      a1,MEMC_CONTROL_INIT1
817         sw      a1,MEMC_CONTROL(a0)
819         li      a1,MEMC_MODEBUF_INIT0
820         sw      a1,MEMC_MODEBUF(a0)
822         li      a1,MEMC_CONTROL_INIT2
823         sw      a1,MEMC_CONTROL(a0)
825         li      a1,MEMC_MODEBUF_INIT1
826         or      a1,a1,t1
827         sw      a1,MEMC_MODEBUF(a0)
829         li      a1,MEMC_CONTROL_INIT3
830         sw      a1,MEMC_CONTROL(a0)
832         li      a1,MEMC_CONTROL_INIT4
833         sw      a1,MEMC_CONTROL(a0)
835         li      a1,MEMC_CONTROL_INIT5
836         sw      a1,MEMC_CONTROL(a0)
837         lw      a1,MEMC_CONTROL(a0)
838         lw      a1,MEMC_CONTROL(a0)
839         lw      a1,MEMC_CONTROL(a0)
841         li      a1,MEMC_CONTROL_INIT5
842         sw      a1,MEMC_CONTROL(a0)
843         lw      a1,MEMC_CONTROL(a0)
844         lw      a1,MEMC_CONTROL(a0)
845         lw      a1,MEMC_CONTROL(a0)
847         li      a1,MEMC_REFRESH_INIT
848         sw      a1,MEMC_REFRESH(a0)
849         
850         li      a1,MEMC_MODEBUF_INIT2
851         or      a1,a1,t1
852         sw      a1,MEMC_MODEBUF(a0)
854         li      a1,MEMC_CONTROL_INIT6
855         sw      a1,MEMC_CONTROL(a0)
857         li      a1,MEMC_CONTROL_INIT7
858         sw      a1,MEMC_CONTROL(a0)
860         /* Wait for SDRAM controller to refresh.
861          * We want 8uS delay.
862          */
863         li      t8,50
864 1:      lw      a1,(SBCONFIGOFF + SBIDLOW)(a0)
865         lw      a1,(SBCONFIGOFF + SBIDHIGH)(a0)
867         bnez    t8,1b
868         subu    t8,1
870         jr      t7
871         nop
873         /* Do an init of the memc core for sdr
874          *      a0:     memc core pointer
875          *      t0:     memc config value
876          *      t1:     memc mode value
877          *      t2:     memc strobe mode ncdl value
878          *      t3:     memc strobe delay ncdl value
879          *      t4:     memc clock delay ncdl value
880          *
881          * Uses a1, t7, t8, t9 (here and by calling sb_core_reset)
882          */
883 sdr_do_init:
884         TRACE(0x42533b)
886         /* Save return address */
887         move    t7,ra
889         bal     sb_core_reset
890         li      a1,0x40
892         /* Initialize for SDR SDRAM */
893         li      a1,MEMC_SD_CONFIG_INIT
894         or      a1,a1,t0
895         sw      a1,MEMC_CONFIG(a0)
897         li      a1,MEMC_SD_DRAMTIM3_INIT # Assume CAS latency of 3
898         andi    t8,t1,0xf0              # Find out the CAS latency
899         bne     t8,0x20,1f
900         nop
901         li      a1,MEMC_SD_DRAMTIM2_INIT # CAS latency is 2
902 1:      
903         sw      a1,MEMC_DRAMTIM(a0)
905         andi    t8,t4,0xff
906         ble     t8,MEMC_CD_THRESHOLD,1f # if (cd <= MEMC_CD_THRESHOLD) rd = cd
907         nop
909         li      t8,MEMC_CD_THRESHOLD    # else rd = MEMC_CD_THRESHOLD
911 1:                                      # t8 is now rd
912         sll     a1,t8,8                 #  .. replicate it 4 times
913         or      a1,a1,t8
914         sll     t8,a1,16
915         or      t8,t8,a1
916         li      a1,MEMC_SD_RDNCDLCOR_INIT
917         or      a1,a1,t8
918         sw      a1,MEMC_RDNCDLCOR(a0)
920         li      a1,MEMC_SD1_WRNCDLCOR_INIT # rev1
921         beq     v1,1,1f
922         nop
924         li      a1,MEMC_SD_WRNCDLCOR_INIT # rev0, 2
926         li      t8,0
927         ble     t4,MEMC_CD_THRESHOLD,2f # if (cd <= MEMC_CD_THRESHOLD) wr = 0
928         nop
929         
930         andi    t8,t4,0xff              # else wr = cd - MEMC_CD_THRESHOLD
931         sub     t8,t8,MEMC_CD_THRESHOLD
932         andi    t8,t8,0xff
934 2:                                      # t8 is now wr, a0 is extra bits
935         or      a1,a1,t8
936         sw      a1,MEMC_WRNCDLCOR(a0)
938         andi    t8,t2,3
939         sll     a1,t8,28
940         andi    t8,t3,0xf
941         sll     t8,t8,24
942         or      t8,t8,a1
943         li      a1,MEMC_SD1_MISCDLYCTL_INIT
944         beq     v1,1,3f                 # If rev1:
945         nop
946                                         # rev0, 2:
947         li      a1,MEMC_SD_MISCDLYCTL_INIT
949         or      a1,a1,t8
950         sw      a1,MEMC_MISCDLYCTL(a0)
952         li      a1,MEMC_SD_CONTROL_INIT0
953         sw      a1,MEMC_CONTROL(a0)
955         li      a1,MEMC_SD_CONTROL_INIT1
956         sw      a1,MEMC_CONTROL(a0)
958         li      a1,MEMC_SD_CONTROL_INIT2
959         sw      a1,MEMC_CONTROL(a0)
960         lw      a1,MEMC_CONTROL(a0)
961         lw      a1,MEMC_CONTROL(a0)
962         lw      a1,MEMC_CONTROL(a0)
964         li      a1,MEMC_SD_CONTROL_INIT2
965         sw      a1,MEMC_CONTROL(a0)
966         lw      a1,MEMC_CONTROL(a0)
967         lw      a1,MEMC_CONTROL(a0)
968         lw      a1,MEMC_CONTROL(a0)
970         li      a1,MEMC_SD_CONTROL_INIT2
971         sw      a1,MEMC_CONTROL(a0)
972         lw      a1,MEMC_CONTROL(a0)
973         lw      a1,MEMC_CONTROL(a0)
974         lw      a1,MEMC_CONTROL(a0)
976         li      a1,MEMC_SD_REFRESH_INIT
977         sw      a1,MEMC_REFRESH(a0)
979         li      a1,MEMC_SD_MODEBUF_INIT
980         or      a1,a1,t1
981         sw      a1,MEMC_MODEBUF(a0)
983         li      a1,MEMC_SD_CONTROL_INIT3
984         sw      a1,MEMC_CONTROL(a0)
986         li      a1,MEMC_SD_CONTROL_INIT4
987         sw      a1,MEMC_CONTROL(a0)
989         li      t8,50
990 1:      lw      a1,(SBCONFIGOFF + SBIDLOW)(a0)
991         lw      a1,(SBCONFIGOFF + SBIDHIGH)(a0)
992         bnez    t8,1b
993         subu    t8,1
995         jr      t7
996         nop
999         /* Special sb_core_reset that makes sure the first time
1000          * clock is enabled, address line 6 is in the state specified
1001          * by a1.
1002          *
1003          * a0:  Core pointer
1004          * a1:  0x40 if a6 needs to be 1, 0 otherwise
1005          * uses t8, t9
1006          */
1008         .align 6
1010 sb_core_reset:
1012         /* Save return address */
1013         move    t9,ra
1014         
1015         /* run uncached */
1016         bal     kseg1_switch
1017         nop                                
1019         /* Figure out our address */
1020         bal     h0
1021         nop
1022 h0:     add     t8,ra,24                # This is (h1 - h0)
1023         andi    t8,t8,0x40
1024         bne     t8,a1,alt_core_reset
1025         nop
1027         /* Set reset while enabling the clock */
1028         li      t8,(((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_RESET)
1029 h1:     sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1030         b       cont
1031         nop
1033         /* Now pad to 0x40: We want (h2 - h1) == 0x40 and there
1034          * are 5 instructions inbetween them.
1035          */
1036         .space  (0x40 - 20)
1038 alt_core_reset:
1039         /* Set reset while enabling the clock */
1040         li      t8,(((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_RESET)
1041 h2:     sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1043 cont:
1044         /* Read back and delay */
1045         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1046         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1047         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1049         /* Clear reset */
1050         li      t8,((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)
1051         sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1053         /* Read back and delay */
1054         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1055         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1056         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1058         /* Leave clock enabled */
1059         li      t8,(SICF_CLOCK_EN << SBTML_SICF_SHIFT)
1060         sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1062         /* Read back and delay */
1063         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1064         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1065         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1067         jr      t9
1068         nop
1070         
1071 kseg1_switch:
1072         and     ra,ra,PHYSADDR_MASK
1073         or      ra,ra,KSEG1
1074         jr      ra
1075         nop 
1076         
1077         .set    reorder
1078         END(sb_draminit)