]> git.ipfire.org Git - people/ms/u-boot.git/blob - board/mpc7448hpc2/asm_init.S
FSL: Move board/mpc8260ads under board/freescale
[people/ms/u-boot.git] / 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 /*
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,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
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 (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
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 */