]>
Commit | Line | Data |
---|---|---|
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 [email protected] | |
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 | |
101 | sdc_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 | 120 | board_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 | |
175 | cont_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 | ||
187 | cont_brd_init: | |
188 | ||
189 | #endif /* CONFIG_DUAL_CPU */ | |
190 | ||
ee311214 | 191 | /* Initialize Tsi108 chip */ |
625bb5dd | 192 | |
193 | do_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 | |
281 | sdc_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 | |
300 | get_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 | |
366 | check_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 | |
404 | set_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 | ||
438 | sdc_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 | |
460 | wait_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 | |
504 | init_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 | 518 | enable_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 | 537 | enable_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 | 549 | disable_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 | 560 | enable_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 | 574 | clear_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; \ | |
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) | |
625bb5dd | 645 | |
646 | #define SPD_MIN_RFRSH (0x80) | |
647 | #define SPD_MAX_RFRSH (0x85) | |
648 | ||
ee311214 | 649 | refresh_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 | |
666 | tsi108_sdram_spd: | |
667 | ||
ee311214 | 668 | li r10,SPD_DIMM0 |
625bb5dd | 669 | xor r11,r11,r11 /* DIMM Base Address: starts from 0 */ |
670 | ||
671 | do_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 | |
704 | do_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 | 712 | cl_4: |
ee311214 | 713 | andi. r6,r3,SPD_CAS_4 |
714 | beq cl_5 | |
715 | li r6,4 | |
716 | b set_cl | |
625bb5dd | 717 | cl_5: |
ee311214 | 718 | andi. r6,r3,SPD_CAS_5 |
719 | beq spd_fail | |
720 | li r6,5 | |
625bb5dd | 721 | set_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 | 731 | set_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 | 746 | set_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 | 760 | set_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 | 774 | set_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 | 793 | set_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 | ||
806 | do_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 | |
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 */ | |
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 | |
829 | do_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 | |
839 | do_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 | |
851 | set_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 | 861 | 1: |
ee311214 | 862 | stw r7,SD_D1_CTRL(r4) |
625bb5dd | 863 | sync |
864 | ||
865 | ||
ee311214 | 866 | /* Program SDRAM DIMMx Base Address Register */ |
625bb5dd | 867 | |
868 | set_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 | ||
896 | set_dimm1_size: | |
ee311214 | 897 | stw r7,SD_D1_BAR(r4) |
625bb5dd | 898 | sync |
899 | spd_done: | |
900 | blr | |
901 | ||
902 | check_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 | 907 | spd_read_fail: |
908 | ori r3,r0,0xdead | |
ee311214 | 909 | b err_hung |
625bb5dd | 910 | spd_fail: |
911 | li r3,0x0bad | |
912 | sync | |
ee311214 | 913 | err_hung: /* hang here for debugging */ |
914 | nop | |
915 | nop | |
916 | b err_hung | |
625bb5dd | 917 | |
918 | #endif /* !SDC_HARDCODED_INIT */ |