GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / shared / sbsdram.S
blob71a21523b086b399e66d095eef7768c6eff750df
1 /*
2  * BCM47XX Sonics SiliconBackplane SDRAM/MEMC core initialization
3  *
4  * Copyright (C) 2012, Broadcom Corporation. All Rights Reserved.
5  * 
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  * 
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * $Id: sbsdram.S,v 1.45 2008-11-14 17:51:32 $
19  */
21 #include <hndsoc.h>
22 #include <sbmemc.h>
23 #include <sbsocram.h>
24 #include <sbchipc.h>
25 #include <bcmdevs.h>
26 #include <bcmnvram.h>
28 #include <mipsinc.h>
30 /* #define      DEBUG_SBSDRAM   1 */
31 #ifdef  DEBUG_SBSDRAM
32         /* Trace function
33          * Write to prog space so we can see it in
34          * the Logic Analizer
35          */
36 #define LATRACEINIT             \
37         li      k0,0xb8000120;  \
38         li      k1,0x11;        \
39         sw      k1,0(k0);       \
40         li      k1,0x01020108;  \
41         sw      k1,4(k0);       \
42         li      k0,0xbb000000
44 #define LATRACE(num, reg)       \
45         sw      reg,((num & 0xff) << 4)(k0)
47 #else
48 #define LATRACEINIT
49 #define LATRACE(num, reg)
50 #endif  /* DEBUG_SBSDRAM */
51 /* Debug macro - write a number to a chipc reg - use it with caution,
52  *  it changes k0 and k1 registers.
53  */
54 #ifdef  BCMDBG
56 #define FLADDR_OFF      4
57 #define FLDATA_OFF      8
59 #define TRACEINIT(x) \
60         li      k0,KSEG1ADDR(0x18000040); \
61         li      k1,x; \
62         sw      k1,FLADDR_OFF(k0)
63         
64 #define TRACE(x) \
65         li      k1,x; \
66         sw      k1,FLADDR_OFF(k0)
68 #define TRACE2(x) \
69         li      k1,x; \
70         sw      k1,FLDATA_OFF(k0)
72 #else
73 #define TRACEINIT(x)
74 #define TRACE(x)
75 #define TRACE2(x)
76 #endif  /* BCMDBG */
79  * Register usage within this file:
80  *
81  *              top     ncdlsearch      test_mem        Xdr_do_init     sb_reset_core
82  *      v0:     retval                  retval
83  *      v1:     corerev -               -               corerev         -
84  *      a0:     coreptr coreptr         -               coreptr         coreptr
85  *      a1:             x               x               x               sdr/ddr flag
86  *      a2:     NVRAM                   x               x
87  *      a3:                             x
88  *      t0:     -       -                               config
89  *      t1:     -       -                               mode
90  *      t2:     -       wr/strm         off             wr/strm
91  *      t3:     -       rd/strd                         rd/strd
92  *      t4:     -       g/clkd                          g/clkd
93  *      t5:                             x
94  *      t6:     retaddr -                               -               -
95  *      t7:     -       -                               retaddr         -
96  *      s0:             pass_count                      -               -
97  *      s1:             wrsum/clkdsum                   -               -
98  *      s2:             rdsum/pass_countmax             -               -
99  *      s3:             gsum/strmmax                    -               -
100  *      s4:             wrlim/stdmmax                   -               -
101  *      s5:             rdlim/clkdmax                   -               -
102  *      s6:             glim/clkdlim                    -               -
103  *      s7:             dll                             -               -
104  *      t8:     -       -                               x               tmp
105  *      t9:     -       -                               x               retaddr
106  *      k0:     trace   trace           trace           -               -
107  *      k1:     trace   trace           trace           -               -
108  *      gp:     PRESERVED
109  *      sp:
110  *      s8:     -       step                            -               -
111  *      ra:
112  */
115         .text
116         .set    mips32
118         LEAF(sb_draminit)
119         .set    noreorder
121         LATRACEINIT
122         TRACEINIT(0x425300)
124         /* Save return address */
125         move    t6,ra
127         /* Scan for a memory controller */
128         move    a0,s2
129 1:      lw      v1,(SBCONFIGOFF + SBIDHIGH)(a0)
130         and     a1,v1,SBIDH_CC_MASK
131         srl     a1,a1,SBIDH_CC_SHIFT
132         beq     a1,MEMC_CORE_ID,foundctrl
133         nop
134         beq     a1,SOCRAM_CORE_ID,foundctrl
135         nop
136         addu    a0,SI_CORE_SIZE
137         bne     a1,(SBIDH_CC_MASK >> SBIDH_CC_SHIFT),1b
138         nop
140         /* No memory controller */
141         li      v0,-1
142         jr      t6
143         nop
145 foundctrl:
146         TRACE(0x425301)
147         /* If we are already in RAM, just go and size it */
148         bal     1f
149         nop
150 1:      li      t0,PHYSADDR_MASK
151         and     t0,t0,ra
152         li      t1,SI_FLASH1
153         blt     t0,t1,memprio_szmem
154         nop
156         /* For socram we don't need any nvram parms, just do a core reset */
157 socram_init:
158         bne     a1,SOCRAM_CORE_ID,read_nvram
159         nop
160         TRACE(0x425302)
161         bal     sb_core_reset
162         li      a2,0
163         /* and size memory */
164         b       memprio_szmem
165         nop
167 read_nvram:
168         TRACE(0x425303)
169         /* Find NVRAM (a2) */
170         /* 1: Isolate memc's corerev in v1 */
171         and     t2,v1,SBIDH_RCE_MASK
172         srl     t2,t2,SBIDH_RCE_SHIFT
173         and     v1,v1,SBIDH_RC_MASK
174         or      v1,t2
176         /* 1.5: 5365a0 lies about its revision, it is really 1 */
177         bnez    v1,1f
178         nop
180         TRACE(0x425304)
181         li      t0,KSEG1ADDR(SI_ENUM_BASE)      # Is there a chipcommon core?
182         lw      t1,CC_CHIPID(t0)                # Get chipid
183         andi    t1,CID_ID_MASK                  # Check chipid
184         bne     t1,BCM5365_CHIP_ID,1f
185         nop
186         li      v1,1
188         /* 2: find_nvram, use the 32MB window */
189 1:      li      t2,KSEG1ADDR(SI_FLASH2 - MAX_NVRAM_SPACE)
190         li      t4,SI_FLASH2_SZ
191         li      t3,FLASH_MIN 
192         li      t0,NVRAM_MAGIC
194 2:      add     a2,t2,t3
195         lw      t1,0(a2)
196         beq     t0,t1,read_parms
197         nop
199         TRACE(0x425306)
200         sll     t3,t3,1
201         ble     t3,t4,2b
202         nop
204         /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
205         li      a2,KSEG1ADDR(SI_FLASH1 + 0x1000)
206         lw      t1,0(a2)
207         beq     t0,t1,read_parms
208         nop
210         TRACE(0x425307)
211         li      a2,KSEG1ADDR(SI_FLASH1 + 0x400)
212         lw      t1,0(a2)
213         beq     t0,t1,read_parms
214         nop
216         TRACE(0x425308)
217         b       memc_init                       # No NVRAM
218         li      a2, 0
220 read_parms:
221         /* Get SDRAM parameters (t0, t1, t2) from NVRAM (a2) */
222         TRACE(0x425309)
223         lw      t0,8(a2)                # SDRAM init
224         srl     t0,16
225         lw      t2,12(a2)
226         andi    t1,t2,0xffff            # SDRAM config
227         srl     t2,16                   # SDRAM refresh
228         lw      t3,16(a2)               # SDRAM ncdl
230 memc_init:
231         /* Initialize memc core */
232         TRACE(0x425309)
233         bnez    a2,1f                   # Already have the parms in
234         nop                             #  t0, t1, t2, t3
236         /* No nvram parms: assume DDRM16MX16X2 */
238         li      t0,MEMC_DDR_INIT
239         li      t1,MEMC_DDR_MODE
240         li      t3,MEMC_DDR1_NCDL       # If rev1 (4712):
241         beq     v1,1,1f
242         nop
243                                         # rev0, 2:
244         li      t3,MEMC_DDR_NCDL
247         andi    a3,t0,MEMC_CONFIG_DDR   # Is it ddr or sdr?
248         TRACE(0x42530a)
249         beqz    a3,memc_sdr_init
250         nop
252         /* Initialize DDR SDRAM */
253 memc_ddr_init:
254         beqz    t3,ddr_find_ncdl        # Do we have ncdl values? (0s)
255         nop
257         li      t4,-1                   # or ffs
258         bne     t3,t4,break_ddr_ncdl
259         nop
261 ddr_find_ncdl:
262         TRACE(0x42530b)
264 /* Register usage */
265 #define pass_count      s0
266 #define wrsum           s1
267 #define rdsum           s2
268 #define gsum            s3
269 #define wrlim           s4
270 #define rdlim           s5
271 #define glim            s6
272 #define dll             s7
273 #define step            s8
274 #define wr              t2
275 #define rd              t3
276 #define g               t4
278         /* Initialize counter & accumulators */
279         move    pass_count,zero
280         move    wrsum,zero
281         move    rdsum,zero
282         move    gsum,zero
284         /* Initialize with default values */
285         li      wr,5
286         li      rd,5
287         bal     ddr_do_init
288         li      g,10
290         /* Read dll value */
291         lw      dll,MEMC_NCDLCTL(a0)
292         LATRACE(0xc, dll)
293         andi    dll,dll,0xfe
294         srl     dll,dll,1
295         beqz    dll,memprio_szmem               /* If zero, leave the default values */
296         nop
298         move    wrlim,dll               /* dll value is lim for wr, rd and g */
299         move    rdlim,dll
300         move    glim,dll
301         LATRACE(0xd, wrlim)
302         LATRACE(0xe, rdlim)
303         LATRACE(0xf, glim)
305         addi    step,dll,15             /* step = (dll + 16 - 1) / 16 */
306         srl     step,step,4
307         LATRACE(0x10, step)
309         sub     wr,zero,dll             /* Negate dll as initial value */
310         move    rd,wr
311         move    g,wr
313         /* Inner loop:  call ddr_do_init to re-initialize and the test mem */
314 loop:
315         LATRACE(0x11, wr)
316         LATRACE(0x12, rd)
317         LATRACE(0x13, g)        
318         bal     ddr_do_init
319         nop
321         bal     test_mem
322         nop
324         LATRACE(0x14, v0)
325         beqz    v0,nextg
326         nop
328         /* Memory is ok */
330         addi    pass_count,1
331         add     wrsum,wrsum,wr
332         add     rdsum,rdsum,rd
333         add     gsum,gsum,g
334         LATRACE(0x15, pass_count)
335         LATRACE(0x16, wrsum)
336         LATRACE(0x17, rdsum)
337         LATRACE(0x18, gsum)
339         bne     wr,dll,1f
340         nop
341         sll     wrlim,dll,1
342         LATRACE(0x19, wrlim)
345         bne     rd,dll,2f
346         nop
347         sll     rdlim,dll,1
348         LATRACE(0x1a, rdlim)
351         bne     g,dll,nextg
352         nop
353         sll     glim,dll,1
354         LATRACE(0x1b, glim)
356 nextg:
357         add     g,g,step
358         ble     g,glim,loop
359         nop
360         sub     g,zero,dll
361         move    glim,dll
362         LATRACE(0x1c, g)
364         /* nextrd: */
365         add     rd,rd,step
366         ble     rd,rdlim,loop
367         nop
368         sub     rd,zero,dll
369         move    rdlim,dll
370         LATRACE(0x1d, rd)
372         /* nextwr: */
373         add     wr,wr,step
374         ble     wr,wrlim,loop
375         nop
377         /* All done, calculate average values and program them */
378         
379         LATRACE(0x1e, pass_count)
380         LATRACE(0x1f, wrsum)
381         LATRACE(0x20, rdsum)
382         LATRACE(0x21, gsum)
383         beqz    pass_count,1f
384         nop
386         div     zero,wrsum,pass_count
387         mflo    wr
389         div     zero,rdsum,pass_count
390         mflo    rd
392         div     zero,gsum,pass_count
393         mflo    g
395         b       ddr_got_ncdl
396         nop
398         /* No passing values, panic! (use defaults) */
400         li      t3,MEMC_DDR1_NCDL       # If rev1:
401         beq     v1,1,2f
402         nop
403                                         # rev0, 2:
404         li      t3,MEMC_DDR_NCDL
407 break_ddr_ncdl:
408         TRACE(0x425322)
409         andi    t4,t3,0xff              # t4:   g
410         srl     t2,t3,16                # t2:   wr
411         andi    t2,t2,0xff
412         srl     t3,t3,8                 # t3:   rd
413         andi    t3,t3,0xff
415 ddr_got_ncdl:
416         LATRACE(0x23, wr)
417         LATRACE(0x24, rd)
418         LATRACE(0x25, g)
419         bal     ddr_do_init
420         nop
422         b       memprio_szmem
423         nop
425 memc_sdr_init:
426         beqz    t3,sdr_find_ncdl        # Do we have ncdl values?
427         nop
429         li      t4,-1
430         bne     t3,t4,break_sdr_ncdl
431         nop
433 sdr_find_ncdl:
434         TRACE(0x425326)
436 /* Register usage */
437 #define pass_count      s0
438 #define clkdsum         s1
439 #define pass_countmax   s2
440 #define strmmax         s3
441 #define strdmax         s4
442 #define clkdmax         s5
443 #define clkdlim         s6
444 #define strm            t2
445 #define strd            t3
446 #define clkd            t4
448 #define STRMLIM         4
449 #define STRDLIM         16
450 #define CLKDLIM         128
451 #define CLKDLIM_IC      256
453         /* Initialize counter & saved values */
454         move    pass_countmax,zero
455         move    strmmax,zero
456         move    strdmax,zero
457         li      clkdlim,CLKDLIM
459         and     strm,t0,0x2000          /* Test for internal clock (Using strm as a temp) */
460         beqz    strm,strmloop
461         nop
463         li      clkdlim,CLKDLIM_IC
465         move    strm,zero               /* strm loop */
466 strmloop:
467         move    strd,zero
468 strdloop:
469         move    pass_count,zero
470         move    clkdsum,zero
471         move    clkd,zero
473         /* Inner loop:  call sdr_do_init to re-initialize and the test mem */
474 clkdloop:
475         LATRACE(0x27, strm)
476         LATRACE(0x28, strd)
477         LATRACE(0x29, clkd)     
478         bal     sdr_do_init
479         nop
481         bal     test_mem
482         nop
484         LATRACE(0x2a, v0)
485         beqz    v0,failclkd
486         nop
488         /* Memory is ok */
490         addi    pass_count,1
491         add     clkdsum,clkdsum,clkd
492         LATRACE(0x2b, pass_count)
493         LATRACE(0x2c, clkdsum)
494         b       nextclkd
495         nop
497 failclkd:
498         bnez    pass_count,clkdout      # End of passing range, leave clkd loop
499         nop
501 nextclkd:
502         addi    clkd,clkd,1
503         blt     clkd,clkdlim,clkdloop
504         nop
506 clkdout:
507         /* If no passing values, skip to next strm */
508         beqz    pass_count,nextstrm
509         nop
511         /* If this is a new max, Save the values */
512         ble     pass_count,pass_countmax,nextstrd
513         nop
515         move    pass_countmax,pass_count
516         div     zero,clkdsum,pass_count
517         mflo    clkdmax
518         move    strdmax,strd
519         move    strmmax,strm
520         LATRACE(0x2d, pass_count)
521         LATRACE(0x2e, clkdmax)
522         LATRACE(0x2f, strdmax)
523         LATRACE(0x30, strmmax)
525 nextstrd:
526         addi    strd,strd,1
527         blt     strd,STRDLIM,strdloop
528         nop
530 nextstrm:
531         addi    strm,strm,1
532         blt     strm,STRMLIM,strmloop
533         nop
535         /* All done, program the new ncdl values */
536         
537         LATRACE(0x31, pass_count)
538         LATRACE(0x32, clkdmax)
539         LATRACE(0x33, strdmax)
540         LATRACE(0x34, strmmax)
542         beqz    pass_countmax,1f
543         nop
545         move    clkd,clkdmax
546         move    strd,strdmax
547         move    strm,strmmax
548         b       sdr_got_ncdl
549         nop
551         /* No passing values, panic! (use defaults) */
553         li      t3,MEMC_SDR1_NCDL       # If rev1:
554         beq     v1,1,2f
555         nop
556                                         # rev0, 2:
557         li      t3,MEMC_SDR_NCDL
560 break_sdr_ncdl:
561         TRACE(0x425335)
562         andi    t4,t3,0xff              # t4:   cd
563         srl     t2,t3,16                # t2:   sm
564         andi    t2,t2,3                 #       sm is 2 bits only
565         srl     t3,t3,8                 # t3:   sd
566         andi    t3,t3,0xf               #       sd is 4 bits
568 sdr_got_ncdl:
569         bal     sdr_do_init
570         nop
572         /* Change the memory priority inversion counter value */
573         /* If an SOCRAM, determine memory size and return */
574 memprio_szmem:
575         TRACE(0x425337)
577 #ifdef APPLE
578         lw      t0, MEMC_PRIORINV(a0) 
579         li      t1, 0xFFFF0000
580         and     t0, t0, t1
581         ori     t0, t0, 0x1
582         sw      t0, MEMC_PRIORINV(a0)
583 #else
584         li      t0,KSEG1ADDR(SI_ENUM_BASE)      # is there a chipcommon core?
585         lw      t1,(SBCONFIGOFF + SBIDHIGH)(t0)
586         and     t1,t1,SBIDH_CC_MASK
587         srl     t1,t1,SBIDH_CC_SHIFT
588         bne     t1,CC_CORE_ID,0f
589         nop
590         lw      t1,CC_CHIPID(t0)                # is this BCM4785 chip?
591         and     t1,t1,CID_ID_MASK
592         bne     t1,BCM4785_CHIP_ID,0f
593         nop
594         lw      t0,MEMC_PRIORINV(a0)            # change PriorInvTim to 2
595         and     t0,t0,0xFFFF0000
596         ori     t0,t0,0x02
597         sw      t0,MEMC_PRIORINV(a0)
598 #endif
599 0:      TRACE(0x425338)
600         lw      t0,(SBCONFIGOFF + SBIDHIGH)(a0)
601         and     t1,t0,SBIDH_CC_MASK
602         srl     t1,t1,SBIDH_CC_SHIFT
603         beq     t1,SOCRAM_CORE_ID,1f
604         nop
605         jr      t6
606         li      v0,0
608         /* The socram core tells us how much memory there is */
609 1:      TRACE(0x425339)
610         lw      t1,SR_COREINFO(a0)
611         and     t0,t0,SBIDH_RC_MASK             /* Find corerev */
612         beq     t0,zero,crev0
614         /* Its corerev >= 1 */
615         and     t2,t1,SRCI_SRNB_MASK            /* Find number of blocks */
616         srl     t2,t2,SRCI_SRNB_SHIFT
617         and     t1,t1,SRCI_SRBSZ_MASK           /* Find block size */
618         addi    t1,t1,SR_BSZ_BASE
619         li      t0,1
620         sll     t0,t0,t1
621         mul     v0,t0,t2
622         jr      t6
623         nop
625 crev0:
626         and     t1,t1,SRCI_MS0_MASK
627         add     t1,t1,SR_MS0_BASE
628         li      v0,1
629         sll     v0,v0,t1
630         jr      t6
631         nop
633         /*
634          * Test memory
635          *
636          * Uses arg in t2(wr/sd), t3(rd/sm) and t4(g/clkd)
637          * Returns success (1) or failure (0) in v0
638          * Uses a1, a2, a3 & t5
639          */
640 test_mem:
641         /* Use t4 to generate a semi-random address in the second KB */
642         li      a1,KSEG1
643         addi    a2,t4,255
644         sll     a2,a2,2
645         add     a1,a1,a2
647         /* First set: 0 & its negation */
648         li      a2,0
649         sw      a2,0(a1)
650         not     a3,a2
651         sw      a3,4(a1)
652         nop
653         lw      t5,0(a1)
654         bne     a2,t5,bad_mem
655         nop
657         lw      t5,4(a1)
658         bne     a3,t5,bad_mem
659         nop
661         /* Second set: 0xaaaaaaaa & its negation */
662         li      a2,0xaaaaaaaa
663         sw      a2,0(a1)
664         not     a3,a2
665         sw      a3,4(a1)
666         nop
667         lw      t5,0(a1)
668         bne     a2,t5,bad_mem
669         nop
671         lw      t5,4(a1)
672         bne     a3,t5,bad_mem
673         nop
675         /* Third set: 0x12345678 & its negation */
676         li      a2,0x12345678
677         sw      a2,0(a1)
678         not     a3,a2
679         sw      a3,4(a1)
680         nop
681         lw      t5,0(a1)
682         bne     a2,t5,bad_mem
683         nop
685         lw      t5,4(a1)
686         bne     a3,t5,bad_mem
687         nop
689         /* Fourth set: the ncdl & its negation */
690         sll     a2,t2,8
691         or      a2,t3
692         sll     a2,a2,8
693         or      a2,t4
694         sw      a2,0(a1)
695         not     a3,a2
696         sw      a3,4(a1)
697         nop
698         lw      t5,0(a1)
699         bne     a2,t5,bad_mem
700         nop
702         lw      t5,4(a1)
703         bne     a3,t5,bad_mem
704         nop
706         /* Fifth set: the CPU count register & its negation */
707         mfc0    a2,$9
708         sw      a2,0(a1)
709         not     a3,a2
710         sw      a3,4(a1)
711         nop
712         lw      t5,0(a1)
713         bne     a2,t5,bad_mem
714         nop
716         lw      t5,4(a1)
717         bne     a3,t5,bad_mem
718         nop
720         jr      ra
721         li      v0,1
723 bad_mem:
724         jr      ra
725         li      v0,0
728         /* Do an init of the memc core for ddr
729          *      a0:     memc core pointer
730          *      t0:     memc config value
731          *      t1:     memc mode value
732          *      t2:     memc wr ncdl value
733          *      t3:     memc rd ncdl value
734          *      t4:     memc g ncdl value
735          *
736          * Uses a1, a2, t7, t8, t9 (here and by calling sb_core_reset)
737          */
738 ddr_do_init:
739         TRACE(0x42533a)
741         /* Save return address */
742         move    t7,ra
744         bal     sb_core_reset
745         li      a1,0
747         li      a1,MEMC_CONFIG_INIT
748         or      a1,a1,t0
749         lui     a2, 0x8                 # set DQMGate for memc rev 4 or more
750         or      a1, a1, a2
751         sw      a1,MEMC_CONFIG(a0)
753         li      a1,MEMC_DRAMTIM25_INIT          # Assume CAS latency of 2.5
754         andi    t8,t1,0xf0                      # Find out the CAS latency
755         bne     t8,0x20,1f
756         nop
757         li      a1,MEMC_DRAMTIM2_INIT           # CAS latency is 2
758 1:      
759         sw      a1,MEMC_DRAMTIM(a0)
761 #ifndef BCM_ATE
762         li      t8,KSEG1ADDR(SI_ENUM_BASE)      # Get package options
763         lw      a1,CC_CHIPID(t8)                # Get chipid
764         li      t9,CID_PKG_MASK                 # Check package options
765         and     a1,a1,t9
766         srl     a1,a1,CID_PKG_SHIFT
767         addi    t8,SBCONFIGOFF                  # Get corerev for chipcommon
768         lw      a2,SBIDHIGH(t8)
769         li      t8,SBIDH_RCE_MASK
770         and     t8,t8,a2
771         srl     t8,SBIDH_RCE_SHIFT
772         li      t9,SBIDH_RC_MASK
773         and     t9,t9,a2
774         or      t8,t8,t9
775         bge     t8,10,1f                        # If ccrev is >= 10 use 4bit pkg opt
776         nop
777         ori     a1,8                            #  else add a bit to the 3bit field
779         beq     a1,HDLSIM_PKG_ID,hdlsim         # Special case for hdl sim:
780         nop
782         li      t8,KSEG1ADDR(SI_ENUM_BASE)      # Get chipid again
783         lw      a2,CC_CHIPID(t8)
784         li      t9,BCM5350_CHIP_ID              # 5350 ChipID
785         li      t8,CID_ID_MASK
786         and     t8,t8,a2
787         bne     t8,t9,notsim                    # if not 5350keep going
788         nop
790         bne     a1,(8 | HDLSIM5350_PKG_ID),notsim       # If 5350, is it (3/4-bit) vsim?
791         nop
792 #endif  /* !BCM_ATE */
794 hdlsim:
795         li      a1,MEMC_RDNCDLCOR_SIMINIT       #  Fixed 0xf6 rdncdl and no inits
796         sw      a1,MEMC_RDNCDLCOR(a0)           #  of wrncdl, dqsgate and miscdly.
798 #ifndef BCM_ATE
799         b       simskip
800         nop
802 notsim: andi    t8,t3,0xff
803         sll     a1,t8,8                         # Replicate rd ncdl 4 times
804         or      a1,a1,t8
805         sll     t8,a1,16
806         or      t8,t8,a1
807         li      a1,MEMC_RDNCDLCOR_INIT
808         or      a1,a1,t8
809         sw      a1,MEMC_RDNCDLCOR(a0)
811         li      a1,MEMC_1_WRNCDLCOR_INIT # If rev1:
812         beq     v1,1,1f
813         nop
814                                         # rev0, 2
815         li      a1,MEMC_WRNCDLCOR_INIT
817         andi    t8,t2,0xff
818         or      a1,a1,t8
819         sw      a1,MEMC_WRNCDLCOR(a0)
821         li      a1,MEMC_DQSGATENCDL_INIT
822         andi    t8,t4,0xff
823         or      a1,a1,t8
824         sw      a1,MEMC_DQSGATENCDL(a0)
826         li      a1,MEMC_1_MISCDLYCTL_INIT # If rev1:
827         beq     v1,1,2f
828         nop
829                                         # rev0,2
830         li      a1,MEMC_MISCDLYCTL_INIT
832         sw      a1,MEMC_MISCDLYCTL(a0)
833 #endif  /* !BCM_ATE */
835 simskip:
836         li      a1,MEMC_NCDLCTL_INIT
837         sw      a1,MEMC_NCDLCTL(a0)
839         li      a1,MEMC_CONTROL_INIT0
840         sw      a1,MEMC_CONTROL(a0)
842         li      a1,MEMC_CONTROL_INIT1
843         sw      a1,MEMC_CONTROL(a0)
845         li      a1,MEMC_MODEBUF_INIT0
846         sw      a1,MEMC_MODEBUF(a0)
848         li      a1,MEMC_CONTROL_INIT2
849         sw      a1,MEMC_CONTROL(a0)
851         li      a1,MEMC_MODEBUF_INIT1
852         or      a1,a1,t1
853         sw      a1,MEMC_MODEBUF(a0)
855         li      a1,MEMC_CONTROL_INIT3
856         sw      a1,MEMC_CONTROL(a0)
858         li      a1,MEMC_CONTROL_INIT4
859         sw      a1,MEMC_CONTROL(a0)
861         li      a1,MEMC_CONTROL_INIT5
862         sw      a1,MEMC_CONTROL(a0)
863         lw      a1,MEMC_CONTROL(a0)
864         lw      a1,MEMC_CONTROL(a0)
865         lw      a1,MEMC_CONTROL(a0)
867         li      a1,MEMC_CONTROL_INIT5
868         sw      a1,MEMC_CONTROL(a0)
869         lw      a1,MEMC_CONTROL(a0)
870         lw      a1,MEMC_CONTROL(a0)
871         lw      a1,MEMC_CONTROL(a0)
873         li      a1,MEMC_REFRESH_INIT
874         sw      a1,MEMC_REFRESH(a0)
875         
876         li      a1,MEMC_MODEBUF_INIT2
877         or      a1,a1,t1
878         sw      a1,MEMC_MODEBUF(a0)
880         li      a1,MEMC_CONTROL_INIT6
881         sw      a1,MEMC_CONTROL(a0)
883         li      a1,MEMC_CONTROL_INIT7
884         sw      a1,MEMC_CONTROL(a0)
886         /* Wait for SDRAM controller to refresh.
887          * We want 8uS delay.
888          */
889         li      t8,50
890 1:      lw      a1,(SBCONFIGOFF + SBIDLOW)(a0)
891         lw      a1,(SBCONFIGOFF + SBIDHIGH)(a0)
893         bnez    t8,1b
894         subu    t8,1
896         jr      t7
897         nop
899         /* Do an init of the memc core for sdr
900          *      a0:     memc core pointer
901          *      t0:     memc config value
902          *      t1:     memc mode value
903          *      t2:     memc strobe mode ncdl value
904          *      t3:     memc strobe delay ncdl value
905          *      t4:     memc clock delay ncdl value
906          *
907          * Uses a1, t7, t8, t9 (here and by calling sb_core_reset)
908          */
909 sdr_do_init:
910         TRACE(0x42533b)
912         /* Save return address */
913         move    t7,ra
915         bal     sb_core_reset
916         li      a1,0x40
918         /* Initialize for SDR SDRAM */
919         li      a1,MEMC_SD_CONFIG_INIT
920         or      a1,a1,t0
921         sw      a1,MEMC_CONFIG(a0)
923         li      a1,MEMC_SD_DRAMTIM3_INIT # Assume CAS latency of 3
924         andi    t8,t1,0xf0              # Find out the CAS latency
925         bne     t8,0x20,1f
926         nop
927         li      a1,MEMC_SD_DRAMTIM2_INIT # CAS latency is 2
928 1:      
929         sw      a1,MEMC_DRAMTIM(a0)
931         andi    t8,t4,0xff
932         ble     t8,MEMC_CD_THRESHOLD,1f # if (cd <= MEMC_CD_THRESHOLD) rd = cd
933         nop
935         li      t8,MEMC_CD_THRESHOLD    # else rd = MEMC_CD_THRESHOLD
937 1:                                      # t8 is now rd
938         sll     a1,t8,8                 #  .. replicate it 4 times
939         or      a1,a1,t8
940         sll     t8,a1,16
941         or      t8,t8,a1
942         li      a1,MEMC_SD_RDNCDLCOR_INIT
943         or      a1,a1,t8
944         sw      a1,MEMC_RDNCDLCOR(a0)
946         li      a1,MEMC_SD1_WRNCDLCOR_INIT # rev1
947         beq     v1,1,1f
948         nop
950         li      a1,MEMC_SD_WRNCDLCOR_INIT # rev0, 2
952         li      t8,0
953         ble     t4,MEMC_CD_THRESHOLD,2f # if (cd <= MEMC_CD_THRESHOLD) wr = 0
954         nop
955         
956         andi    t8,t4,0xff              # else wr = cd - MEMC_CD_THRESHOLD
957         sub     t8,t8,MEMC_CD_THRESHOLD
958         andi    t8,t8,0xff
960 2:                                      # t8 is now wr, a0 is extra bits
961         or      a1,a1,t8
962         sw      a1,MEMC_WRNCDLCOR(a0)
964         andi    t8,t2,3
965         sll     a1,t8,28
966         andi    t8,t3,0xf
967         sll     t8,t8,24
968         or      t8,t8,a1
969         li      a1,MEMC_SD1_MISCDLYCTL_INIT
970         beq     v1,1,3f                 # If rev1:
971         nop
972                                         # rev0, 2:
973         li      a1,MEMC_SD_MISCDLYCTL_INIT
975         or      a1,a1,t8
976         sw      a1,MEMC_MISCDLYCTL(a0)
978         li      a1,MEMC_SD_CONTROL_INIT0
979         sw      a1,MEMC_CONTROL(a0)
981         li      a1,MEMC_SD_CONTROL_INIT1
982         sw      a1,MEMC_CONTROL(a0)
984         li      a1,MEMC_SD_CONTROL_INIT2
985         sw      a1,MEMC_CONTROL(a0)
986         lw      a1,MEMC_CONTROL(a0)
987         lw      a1,MEMC_CONTROL(a0)
988         lw      a1,MEMC_CONTROL(a0)
990         li      a1,MEMC_SD_CONTROL_INIT2
991         sw      a1,MEMC_CONTROL(a0)
992         lw      a1,MEMC_CONTROL(a0)
993         lw      a1,MEMC_CONTROL(a0)
994         lw      a1,MEMC_CONTROL(a0)
996         li      a1,MEMC_SD_CONTROL_INIT2
997         sw      a1,MEMC_CONTROL(a0)
998         lw      a1,MEMC_CONTROL(a0)
999         lw      a1,MEMC_CONTROL(a0)
1000         lw      a1,MEMC_CONTROL(a0)
1002         li      a1,MEMC_SD_REFRESH_INIT
1003         sw      a1,MEMC_REFRESH(a0)
1005         li      a1,MEMC_SD_MODEBUF_INIT
1006         or      a1,a1,t1
1007         sw      a1,MEMC_MODEBUF(a0)
1009         li      a1,MEMC_SD_CONTROL_INIT3
1010         sw      a1,MEMC_CONTROL(a0)
1012         li      a1,MEMC_SD_CONTROL_INIT4
1013         sw      a1,MEMC_CONTROL(a0)
1015         li      t8,50
1016 1:      lw      a1,(SBCONFIGOFF + SBIDLOW)(a0)
1017         lw      a1,(SBCONFIGOFF + SBIDHIGH)(a0)
1018         bnez    t8,1b
1019         subu    t8,1
1021         jr      t7
1022         nop
1025         /* Special sb_core_reset that makes sure the first time
1026          * clock is enabled, address line 6 is in the state specified
1027          * by a1.
1028          *
1029          * a0:  Core pointer
1030          * a1:  0x40 if a6 needs to be 1, 0 otherwise
1031          * uses t8, t9
1032          */
1034         .align 6
1036 sb_core_reset:
1038         /* Save return address */
1039         move    t9,ra
1040         
1041         /* run uncached */
1042         bal     kseg1_switch
1043         nop                                
1045         /* Figure out our address */
1046         bal     h0
1047         nop
1048 h0:     add     t8,ra,24                # This is (h1 - h0)
1049         andi    t8,t8,0x40
1050         bne     t8,a1,alt_core_reset
1051         nop
1053         /* Set reset while enabling the clock */
1054         li      t8,(((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_RESET)
1055 h1:     sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1056         b       cont
1057         nop
1059         /* Now pad to 0x40: We want (h2 - h1) == 0x40 and there
1060          * are 5 instructions inbetween them.
1061          */
1062         .space  (0x40 - 20)
1064 alt_core_reset:
1065         /* Set reset while enabling the clock */
1066         li      t8,(((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_RESET)
1067 h2:     sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1069 cont:
1070         /* Read back and delay */
1071         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1072         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1073         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1075         /* Clear reset */
1076         li      t8,((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)
1077         sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1079         /* Read back and delay */
1080         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1081         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1082         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1084         /* Leave clock enabled */
1085         li      t8,(SICF_CLOCK_EN << SBTML_SICF_SHIFT)
1086         sw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1088         /* Read back and delay */
1089         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1090         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1091         lw      t8,(SBCONFIGOFF + SBTMSTATELOW)(a0)
1093         jr      t9
1094         nop
1096         
1097 kseg1_switch:
1098         and     ra,ra,PHYSADDR_MASK
1099         or      ra,ra,KSEG1
1100         jr      ra
1101         nop 
1102         
1103         .set    reorder
1104         END(sb_draminit)