* Patch by Rune Torgersen, 4 Jun 2003:
[platform/kernel/u-boot.git] / board / mpc8266ads / mpc8266ads.c
1 /*
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>
35 #include <pci.h>
36
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  */
49 #define CONFIG_PBI              PSDMR_PBI
50 #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
62 const iop_conf_t iop_conf_tab[4][32] = {
63
64     /* Port A configuration */
65     {   /*            conf ppar psor pdir podr pdat */
66         /* PA31 */ {   0,   1,   0,   1,   0,   0   }, /* FCC1 TxENB */
67         /* 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 */
159         /* PC10 */ {   1,   0,   0,   1,   0,   0   }, /* LXT970 FETHMDC */
160         /* PC9  */ {   1,   0,   0,   0,   0,   0   }, /* LXT970 FETHMDIO */
161         /* 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
209 typedef 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
220 typedef struct pci_ic_s {
221         unsigned long pci_int_stat;
222         unsigned long pci_int_mask;
223 } pci_ic_t;
224
225 void 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
235 int board_pre_init (void)
236 {
237     volatile bcsr_t  *bcsr         = (bcsr_t *)CFG_BCSR;
238     volatile pci_ic_t *pci_ic      = (pci_ic_t *) CFG_PCI_INT;
239
240     bcsr->bcsr1                    = ~FETHIEN & ~RS232EN_1 & ~RS232EN_2;
241
242     /* mask all PCI interrupts */
243     pci_ic->pci_int_mask |= 0xfff00000;
244     
245     return 0;
246 }
247
248 int checkboard(void)
249 {
250     puts ("Board: Motorola MPC8266ADS\n");
251     return 0;
252 }
253
254 long 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
264     uint   psrt = 0x21;                                 /* for no SPD */
265     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 */
284     data_width = rows = banks = cols = caslatency = 0;
285
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;
294     for(j = 1; j < 64; j++) 
295         {       /* 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;
304                 else if(j == 12) 
305                 {
306                         /*
307                                  * Refresh rate: this assumes the prescaler is set to
308                          * approximately 0.39uSec per tick and the target refresh period 
309                          * is about 85% of maximum.
310                          */
311                         switch(data & 0x7F) 
312                         {
313                                         default:
314                                         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;
320                         }
321                 }
322                 else if(j == 17) banks       = data;
323                 else if(j == 18) 
324                 {
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
335                         else 
336                         {
337                         printf ("WARNING: Unknown CAS latency 0x%02X, using 3\n",
338                                         data);
339                         }
340                 }
341                 else if(j == 63) 
342                 {
343                         if(data != cksum) 
344                         {
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);
382     /* hack for high density memory (512MB per CS) */
383     /* !!!!! Will ONLY work with Page Based Interleave !!!!!
384              ( PSDMR[PBI] = 1 ) 
385     */
386     /* 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. 
390        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
394        Also be aware that the MPC8266ADS board Rev B has not connected 
395        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;
401
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             |\
442              PSDMR_BUFCMD)           |\
443              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                   |\
456              BUFCMD)                 |\
457              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      */
511
512     memctl->memc_mptpr = CFG_MPTPR;
513     memctl->memc_psrt  = psrt;
514
515     memctl->memc_br2 = CFG_BR2_PRELIM;
516     memctl->memc_or2 = or;
517     
518     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      */
535     if(chipselects > 1) 
536         {
537         ramaddr += sdram_size;
538
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     }
555
556         /* 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 }
566
567
568 #ifdef  CONFIG_PCI
569 struct pci_controller hose;
570
571 extern void pci_mpc8250_init(struct pci_controller *);
572
573 void pci_init_board(void)
574 {
575         pci_mpc8250_init(&hose);
576 }
577 #endif