blob: a7a40a134c76fe7a2060bec341aba9558d9e8289 [file] [log] [blame]
roy zang92dda872006-12-01 11:47:36 +08001/*
roy zangaceddd82006-11-02 18:52:21 +08002 * (C) Copyright 2004-05; Tundra Semiconductor Corp.
roy zang92dda872006-12-01 11:47:36 +08003 *
roy zangaceddd82006-11-02 18:52:21 +08004 * Added automatic detect of SDC settings
5 * Copyright (c) 2005 Freescale Semiconductor, Inc.
6 * Maintainer tie-fei.zang@freescale.com
roy zang92dda872006-12-01 11:47:36 +08007 *
roy zangaceddd82006-11-02 18:52:21 +08008 * 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
roy zang92dda872006-12-01 11:47:36 +080022 */
roy zangaceddd82006-11-02 18:52:21 +080023
roy zang92dda872006-12-01 11:47:36 +080024/*
roy zangaceddd82006-11-02 18:52:21 +080025 * FILENAME: asm_init.s
26 *
27 * Originator: Alex Bounine
28 *
29 * DESCRIPTION:
30 * Initialization code for the Tundra Tsi108 bridge chip
31 *
roy zang92dda872006-12-01 11:47:36 +080032 */
roy zangaceddd82006-11-02 18:52:21 +080033
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
roy zang92dda872006-12-01 11:47:36 +080043/*
roy zangaceddd82006-11-02 18:52:21 +080044 * Build Configuration Options
45 */
46
roy zang92dda872006-12-01 11:47:36 +080047/* #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 */
roy zangaceddd82006-11-02 18:52:21 +080050
roy zang92dda872006-12-01 11:47:36 +080051/*
roy zangaceddd82006-11-02 18:52:21 +080052 * Hardcoded SDC settings
53 */
54
55#ifdef SDC_HARDCODED_INIT
56
57/* Micron MT9HTF6472AY-40EA1 : Unbuffered, 512MB, 400, CL3, Single Rank */
58
roy zang92dda872006-12-01 11:47:36 +080059#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 */
roy zangaceddd82006-11-02 18:52:21 +080065
66#endif /* SDC_HARDCODED_INIT */
67
roy zang92dda872006-12-01 11:47:36 +080068/*
roy zangaceddd82006-11-02 18:52:21 +080069 CPU Configuration:
70
71 CPU Address and Data Parity enables.
72
73#define CPU_AP
74#define CPU_DP
roy zang92dda872006-12-01 11:47:36 +080075*/
roy zangaceddd82006-11-02 18:52:21 +080076
roy zang92dda872006-12-01 11:47:36 +080077/*
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 */
roy zangaceddd82006-11-02 18:52:21 +080086
87#define LOAD_PTR(reg,const32) \
roy zang92dda872006-12-01 11:47:36 +080088 addis reg,r0,const32@h; ori reg,reg,const32@l
roy zangaceddd82006-11-02 18:52:21 +080089
90#define LOAD_U32(reg,const32) \
roy zang92dda872006-12-01 11:47:36 +080091 addis reg,r0,const32@h; ori reg,reg,const32@l
roy zangaceddd82006-11-02 18:52:21 +080092
roy zang92dda872006-12-01 11:47:36 +080093/* LOADMEM initializes a register with the contents of a specified 32-bit
94 * memory location, usually a CSR value.
95 */
roy zangaceddd82006-11-02 18:52:21 +080096
97#define LOAD_MEM(reg,addr32) \
roy zang92dda872006-12-01 11:47:36 +080098 addis reg,r0,addr32@ha; lwz reg,addr32@l(reg)
roy zangaceddd82006-11-02 18:52:21 +080099
100#ifndef SDC_HARDCODED_INIT
101sdc_clk_sync:
102 /* MHz: 0,0,183,100,133,167,200,233 */
roy zang92dda872006-12-01 11:47:36 +0800103 .long 0, 0, 6, 10, 8, 6, 5, 4 /* nSec */
roy zangaceddd82006-11-02 18:52:21 +0800104#endif
105
roy zang92dda872006-12-01 11:47:36 +0800106/*
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 */
roy zangaceddd82006-11-02 18:52:21 +0800118
roy zang92dda872006-12-01 11:47:36 +0800119 .globl board_asm_init
roy zangaceddd82006-11-02 18:52:21 +0800120board_asm_init:
roy zang92dda872006-12-01 11:47:36 +0800121 mflr r19 /* Save LR to be able return later. */
122 bl icache_enable /* Enable icache to reduce reads from flash. */
roy zangaceddd82006-11-02 18:52:21 +0800123
roy zang92dda872006-12-01 11:47:36 +0800124/* Initialize pointer to Tsi108 register space */
roy zangaceddd82006-11-02 18:52:21 +0800125
roy zang92dda872006-12-01 11:47:36 +0800126 LOAD_PTR(r29,CFG_TSI108_CSR_RST_BASE)/* r29 - pointer to tsi108 CSR space */
127 ori r4,r29,TSI108_PB_REG_OFFSET
roy zangaceddd82006-11-02 18:52:21 +0800128
roy zang92dda872006-12-01 11:47:36 +0800129/* Check Processor Version Number */
roy zangaceddd82006-11-02 18:52:21 +0800130
roy zang92dda872006-12-01 11:47:36 +0800131 mfspr r3, PVR
132 rlwinm r3,r3,16,16,23 /* get ((Processor Version Number) & 0xFF00) */
roy zangaceddd82006-11-02 18:52:21 +0800133
roy zang92dda872006-12-01 11:47:36 +0800134 cmpli 0,0,r3,0x8000 /* MPC74xx */
135 bne cont_brd_init
roy zangaceddd82006-11-02 18:52:21 +0800136
roy zang92dda872006-12-01 11:47:36 +0800137 /*
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 */
roy zangaceddd82006-11-02 18:52:21 +0800142
roy zang92dda872006-12-01 11:47:36 +0800143 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
roy zangaceddd82006-11-02 18:52:21 +0800149
roy zang92dda872006-12-01 11:47:36 +0800150 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800156
roy zang92dda872006-12-01 11:47:36 +0800157 /* Sri: code to enable FP unit */
158 mfmsr r3
159 ori r3, r3, 0x2000
160 mtmsr r3
161 isync
162 sync
roy zangaceddd82006-11-02 18:52:21 +0800163
roy zang92dda872006-12-01 11:47:36 +0800164 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800174
175cont_brd_init:
176
roy zang92dda872006-12-01 11:47:36 +0800177 /* 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 */
roy zangaceddd82006-11-02 18:52:21 +0800181
roy zang92dda872006-12-01 11:47:36 +0800182 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
roy zangaceddd82006-11-02 18:52:21 +0800185#else
186
187cont_brd_init:
188
189#endif /* CONFIG_DUAL_CPU */
190
roy zang92dda872006-12-01 11:47:36 +0800191 /* Initialize Tsi108 chip */
roy zangaceddd82006-11-02 18:52:21 +0800192
193do_tsi108_init:
194
roy zang92dda872006-12-01 11:47:36 +0800195 /*
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 */
roy zangaceddd82006-11-02 18:52:21 +0800202
203#ifdef CONFIG_TSI108EMU
roy zang92dda872006-12-01 11:47:36 +0800204 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
roy zangaceddd82006-11-02 18:52:21 +0800211#endif
212
roy zang92dda872006-12-01 11:47:36 +0800213 /* Initialize PB interface. */
roy zangaceddd82006-11-02 18:52:21 +0800214
roy zang92dda872006-12-01 11:47:36 +0800215 ori r4,r29,TSI108_PB_REG_OFFSET
roy zangaceddd82006-11-02 18:52:21 +0800216
217#if (CFG_TSI108_CSR_BASE != CFG_TSI108_CSR_RST_BASE)
roy zang92dda872006-12-01 11:47:36 +0800218 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800227#endif
228
roy zang92dda872006-12-01 11:47:36 +0800229 /* Set PB Slave configuration register */
roy zangaceddd82006-11-02 18:52:21 +0800230
roy zang92dda872006-12-01 11:47:36 +0800231 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
roy zangaceddd82006-11-02 18:52:21 +0800237
roy zang92dda872006-12-01 11:47:36 +0800238 /* Configure PB Arbiter */
roy zangaceddd82006-11-02 18:52:21 +0800239
roy zang92dda872006-12-01 11:47:36 +0800240 lwz r5,PB_ARB_CTRL(r4) /* Read PB Arbiter Control Register */
241 li r3, 0x00F0 /* ARB_PIPELINE_DEP mask */
roy zangaceddd82006-11-02 18:52:21 +0800242#ifdef DISABLE_PBM
roy zang92dda872006-12-01 11:47:36 +0800243 ori r3,r3,0x1000 /* add PBM_EN to clear (enabled by default) */
roy zangaceddd82006-11-02 18:52:21 +0800244#endif
roy zang92dda872006-12-01 11:47:36 +0800245 andc r5,r5,r3 /* Clear the masked bit fields */
246 ori r5,r5,0x0001 /* Set pipeline depth */
247 stw r5,PB_ARB_CTRL(r4)
roy zangaceddd82006-11-02 18:52:21 +0800248
roy zang92dda872006-12-01 11:47:36 +0800249#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
roy zangaceddd82006-11-02 18:52:21 +0800253
roy zang92dda872006-12-01 11:47:36 +0800254 LOAD_U32(r5,0x) /* value for PB_MCMD */
255 stw r5,PB_MCMD(r4)
256 sync
roy zangaceddd82006-11-02 18:52:21 +0800257#endif
258
roy zang92dda872006-12-01 11:47:36 +0800259 /* 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 */
roy zangaceddd82006-11-02 18:52:21 +0800264
roy zang92dda872006-12-01 11:47:36 +0800265 LOAD_U32(r3,0xC0002234)
266 lwz r3,0(r3)
267 rlwinm r3,r3,16,29,31
roy zangaceddd82006-11-02 18:52:21 +0800268
roy zang92dda872006-12-01 11:47:36 +0800269 cmpi 0,0,r3,0x0004
270 bgt sdc_init
roy zangaceddd82006-11-02 18:52:21 +0800271
272#ifndef CONFIG_TSI108EMU
roy zang92dda872006-12-01 11:47:36 +0800273 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800277#endif
278
roy zang92dda872006-12-01 11:47:36 +0800279 /* Initialize SDRAM controller. */
roy zangaceddd82006-11-02 18:52:21 +0800280
281sdc_init:
282
283#ifndef SDC_HARDCODED_INIT
roy zang92dda872006-12-01 11:47:36 +0800284 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800299
300get_nsec:
roy zang92dda872006-12-01 11:47:36 +0800301 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 */
roy zangaceddd82006-11-02 18:52:21 +0800304#endif /* !SDC_HARDCODED_INIT */
305
roy zang92dda872006-12-01 11:47:36 +0800306 ori r4,r29,TSI108_SD_REG_OFFSET /* r4 - ptr to SDRAM registers */
roy zangaceddd82006-11-02 18:52:21 +0800307
roy zang92dda872006-12-01 11:47:36 +0800308 /* Initialize SDRAM controller. SDRAM Size = 512MB, One DIMM. */
roy zangaceddd82006-11-02 18:52:21 +0800309
roy zang92dda872006-12-01 11:47:36 +0800310 LOAD_U32(r5,0x00)
311 stw r5,SD_INT_ENABLE(r4) /* Ensure that interrupts are disabled */
roy zangaceddd82006-11-02 18:52:21 +0800312#ifdef ENABLE_SDRAM_ECC
roy zang92dda872006-12-01 11:47:36 +0800313 li r5, 0x01
roy zangaceddd82006-11-02 18:52:21 +0800314#endif /* ENABLE_SDRAM_ECC */
roy zang92dda872006-12-01 11:47:36 +0800315 stw r5,SD_ECC_CTRL(r4) /* Enable/Disable ECC */
316 sync
roy zangaceddd82006-11-02 18:52:21 +0800317
318#ifdef SDC_HARDCODED_INIT /* config sdram controller with hardcoded values */
319
roy zang92dda872006-12-01 11:47:36 +0800320 /* First read the CG_PWRUP_STATUS register to get the
321 * memory speed from bits 22,21,20
322 */
roy zangaceddd82006-11-02 18:52:21 +0800323
roy zang92dda872006-12-01 11:47:36 +0800324 LOAD_U32(r3,0xC0002234)
325 lwz r3,0(r3)
326 rlwinm r3,r3,12,29,31
roy zangaceddd82006-11-02 18:52:21 +0800327
roy zang92dda872006-12-01 11:47:36 +0800328 /* Now first check for 166, then 200, or default */
roy zangaceddd82006-11-02 18:52:21 +0800329
roy zang92dda872006-12-01 11:47:36 +0800330 cmpi 0,0,r3,0x0005
331 bne check_for_200mhz
roy zangaceddd82006-11-02 18:52:21 +0800332
roy zang92dda872006-12-01 11:47:36 +0800333 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800341
roy zang92dda872006-12-01 11:47:36 +0800342 /* Initialize DIMM0 control and BAR registers */
343 LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
roy zangaceddd82006-11-02 18:52:21 +0800344#ifdef SDC_AUTOPRECH_EN
roy zang92dda872006-12-01 11:47:36 +0800345 oris r5,r5,0x0001 /* set auto precharge EN bit */
roy zangaceddd82006-11-02 18:52:21 +0800346#endif
roy zang92dda872006-12-01 11:47:36 +0800347 stw r5,SD_D0_CTRL(r4)
348 LOAD_U32(r5,VAL_SD_D0_BAR)
349 stw r5,SD_D0_BAR(r4)
350 sync
roy zangaceddd82006-11-02 18:52:21 +0800351
roy zang92dda872006-12-01 11:47:36 +0800352 /* 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 */
roy zangaceddd82006-11-02 18:52:21 +0800356#ifdef SDC_AUTOPRECH_EN
roy zang92dda872006-12-01 11:47:36 +0800357 oris r5,r5,0x0001 /* set auto precharge EN bit */
roy zangaceddd82006-11-02 18:52:21 +0800358#endif
roy zang92dda872006-12-01 11:47:36 +0800359 stw r5,SD_D1_CTRL(r4)
360 LOAD_U32(r5,VAL_SD_D1_BAR)
361 stw r5,SD_D1_BAR(r4)
362 sync
roy zangaceddd82006-11-02 18:52:21 +0800363
roy zang92dda872006-12-01 11:47:36 +0800364 b sdc_init_done
roy zangaceddd82006-11-02 18:52:21 +0800365
366check_for_200mhz:
367
roy zang92dda872006-12-01 11:47:36 +0800368 cmpi 0,0,r3,0x0006
369 bne set_default_values
roy zangaceddd82006-11-02 18:52:21 +0800370
roy zang92dda872006-12-01 11:47:36 +0800371 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800379
roy zang92dda872006-12-01 11:47:36 +0800380 /* Initialize DIMM0 control and BAR registers */
381 LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
roy zangaceddd82006-11-02 18:52:21 +0800382#ifdef SDC_AUTOPRECH_EN
roy zang92dda872006-12-01 11:47:36 +0800383 oris r5,r5,0x0001 /* set auto precharge EN bit */
roy zangaceddd82006-11-02 18:52:21 +0800384#endif
roy zang92dda872006-12-01 11:47:36 +0800385 stw r5,SD_D0_CTRL(r4)
386 LOAD_U32(r5,VAL_SD_D0_BAR)
387 stw r5,SD_D0_BAR(r4)
388 sync
roy zangaceddd82006-11-02 18:52:21 +0800389
roy zang92dda872006-12-01 11:47:36 +0800390 /* 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 */
roy zangaceddd82006-11-02 18:52:21 +0800394#ifdef SDC_AUTOPRECH_EN
roy zang92dda872006-12-01 11:47:36 +0800395 oris r5,r5,0x0001 /* set auto precharge EN bit */
roy zangaceddd82006-11-02 18:52:21 +0800396#endif
roy zang92dda872006-12-01 11:47:36 +0800397 stw r5,SD_D1_CTRL(r4)
398 LOAD_U32(r5,VAL_SD_D1_BAR)
399 stw r5,SD_D1_BAR(r4)
400 sync
roy zangaceddd82006-11-02 18:52:21 +0800401
roy zang92dda872006-12-01 11:47:36 +0800402 b sdc_init_done
roy zangaceddd82006-11-02 18:52:21 +0800403
404set_default_values:
405
roy zang92dda872006-12-01 11:47:36 +0800406 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800412
roy zang92dda872006-12-01 11:47:36 +0800413 /* Initialize DIMM0 control and BAR registers */
414 LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
roy zangaceddd82006-11-02 18:52:21 +0800415#ifdef SDC_AUTOPRECH_EN
roy zang92dda872006-12-01 11:47:36 +0800416 oris r5,r5,0x0001 /* set auto precharge EN bit */
roy zangaceddd82006-11-02 18:52:21 +0800417#endif
roy zang92dda872006-12-01 11:47:36 +0800418 stw r5,SD_D0_CTRL(r4)
419 LOAD_U32(r5,VAL_SD_D0_BAR)
420 stw r5,SD_D0_BAR(r4)
421 sync
roy zangaceddd82006-11-02 18:52:21 +0800422
roy zang92dda872006-12-01 11:47:36 +0800423 /* 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 */
roy zangaceddd82006-11-02 18:52:21 +0800427#ifdef SDC_AUTOPRECH_EN
roy zang92dda872006-12-01 11:47:36 +0800428 oris r5,r5,0x0001 /* set auto precharge EN bit */
roy zangaceddd82006-11-02 18:52:21 +0800429#endif
roy zang92dda872006-12-01 11:47:36 +0800430 stw r5,SD_D1_CTRL(r4)
431 LOAD_U32(r5,VAL_SD_D1_BAR)
432 stw r5,SD_D1_BAR(r4)
433 sync
roy zangaceddd82006-11-02 18:52:21 +0800434#else /* !SDC_HARDCODED_INIT */
roy zang92dda872006-12-01 11:47:36 +0800435 bl tsi108_sdram_spd /* automatically detect SDC settings */
roy zangaceddd82006-11-02 18:52:21 +0800436#endif /* SDC_HARDCODED_INIT */
437
438sdc_init_done:
439
440#ifdef DISABLE_PBM
roy zang92dda872006-12-01 11:47:36 +0800441 LOAD_U32(r5,0x00000030) /* PB_EN + OCN_EN */
roy zangaceddd82006-11-02 18:52:21 +0800442#else
roy zang92dda872006-12-01 11:47:36 +0800443 LOAD_U32(r5,0x00000230) /* PB_EN + OCN_EN + PB/OCN=80/20 */
roy zangaceddd82006-11-02 18:52:21 +0800444#endif /* DISABLE_PBM */
445
446#ifdef CONFIG_TSI108EMU
roy zang92dda872006-12-01 11:47:36 +0800447 oris r5,r5,0x0010 /* set EMULATION_MODE bit */
roy zangaceddd82006-11-02 18:52:21 +0800448#endif
449
roy zang92dda872006-12-01 11:47:36 +0800450 stw r5,SD_CTRL(r4)
451 eieio
452 sync
roy zangaceddd82006-11-02 18:52:21 +0800453
roy zang92dda872006-12-01 11:47:36 +0800454 /* Enable SDRAM access */
roy zangaceddd82006-11-02 18:52:21 +0800455
roy zang92dda872006-12-01 11:47:36 +0800456 oris r5,r5,0x8000 /* start SDC: set SD_CTRL[ENABLE] bit */
457 stw r5,SD_CTRL(r4)
458 sync
roy zangaceddd82006-11-02 18:52:21 +0800459
460wait_init_complete:
roy zang92dda872006-12-01 11:47:36 +0800461 lwz r5,SD_STATUS(r4)
462 andi. r5,r5,0x0001
463 /* wait until SDRAM initialization is complete */
464 beq wait_init_complete
roy zangaceddd82006-11-02 18:52:21 +0800465
roy zang92dda872006-12-01 11:47:36 +0800466 /* Map SDRAM into the processor bus address space */
roy zangaceddd82006-11-02 18:52:21 +0800467
roy zang92dda872006-12-01 11:47:36 +0800468 ori r4,r29,TSI108_PB_REG_OFFSET
roy zangaceddd82006-11-02 18:52:21 +0800469
roy zang92dda872006-12-01 11:47:36 +0800470 /* Setup BARs associated with direct path PB<->SDRAM */
roy zangaceddd82006-11-02 18:52:21 +0800471
roy zang92dda872006-12-01 11:47:36 +0800472 /* PB_SDRAM_BAR1:
473 * provides a direct path to the main system memory (cacheable SDRAM)
474 */
roy zangaceddd82006-11-02 18:52:21 +0800475
roy zang92dda872006-12-01 11:47:36 +0800476 /* BA=0,Size=512MB, ENable, No Addr.Translation */
477 LOAD_U32(r5, 0x00000011)
478 stw r5,PB_SDRAM_BAR1(r4)
479 sync
roy zangaceddd82006-11-02 18:52:21 +0800480
roy zang92dda872006-12-01 11:47:36 +0800481 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800486
roy zang92dda872006-12-01 11:47:36 +0800487 /* 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 */
roy zangaceddd82006-11-02 18:52:21 +0800493
roy zang92dda872006-12-01 11:47:36 +0800494 LOAD_U32(r5, 0x40010011)
495 stw r5,PB_SDRAM_BAR2(r4)
496 sync
roy zangaceddd82006-11-02 18:52:21 +0800497
roy zang92dda872006-12-01 11:47:36 +0800498 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800503
504init_done:
505
roy zang92dda872006-12-01 11:47:36 +0800506 /* All done. Restore LR and return. */
507 mtlr r19
508 blr
roy zangaceddd82006-11-02 18:52:21 +0800509
510#if (0)
roy zang92dda872006-12-01 11:47:36 +0800511 /*
512 * init_cpu1
513 * This routine enables CPU1 on the dual-processor system.
514 * Now there is only one processor in the system
515 */
roy zangaceddd82006-11-02 18:52:21 +0800516
roy zang92dda872006-12-01 11:47:36 +0800517 .global enable_cpu1
roy zangaceddd82006-11-02 18:52:21 +0800518enable_cpu1:
519
roy zang92dda872006-12-01 11:47:36 +0800520 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)
roy zangaceddd82006-11-02 18:52:21 +0800527
roy zang92dda872006-12-01 11:47:36 +0800528 blr
roy zangaceddd82006-11-02 18:52:21 +0800529#endif
530
roy zang92dda872006-12-01 11:47:36 +0800531 /*
532 * enable_EI
533 * Enable CPU core external interrupt
534 */
roy zangaceddd82006-11-02 18:52:21 +0800535
roy zang92dda872006-12-01 11:47:36 +0800536 .global enable_EI
roy zangaceddd82006-11-02 18:52:21 +0800537enable_EI:
roy zang92dda872006-12-01 11:47:36 +0800538 mfmsr r3
539 ori r3,r3,0x8000 /* set EE bit */
540 mtmsr r3
541 blr
roy zangaceddd82006-11-02 18:52:21 +0800542
roy zang92dda872006-12-01 11:47:36 +0800543 /*
544 * disable_EI
545 * Disable CPU core external interrupt
546 */
roy zangaceddd82006-11-02 18:52:21 +0800547
roy zang92dda872006-12-01 11:47:36 +0800548 .global disable_EI
roy zangaceddd82006-11-02 18:52:21 +0800549disable_EI:
roy zang92dda872006-12-01 11:47:36 +0800550 mfmsr r3
551 li r4,-32768 /* aka "li r4,0x8000" */
552 andc r3,r3,r4 /* clear EE bit */
553 mtmsr r3
554 blr
roy zangaceddd82006-11-02 18:52:21 +0800555
556#ifdef ENABLE_SDRAM_ECC
roy zang92dda872006-12-01 11:47:36 +0800557 /* enables SDRAM ECC */
roy zangaceddd82006-11-02 18:52:21 +0800558
roy zang92dda872006-12-01 11:47:36 +0800559 .global enable_ECC
roy zangaceddd82006-11-02 18:52:21 +0800560enable_ECC:
roy zang92dda872006-12-01 11:47:36 +0800561 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
roy zangaceddd82006-11-02 18:52:21 +0800566
roy zang92dda872006-12-01 11:47:36 +0800567 /*
568 * clear_ECC_err
569 * Clears all pending SDRAM ECC errors
570 * (normally after SDRAM scrubbing/initialization)
571 */
roy zangaceddd82006-11-02 18:52:21 +0800572
roy zang92dda872006-12-01 11:47:36 +0800573 .global clear_ECC_err
roy zangaceddd82006-11-02 18:52:21 +0800574clear_ECC_err:
roy zang92dda872006-12-01 11:47:36 +0800575 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
roy zangaceddd82006-11-02 18:52:21 +0800579
580#endif /* ENABLE_SDRAM_ECC */
581
582#ifndef SDC_HARDCODED_INIT
583
roy zang92dda872006-12-01 11:47:36 +0800584 /* SDRAM SPD Support */
roy zangaceddd82006-11-02 18:52:21 +0800585#define SD_I2C_CTRL1 (0x400)
586#define SD_I2C_CTRL2 (0x404)
587#define SD_I2C_RD_DATA (0x408)
roy zang92dda872006-12-01 11:47:36 +0800588#define SD_I2C_WR_DATA (0x40C)
roy zangaceddd82006-11-02 18:52:21 +0800589
roy zang92dda872006-12-01 11:47:36 +0800590 /*
591 * SDRAM SPD Support Macros
592 */
roy zangaceddd82006-11-02 18:52:21 +0800593
594#define SPD_DIMM0 (0x00000100)
roy zang92dda872006-12-01 11:47:36 +0800595#define SPD_DIMM1 (0x00000200) /* SPD_DIMM1 was 0x00000000 */
roy zangaceddd82006-11-02 18:52:21 +0800596
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
roy zang92dda872006-12-01 11:47:36 +0800626#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)
roy zangaceddd82006-11-02 18:52:21 +0800645
646#define SPD_MIN_RFRSH (0x80)
647#define SPD_MAX_RFRSH (0x85)
648
roy zang92dda872006-12-01 11:47:36 +0800649refresh_rates: /* in nSec */
roy zangaceddd82006-11-02 18:52:21 +0800650 .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
roy zang92dda872006-12-01 11:47:36 +0800657/*
roy zangaceddd82006-11-02 18:52:21 +0800658 * 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
roy zang92dda872006-12-01 11:47:36 +0800664 */
roy zangaceddd82006-11-02 18:52:21 +0800665
666tsi108_sdram_spd:
667
roy zang92dda872006-12-01 11:47:36 +0800668 li r10,SPD_DIMM0
roy zangaceddd82006-11-02 18:52:21 +0800669 xor r11,r11,r11 /* DIMM Base Address: starts from 0 */
670
671do_first_dimm:
672
roy zang92dda872006-12-01 11:47:36 +0800673 /* Program Refresh Rate Register */
roy zangaceddd82006-11-02 18:52:21 +0800674
roy zang92dda872006-12-01 11:47:36 +0800675 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 */
roy zangaceddd82006-11-02 18:52:21 +0800689 sync
690
roy zang92dda872006-12-01 11:47:36 +0800691 /* Program SD Timing Register */
roy zangaceddd82006-11-02 18:52:21 +0800692
roy zang92dda872006-12-01 11:47:36 +0800693 li r7, 0 /* clear r7 prior parameter collection */
roy zangaceddd82006-11-02 18:52:21 +0800694
roy zang92dda872006-12-01 11:47:36 +0800695 READ_SPD(20) /* get DIMM type: Registered or Unbuffered */
roy zangaceddd82006-11-02 18:52:21 +0800696 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800697 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 */
roy zangaceddd82006-11-02 18:52:21 +0800703
704do_cl:
roy zang92dda872006-12-01 11:47:36 +0800705 READ_SPD(18) /* Get CAS Latency */
roy zangaceddd82006-11-02 18:52:21 +0800706 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800707 li r5,ERR_CL_VALUE
708 andi. r6,r3,SPD_CAS_3
709 beq cl_4
710 li r6,3
711 b set_cl
roy zangaceddd82006-11-02 18:52:21 +0800712cl_4:
roy zang92dda872006-12-01 11:47:36 +0800713 andi. r6,r3,SPD_CAS_4
714 beq cl_5
715 li r6,4
716 b set_cl
roy zangaceddd82006-11-02 18:52:21 +0800717cl_5:
roy zang92dda872006-12-01 11:47:36 +0800718 andi. r6,r3,SPD_CAS_5
719 beq spd_fail
720 li r6,5
roy zangaceddd82006-11-02 18:52:21 +0800721set_cl:
roy zang92dda872006-12-01 11:47:36 +0800722 rlwimi r7,r6,24,5,7
roy zangaceddd82006-11-02 18:52:21 +0800723
roy zang92dda872006-12-01 11:47:36 +0800724 READ_SPD(30) /* Get tRAS */
roy zangaceddd82006-11-02 18:52:21 +0800725 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800726 divwu r6,r3,r9
727 mullw r8,r6,r9
728 subf. r8,r8,r3
roy zangaceddd82006-11-02 18:52:21 +0800729 beq set_tras
roy zang92dda872006-12-01 11:47:36 +0800730 addi r6,r6,1
roy zangaceddd82006-11-02 18:52:21 +0800731set_tras:
732 li r5,ERR_TRAS_FAIL
roy zang92dda872006-12-01 11:47:36 +0800733 cmpi 0,0,r6,0x0F /* max supported value */
734 bgt spd_fail
735 rlwimi r7,r6,16,12,15
roy zangaceddd82006-11-02 18:52:21 +0800736
737 READ_SPD(29) /* Get tRCD */
738 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800739 /* 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
roy zangaceddd82006-11-02 18:52:21 +0800744 beq set_trcd
roy zang92dda872006-12-01 11:47:36 +0800745 addi r6,r6,1
roy zangaceddd82006-11-02 18:52:21 +0800746set_trcd:
roy zang92dda872006-12-01 11:47:36 +0800747 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
roy zangaceddd82006-11-02 18:52:21 +0800751
752 READ_SPD(27) /* Get tRP value */
753 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800754 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
roy zangaceddd82006-11-02 18:52:21 +0800758 beq set_trp
roy zang92dda872006-12-01 11:47:36 +0800759 addi r6,r6,1
roy zangaceddd82006-11-02 18:52:21 +0800760set_trp:
roy zang92dda872006-12-01 11:47:36 +0800761 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
roy zangaceddd82006-11-02 18:52:21 +0800765
766 READ_SPD(36) /* Get tWR value */
767 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800768 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
roy zangaceddd82006-11-02 18:52:21 +0800772 beq set_twr
roy zang92dda872006-12-01 11:47:36 +0800773 addi r6,r6,1
roy zangaceddd82006-11-02 18:52:21 +0800774set_twr:
roy zang92dda872006-12-01 11:47:36 +0800775 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
roy zangaceddd82006-11-02 18:52:21 +0800780
781 READ_SPD(42) /* Get tRFC */
782 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800783 li r5, ERR_TRFC_FAIL
roy zangaceddd82006-11-02 18:52:21 +0800784 /* Tsi108 spec: tRFC=(tRFC + 1)/2 */
roy zang92dda872006-12-01 11:47:36 +0800785 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
roy zangaceddd82006-11-02 18:52:21 +0800791 beq set_trfc
roy zang92dda872006-12-01 11:47:36 +0800792 addi r6,r6,1
roy zangaceddd82006-11-02 18:52:21 +0800793set_trfc:
roy zang92dda872006-12-01 11:47:36 +0800794 cmpi 0,0,r6,0x1F /* max supported value */
795 bgt spd_fail
796 rlwimi r7,r6,0,27,31
roy zangaceddd82006-11-02 18:52:21 +0800797
798 stw r7,SD_TIMING(r4)
799 sync
800
roy zang92dda872006-12-01 11:47:36 +0800801 /*
roy zangaceddd82006-11-02 18:52:21 +0800802 * The following two registers are set on per-DIMM basis.
803 * The SD_REFRESH and SD_TIMING settings are common for both DIMMS
roy zangaceddd82006-11-02 18:52:21 +0800804 */
805
806do_each_dimm:
807
roy zang92dda872006-12-01 11:47:36 +0800808 /* Program SDRAM DIMM Control Register */
roy zangaceddd82006-11-02 18:52:21 +0800809
roy zang92dda872006-12-01 11:47:36 +0800810 li r7, 0 /* clear r7 prior parameter collection */
roy zangaceddd82006-11-02 18:52:21 +0800811
812 READ_SPD(13) /* Get Primary SDRAM Width */
813 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800814 cmpi 0,0,r3,4 /* Check for 4-bit SDRAM */
815 beq do_nbank
816 oris r7,r7,0x0010 /* Set MEM_WIDTH bit */
roy zangaceddd82006-11-02 18:52:21 +0800817
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 */
roy zang92dda872006-12-01 11:47:36 +0800822 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
roy zangaceddd82006-11-02 18:52:21 +0800828
829do_nrank:
roy zang92dda872006-12-01 11:47:36 +0800830 READ_SPD(5) /* Get # of Ranks */
roy zangaceddd82006-11-02 18:52:21 +0800831 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800832 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
roy zangaceddd82006-11-02 18:52:21 +0800838
839do_addr_mode:
roy zang92dda872006-12-01 11:47:36 +0800840 READ_SPD(4) /* Get # of Column Addresses */
roy zangaceddd82006-11-02 18:52:21 +0800841 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800842 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 */
roy zangaceddd82006-11-02 18:52:21 +0800850
851set_dimm_ctrl:
852#ifdef SDC_AUTOPRECH_EN
roy zang92dda872006-12-01 11:47:36 +0800853 oris r7,r7,0x0001 /* set auto precharge EN bit */
roy zangaceddd82006-11-02 18:52:21 +0800854#endif
roy zang92dda872006-12-01 11:47:36 +0800855 ori r7,r7,1 /* set ENABLE bit */
856 cmpi 0,0,r10,SPD_DIMM0
857 bne 1f
858 stw r7,SD_D0_CTRL(r4)
roy zangaceddd82006-11-02 18:52:21 +0800859 sync
roy zang92dda872006-12-01 11:47:36 +0800860 b set_dimm_bar
roy zangaceddd82006-11-02 18:52:21 +08008611:
roy zang92dda872006-12-01 11:47:36 +0800862 stw r7,SD_D1_CTRL(r4)
roy zangaceddd82006-11-02 18:52:21 +0800863 sync
864
865
roy zang92dda872006-12-01 11:47:36 +0800866 /* Program SDRAM DIMMx Base Address Register */
roy zangaceddd82006-11-02 18:52:21 +0800867
868set_dimm_bar:
869 READ_SPD(5) /* get # of Ranks */
870 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800871 andi. r7,r3,0x7
872 addi r7,r7,1
873 READ_SPD(31) /* Read DIMM rank density */
roy zangaceddd82006-11-02 18:52:21 +0800874 beq spd_read_fail
roy zang92dda872006-12-01 11:47:36 +0800875 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 */
roy zangaceddd82006-11-02 18:52:21 +0800886
roy zang92dda872006-12-01 11:47:36 +0800887 cmpi 0,0,r10,SPD_DIMM0
888 bne set_dimm1_size
889 stw r7,SD_D0_BAR(r4)
roy zangaceddd82006-11-02 18:52:21 +0800890 sync
roy zang92dda872006-12-01 11:47:36 +0800891 li r10,SPD_DIMM1
roy zangaceddd82006-11-02 18:52:21 +0800892 READ_SPD(0)
893 bne do_each_dimm
894 b spd_done
895
896set_dimm1_size:
roy zang92dda872006-12-01 11:47:36 +0800897 stw r7,SD_D1_BAR(r4)
roy zangaceddd82006-11-02 18:52:21 +0800898 sync
899spd_done:
900 blr
901
902check_next_slot:
roy zang92dda872006-12-01 11:47:36 +0800903 cmpi 0,0,r10,SPD_DIMM1
904 beq spd_read_fail
905 li r10,SPD_DIMM1
906 b do_first_dimm
roy zangaceddd82006-11-02 18:52:21 +0800907spd_read_fail:
908 ori r3,r0,0xdead
roy zang92dda872006-12-01 11:47:36 +0800909 b err_hung
roy zangaceddd82006-11-02 18:52:21 +0800910spd_fail:
911 li r3,0x0bad
912 sync
roy zang92dda872006-12-01 11:47:36 +0800913err_hung: /* hang here for debugging */
914 nop
915 nop
916 b err_hung
roy zangaceddd82006-11-02 18:52:21 +0800917
918#endif /* !SDC_HARDCODED_INIT */