]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/mpc7448hpc2/asm_init.S
Add mpc7448hpc2 (mpc7448 + tsi108) board associated code support.
[people/ms/u-boot.git] / board / mpc7448hpc2 / asm_init.S
CommitLineData
625bb5dd 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
100sdc_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
122board_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
182cont_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
196cont_brd_init:
197
198#endif /* CONFIG_DUAL_CPU */
199
200 /* Initialize Tsi108 chip
201 ---------------------------------------------------------------------------
202 */
203
204do_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
300sdc_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
319get_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
384check_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
422set_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
459sdc_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
481wait_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
521init_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
535enable_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
555enable_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
568disable_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
583enable_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
598clear_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;\
6641: ;\
665 addic. r3, r3, -1;\
666 bne 1b;\
6672: ;\
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
677refresh_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
694tsi108_sdram_spd:
695
696 li r10,SPD_DIMM0
697 xor r11,r11,r11 /* DIMM Base Address: starts from 0 */
698
699do_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
736do_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
744cl_4:
745 andi. r6,r3,SPD_CAS_4
746 beq cl_5
747 li r6,4
748 b set_cl
749cl_5:
750 andi. r6,r3,SPD_CAS_5
751 beq spd_fail
752 li r6,5
753set_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
763set_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
777set_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
791set_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
805set_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
824set_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
838do_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
852do_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
863do_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
873do_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
885set_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
8951:
896 stw r7,SD_D1_CTRL(r4)
897 sync
898
899
900 /********************************************
901 * Program SDRAM DIMMx Base Address Register
902 */
903
904set_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
932set_dimm1_size:
933 stw r7,SD_D1_BAR(r4)
934 sync
935spd_done:
936 blr
937
938check_next_slot:
939 cmpi 0,0,r10,SPD_DIMM1
940 beq spd_read_fail
941 li r10,SPD_DIMM1
942 b do_first_dimm
943spd_read_fail:
944 ori r3,r0,0xdead
945 b err_hung
946spd_fail:
947 li r3,0x0bad
948 sync
949err_hung: /* hang here for debugging */
950 nop
951 nop
952 b err_hung
953
954#endif /* !SDC_HARDCODED_INIT */
955