]> git.sur5r.net Git - u-boot/blob - board/mpc7448hpc2/asm_init.S
Solve the copyright conflicts when merging 'master' into hpc2.
[u-boot] / board / mpc7448hpc2 / asm_init.S
1 /*****************************************************************************
2  * (C) Copyright 2004-05;  Tundra Semiconductor Corp.
3  * 
4  * Added automatic detect of SDC settings
5  * Copyright (c) 2005 Freescale Semiconductor, Inc.
6  * Maintainer tie-fei.zang@freescale.com
7  * 
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  ****************************************************************************/
23
24 /*----------------------------------------------------------------------------
25  * FILENAME: asm_init.s
26  *
27  * Originator: Alex Bounine
28  *
29  * DESCRIPTION:
30  * Initialization code for the Tundra Tsi108 bridge chip
31  *
32  *---------------------------------------------------------------------------*/
33
34 #include <config.h>
35 #include <version.h>
36
37 #include <ppc_asm.tmpl>
38 #include <ppc_defs.h>
39 #include <asm/processor.h>
40
41 #include <tsi108.h>
42
43 /*===========================================================================
44  * Build Configuration Options
45  */
46
47 /* #define DISABLE_PBM       disables usage of PB Master */
48 /* #define SDC_HARDCODED_INIT  config SDRAM controller with hardcoded values */
49 /* #define SDC_AUTOPRECH_EN    enable SDRAM auto precharge */
50
51 /* ===========================================================================
52  * Hardcoded SDC settings
53  */
54
55 #ifdef SDC_HARDCODED_INIT
56
57 /* Micron MT9HTF6472AY-40EA1 : Unbuffered, 512MB, 400, CL3, Single Rank */
58
59 #define VAL_SD_REFRESH  (0x61A)
60 #define VAL_SD_TIMING   (0x0308336b)
61 #define VAL_SD_D0_CTRL  (0x07100021) /* auto-precharge disabled */
62 #define VAL_SD_D0_BAR   (0x0FE00000) /* 512MB @ 0x00000000 */
63 #define VAL_SD_D1_CTRL  (0x07100021) /* auto-precharge disabled */
64 #define VAL_SD_D1_BAR   (0x0FE00200) /* 512MB @ 0x20000000 */
65
66 #endif /* SDC_HARDCODED_INIT */
67
68 /*---------------------------------------------------------------------------
69  CPU Configuration:
70
71  CPU Address and Data Parity enables.
72
73 #define CPU_AP
74 #define CPU_DP
75
76 ===========================================================================
77  Macros
78
79  !!! Attention !!! Macros LOAD_PTR, LOAD_U32 and LOAD_MEM defined below are
80  expected to work correctly for the CSR space within 32KB range.
81
82  LOAD_PTR and LOAD_U32 - load specified register with a 32 bit constant.
83  These macros are absolutely identical except their names. This difference
84  is provided intentionally for better readable code.
85  -------------------------------------------------------------------------*/
86
87 #define LOAD_PTR(reg,const32) \
88       addis reg,r0,const32@h; ori reg,reg,const32@l
89
90 #define LOAD_U32(reg,const32) \
91       addis reg,r0,const32@h; ori reg,reg,const32@l
92
93 /* LOADMEM initializes a register with the contents of a specified 32-bit memory
94  location, usually a CSR value.*/
95
96 #define LOAD_MEM(reg,addr32) \
97       addis reg,r0,addr32@ha; lwz reg,addr32@l(reg)
98
99 #ifndef SDC_HARDCODED_INIT
100 sdc_clk_sync:
101         /* MHz: 0,0,183,100,133,167,200,233 */
102         .long   0,0,  6, 10,  8,  6,  5,  4  /* nSec */
103 #endif
104
105 /*===========================================================================
106  board_asm_init() - early initialization function. Coded to be portable to
107                     dual-CPU configuration.
108  Checks CPU number and performs board HW initialization if called for CPU0.
109
110  Registers used: r3,r4,r5,r6,r19,r29
111 ===========================================================================
112
113 ---------------------------------------------------------------------------
114  NOTE: For dual-CPU configuration only CPU0 is allowed to configure Tsi108
115        and the rest of the board. Current implementation demonstrates two
116        possible ways to identify CPU number:
117         - for MPC74xx platform: uses MSSCR0[ID] bit as defined in UM.
118         - for PPC750FX/GX boards: uses WHO_AM_I bit reported by Tsi108.
119 ---------------------------------------------------------------------------*/
120
121     .globl board_asm_init
122 board_asm_init:
123
124     mflr    r19          /* Save LR to be able return later. */
125
126     bl icache_enable     /* Enable icache to reduce reads from flash. */
127
128     /* Initialize pointer to Tsi108 register space
129     -------------------------------------------------------------------------*/
130
131     LOAD_PTR(r29,CFG_TSI108_CSR_RST_BASE)/* r29 - pointer to tsi108 CSR space */
132     ori r4,r29,TSI108_PB_REG_OFFSET
133
134     /*-------------------------------------------------------------------------
135      Check Processor Version Number */
136
137     mfspr   r3, PVR
138     rlwinm  r3,r3,16,16,23  /* get ((Processor Version Number) & 0xFF00) */
139
140     cmpli   0,0,r3,0x8000   /* MPC74xx */
141     bne     cont_brd_init
142
143     /* ------------------------------------------
144      For MPC744x/5x enable extended BATs[4-7]
145      Sri: Set HIGH_BAT_EN and XBSEN, and SPD =1
146           to disable prefetch 
147      */
148
149     mfspr   r5, HID0
150     oris    r5, r5, 0x0080  /* Set HID0[HIGH_BAT_EN] bit #8 */
151     ori     r5, r5, 0x0380    /* Set SPD,XBSEN,SGE bits #22,23,24 */
152     mtspr   HID0, r5
153     isync
154     sync
155
156     /* Adding code to disable external interventions in MPX bus mode */
157     mfspr   r3, 1014
158     oris    r3, r3, 0x0100 /* Set the EIDIS bit in MSSCR0:  bit 7 */
159     mtspr   1014, r3
160     isync
161     sync
162
163     /* Sri: code to enable FP unit */
164     mfmsr   r3
165     ori     r3, r3, 0x2000
166     mtmsr   r3
167     isync
168     sync
169
170 #if(1) /* def CONFIG_DUAL_CPU
171     -------------------------------------------------------------------------
172      For MPC74xx processor, use MSSCR0[ID] bit to identify CPU number.
173      */
174
175     mfspr   r3,1014         /* read MSSCR0 */
176     rlwinm. r3,r3,27,31,31  /* get processor ID number */
177     mtspr   SPRN_PIR,r3     /* Save CPU ID */
178     sync
179     bne init_done
180     b do_tsi108_init
181
182 cont_brd_init:
183
184     /* An alternative method of checking the processor number (in addition
185        to configuration using MSSCR0[ID] bit on MPC74xx). 
186        Good for IBM PPC750FX/GX.
187      */
188
189     lwz r3,PB_BUS_MS_SELECT(r4) /* read PB_ID register */
190     rlwinm. r3,r3,24,31,31      /* get processor ID number */
191
192     bne init_done
193
194 #else
195
196 cont_brd_init:
197
198 #endif /* CONFIG_DUAL_CPU */
199
200     /* Initialize Tsi108 chip
201     ---------------------------------------------------------------------------
202      */
203
204 do_tsi108_init:
205
206     /*--------------------------------------------------------------------------
207      Adjust HLP/Flash parameters. By default after reset the HLP port is set
208      to support slow devices. Better performance can be achived when an optimal
209      parameters are used for specific EPROM device.
210      NOTE: This should be performed ASAP for the emulation platform because
211      it has 5MHz HLP clocking.
212      */
213
214 #ifdef CONFIG_TSI108EMU
215     ori r4,r29,TSI108_HLP_REG_OFFSET
216     LOAD_U32(r5,0x434422c0)
217     stw r5,0x08(r4)            /* set HLP B0_CTRL0 */
218     sync
219     LOAD_U32(r5,0xd0012000)
220     stw r5,0x0c(r4)            /* set HLP B0_CTRL1 */
221     sync
222 #endif
223
224     /* -------------------------------------------------------------------------
225      * Initialize PB interface.
226      */
227
228     ori r4,r29,TSI108_PB_REG_OFFSET
229
230 #if (CFG_TSI108_CSR_BASE != CFG_TSI108_CSR_RST_BASE)
231     /* Relocate (if required) Tsi108 registers. Set new value for PB_REG_BAR:
232      * Note we are in the 32-bit address mode.
233      */
234     LOAD_U32(r5,(CFG_TSI108_CSR_BASE | 0x01)) /* value for PB_REG_BAR: BA + EN*/
235     stw r5,PB_REG_BAR(r4)
236     andis. r29,r5,0xFFFF
237     sync
238
239     ori r4,r29,TSI108_PB_REG_OFFSET
240 #endif
241
242     /* Set PB Slave configuration register */
243
244 /*    LOAD_U32(r5,0x000024C7)  value for PB_SCR: TEA enabled,AACK delay = 7 */
245     LOAD_U32(r5,0x00002481) /* value for PB_SCR: TEA enabled,AACK delay = 1 */
246     lwz r3, PB_RSR(r4)      /* get PB bus mode */
247     xori r3,r3,0x0001       /* mask PB_BMODE: r3 -> (0 = 60X, 1 = MPX) */
248     rlwimi  r5,r3,14,17,17  /* for MPX: set DTI_MODE bit */
249     stw r5,PB_SCR(r4)
250     sync
251
252     /* Configure PB Arbiter */
253
254     lwz r5,PB_ARB_CTRL(r4)      /* Read PB Arbiter Control Register */
255     li r3, 0x00F0               /* ARB_PIPELINE_DEP mask */
256 #ifdef DISABLE_PBM
257     ori r3,r3,0x1000            /* add PBM_EN to clear (enabled by default) */
258 #endif
259     andc r5,r5,r3               /* Clear the masked bit fields */
260 /*    ori r5,r5,0x0040             Set pipeline depth 4
261     ori r5,r5,0x0080             Set pipeline depth 8
262     ori r5,r5,0x0020            !!!avb Testing: set pipeline depth 2 */
263     ori r5,r5,0x0001
264     stw r5,PB_ARB_CTRL(r4)
265
266 #if (0) /* currently using the default settings for PBM after reset */
267     LOAD_U32(r5,0x) /* value for PB_MCR */
268     stw r5,PB_MCR(r4)
269     sync
270
271     LOAD_U32(r5,0x) /* value for PB_MCMD */
272     stw r5,PB_MCMD(r4)
273     sync
274 #endif
275
276 /* Disable or enable PVT based on processor bus frequency
277    1. Read CG_PWRUP_STATUS register field bits 18,17,16
278    2. See if the value is < or > 133mhz (18:16 = 100)
279    3. If > enable PVT 
280    */
281
282     LOAD_U32(r3,0xC0002234)
283     lwz  r3,0(r3)
284     rlwinm  r3,r3,16,29,31
285
286     cmpi 0,0,r3,0x0004
287     bgt sdc_init
288
289 #ifndef CONFIG_TSI108EMU
290    /* FIXME:    Disable PB calibration control for any real Tsi108 board */
291     li  r5,0x0101 /* disable calibration control */
292     stw r5,PB_PVT_CTRL2(r4)
293     sync
294 #endif
295
296 /*---------------------------------------------------------------------------
297  Initialize SDRAM controller.
298 ----------------------------------------------------------------------------*/
299
300 sdc_init:
301
302 #ifndef SDC_HARDCODED_INIT
303     /* get SDC clock prior doing sdram controller autoconfig */
304     ori r4,r29,TSI108_CLK_REG_OFFSET    /* r4 - ptr to CG registers */
305     lwz r3, CG_PWRUP_STATUS(r4)         /* get CG configuration */
306     rlwinm r3,r3,12,29,31                       /* r3 - SD clk */
307     lis r5,sdc_clk_sync@h
308     ori r5,r5,sdc_clk_sync@l
309        /* Sri:  At this point check if r3 = 001. If yes,
310         * the memory frequency should be same as the 
311         * MPX bus frequency
312         */
313     cmpi 0,0,r3,0x0001
314     bne get_nsec
315     lwz r6, CG_PWRUP_STATUS(r4)
316     rlwinm r6,r6,16,29,31
317     mr r3,r6
318
319 get_nsec:
320     rlwinm r3,r3,2,0,31
321     lwzx r9,r5,r3       /* get SD clk rate in nSec */
322        /* ATTN: r9 will be used by SPD routine */
323 #endif /* !SDC_HARDCODED_INIT */
324
325     ori r4,r29,TSI108_SD_REG_OFFSET /* r4 - ptr to SDRAM registers */
326
327     /* Initialize SDRAM controller. SDRAM Size = 512MB, One DIMM. */
328
329     LOAD_U32(r5,0x00)
330     stw r5,SD_INT_ENABLE(r4)    /* Ensure that interrupts are disabled */
331 #ifdef ENABLE_SDRAM_ECC
332     li r5, 0x01
333 #endif /* ENABLE_SDRAM_ECC */
334     stw r5,SD_ECC_CTRL(r4)      /* Enable/Disable ECC */
335     sync
336
337 #ifdef SDC_HARDCODED_INIT /* config sdram controller with hardcoded values */
338
339     /* First read the CG_PWRUP_STATUS register to get the
340        memory speed from bits 22,21,20 */
341
342     LOAD_U32(r3,0xC0002234)
343     lwz  r3,0(r3)
344     rlwinm  r3,r3,12,29,31
345
346     /* Now first check for 166, then 200, or default */
347
348     cmpi 0,0,r3,0x0005
349     bne check_for_200mhz
350
351     /* set values for 166 Mhz memory speed */
352
353     /* Set refresh rate and timing parameters */
354     LOAD_U32(r5,0x00000515)
355     stw r5,SD_REFRESH(r4)
356     LOAD_U32(r5,0x03073368)
357     stw r5,SD_TIMING(r4)
358     sync
359
360     /* Initialize DIMM0 control and BAR registers */
361     LOAD_U32(r5,VAL_SD_D0_CTRL)   /* auto-precharge disabled */
362 #ifdef SDC_AUTOPRECH_EN
363     oris r5,r5,0x0001   /* set auto precharge EN bit */
364 #endif
365     stw r5,SD_D0_CTRL(r4)
366     LOAD_U32(r5,VAL_SD_D0_BAR)
367     stw r5,SD_D0_BAR(r4)
368     sync
369
370     /* Initialize DIMM1 control and BAR registers
371      *  (same as dimm 0, next 512MB, disabled)
372      */
373     LOAD_U32(r5,VAL_SD_D1_CTRL)  /* auto-precharge disabled */
374 #ifdef SDC_AUTOPRECH_EN
375     oris r5,r5,0x0001   /* set auto precharge EN bit */
376 #endif
377     stw r5,SD_D1_CTRL(r4)
378     LOAD_U32(r5,VAL_SD_D1_BAR)
379     stw r5,SD_D1_BAR(r4)
380     sync
381
382     b sdc_init_done
383
384 check_for_200mhz:
385
386     cmpi 0,0,r3,0x0006
387     bne set_default_values
388
389     /* set values for 200Mhz memory speed */
390
391     /* Set refresh rate and timing parameters */
392     LOAD_U32(r5,0x0000061a)
393     stw r5,SD_REFRESH(r4)
394     LOAD_U32(r5,0x03083348)
395     stw r5,SD_TIMING(r4)
396     sync
397
398     /* Initialize DIMM0 control and BAR registers */
399     LOAD_U32(r5,VAL_SD_D0_CTRL)   /* auto-precharge disabled */
400 #ifdef SDC_AUTOPRECH_EN
401     oris r5,r5,0x0001   /* set auto precharge EN bit */
402 #endif
403     stw r5,SD_D0_CTRL(r4)
404     LOAD_U32(r5,VAL_SD_D0_BAR)
405     stw r5,SD_D0_BAR(r4)
406     sync
407
408     /* Initialize DIMM1 control and BAR registers
409      *  (same as dimm 0, next 512MB, disabled)
410      */
411     LOAD_U32(r5,VAL_SD_D1_CTRL)  /* auto-precharge disabled */
412 #ifdef SDC_AUTOPRECH_EN
413     oris r5,r5,0x0001   /* set auto precharge EN bit */
414 #endif
415     stw r5,SD_D1_CTRL(r4)
416     LOAD_U32(r5,VAL_SD_D1_BAR)
417     stw r5,SD_D1_BAR(r4)
418     sync
419
420     b sdc_init_done
421
422 set_default_values:
423
424     /* Set refresh rate and timing parameters */
425     LOAD_U32(r5,VAL_SD_REFRESH)
426     stw r5,SD_REFRESH(r4)
427     LOAD_U32(r5,VAL_SD_TIMING)
428     stw r5,SD_TIMING(r4)
429     sync
430
431     /* Initialize DIMM0 control and BAR registers */
432     LOAD_U32(r5,VAL_SD_D0_CTRL)   /* auto-precharge disabled */
433 #ifdef SDC_AUTOPRECH_EN
434     oris r5,r5,0x0001   /* set auto precharge EN bit */
435 #endif
436     stw r5,SD_D0_CTRL(r4)
437     LOAD_U32(r5,VAL_SD_D0_BAR)
438     stw r5,SD_D0_BAR(r4)
439     sync
440
441     /* Initialize DIMM1 control and BAR registers
442      *  (same as dimm 0, next 512MB, disabled)
443      */
444     LOAD_U32(r5,VAL_SD_D1_CTRL)  /* auto-precharge disabled */
445 #ifdef SDC_AUTOPRECH_EN
446     oris r5,r5,0x0001   /* set auto precharge EN bit */
447 #endif
448     stw r5,SD_D1_CTRL(r4)
449     LOAD_U32(r5,VAL_SD_D1_BAR)
450     stw r5,SD_D1_BAR(r4)
451     sync
452
453 #else /* !SDC_HARDCODED_INIT */
454         
455     bl tsi108_sdram_spd         /* automatically detect SDC settings */
456      
457 #endif /* SDC_HARDCODED_INIT */
458
459 sdc_init_done:
460
461 #ifdef DISABLE_PBM
462     LOAD_U32(r5,0x00000030)     /* PB_EN + OCN_EN */
463 #else
464     LOAD_U32(r5,0x00000230)     /* PB_EN + OCN_EN + PB/OCN=80/20 */
465 #endif /* DISABLE_PBM */
466
467 #ifdef CONFIG_TSI108EMU
468     oris r5,r5,0x0010   /* set EMULATION_MODE bit */
469 #endif
470
471     stw r5,SD_CTRL(r4)
472     eieio
473     sync
474
475     /* Enable SDRAM access */
476
477     oris r5,r5,0x8000   /* start SDC: set SD_CTRL[ENABLE] bit */
478     stw r5,SD_CTRL(r4)
479     sync
480
481 wait_init_complete:
482     lwz r5,SD_STATUS(r4)
483     andi.   r5,r5,0x0001
484     beq wait_init_complete  /* wait until SDRAM initialization is complete */
485
486 /*---------------------------------------------------------------------------
487  Map SDRAM into the processor bus address space
488 ---------------------------------------------------------------------------*/
489
490     ori r4,r29,TSI108_PB_REG_OFFSET
491
492     /* Setup BARs associated with direct path PB<->SDRAM */
493
494     /* PB_SDRAM_BAR1:
495        provides a direct path to the main system memory (cacheable SDRAM) */
496
497     LOAD_U32(r5, 0x00000011)  /* BA=0,Size=512MB, ENable, No Addr.Translation */
498     stw r5,PB_SDRAM_BAR1(r4)
499     sync
500
501     /* Make sure that PB_SDRAM_BAR1 decoder is set
502        (to allow following immediate read from SDRAM) */
503     lwz r5,PB_SDRAM_BAR1(r4)
504     sync
505
506     /* PB_SDRAM_BAR2:
507        provides non-cacheable alias (via the direct path) to main system memory.
508        Size = 512MB, ENable, Addr.Translation - ON,
509        BA = 0x0_40000000, TA = 0x0_00000000 */
510
511     LOAD_U32(r5, 0x40010011)
512     stw r5,PB_SDRAM_BAR2(r4)
513     sync
514
515     /* Make sure that PB_SDRAM_BAR2 decoder is set
516       (to allow following immediate read from SDRAM) */
517     lwz r5,PB_SDRAM_BAR2(r4)
518     sync
519
520
521 init_done:
522
523     /* All done. Restore LR and return. */
524     mtlr    r19
525     blr
526
527 #if (0)
528 /*===========================================================================
529  init_cpu1
530
531  This routine enables CPU1 on the dual-processor system.
532 ===========================================================================*/
533
534     .global enable_cpu1
535 enable_cpu1:
536
537     lis r3,Tsi108_Base@ha       /* Get Grendel CSR Base Addr */
538     addi    r3,r3,Tsi108_Base@l
539     lwz r3,0(r3)                /* R3 = CSR Base Addr */
540     ori r4,r3,TSI108_PB_REG_OFFSET
541     lwz r3,PB_ARB_CTRL(r4)      /* Read PB Arbiter Control Register */
542     ori r3,r3,0x0200            /* Set M1_EN bit */
543     stw r3,PB_ARB_CTRL(r4)
544
545     blr
546 #endif
547
548 /*===========================================================================
549  enable_EI
550
551  Enable CPU core external interrupt
552 ===========================================================================*/
553
554     .global enable_EI
555 enable_EI:
556     mfmsr    r3
557     ori      r3,r3,0x8000   /* set EE bit */
558     mtmsr    r3
559     blr
560
561 /*===========================================================================
562  disable_EI
563
564  Disable CPU core external interrupt
565 ===========================================================================*/
566
567     .global disable_EI
568 disable_EI:
569     mfmsr   r3
570     li  r4,-32768   /* aka "li  r4,0x8000" */
571     andc r3,r3,r4   /* clear EE bit */
572     mtmsr   r3
573     blr
574
575 #ifdef ENABLE_SDRAM_ECC
576 /*===========================================================================
577  enable_ECC
578
579  enables SDRAM ECC
580 ===========================================================================*/
581
582     .global enable_ECC
583 enable_ECC:
584     ori r4,r29,TSI108_SD_REG_OFFSET
585     lwz r3,SD_ECC_CTRL(r4)      /* Read SDRAM ECC Control Register */
586     ori r3,r3,0x0001            /* Set ECC_EN bit */
587     stw r3,SD_ECC_CTRL(r4)
588     blr
589
590 /*===========================================================================
591  clear_ECC_err
592
593  Clears all pending SDRAM ECC errors
594  (normally after SDRAM scrubbing/initialization)
595 ===========================================================================*/
596
597     .global clear_ECC_err
598 clear_ECC_err:
599     ori r4,r29,TSI108_SD_REG_OFFSET
600 /*    lwz r3,SD_INT_STATUS(r4)       Read SDRAM ECC Control Register */
601     ori r3,r0,0x0030                /* ECC_UE_INT + ECC_CE_INT bits */
602     stw r3,SD_INT_STATUS(r4)
603     blr
604
605 #endif /* ENABLE_SDRAM_ECC */
606
607 #ifndef SDC_HARDCODED_INIT
608
609 /********************************************************************
610  * SDRAM SPD Support
611  */
612
613 #define SD_I2C_CTRL1    (0x400)
614 #define SD_I2C_CTRL2    (0x404)
615 #define SD_I2C_RD_DATA  (0x408)
616 #define SD_I2C_WR_DATA  (0x40C)
617
618 /*
619  * SDRAM SPD Support Macros
620  */
621
622 #define SPD_DIMM0       (0x00000100)
623 #define SPD_DIMM1       (0x00000200) /* SPD_DIMM1 was 0x00000000 */
624
625 #define SPD_RDIMM                       (0x01)
626 #define SPD_UDIMM                       (0x02)
627
628 #define SPD_CAS_3                       0x8
629 #define SPD_CAS_4                       0x10
630 #define SPD_CAS_5                       0x20
631
632 #define ERR_NO_DIMM_FOUND               (0xdb0)
633 #define ERR_TRAS_FAIL                   (0xdb1)
634 #define ERR_TRCD_FAIL                   (0xdb2)
635 #define ERR_TRP_FAIL                    (0xdb3)
636 #define ERR_TWR_FAIL                    (0xdb4)
637 #define ERR_UNKNOWN_PART                (0xdb5)
638 #define ERR_NRANK_INVALID               (0xdb6)
639 #define ERR_DIMM_SIZE                   (0xdb7)
640 #define ERR_ADDR_MODE                   (0xdb8)
641 #define ERR_RFRSH_RATE                  (0xdb9)
642 #define ERR_DIMM_TYPE                   (0xdba)
643 #define ERR_CL_VALUE                    (0xdbb)
644 #define ERR_TRFC_FAIL                   (0xdbc)
645
646 /* READ_SPD requirements:
647  * byte - byte address in SPD device (0 - 255)
648  * r3 = will return data read from I2C Byte location
649  * r4 - unchanged (SDC base addr)
650  * r5 - clobbered in routine (I2C status)
651  * r10 - number of DDR slot where first SPD device is detected
652  */
653
654 #define READ_SPD(byte_num)      \
655         addis r3, 0, byte_num@l;\
656         or      r3, r3, r10;\
657         ori r3, r3, 0x0A;\
658         stw r3, SD_I2C_CTRL1(r4);\
659         li r3, I2C_CNTRL2_START;\
660         stw r3, SD_I2C_CTRL2(r4);\
661         eieio;\
662         sync;\
663         li r3, 0x100;\
664 1:                              ;\
665         addic. r3, r3, -1;\
666         bne 1b;\
667 2:                ;\
668         lwz r5, SD_I2C_CTRL2(r4);\
669         rlwinm. r3,r5,0,23,23;\
670         bne 2b;\
671         rlwinm. r3,r5,0,3,3;\
672         lwz r3, SD_I2C_RD_DATA(r4)
673
674 #define SPD_MIN_RFRSH   (0x80)
675 #define SPD_MAX_RFRSH   (0x85)
676
677 refresh_rates: /* in nSec */
678         .long   15625   /* Normal (0x80) */
679         .long   3900    /* Reduced 0.25x (0x81) */
680         .long   7800    /* Reduced 0.5x (0x82) */
681         .long   31300   /* Extended 2x (0x83) */
682         .long   62500   /* Extended 4x (0x84) */
683         .long   125000  /* Extended 8x (0x85) */
684
685 /*===========================================================================
686  * tsi108_sdram_spd
687  *
688  * Inittializes SDRAM Controller using DDR2 DIMM Serial Presence Detect data
689  * Uses registers: r4 - SDC base address (not changed)
690  *                                 r9 - SDC clocking period in nSec
691  * Changes registers: r3,r5,r6,r7,r8,r10,r11
692  *==========================================================================*/
693
694 tsi108_sdram_spd:
695
696         li r10,SPD_DIMM0
697         xor     r11,r11,r11             /* DIMM Base Address: starts from 0 */
698
699 do_first_dimm:
700
701         /**************************************
702          * Program Refresh Rate Register
703          */
704
705         READ_SPD(12)    /* get Refresh Rate */
706         beq check_next_slot
707         li r5, ERR_RFRSH_RATE
708         cmpi 0,0,r3,SPD_MIN_RFRSH
709         ble spd_fail
710         cmpi 0,0,r3,SPD_MAX_RFRSH
711         bgt spd_fail
712         addi r3,r3,-SPD_MIN_RFRSH
713         rlwinm r3,r3,2,0,31
714         lis r5,refresh_rates@h
715         ori r5,r5,refresh_rates@l
716         lwzx r5,r5,r3   /* get refresh rate in nSec */
717         divwu r5,r5,r9  /* calculate # of SDC clocks */
718         stw r5,SD_REFRESH(r4)   /* Set refresh rate */
719         sync
720
721         /**************************************
722          * Program SD Timing Register
723          */
724
725         li r7, 0                /* clear r7 prior parameter collection */
726
727         READ_SPD(20)    /* get DIMM type: Registered or Unbuffered */
728         beq     spd_read_fail
729         li r5, ERR_DIMM_TYPE
730         cmpi 0,0,r3,SPD_UDIMM
731         beq do_cl
732         cmpi 0,0,r3,SPD_RDIMM
733         bne spd_fail
734         oris r7,r7,0x1000       /* set SD_TIMING[DIMM_TYPE] bit */
735
736 do_cl:
737         READ_SPD(18)    /* Get CAS Latency */
738         beq     spd_read_fail
739         li r5,ERR_CL_VALUE
740         andi. r6,r3,SPD_CAS_3
741         beq cl_4
742         li r6,3
743         b set_cl
744 cl_4:
745         andi. r6,r3,SPD_CAS_4
746         beq cl_5
747         li r6,4
748         b set_cl
749 cl_5:
750         andi. r6,r3,SPD_CAS_5
751         beq spd_fail
752         li r6,5
753 set_cl:
754         rlwimi r7,r6,24,5,7
755
756         READ_SPD(30)    /* Get tRAS */
757         beq     spd_read_fail
758         divwu r6,r3,r9
759         mullw r8,r6,r9
760         subf. r8,r8,r3
761         beq     set_tras
762         addi r6,r6,1
763 set_tras:
764         li r5,ERR_TRAS_FAIL
765         cmpi 0,0,r6,0x0F        /* max supported value */
766         bgt spd_fail
767         rlwimi r7,r6,16,12,15
768
769         READ_SPD(29)    /* Get tRCD */
770         beq     spd_read_fail
771         rlwinm r3,r3,30,2,31/* right shift tRCD by 2 bits as per DDR2 spec */
772         divwu r6,r3,r9
773         mullw r8,r6,r9
774         subf. r8,r8,r3
775         beq     set_trcd
776         addi r6,r6,1
777 set_trcd:
778         li r5,ERR_TRCD_FAIL
779         cmpi 0,0,r6,0x07        /* max supported value */
780         bgt spd_fail
781         rlwimi r7,r6,12,17,19
782
783         READ_SPD(27)    /* Get tRP value */
784         beq     spd_read_fail
785         rlwinm r3,r3,30,2,31    /* right shift tRP by 2 bits as per DDR2 spec */
786         divwu r6,r3,r9
787         mullw r8,r6,r9
788         subf. r8,r8,r3
789         beq     set_trp
790         addi r6,r6,1
791 set_trp:
792         li r5,ERR_TRP_FAIL
793         cmpi 0,0,r6,0x07        /* max supported value */
794         bgt spd_fail
795         rlwimi r7,r6,8,21,23
796
797         READ_SPD(36)    /* Get tWR value */
798         beq     spd_read_fail
799         rlwinm r3,r3,30,2,31    /* right shift tWR by 2 bits as per DDR2 spec */
800         divwu r6,r3,r9
801         mullw r8,r6,r9
802         subf. r8,r8,r3
803         beq     set_twr
804         addi r6,r6,1
805 set_twr:
806         addi r6,r6,-1           /* Tsi108 SDC always gives one extra clock */
807         li r5,ERR_TWR_FAIL
808         cmpi 0,0,r6,0x07        /* max supported value */
809         bgt spd_fail
810         rlwimi r7,r6,5,24,26
811
812         READ_SPD(42)    /* Get tRFC */
813         beq     spd_read_fail
814         li r5, ERR_TRFC_FAIL
815         /* Tsi108 spec: tRFC=(tRFC + 1)/2 */
816         addi r3,r3,1
817         rlwinm. r3,r3,31,1,31 /* divide by 2 */
818         beq spd_fail
819         divwu r6,r3,r9
820         mullw r8,r6,r9
821         subf. r8,r8,r3
822         beq     set_trfc
823         addi r6,r6,1
824 set_trfc:
825         cmpi 0,0,r6,0x1F        /* max supported value */
826         bgt spd_fail
827         rlwimi r7,r6,0,27,31
828
829         stw     r7,SD_TIMING(r4)
830         sync
831
832         /*=====================================================================
833          * The following two registers are set on per-DIMM basis.
834          * The SD_REFRESH and SD_TIMING settings are common for both DIMMS
835          *=====================================================================
836          */
837
838 do_each_dimm:
839
840         /*****************************************
841          * Program SDRAM DIMM Control Register
842          */
843
844         li r7, 0                /* clear r7 prior parameter collection */
845
846         READ_SPD(13)            /* Get Primary SDRAM Width */
847         beq     spd_read_fail
848         cmpi 0,0,r3,4   /* Check for 4-bit SDRAM */
849         beq do_nbank
850         oris r7,r7,0x0010       /* Set MEM_WIDTH bit */
851
852 do_nbank:
853         READ_SPD(17)            /* Get Number of banks on SDRAM device */
854         beq     spd_read_fail
855         /* Grendel only distinguish betw. 4 or 8-bank memory parts */
856         li r5,ERR_UNKNOWN_PART  /* non-supported memory part */
857         cmpi 0,0,r3,4
858         beq do_nrank
859         cmpi 0,0,r3,8
860         bne spd_fail
861         ori r7,r7,0x1000
862
863 do_nrank:
864         READ_SPD(5)     /* Get # of Ranks */
865         beq     spd_read_fail
866         li r5,ERR_NRANK_INVALID
867         andi. r6,r3,0x7 /* Use bits [2..0] only */
868         beq do_addr_mode
869         cmpi 0,0,r6,1
870         bgt spd_fail
871         rlwimi r7,r6,8,23,23
872
873 do_addr_mode:
874         READ_SPD(4)     /* Get # of Column Addresses */
875         beq     spd_read_fail
876         li r5, ERR_ADDR_MODE
877         andi. r3,r3,0x0f        /* cut off reserved bits */
878         cmpi 0,0,r3,8
879         ble spd_fail
880         cmpi 0,0,r3,15
881         bgt spd_fail
882         addi r6,r3,-8   /* calculate ADDR_MODE parameter */
883         rlwimi r7,r6,4,24,27    /* set ADDR_MODE field */
884
885 set_dimm_ctrl:
886 #ifdef SDC_AUTOPRECH_EN
887     oris r7,r7,0x0001   /* set auto precharge EN bit */
888 #endif
889         ori r7,r7,1     /* set ENABLE bit */
890         cmpi 0,0,r10,SPD_DIMM0
891         bne 1f
892         stw r7,SD_D0_CTRL(r4)
893         sync
894         b set_dimm_bar
895 1:
896         stw r7,SD_D1_CTRL(r4)
897         sync
898
899
900         /********************************************
901          * Program SDRAM DIMMx Base Address Register
902          */
903
904 set_dimm_bar:
905         READ_SPD(5)             /* get # of Ranks */
906         beq     spd_read_fail
907         andi.r7,r3,0x7
908         addi r7,r7,1
909         READ_SPD(31)    /* Read DIMM rank density */
910         beq     spd_read_fail
911         rlwinm r5,r3,27,29,31
912         rlwinm r6,r3,3,24,28
913         or r5,r6,r5             /* r5 = Normalized Rank Density byte */
914         lis r8, 0x0080          /* 128MB >> 4 */
915         mullw r8,r8,r5          /* r8 = (rank_size >> 4) */
916         mullw r8,r8,r7          /* r8 = (DIMM_size >> 4) */
917         neg r7,r8
918         rlwinm r7,r7,28,4,31
919         or r7,r7,r11            /* set ADDR field */
920         rlwinm r8,r8,12,20,31
921         add r11,r11,r8          /* set Base Addr for next DIMM */
922
923         cmpi 0,0,r10,SPD_DIMM0
924         bne set_dimm1_size
925         stw r7,SD_D0_BAR(r4)
926         sync
927         li r10,SPD_DIMM1
928         READ_SPD(0)
929         bne do_each_dimm
930         b spd_done
931
932 set_dimm1_size:
933         stw r7,SD_D1_BAR(r4)
934         sync
935 spd_done:
936         blr
937
938 check_next_slot:
939         cmpi 0,0,r10,SPD_DIMM1
940         beq spd_read_fail
941         li r10,SPD_DIMM1
942         b do_first_dimm
943 spd_read_fail:
944         ori     r3,r0,0xdead
945         b err_hung
946 spd_fail:
947         li      r3,0x0bad
948         sync
949 err_hung:   /* hang here for debugging */
950     nop
951     nop
952     b err_hung
953
954 #endif /* !SDC_HARDCODED_INIT */
955