]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/freescale/mpc7448hpc2/asm_init.S
rename CFG_ macros to CONFIG_SYS
[people/ms/u-boot.git] / board / freescale / mpc7448hpc2 / asm_init.S
CommitLineData
ee311214 1/*
625bb5dd 2 * (C) Copyright 2004-05; Tundra Semiconductor Corp.
ee311214 3 *
625bb5dd 4 * Added automatic detect of SDC settings
5 * Copyright (c) 2005 Freescale Semiconductor, Inc.
6 * Maintainer tie-fei.zang@freescale.com
ee311214 7 *
625bb5dd 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
ee311214 22 */
625bb5dd 23
ee311214 24/*
625bb5dd 25 * FILENAME: asm_init.s
26 *
27 * Originator: Alex Bounine
28 *
29 * DESCRIPTION:
30 * Initialization code for the Tundra Tsi108 bridge chip
31 *
ee311214 32 */
625bb5dd 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
ee311214 43/*
625bb5dd 44 * Build Configuration Options
45 */
46
ee311214 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 */
625bb5dd 50
ee311214 51/*
625bb5dd 52 * Hardcoded SDC settings
53 */
54
55#ifdef SDC_HARDCODED_INIT
56
57/* Micron MT9HTF6472AY-40EA1 : Unbuffered, 512MB, 400, CL3, Single Rank */
58
ee311214 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 */
625bb5dd 65
66#endif /* SDC_HARDCODED_INIT */
67
ee311214 68/*
625bb5dd 69 CPU Configuration:
70
71 CPU Address and Data Parity enables.
72
73#define CPU_AP
74#define CPU_DP
ee311214 75*/
625bb5dd 76
ee311214 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 */
625bb5dd 86
87#define LOAD_PTR(reg,const32) \
ee311214 88 addis reg,r0,const32@h; ori reg,reg,const32@l
625bb5dd 89
90#define LOAD_U32(reg,const32) \
ee311214 91 addis reg,r0,const32@h; ori reg,reg,const32@l
625bb5dd 92
ee311214 93/* LOADMEM initializes a register with the contents of a specified 32-bit
94 * memory location, usually a CSR value.
95 */
625bb5dd 96
97#define LOAD_MEM(reg,addr32) \
ee311214 98 addis reg,r0,addr32@ha; lwz reg,addr32@l(reg)
625bb5dd 99
100#ifndef SDC_HARDCODED_INIT
101sdc_clk_sync:
102 /* MHz: 0,0,183,100,133,167,200,233 */
ee311214 103 .long 0, 0, 6, 10, 8, 6, 5, 4 /* nSec */
625bb5dd 104#endif
105
ee311214 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 */
625bb5dd 118
ee311214 119 .globl board_asm_init
625bb5dd 120board_asm_init:
ee311214 121 mflr r19 /* Save LR to be able return later. */
122 bl icache_enable /* Enable icache to reduce reads from flash. */
625bb5dd 123
ee311214 124/* Initialize pointer to Tsi108 register space */
625bb5dd 125
6d0f6bcf 126 LOAD_PTR(r29,CONFIG_SYS_TSI108_CSR_RST_BASE)/* r29 - pointer to tsi108 CSR space */
ee311214 127 ori r4,r29,TSI108_PB_REG_OFFSET
625bb5dd 128
ee311214 129/* Check Processor Version Number */
625bb5dd 130
ee311214 131 mfspr r3, PVR
132 rlwinm r3,r3,16,16,23 /* get ((Processor Version Number) & 0xFF00) */
625bb5dd 133
ee311214 134 cmpli 0,0,r3,0x8000 /* MPC74xx */
135 bne cont_brd_init
625bb5dd 136
ee311214 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 */
625bb5dd 142
ee311214 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
625bb5dd 149
ee311214 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
625bb5dd 156
ee311214 157 /* Sri: code to enable FP unit */
158 mfmsr r3
159 ori r3, r3, 0x2000
160 mtmsr r3
161 isync
162 sync
625bb5dd 163
ee311214 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
625bb5dd 174
175cont_brd_init:
176
ee311214 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 */
625bb5dd 181
ee311214 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
625bb5dd 185#else
186
187cont_brd_init:
188
189#endif /* CONFIG_DUAL_CPU */
190
ee311214 191 /* Initialize Tsi108 chip */
625bb5dd 192
193do_tsi108_init:
194
ee311214 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 */
625bb5dd 202
203#ifdef CONFIG_TSI108EMU
ee311214 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
625bb5dd 211#endif
212
ee311214 213 /* Initialize PB interface. */
625bb5dd 214
ee311214 215 ori r4,r29,TSI108_PB_REG_OFFSET
625bb5dd 216
6d0f6bcf 217#if (CONFIG_SYS_TSI108_CSR_BASE != CONFIG_SYS_TSI108_CSR_RST_BASE)
ee311214 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 */
6d0f6bcf 222 LOAD_U32(r5,(CONFIG_SYS_TSI108_CSR_BASE | 0x01)) /* PB_REG_BAR: BA + EN */
ee311214 223 stw r5,PB_REG_BAR(r4)
224 andis. r29,r5,0xFFFF
225 sync
226 ori r4,r29,TSI108_PB_REG_OFFSET
625bb5dd 227#endif
228
ee311214 229 /* Set PB Slave configuration register */
625bb5dd 230
ee311214 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
625bb5dd 237
ee311214 238 /* Configure PB Arbiter */
625bb5dd 239
ee311214 240 lwz r5,PB_ARB_CTRL(r4) /* Read PB Arbiter Control Register */
241 li r3, 0x00F0 /* ARB_PIPELINE_DEP mask */
625bb5dd 242#ifdef DISABLE_PBM
ee311214 243 ori r3,r3,0x1000 /* add PBM_EN to clear (enabled by default) */
625bb5dd 244#endif
ee311214 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
625bb5dd 257#endif
258
ee311214 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 */
625bb5dd 264
ee311214 265 LOAD_U32(r3,0xC0002234)
266 lwz r3,0(r3)
267 rlwinm r3,r3,16,29,31
625bb5dd 268
ee311214 269 cmpi 0,0,r3,0x0004
270 bgt sdc_init
625bb5dd 271
272#ifndef CONFIG_TSI108EMU
ee311214 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
625bb5dd 277#endif
278
ee311214 279 /* Initialize SDRAM controller. */
625bb5dd 280
281sdc_init:
282
283#ifndef SDC_HARDCODED_INIT
ee311214 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
625bb5dd 299
300get_nsec:
ee311214 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 */
625bb5dd 304#endif /* !SDC_HARDCODED_INIT */
305
ee311214 306 ori r4,r29,TSI108_SD_REG_OFFSET /* r4 - ptr to SDRAM registers */
625bb5dd 307
ee311214 308 /* Initialize SDRAM controller. SDRAM Size = 512MB, One DIMM. */
625bb5dd 309
ee311214 310 LOAD_U32(r5,0x00)
311 stw r5,SD_INT_ENABLE(r4) /* Ensure that interrupts are disabled */
625bb5dd 312#ifdef ENABLE_SDRAM_ECC
ee311214 313 li r5, 0x01
625bb5dd 314#endif /* ENABLE_SDRAM_ECC */
ee311214 315 stw r5,SD_ECC_CTRL(r4) /* Enable/Disable ECC */
316 sync
625bb5dd 317
318#ifdef SDC_HARDCODED_INIT /* config sdram controller with hardcoded values */
319
ee311214 320 /* First read the CG_PWRUP_STATUS register to get the
321 * memory speed from bits 22,21,20
322 */
625bb5dd 323
ee311214 324 LOAD_U32(r3,0xC0002234)
325 lwz r3,0(r3)
326 rlwinm r3,r3,12,29,31
625bb5dd 327
ee311214 328 /* Now first check for 166, then 200, or default */
625bb5dd 329
ee311214 330 cmpi 0,0,r3,0x0005
331 bne check_for_200mhz
625bb5dd 332
ee311214 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
625bb5dd 341
ee311214 342 /* Initialize DIMM0 control and BAR registers */
343 LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
625bb5dd 344#ifdef SDC_AUTOPRECH_EN
ee311214 345 oris r5,r5,0x0001 /* set auto precharge EN bit */
625bb5dd 346#endif
ee311214 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 */
625bb5dd 356#ifdef SDC_AUTOPRECH_EN
ee311214 357 oris r5,r5,0x0001 /* set auto precharge EN bit */
625bb5dd 358#endif
ee311214 359 stw r5,SD_D1_CTRL(r4)
360 LOAD_U32(r5,VAL_SD_D1_BAR)
361 stw r5,SD_D1_BAR(r4)
362 sync
625bb5dd 363
ee311214 364 b sdc_init_done
625bb5dd 365
366check_for_200mhz:
367
ee311214 368 cmpi 0,0,r3,0x0006
369 bne set_default_values
625bb5dd 370
ee311214 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
625bb5dd 379
ee311214 380 /* Initialize DIMM0 control and BAR registers */
381 LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
625bb5dd 382#ifdef SDC_AUTOPRECH_EN
ee311214 383 oris r5,r5,0x0001 /* set auto precharge EN bit */
625bb5dd 384#endif
ee311214 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 */
625bb5dd 394#ifdef SDC_AUTOPRECH_EN
ee311214 395 oris r5,r5,0x0001 /* set auto precharge EN bit */
625bb5dd 396#endif
ee311214 397 stw r5,SD_D1_CTRL(r4)
398 LOAD_U32(r5,VAL_SD_D1_BAR)
399 stw r5,SD_D1_BAR(r4)
400 sync
625bb5dd 401
ee311214 402 b sdc_init_done
625bb5dd 403
404set_default_values:
405
ee311214 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
625bb5dd 412
ee311214 413 /* Initialize DIMM0 control and BAR registers */
414 LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
625bb5dd 415#ifdef SDC_AUTOPRECH_EN
ee311214 416 oris r5,r5,0x0001 /* set auto precharge EN bit */
625bb5dd 417#endif
53677ef1 418 stw r5,SD_D0_CTRL(r4)
ee311214 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 */
625bb5dd 427#ifdef SDC_AUTOPRECH_EN
ee311214 428 oris r5,r5,0x0001 /* set auto precharge EN bit */
625bb5dd 429#endif
ee311214 430 stw r5,SD_D1_CTRL(r4)
431 LOAD_U32(r5,VAL_SD_D1_BAR)
432 stw r5,SD_D1_BAR(r4)
433 sync
625bb5dd 434#else /* !SDC_HARDCODED_INIT */
ee311214 435 bl tsi108_sdram_spd /* automatically detect SDC settings */
625bb5dd 436#endif /* SDC_HARDCODED_INIT */
437
438sdc_init_done:
439
440#ifdef DISABLE_PBM
ee311214 441 LOAD_U32(r5,0x00000030) /* PB_EN + OCN_EN */
625bb5dd 442#else
ee311214 443 LOAD_U32(r5,0x00000230) /* PB_EN + OCN_EN + PB/OCN=80/20 */
625bb5dd 444#endif /* DISABLE_PBM */
445
446#ifdef CONFIG_TSI108EMU
ee311214 447 oris r5,r5,0x0010 /* set EMULATION_MODE bit */
625bb5dd 448#endif
449
ee311214 450 stw r5,SD_CTRL(r4)
451 eieio
452 sync
625bb5dd 453
ee311214 454 /* Enable SDRAM access */
625bb5dd 455
ee311214 456 oris r5,r5,0x8000 /* start SDC: set SD_CTRL[ENABLE] bit */
457 stw r5,SD_CTRL(r4)
458 sync
625bb5dd 459
460wait_init_complete:
ee311214 461 lwz r5,SD_STATUS(r4)
462 andi. r5,r5,0x0001
463 /* wait until SDRAM initialization is complete */
464 beq wait_init_complete
625bb5dd 465
ee311214 466 /* Map SDRAM into the processor bus address space */
625bb5dd 467
ee311214 468 ori r4,r29,TSI108_PB_REG_OFFSET
625bb5dd 469
ee311214 470 /* Setup BARs associated with direct path PB<->SDRAM */
625bb5dd 471
ee311214 472 /* PB_SDRAM_BAR1:
473 * provides a direct path to the main system memory (cacheable SDRAM)
474 */
625bb5dd 475
ee311214 476 /* BA=0,Size=512MB, ENable, No Addr.Translation */
477 LOAD_U32(r5, 0x00000011)
478 stw r5,PB_SDRAM_BAR1(r4)
479 sync
625bb5dd 480
ee311214 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
625bb5dd 486
ee311214 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 */
625bb5dd 493
ee311214 494 LOAD_U32(r5, 0x40010011)
495 stw r5,PB_SDRAM_BAR2(r4)
496 sync
625bb5dd 497
ee311214 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
625bb5dd 503
504init_done:
505
ee311214 506 /* All done. Restore LR and return. */
507 mtlr r19
508 blr
625bb5dd 509
510#if (0)
ee311214 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 */
625bb5dd 516
ee311214 517 .global enable_cpu1
625bb5dd 518enable_cpu1:
519
ee311214 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)
625bb5dd 527
ee311214 528 blr
625bb5dd 529#endif
530
ee311214 531 /*
532 * enable_EI
533 * Enable CPU core external interrupt
534 */
625bb5dd 535
ee311214 536 .global enable_EI
625bb5dd 537enable_EI:
ee311214 538 mfmsr r3
539 ori r3,r3,0x8000 /* set EE bit */
540 mtmsr r3
541 blr
625bb5dd 542
ee311214 543 /*
544 * disable_EI
545 * Disable CPU core external interrupt
546 */
625bb5dd 547
ee311214 548 .global disable_EI
625bb5dd 549disable_EI:
ee311214 550 mfmsr r3
551 li r4,-32768 /* aka "li r4,0x8000" */
552 andc r3,r3,r4 /* clear EE bit */
553 mtmsr r3
554 blr
625bb5dd 555
556#ifdef ENABLE_SDRAM_ECC
ee311214 557 /* enables SDRAM ECC */
625bb5dd 558
ee311214 559 .global enable_ECC
625bb5dd 560enable_ECC:
ee311214 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
625bb5dd 566
ee311214 567 /*
568 * clear_ECC_err
569 * Clears all pending SDRAM ECC errors
570 * (normally after SDRAM scrubbing/initialization)
571 */
625bb5dd 572
ee311214 573 .global clear_ECC_err
625bb5dd 574clear_ECC_err:
ee311214 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
625bb5dd 579
580#endif /* ENABLE_SDRAM_ECC */
581
582#ifndef SDC_HARDCODED_INIT
583
ee311214 584 /* SDRAM SPD Support */
625bb5dd 585#define SD_I2C_CTRL1 (0x400)
586#define SD_I2C_CTRL2 (0x404)
587#define SD_I2C_RD_DATA (0x408)
ee311214 588#define SD_I2C_WR_DATA (0x40C)
625bb5dd 589
ee311214 590 /*
591 * SDRAM SPD Support Macros
592 */
625bb5dd 593
594#define SPD_DIMM0 (0x00000100)
ee311214 595#define SPD_DIMM1 (0x00000200) /* SPD_DIMM1 was 0x00000000 */
625bb5dd 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
ee311214 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)
625bb5dd 645
646#define SPD_MIN_RFRSH (0x80)
647#define SPD_MAX_RFRSH (0x85)
648
ee311214 649refresh_rates: /* in nSec */
625bb5dd 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
ee311214 657/*
625bb5dd 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
ee311214 664 */
625bb5dd 665
666tsi108_sdram_spd:
667
ee311214 668 li r10,SPD_DIMM0
625bb5dd 669 xor r11,r11,r11 /* DIMM Base Address: starts from 0 */
670
671do_first_dimm:
672
ee311214 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
625bb5dd 690
ee311214 691 /* Program SD Timing Register */
625bb5dd 692
ee311214 693 li r7, 0 /* clear r7 prior parameter collection */
625bb5dd 694
ee311214 695 READ_SPD(20) /* get DIMM type: Registered or Unbuffered */
625bb5dd 696 beq spd_read_fail
ee311214 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 */
625bb5dd 703
704do_cl:
ee311214 705 READ_SPD(18) /* Get CAS Latency */
625bb5dd 706 beq spd_read_fail
ee311214 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
625bb5dd 712cl_4:
ee311214 713 andi. r6,r3,SPD_CAS_4
714 beq cl_5
715 li r6,4
716 b set_cl
625bb5dd 717cl_5:
ee311214 718 andi. r6,r3,SPD_CAS_5
719 beq spd_fail
720 li r6,5
625bb5dd 721set_cl:
ee311214 722 rlwimi r7,r6,24,5,7
625bb5dd 723
ee311214 724 READ_SPD(30) /* Get tRAS */
625bb5dd 725 beq spd_read_fail
ee311214 726 divwu r6,r3,r9
727 mullw r8,r6,r9
728 subf. r8,r8,r3
625bb5dd 729 beq set_tras
ee311214 730 addi r6,r6,1
625bb5dd 731set_tras:
732 li r5,ERR_TRAS_FAIL
ee311214 733 cmpi 0,0,r6,0x0F /* max supported value */
734 bgt spd_fail
735 rlwimi r7,r6,16,12,15
625bb5dd 736
737 READ_SPD(29) /* Get tRCD */
738 beq spd_read_fail
ee311214 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
625bb5dd 744 beq set_trcd
ee311214 745 addi r6,r6,1
625bb5dd 746set_trcd:
ee311214 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
625bb5dd 751
752 READ_SPD(27) /* Get tRP value */
753 beq spd_read_fail
ee311214 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
625bb5dd 758 beq set_trp
ee311214 759 addi r6,r6,1
625bb5dd 760set_trp:
ee311214 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
625bb5dd 765
766 READ_SPD(36) /* Get tWR value */
767 beq spd_read_fail
ee311214 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
625bb5dd 772 beq set_twr
ee311214 773 addi r6,r6,1
625bb5dd 774set_twr:
ee311214 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
625bb5dd 780
781 READ_SPD(42) /* Get tRFC */
782 beq spd_read_fail
ee311214 783 li r5, ERR_TRFC_FAIL
625bb5dd 784 /* Tsi108 spec: tRFC=(tRFC + 1)/2 */
ee311214 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
625bb5dd 791 beq set_trfc
ee311214 792 addi r6,r6,1
625bb5dd 793set_trfc:
ee311214 794 cmpi 0,0,r6,0x1F /* max supported value */
795 bgt spd_fail
796 rlwimi r7,r6,0,27,31
625bb5dd 797
798 stw r7,SD_TIMING(r4)
799 sync
800
ee311214 801 /*
625bb5dd 802 * The following two registers are set on per-DIMM basis.
803 * The SD_REFRESH and SD_TIMING settings are common for both DIMMS
625bb5dd 804 */
805
806do_each_dimm:
807
ee311214 808 /* Program SDRAM DIMM Control Register */
625bb5dd 809
ee311214 810 li r7, 0 /* clear r7 prior parameter collection */
625bb5dd 811
812 READ_SPD(13) /* Get Primary SDRAM Width */
813 beq spd_read_fail
ee311214 814 cmpi 0,0,r3,4 /* Check for 4-bit SDRAM */
815 beq do_nbank
816 oris r7,r7,0x0010 /* Set MEM_WIDTH bit */
625bb5dd 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 */
ee311214 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
625bb5dd 828
829do_nrank:
ee311214 830 READ_SPD(5) /* Get # of Ranks */
625bb5dd 831 beq spd_read_fail
ee311214 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
625bb5dd 838
839do_addr_mode:
ee311214 840 READ_SPD(4) /* Get # of Column Addresses */
625bb5dd 841 beq spd_read_fail
ee311214 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 */
625bb5dd 850
851set_dimm_ctrl:
852#ifdef SDC_AUTOPRECH_EN
ee311214 853 oris r7,r7,0x0001 /* set auto precharge EN bit */
625bb5dd 854#endif
ee311214 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)
625bb5dd 859 sync
ee311214 860 b set_dimm_bar
625bb5dd 8611:
ee311214 862 stw r7,SD_D1_CTRL(r4)
625bb5dd 863 sync
864
865
ee311214 866 /* Program SDRAM DIMMx Base Address Register */
625bb5dd 867
868set_dimm_bar:
869 READ_SPD(5) /* get # of Ranks */
870 beq spd_read_fail
ee311214 871 andi. r7,r3,0x7
872 addi r7,r7,1
873 READ_SPD(31) /* Read DIMM rank density */
625bb5dd 874 beq spd_read_fail
ee311214 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
625bb5dd 892 READ_SPD(0)
893 bne do_each_dimm
894 b spd_done
895
896set_dimm1_size:
ee311214 897 stw r7,SD_D1_BAR(r4)
625bb5dd 898 sync
899spd_done:
900 blr
901
902check_next_slot:
ee311214 903 cmpi 0,0,r10,SPD_DIMM1
904 beq spd_read_fail
905 li r10,SPD_DIMM1
906 b do_first_dimm
625bb5dd 907spd_read_fail:
908 ori r3,r0,0xdead
ee311214 909 b err_hung
625bb5dd 910spd_fail:
911 li r3,0x0bad
912 sync
ee311214 913err_hung: /* hang here for debugging */
914 nop
915 nop
916 b err_hung
625bb5dd 917
918#endif /* !SDC_HARDCODED_INIT */