blob: d97b5c1f8d2015e1925f62d07ebcd67c3dffbec3 [file] [log] [blame]
wdenkdb2f721f2003-03-06 00:58:30 +00001/*
2 * (C) Copyright 2001
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * Modified during 2001 by
6 * Advanced Communications Technologies (Australia) Pty. Ltd.
7 * Howard Walker, Tuong Vu-Dinh
8 *
9 * (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
10 * Added support for the 16M dram simm on the 8260ads boards
11 *
12 * See file CREDITS for list of people who contributed to this
13 * project.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
29 */
30
31#include <common.h>
32#include <ioports.h>
33#include <i2c.h>
34#include <mpc8260.h>
wdenk5d232d02003-05-22 22:52:13 +000035#include <pci.h>
wdenkdb2f721f2003-03-06 00:58:30 +000036
37/*
38 * PBI Page Based Interleaving
39 * PSDMR_PBI page based interleaving
40 * 0 bank based interleaving
41 * External Address Multiplexing (EAMUX) adds a clock to address cycles
42 * (this can help with marginal board layouts)
43 * PSDMR_EAMUX adds a clock
44 * 0 no extra clock
45 * Buffer Command (BUFCMD) adds a clock to command cycles.
46 * PSDMR_BUFCMD adds a clock
47 * 0 no extra clock
48 */
wdenk3595ac42003-06-22 17:18:28 +000049#define CONFIG_PBI PSDMR_PBI
wdenkdb2f721f2003-03-06 00:58:30 +000050#define PESSIMISTIC_SDRAM 0
51#define EAMUX 0 /* EST requires EAMUX */
52#define BUFCMD 0
53
54
55/*
56 * I/O Port configuration table
57 *
58 * if conf is 1, then that port pin will be configured at boot time
59 * according to the five values podr/pdir/ppar/psor/pdat for that entry
60 */
61
62const iop_conf_t iop_conf_tab[4][32] = {
63
64 /* Port A configuration */
65 { /* conf ppar psor pdir podr pdat */
wdenk8bde7f72003-06-27 21:31:46 +000066 /* PA31 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxENB */
wdenkdb2f721f2003-03-06 00:58:30 +000067 /* PA30 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 TxClav */
68 /* PA29 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxSOC */
69 /* PA28 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 RxENB */
70 /* PA27 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxSOC */
71 /* PA26 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxClav */
72 /* PA25 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */
73 /* PA24 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */
74 /* PA23 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */
75 /* PA22 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */
76 /* PA21 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */
77 /* PA20 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */
78 /* PA19 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */
79 /* PA18 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */
80 /* PA17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */
81 /* PA16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */
82 /* PA15 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */
83 /* PA14 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */
84 /* PA13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */
85 /* PA12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */
86 /* PA11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */
87 /* PA10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */
88 /* PA9 */ { 0, 1, 1, 1, 0, 0 }, /* FCC1 L1TXD */
89 /* PA8 */ { 0, 1, 1, 0, 0, 0 }, /* FCC1 L1RXD */
90 /* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */
91 /* PA6 */ { 1, 1, 1, 1, 0, 0 }, /* TDM A1 L1RSYNC */
92 /* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */
93 /* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */
94 /* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */
95 /* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */
96 /* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* FREERUN */
97 /* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */
98 },
99
100 /* Port B configuration */
101 { /* conf ppar psor pdir podr pdat */
102 /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
103 /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
104 /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
105 /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
106 /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
107 /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
108 /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
109 /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
110 /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
111 /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
112 /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
113 /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
114 /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
115 /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
116 /* PB17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_DIV */
117 /* PB16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_ERR */
118 /* PB15 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_ERR */
119 /* PB14 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_EN */
120 /* PB13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:COL */
121 /* PB12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:CRS */
122 /* PB11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
123 /* PB10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
124 /* PB9 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
125 /* PB8 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */
126 /* PB7 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
127 /* PB6 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
128 /* PB5 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
129 /* PB4 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */
130 /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
131 /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
132 /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
133 /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
134 },
135
136 /* Port C */
137 { /* conf ppar psor pdir podr pdat */
138 /* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */
139 /* PC30 */ { 0, 0, 0, 1, 0, 0 }, /* PC30 */
140 /* PC29 */ { 0, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */
141 /* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */
142 /* PC27 */ { 0, 0, 0, 1, 0, 0 }, /* UART Clock in */
143 /* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */
144 /* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */
145 /* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */
146 /* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* ATMTFCLK */
147 /* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* ATMRFCLK */
148 /* PC21 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */
149 /* PC20 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */
150 /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK CLK13 */
151 /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK14) */
152 /* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */
153 /* PC16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK16) */
154 /* PC15 */ { 0, 0, 0, 1, 0, 0 }, /* PC15 */
155 /* PC14 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */
156 /* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
157 /* PC12 */ { 0, 1, 0, 1, 0, 0 }, /* PC12 */
158 /* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* LXT971 transmit control */
wdenk5d232d02003-05-22 22:52:13 +0000159 /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* LXT970 FETHMDC */
160 /* PC9 */ { 1, 0, 0, 0, 0, 0 }, /* LXT970 FETHMDIO */
wdenkdb2f721f2003-03-06 00:58:30 +0000161 /* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */
162 /* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */
163 /* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */
164 /* PC5 */ { 0, 0, 0, 1, 0, 0 }, /* PC5 */
165 /* PC4 */ { 0, 0, 0, 1, 0, 0 }, /* PC4 */
166 /* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */
167 /* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* ENET FDE */
168 /* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* ENET DSQE */
169 /* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* ENET LBK */
170 },
171
172 /* Port D */
173 { /* conf ppar psor pdir podr pdat */
174 /* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */
175 /* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */
176 /* PD29 */ { 0, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */
177 /* PD28 */ { 0, 1, 0, 0, 0, 0 }, /* PD28 */
178 /* PD27 */ { 0, 1, 1, 1, 0, 0 }, /* PD27 */
179 /* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */
180 /* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */
181 /* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */
182 /* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* PD23 */
183 /* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */
184 /* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */
185 /* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */
186 /* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
187 /* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */
188 /* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
189 /* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
190 /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
191 /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
192 /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */
193 /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */
194 /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */
195 /* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */
196 /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
197 /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
198 /* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */
199 /* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */
200 /* PD5 */ { 0, 0, 0, 1, 0, 1 }, /* PD5 */
201 /* PD4 */ { 0, 0, 0, 1, 0, 1 }, /* PD4 */
202 /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
203 /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
204 /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
205 /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
206 }
207};
208
209typedef struct bscr_ {
210 unsigned long bcsr0;
211 unsigned long bcsr1;
212 unsigned long bcsr2;
213 unsigned long bcsr3;
214 unsigned long bcsr4;
215 unsigned long bcsr5;
216 unsigned long bcsr6;
217 unsigned long bcsr7;
218} bcsr_t;
219
wdenk5d232d02003-05-22 22:52:13 +0000220typedef struct pci_ic_s {
221 unsigned long pci_int_stat;
222 unsigned long pci_int_mask;
223} pci_ic_t;
224
wdenkdb2f721f2003-03-06 00:58:30 +0000225void reset_phy(void)
226{
227 volatile bcsr_t *bcsr = (bcsr_t *)CFG_BCSR;
228
229 /* reset the FEC port */
230 bcsr->bcsr1 &= ~FETH_RST;
231 bcsr->bcsr1 |= FETH_RST;
232}
233
234
235int board_pre_init (void)
236{
237 volatile bcsr_t *bcsr = (bcsr_t *)CFG_BCSR;
wdenk5d232d02003-05-22 22:52:13 +0000238 volatile pci_ic_t *pci_ic = (pci_ic_t *) CFG_PCI_INT;
wdenkdb2f721f2003-03-06 00:58:30 +0000239
wdenk5d232d02003-05-22 22:52:13 +0000240 bcsr->bcsr1 = ~FETHIEN & ~RS232EN_1 & ~RS232EN_2;
241
242 /* mask all PCI interrupts */
243 pci_ic->pci_int_mask |= 0xfff00000;
wdenk8bde7f72003-06-27 21:31:46 +0000244
wdenkdb2f721f2003-03-06 00:58:30 +0000245 return 0;
246}
247
248int checkboard(void)
249{
250 puts ("Board: Motorola MPC8266ADS\n");
251 return 0;
252}
253
254long int initdram(int board_type)
255{
256 /* Autoinit part stolen from board/sacsng/sacsng.c */
257 volatile immap_t *immap = (immap_t *)CFG_IMMR;
258 volatile memctl8260_t *memctl = &immap->im_memctl;
259 volatile uchar c = 0xff;
260 volatile uchar *ramaddr = (uchar *)(CFG_SDRAM_BASE + 0x8);
261 uint psdmr = CFG_PSDMR;
262 int i;
263
wdenk5d232d02003-05-22 22:52:13 +0000264 uint psrt = 0x21; /* for no SPD */
wdenkdb2f721f2003-03-06 00:58:30 +0000265 uint chipselects = 1; /* for no SPD */
266 uint sdram_size = CFG_SDRAM_SIZE * 1024 * 1024; /* for no SPD */
267 uint or = CFG_OR2_PRELIM; /* for no SPD */
268 uint data_width;
269 uint rows;
270 uint banks;
271 uint cols;
272 uint caslatency;
273 uint width;
274 uint rowst;
275 uint sdam;
276 uint bsma;
277 uint sda10;
278 u_char spd_size;
279 u_char data;
280 u_char cksum;
281 int j;
282
283 /* Keep the compiler from complaining about potentially uninitialized vars */
wdenk5d232d02003-05-22 22:52:13 +0000284 data_width = rows = banks = cols = caslatency = 0;
wdenkdb2f721f2003-03-06 00:58:30 +0000285
286 /*
287 * Read the SDRAM SPD EEPROM via I2C.
288 */
289 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
290
291 i2c_read(SDRAM_SPD_ADDR, 0, 1, &data, 1);
292 spd_size = data;
293 cksum = data;
wdenk8bde7f72003-06-27 21:31:46 +0000294 for(j = 1; j < 64; j++)
wdenkdb2f721f2003-03-06 00:58:30 +0000295 { /* read only the checksummed bytes */
296 /* note: the I2C address autoincrements when alen == 0 */
297 i2c_read(SDRAM_SPD_ADDR, 0, 0, &data, 1);
298 /*printf("addr %d = 0x%02x\n", j, data);*/
299 if(j == 5) chipselects = data & 0x0F;
300 else if(j == 6) data_width = data;
301 else if(j == 7) data_width |= data << 8;
302 else if(j == 3) rows = data & 0x0F;
303 else if(j == 4) cols = data & 0x0F;
wdenk8bde7f72003-06-27 21:31:46 +0000304 else if(j == 12)
wdenkdb2f721f2003-03-06 00:58:30 +0000305 {
306 /*
307 * Refresh rate: this assumes the prescaler is set to
wdenk8bde7f72003-06-27 21:31:46 +0000308 * approximately 0.39uSec per tick and the target refresh period
wdenk5d232d02003-05-22 22:52:13 +0000309 * is about 85% of maximum.
wdenkdb2f721f2003-03-06 00:58:30 +0000310 */
wdenk8bde7f72003-06-27 21:31:46 +0000311 switch(data & 0x7F)
wdenkdb2f721f2003-03-06 00:58:30 +0000312 {
313 default:
wdenk5d232d02003-05-22 22:52:13 +0000314 case 0: psrt = 0x21; /* 15.625uS */ break;
315 case 1: psrt = 0x07; /* 3.9uS */ break;
316 case 2: psrt = 0x0F; /* 7.8uS */ break;
317 case 3: psrt = 0x43; /* 31.3uS */ break;
318 case 4: psrt = 0x87; /* 62.5uS */ break;
319 case 5: psrt = 0xFF; /* 125uS */ break;
wdenkdb2f721f2003-03-06 00:58:30 +0000320 }
321 }
322 else if(j == 17) banks = data;
wdenk8bde7f72003-06-27 21:31:46 +0000323 else if(j == 18)
wdenkdb2f721f2003-03-06 00:58:30 +0000324 {
325 caslatency = 3; /* default CL */
326# if(PESSIMISTIC_SDRAM)
327 if((data & 0x04) != 0) caslatency = 3;
328 else if((data & 0x02) != 0) caslatency = 2;
329 else if((data & 0x01) != 0) caslatency = 1;
330# else
331 if((data & 0x01) != 0) caslatency = 1;
332 else if((data & 0x02) != 0) caslatency = 2;
333 else if((data & 0x04) != 0) caslatency = 3;
334# endif
wdenk8bde7f72003-06-27 21:31:46 +0000335 else
wdenkdb2f721f2003-03-06 00:58:30 +0000336 {
337 printf ("WARNING: Unknown CAS latency 0x%02X, using 3\n",
338 data);
339 }
340 }
wdenk8bde7f72003-06-27 21:31:46 +0000341 else if(j == 63)
wdenkdb2f721f2003-03-06 00:58:30 +0000342 {
wdenk8bde7f72003-06-27 21:31:46 +0000343 if(data != cksum)
wdenkdb2f721f2003-03-06 00:58:30 +0000344 {
345 printf ("WARNING: Configuration data checksum failure:"
346 " is 0x%02x, calculated 0x%02x\n",
347 data, cksum);
348 }
349 }
350 cksum += data;
351 }
352
353 /* We don't trust CL less than 2 (only saw it on an old 16MByte DIMM) */
354 if(caslatency < 2) {
355 printf("CL was %d, forcing to 2\n", caslatency);
356 caslatency = 2;
357 }
358 if(rows > 14) {
359 printf("This doesn't look good, rows = %d, should be <= 14\n", rows);
360 rows = 14;
361 }
362 if(cols > 11) {
363 printf("This doesn't look good, columns = %d, should be <= 11\n", cols);
364 cols = 11;
365 }
366
367 if((data_width != 64) && (data_width != 72))
368 {
369 printf("WARNING: SDRAM width unsupported, is %d, expected 64 or 72.\n",
370 data_width);
371 }
372 width = 3; /* 2^3 = 8 bytes = 64 bits wide */
373 /*
374 * Convert banks into log2(banks)
375 */
376 if (banks == 2) banks = 1;
377 else if(banks == 4) banks = 2;
378 else if(banks == 8) banks = 3;
379
380
381 sdram_size = 1 << (rows + cols + banks + width);
wdenk3595ac42003-06-22 17:18:28 +0000382 /* hack for high density memory (512MB per CS) */
383 /* !!!!! Will ONLY work with Page Based Interleave !!!!!
wdenk8bde7f72003-06-27 21:31:46 +0000384 ( PSDMR[PBI] = 1 )
wdenk3595ac42003-06-22 17:18:28 +0000385 */
wdenk8bde7f72003-06-27 21:31:46 +0000386 /* mamory actually has 11 column addresses, but the memory controller
387 doesn't really care.
388 the calculations that follow will however move the rows so that
389 they are muxed one bit off if you use 11 bit columns.
wdenk3595ac42003-06-22 17:18:28 +0000390 The solution is to tell the memory controller the correct size of the memory
391 but change the number of columns to 10 afterwards.
392 The 11th column addre will still be mucxed correctly onto the bus.
393
wdenk8bde7f72003-06-27 21:31:46 +0000394 Also be aware that the MPC8266ADS board Rev B has not connected
wdenk3595ac42003-06-22 17:18:28 +0000395 Row addres 13 to anything.
396
397 The fix is to connect ADD16 (from U37-47) to SADDR12 (U28-126)
398 */
399 if (cols > 10)
400 cols = 10;
wdenkdb2f721f2003-03-06 00:58:30 +0000401
402#if(CONFIG_PBI == 0) /* bank-based interleaving */
403 rowst = ((32 - 6) - (rows + cols + width)) * 2;
404#else
405 rowst = 32 - (rows + banks + cols + width);
406#endif
407
408 or = ~(sdram_size - 1) | /* SDAM address mask */
409 ((banks-1) << 13) | /* banks per device */
410 (rowst << 9) | /* rowst */
411 ((rows - 9) << 6); /* numr */
412
413
414 /*printf("memctl->memc_or2 = 0x%08x\n", or);*/
415
416 /*
417 * SDAM specifies the number of columns that are multiplexed
418 * (reference AN2165/D), defined to be (columns - 6) for page
419 * interleave, (columns - 8) for bank interleave.
420 *
421 * BSMA is 14 - max(rows, cols). The bank select lines come
422 * into play above the highest "address" line going into the
423 * the SDRAM.
424 */
425#if(CONFIG_PBI == 0) /* bank-based interleaving */
426 sdam = cols - 8;
427 bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols);
428 sda10 = sdam + 2;
429#else
430 sdam = cols - 6;
431 bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols);
432 sda10 = sdam;
433#endif
434#if(PESSIMISTIC_SDRAM)
435 psdmr = (CONFIG_PBI |\
436 PSDMR_RFEN |\
437 PSDMR_RFRC_16_CLK |\
438 PSDMR_PRETOACT_8W |\
439 PSDMR_ACTTORW_8W |\
440 PSDMR_WRC_4C |\
441 PSDMR_EAMUX |\
wdenk8bde7f72003-06-27 21:31:46 +0000442 PSDMR_BUFCMD) |\
wdenkdb2f721f2003-03-06 00:58:30 +0000443 caslatency |\
444 ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \
445 (sdam << 24) |\
446 (bsma << 21) |\
447 (sda10 << 18);
448#else
449 psdmr = (CONFIG_PBI |\
450 PSDMR_RFEN |\
451 PSDMR_RFRC_7_CLK |\
452 PSDMR_PRETOACT_3W | /* 1 for 7E parts (fast PC-133) */ \
453 PSDMR_ACTTORW_2W | /* 1 for 7E parts (fast PC-133) */ \
454 PSDMR_WRC_1C | /* 1 clock + 7nSec */
455 EAMUX |\
wdenk8bde7f72003-06-27 21:31:46 +0000456 BUFCMD) |\
wdenkdb2f721f2003-03-06 00:58:30 +0000457 caslatency |\
458 ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \
459 (sdam << 24) |\
460 (bsma << 21) |\
461 (sda10 << 18);
462#endif
463 /*printf("psdmr = 0x%08x\n", psdmr);*/
464
465 /*
466 * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
467 *
468 * "At system reset, initialization software must set up the
469 * programmable parameters in the memory controller banks registers
470 * (ORx, BRx, P/LSDMR). After all memory parameters are configured,
471 * system software should execute the following initialization sequence
472 * for each SDRAM device.
473 *
474 * 1. Issue a PRECHARGE-ALL-BANKS command
475 * 2. Issue eight CBR REFRESH commands
476 * 3. Issue a MODE-SET command to initialize the mode register
477 *
478 * Quote from Micron MT48LC8M16A2 data sheet:
479 *
480 * "...the SDRAM requires a 100uS delay prior to issuing any
481 * command other than a COMMAND INHIBIT or NOP. Starting at some
482 * point during this 100uS period and continuing at least through
483 * the end of this period, COMMAND INHIBIT or NOP commands should
484 * be applied."
485 *
486 * "Once the 100uS delay has been satisfied with at least one COMMAND
487 * INHIBIT or NOP command having been applied, a /PRECHARGE command/
488 * should be applied. All banks must then be precharged, thereby
489 * placing the device in the all banks idle state."
490 *
491 * "Once in the idle state, /two/ AUTO REFRESH cycles must be
492 * performed. After the AUTO REFRESH cycles are complete, the
493 * SDRAM is ready for mode register programming."
494 *
495 * (/emphasis/ mine, gvb)
496 *
497 * The way I interpret this, Micron start up sequence is:
498 * 1. Issue a PRECHARGE-BANK command (initial precharge)
499 * 2. Issue a PRECHARGE-ALL-BANKS command ("all banks ... precharged")
500 * 3. Issue two (presumably, doing eight is OK) CBR REFRESH commands
501 * 4. Issue a MODE-SET command to initialize the mode register
502 *
503 * --------
504 *
505 * The initial commands are executed by setting P/LSDMR[OP] and
506 * accessing the SDRAM with a single-byte transaction."
507 *
508 * The appropriate BRx/ORx registers have already been set when we
509 * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
510 */
wdenk7a8e9bed2003-05-31 18:35:21 +0000511
wdenkdb2f721f2003-03-06 00:58:30 +0000512 memctl->memc_mptpr = CFG_MPTPR;
513 memctl->memc_psrt = psrt;
514
wdenk7a8e9bed2003-05-31 18:35:21 +0000515 memctl->memc_br2 = CFG_BR2_PRELIM;
516 memctl->memc_or2 = or;
wdenk8bde7f72003-06-27 21:31:46 +0000517
wdenkdb2f721f2003-03-06 00:58:30 +0000518 memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
519 *ramaddr = c;
520
521 memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
522 for (i = 0; i < 8; i++)
523 *ramaddr = c;
524
525 memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
526 *ramaddr = c;
527
528 memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
529 *ramaddr = c;
530
531 /*
532 * Do it a second time for the second set of chips if the DIMM has
533 * two chip selects (double sided).
534 */
wdenk8bde7f72003-06-27 21:31:46 +0000535 if(chipselects > 1)
wdenkdb2f721f2003-03-06 00:58:30 +0000536 {
wdenk8bde7f72003-06-27 21:31:46 +0000537 ramaddr += sdram_size;
wdenkdb2f721f2003-03-06 00:58:30 +0000538
539 memctl->memc_br3 = CFG_BR3_PRELIM + sdram_size;
540 memctl->memc_or3 = or;
541
542 memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
543 *ramaddr = c;
544
545 memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
546 for (i = 0; i < 8; i++)
547 *ramaddr = c;
548
549 memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
550 *ramaddr = c;
551
552 memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
553 *ramaddr = c;
554 }
wdenkdb2f721f2003-03-06 00:58:30 +0000555
wdenkdb2f721f2003-03-06 00:58:30 +0000556 /* print info */
557 printf("SDRAM configuration read from SPD\n");
558 printf("\tSize per side = %dMB\n", sdram_size >> 20);
559 printf("\tOrganization: %d sides, %d banks, %d Columns, %d Rows, Data width = %d bits\n", chipselects, 1<<(banks), cols, rows, data_width);
560 printf("\tRefresh rate = %d, CAS latency = %d\n", psrt, caslatency);
561 printf("\tTotal size: ");
562
563 return (sdram_size * chipselects);
564 /*return (16 * 1024 * 1024);*/
565}
wdenk5d232d02003-05-22 22:52:13 +0000566
wdenk7a8e9bed2003-05-31 18:35:21 +0000567
wdenk5d232d02003-05-22 22:52:13 +0000568#ifdef CONFIG_PCI
569struct pci_controller hose;
570
571extern void pci_mpc8250_init(struct pci_controller *);
572
573void pci_init_board(void)
574{
575 pci_mpc8250_init(&hose);
576}
577#endif