]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/freescale/mpc7448hpc2/asm_init.S
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / board / freescale / 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 /*
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
101 sdc_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
120 board_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,CONFIG_SYS_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
175 cont_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
187 cont_brd_init:
188
189 #endif /* CONFIG_DUAL_CPU */
190
191         /* Initialize Tsi108 chip */
192
193 do_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 (CONFIG_SYS_TSI108_CSR_BASE != CONFIG_SYS_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,(CONFIG_SYS_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
281 sdc_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
300 get_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
366 check_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
404 set_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
438 sdc_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
460 wait_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
504 init_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
518 enable_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
537 enable_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
549 disable_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
560 enable_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
574 clear_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;              \
636 1:;                                     \
637         addic.  r3, r3, -1;             \
638         bne     1b;                     \
639 2:;                                     \
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
649 refresh_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
666 tsi108_sdram_spd:
667
668         li      r10,SPD_DIMM0
669         xor     r11,r11,r11             /* DIMM Base Address: starts from 0 */
670
671 do_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
704 do_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
712 cl_4:
713         andi.   r6,r3,SPD_CAS_4
714         beq     cl_5
715         li      r6,4
716         b       set_cl
717 cl_5:
718         andi.   r6,r3,SPD_CAS_5
719         beq     spd_fail
720         li      r6,5
721 set_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
731 set_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
746 set_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
760 set_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
774 set_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
793 set_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
806 do_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
818 do_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
829 do_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
839 do_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
851 set_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
861 1:
862         stw     r7,SD_D1_CTRL(r4)
863         sync
864
865
866         /* Program SDRAM DIMMx Base Address Register */
867
868 set_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
896 set_dimm1_size:
897         stw     r7,SD_D1_BAR(r4)
898         sync
899 spd_done:
900         blr
901
902 check_next_slot:
903         cmpi    0,0,r10,SPD_DIMM1
904         beq     spd_read_fail
905         li      r10,SPD_DIMM1
906         b       do_first_dimm
907 spd_read_fail:
908         ori     r3,r0,0xdead
909         b       err_hung
910 spd_fail:
911         li      r3,0x0bad
912         sync
913 err_hung:       /* hang here for debugging */
914         nop
915         nop
916         b       err_hung
917
918 #endif /* !SDC_HARDCODED_INIT */