source: SVN/rincon/u-boot/board/freescale/mpc7448hpc2/asm_init.S @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

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