]>
Commit | Line | Data |
---|---|---|
db2f721f | 1 | /* |
55e33279 | 2 | * (C) Copyright 2001-2011 |
db2f721f WD |
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 | * | |
1a459660 | 12 | * SPDX-License-Identifier: GPL-2.0+ |
db2f721f WD |
13 | */ |
14 | ||
15 | #include <common.h> | |
16 | #include <ioports.h> | |
17 | #include <i2c.h> | |
18 | #include <mpc8260.h> | |
5d232d0e | 19 | #include <pci.h> |
db2f721f WD |
20 | |
21 | /* | |
22 | * PBI Page Based Interleaving | |
23 | * PSDMR_PBI page based interleaving | |
24 | * 0 bank based interleaving | |
25 | * External Address Multiplexing (EAMUX) adds a clock to address cycles | |
26 | * (this can help with marginal board layouts) | |
27 | * PSDMR_EAMUX adds a clock | |
28 | * 0 no extra clock | |
29 | * Buffer Command (BUFCMD) adds a clock to command cycles. | |
30 | * PSDMR_BUFCMD adds a clock | |
31 | * 0 no extra clock | |
32 | */ | |
b70e7a00 | 33 | #define CONFIG_PBI 0 |
db2f721f WD |
34 | #define PESSIMISTIC_SDRAM 0 |
35 | #define EAMUX 0 /* EST requires EAMUX */ | |
36 | #define BUFCMD 0 | |
37 | ||
38 | ||
39 | /* | |
40 | * I/O Port configuration table | |
41 | * | |
42 | * if conf is 1, then that port pin will be configured at boot time | |
43 | * according to the five values podr/pdir/ppar/psor/pdat for that entry | |
44 | */ | |
45 | ||
46 | const iop_conf_t iop_conf_tab[4][32] = { | |
47 | ||
55e33279 WD |
48 | /* Port A configuration */ |
49 | { /* conf ppar psor pdir podr pdat */ | |
8bde7f77 | 50 | /* PA31 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxENB */ |
db2f721f WD |
51 | /* PA30 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 TxClav */ |
52 | /* PA29 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxSOC */ | |
53 | /* PA28 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 RxENB */ | |
54 | /* PA27 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxSOC */ | |
55 | /* PA26 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxClav */ | |
56 | /* PA25 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */ | |
57 | /* PA24 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */ | |
58 | /* PA23 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */ | |
59 | /* PA22 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */ | |
60 | /* PA21 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */ | |
61 | /* PA20 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */ | |
62 | /* PA19 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */ | |
63 | /* PA18 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */ | |
64 | /* PA17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */ | |
65 | /* PA16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */ | |
66 | /* PA15 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */ | |
67 | /* PA14 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */ | |
68 | /* PA13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */ | |
69 | /* PA12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */ | |
70 | /* PA11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */ | |
71 | /* PA10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */ | |
72 | /* PA9 */ { 0, 1, 1, 1, 0, 0 }, /* FCC1 L1TXD */ | |
73 | /* PA8 */ { 0, 1, 1, 0, 0, 0 }, /* FCC1 L1RXD */ | |
74 | /* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */ | |
75 | /* PA6 */ { 1, 1, 1, 1, 0, 0 }, /* TDM A1 L1RSYNC */ | |
76 | /* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */ | |
77 | /* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */ | |
78 | /* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */ | |
79 | /* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */ | |
80 | /* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* FREERUN */ | |
81 | /* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */ | |
55e33279 | 82 | }, |
db2f721f | 83 | |
55e33279 WD |
84 | /* Port B configuration */ |
85 | { /* conf ppar psor pdir podr pdat */ | |
db2f721f WD |
86 | /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */ |
87 | /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */ | |
88 | /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */ | |
89 | /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */ | |
90 | /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */ | |
91 | /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */ | |
92 | /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */ | |
93 | /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */ | |
94 | /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */ | |
95 | /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */ | |
96 | /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */ | |
97 | /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */ | |
98 | /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */ | |
99 | /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */ | |
100 | /* PB17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_DIV */ | |
101 | /* PB16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_ERR */ | |
102 | /* PB15 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_ERR */ | |
103 | /* PB14 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_EN */ | |
104 | /* PB13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:COL */ | |
105 | /* PB12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:CRS */ | |
106 | /* PB11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ | |
107 | /* PB10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ | |
108 | /* PB9 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ | |
109 | /* PB8 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ | |
110 | /* PB7 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ | |
111 | /* PB6 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ | |
112 | /* PB5 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ | |
113 | /* PB4 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ | |
114 | /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ | |
115 | /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ | |
116 | /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ | |
117 | /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ | |
55e33279 | 118 | }, |
db2f721f | 119 | |
55e33279 WD |
120 | /* Port C */ |
121 | { /* conf ppar psor pdir podr pdat */ | |
db2f721f WD |
122 | /* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */ |
123 | /* PC30 */ { 0, 0, 0, 1, 0, 0 }, /* PC30 */ | |
124 | /* PC29 */ { 0, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */ | |
125 | /* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */ | |
126 | /* PC27 */ { 0, 0, 0, 1, 0, 0 }, /* UART Clock in */ | |
127 | /* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */ | |
128 | /* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */ | |
129 | /* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */ | |
130 | /* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* ATMTFCLK */ | |
131 | /* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* ATMRFCLK */ | |
132 | /* PC21 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */ | |
133 | /* PC20 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */ | |
134 | /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK CLK13 */ | |
135 | /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK14) */ | |
136 | /* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */ | |
137 | /* PC16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK16) */ | |
138 | /* PC15 */ { 0, 0, 0, 1, 0, 0 }, /* PC15 */ | |
139 | /* PC14 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */ | |
140 | /* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */ | |
141 | /* PC12 */ { 0, 1, 0, 1, 0, 0 }, /* PC12 */ | |
142 | /* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* LXT971 transmit control */ | |
5d232d0e WD |
143 | /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* LXT970 FETHMDC */ |
144 | /* PC9 */ { 1, 0, 0, 0, 0, 0 }, /* LXT970 FETHMDIO */ | |
db2f721f WD |
145 | /* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */ |
146 | /* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */ | |
147 | /* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */ | |
148 | /* PC5 */ { 0, 0, 0, 1, 0, 0 }, /* PC5 */ | |
149 | /* PC4 */ { 0, 0, 0, 1, 0, 0 }, /* PC4 */ | |
150 | /* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */ | |
151 | /* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* ENET FDE */ | |
152 | /* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* ENET DSQE */ | |
153 | /* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* ENET LBK */ | |
55e33279 | 154 | }, |
db2f721f | 155 | |
55e33279 WD |
156 | /* Port D */ |
157 | { /* conf ppar psor pdir podr pdat */ | |
db2f721f WD |
158 | /* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */ |
159 | /* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */ | |
160 | /* PD29 */ { 0, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */ | |
161 | /* PD28 */ { 0, 1, 0, 0, 0, 0 }, /* PD28 */ | |
162 | /* PD27 */ { 0, 1, 1, 1, 0, 0 }, /* PD27 */ | |
163 | /* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */ | |
164 | /* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */ | |
165 | /* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */ | |
166 | /* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* PD23 */ | |
167 | /* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */ | |
168 | /* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */ | |
169 | /* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */ | |
170 | /* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */ | |
171 | /* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */ | |
172 | /* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */ | |
173 | /* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */ | |
174 | /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */ | |
175 | /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */ | |
176 | /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */ | |
177 | /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */ | |
178 | /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */ | |
179 | /* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */ | |
180 | /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */ | |
181 | /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */ | |
182 | /* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */ | |
183 | /* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */ | |
184 | /* PD5 */ { 0, 0, 0, 1, 0, 1 }, /* PD5 */ | |
185 | /* PD4 */ { 0, 0, 0, 1, 0, 1 }, /* PD4 */ | |
186 | /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ | |
187 | /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ | |
188 | /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ | |
189 | /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ | |
55e33279 | 190 | } |
db2f721f WD |
191 | }; |
192 | ||
193 | typedef struct bscr_ { | |
194 | unsigned long bcsr0; | |
195 | unsigned long bcsr1; | |
196 | unsigned long bcsr2; | |
197 | unsigned long bcsr3; | |
198 | unsigned long bcsr4; | |
199 | unsigned long bcsr5; | |
200 | unsigned long bcsr6; | |
201 | unsigned long bcsr7; | |
202 | } bcsr_t; | |
203 | ||
5d232d0e WD |
204 | typedef struct pci_ic_s { |
205 | unsigned long pci_int_stat; | |
206 | unsigned long pci_int_mask; | |
207 | } pci_ic_t; | |
208 | ||
db2f721f WD |
209 | void reset_phy(void) |
210 | { | |
55e33279 | 211 | volatile bcsr_t *bcsr = (bcsr_t *)CONFIG_SYS_BCSR; |
db2f721f | 212 | |
55e33279 WD |
213 | /* reset the FEC port */ |
214 | bcsr->bcsr1 &= ~FETH_RST; | |
215 | bcsr->bcsr1 |= FETH_RST; | |
db2f721f WD |
216 | } |
217 | ||
218 | ||
55e33279 | 219 | int board_early_init_f(void) |
db2f721f | 220 | { |
55e33279 WD |
221 | volatile bcsr_t *bcsr = (bcsr_t *)CONFIG_SYS_BCSR; |
222 | volatile pci_ic_t *pci_ic = (pci_ic_t *)CONFIG_SYS_PCI_INT; | |
5d232d0e | 223 | |
55e33279 | 224 | bcsr->bcsr1 = ~FETHIEN & ~RS232EN_1 & ~RS232EN_2; |
db2f721f | 225 | |
55e33279 WD |
226 | /* mask all PCI interrupts */ |
227 | pci_ic->pci_int_mask |= 0xfff00000; | |
8bde7f77 | 228 | |
55e33279 | 229 | return 0; |
db2f721f WD |
230 | } |
231 | ||
232 | int checkboard(void) | |
233 | { | |
55e33279 WD |
234 | puts("Board: Motorola MPC8266ADS\n"); |
235 | return 0; | |
db2f721f WD |
236 | } |
237 | ||
9973e3c6 | 238 | phys_size_t initdram(int board_type) |
db2f721f WD |
239 | { |
240 | /* Autoinit part stolen from board/sacsng/sacsng.c */ | |
55e33279 WD |
241 | volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; |
242 | volatile memctl8260_t *memctl = &immap->im_memctl; | |
243 | volatile uchar c = 0xff; | |
244 | volatile uchar *ramaddr = (uchar *) (CONFIG_SYS_SDRAM_BASE + 0x8); | |
245 | uint psdmr = CONFIG_SYS_PSDMR; | |
246 | int i; | |
247 | ||
248 | uint psrt = 0x21; /* for no SPD */ | |
249 | uint chipselects = 1; /* for no SPD */ | |
250 | uint sdram_size = CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; /* for no SPD */ | |
251 | uint or = CONFIG_SYS_OR2_PRELIM; /* for no SPD */ | |
252 | uint data_width; | |
253 | uint rows; | |
254 | uint banks; | |
255 | uint cols; | |
256 | uint caslatency; | |
257 | uint width; | |
258 | uint rowst; | |
259 | uint sdam; | |
260 | uint bsma; | |
261 | uint sda10; | |
55e33279 WD |
262 | u_char data; |
263 | u_char cksum; | |
264 | int j; | |
265 | ||
266 | /* | |
267 | * Keep the compiler from complaining about | |
268 | * potentially uninitialized vars | |
269 | */ | |
270 | data_width = rows = banks = cols = caslatency = 0; | |
271 | ||
272 | /* | |
273 | * Read the SDRAM SPD EEPROM via I2C. | |
274 | */ | |
275 | i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); | |
276 | ||
277 | i2c_read(SDRAM_SPD_ADDR, 0, 1, &data, 1); | |
55e33279 WD |
278 | cksum = data; |
279 | for (j = 1; j < 64; j++) { /* read only the checksummed bytes */ | |
280 | /* note: the I2C address autoincrements when alen == 0 */ | |
db2f721f | 281 | i2c_read(SDRAM_SPD_ADDR, 0, 0, &data, 1); |
55e33279 WD |
282 | /*printf("addr %d = 0x%02x\n", j, data); */ |
283 | if (j == 5) | |
284 | chipselects = data & 0x0F; | |
285 | else if (j == 6) | |
286 | data_width = data; | |
287 | else if (j == 7) | |
288 | data_width |= data << 8; | |
289 | else if (j == 3) | |
290 | rows = data & 0x0F; | |
291 | else if (j == 4) | |
292 | cols = data & 0x0F; | |
293 | else if (j == 12) { | |
db2f721f | 294 | /* |
55e33279 WD |
295 | * Refresh rate: this assumes the prescaler is set to |
296 | * approximately 0.39uSec per tick and the target | |
297 | * refresh period is about 85% of maximum. | |
db2f721f | 298 | */ |
55e33279 WD |
299 | switch (data & 0x7F) { |
300 | default: | |
301 | case 0: | |
302 | psrt = 0x21; /* 15.625uS */ | |
303 | break; | |
304 | case 1: | |
305 | psrt = 0x07; /* 3.9uS */ | |
306 | break; | |
307 | case 2: | |
308 | psrt = 0x0F; /* 7.8uS */ | |
309 | break; | |
310 | case 3: | |
311 | psrt = 0x43; /* 31.3uS */ | |
312 | break; | |
313 | case 4: | |
314 | psrt = 0x87; /* 62.5uS */ | |
315 | break; | |
316 | case 5: | |
317 | psrt = 0xFF; /* 125uS */ | |
318 | break; | |
db2f721f | 319 | } |
55e33279 WD |
320 | } else if (j == 17) |
321 | banks = data; | |
322 | else if (j == 18) { | |
323 | caslatency = 3; /* default CL */ | |
324 | #if (PESSIMISTIC_SDRAM) | |
325 | if ((data & 0x04) != 0) | |
326 | caslatency = 3; | |
327 | else if ((data & 0x02) != 0) | |
328 | caslatency = 2; | |
329 | else if ((data & 0x01) != 0) | |
330 | caslatency = 1; | |
331 | #else | |
332 | if ((data & 0x01) != 0) | |
333 | caslatency = 1; | |
334 | else if ((data & 0x02) != 0) | |
335 | caslatency = 2; | |
336 | else if ((data & 0x04) != 0) | |
337 | caslatency = 3; | |
338 | #endif | |
339 | else { | |
340 | printf("WARNING: Unknown CAS latency 0x%02X, using 3\n", | |
db2f721f WD |
341 | data); |
342 | } | |
55e33279 WD |
343 | } else if (j == 63) { |
344 | if (data != cksum) { | |
345 | printf("WARNING: Configuration data checksum failure:" | |
db2f721f | 346 | " is 0x%02x, calculated 0x%02x\n", |
55e33279 | 347 | data, cksum); |
db2f721f WD |
348 | } |
349 | } | |
350 | cksum += data; | |
55e33279 | 351 | } |
db2f721f | 352 | |
55e33279 WD |
353 | /* We don't trust CL less than 2 (only saw it on an old 16MByte DIMM) */ |
354 | if (caslatency < 2) { | |
db2f721f WD |
355 | printf("CL was %d, forcing to 2\n", caslatency); |
356 | caslatency = 2; | |
55e33279 WD |
357 | } |
358 | if (rows > 14) { | |
359 | printf("This doesn't look good, rows = %d, should be <= 14\n", | |
360 | rows); | |
db2f721f | 361 | rows = 14; |
55e33279 WD |
362 | } |
363 | if (cols > 11) { | |
364 | printf("This doesn't look good, columns = %d, should be <= 11\n", | |
365 | cols); | |
db2f721f | 366 | cols = 11; |
55e33279 | 367 | } |
db2f721f | 368 | |
55e33279 | 369 | if ((data_width != 64) && (data_width != 72)) { |
db2f721f WD |
370 | printf("WARNING: SDRAM width unsupported, is %d, expected 64 or 72.\n", |
371 | data_width); | |
55e33279 WD |
372 | } |
373 | width = 3; /* 2^3 = 8 bytes = 64 bits wide */ | |
374 | /* | |
375 | * Convert banks into log2(banks) | |
376 | */ | |
377 | if (banks == 2) | |
378 | banks = 1; | |
379 | else if (banks == 4) | |
380 | banks = 2; | |
381 | else if (banks == 8) | |
382 | banks = 3; | |
383 | ||
384 | ||
385 | sdram_size = 1 << (rows + cols + banks + width); | |
386 | /* hack for high density memory (512MB per CS) */ | |
387 | /* !!!!! Will ONLY work with Page Based Interleave !!!!! | |
388 | ( PSDMR[PBI] = 1 ) | |
389 | */ | |
390 | /* | |
391 | * memory actually has 11 column addresses, but the memory | |
392 | * controller doesn't really care. | |
393 | * | |
394 | * the calculations that follow will however move the rows so | |
395 | * that they are muxed one bit off if you use 11 bit columns. | |
396 | * | |
397 | * The solution is to tell the memory controller the correct | |
398 | * size of the memory but change the number of columns to 10 | |
399 | * afterwards. | |
400 | * | |
401 | * The 11th column addre will still be mucxed correctly onto | |
402 | * the bus. | |
403 | * | |
404 | * Also be aware that the MPC8266ADS board Rev B has not | |
405 | * connected Row address 13 to anything. | |
406 | * | |
407 | * The fix is to connect ADD16 (from U37-47) to SADDR12 (U28-126) | |
408 | */ | |
409 | if (cols > 10) | |
410 | cols = 10; | |
411 | ||
412 | #if (CONFIG_PBI == 0) /* bank-based interleaving */ | |
413 | rowst = ((32 - 6) - (rows + cols + width)) * 2; | |
db2f721f | 414 | #else |
55e33279 | 415 | rowst = 32 - (rows + banks + cols + width); |
db2f721f WD |
416 | #endif |
417 | ||
55e33279 WD |
418 | or = ~(sdram_size - 1) | /* SDAM address mask */ |
419 | ((banks - 1) << 13) | /* banks per device */ | |
420 | (rowst << 9) | /* rowst */ | |
421 | ((rows - 9) << 6); /* numr */ | |
422 | ||
423 | ||
424 | /*printf("memctl->memc_or2 = 0x%08x\n", or); */ | |
425 | ||
426 | /* | |
427 | * SDAM specifies the number of columns that are multiplexed | |
428 | * (reference AN2165/D), defined to be (columns - 6) for page | |
429 | * interleave, (columns - 8) for bank interleave. | |
430 | * | |
431 | * BSMA is 14 - max(rows, cols). The bank select lines come | |
432 | * into play above the highest "address" line going into the | |
433 | * the SDRAM. | |
434 | */ | |
435 | #if (CONFIG_PBI == 0) /* bank-based interleaving */ | |
436 | sdam = cols - 8; | |
437 | bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols); | |
438 | sda10 = sdam + 2; | |
db2f721f | 439 | #else |
55e33279 WD |
440 | sdam = cols + banks - 8; |
441 | bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols); | |
442 | sda10 = sdam; | |
db2f721f | 443 | #endif |
55e33279 WD |
444 | #if (PESSIMISTIC_SDRAM) |
445 | psdmr = (CONFIG_PBI | PSDMR_RFEN | PSDMR_RFRC_16_CLK | | |
446 | PSDMR_PRETOACT_8W | PSDMR_ACTTORW_8W | PSDMR_WRC_4C | | |
447 | PSDMR_EAMUX | PSDMR_BUFCMD) | caslatency | | |
448 | ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ | |
449 | (sdam << 24) | (bsma << 21) | (sda10 << 18); | |
db2f721f | 450 | #else |
55e33279 WD |
451 | psdmr = (CONFIG_PBI | PSDMR_RFEN | 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 | BUFCMD) | caslatency | | |
456 | ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ | |
457 | (sdam << 24) | (bsma << 21) | (sda10 << 18); | |
db2f721f | 458 | #endif |
55e33279 WD |
459 | /*printf("psdmr = 0x%08x\n", psdmr); */ |
460 | ||
461 | /* | |
462 | * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35): | |
463 | * | |
464 | * "At system reset, initialization software must set up the | |
465 | * programmable parameters in the memory controller banks registers | |
466 | * (ORx, BRx, P/LSDMR). After all memory parameters are configured, | |
467 | * system software should execute the following initialization sequence | |
468 | * for each SDRAM device. | |
469 | * | |
470 | * 1. Issue a PRECHARGE-ALL-BANKS command | |
471 | * 2. Issue eight CBR REFRESH commands | |
472 | * 3. Issue a MODE-SET command to initialize the mode register | |
473 | * | |
474 | * Quote from Micron MT48LC8M16A2 data sheet: | |
475 | * | |
476 | * "...the SDRAM requires a 100uS delay prior to issuing any | |
477 | * command other than a COMMAND INHIBIT or NOP. Starting at some | |
478 | * point during this 100uS period and continuing at least through | |
479 | * the end of this period, COMMAND INHIBIT or NOP commands should | |
480 | * be applied." | |
481 | * | |
482 | * "Once the 100uS delay has been satisfied with at least one COMMAND | |
483 | * INHIBIT or NOP command having been applied, a /PRECHARGE command/ | |
484 | * should be applied. All banks must then be precharged, thereby | |
485 | * placing the device in the all banks idle state." | |
486 | * | |
487 | * "Once in the idle state, /two/ AUTO REFRESH cycles must be | |
488 | * performed. After the AUTO REFRESH cycles are complete, the | |
489 | * SDRAM is ready for mode register programming." | |
490 | * | |
491 | * (/emphasis/ mine, gvb) | |
492 | * | |
493 | * The way I interpret this, Micron start up sequence is: | |
494 | * 1. Issue a PRECHARGE-BANK command (initial precharge) | |
495 | * 2. Issue a PRECHARGE-ALL-BANKS command ("all banks ... precharged") | |
496 | * 3. Issue two (presumably, doing eight is OK) CBR REFRESH commands | |
497 | * 4. Issue a MODE-SET command to initialize the mode register | |
498 | * | |
499 | * -------- | |
500 | * | |
501 | * The initial commands are executed by setting P/LSDMR[OP] and | |
502 | * accessing the SDRAM with a single-byte transaction." | |
503 | * | |
504 | * The appropriate BRx/ORx registers have already been set | |
505 | * when we get here. The SDRAM can be accessed at the address | |
506 | * CONFIG_SYS_SDRAM_BASE. | |
507 | */ | |
508 | ||
509 | memctl->memc_mptpr = CONFIG_SYS_MPTPR; | |
510 | memctl->memc_psrt = psrt; | |
511 | ||
512 | memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM; | |
513 | memctl->memc_or2 = or; | |
514 | ||
515 | memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; | |
db2f721f WD |
516 | *ramaddr = c; |
517 | ||
55e33279 WD |
518 | memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; |
519 | for (i = 0; i < 8; i++) | |
520 | *ramaddr = c; | |
521 | ||
522 | memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; | |
523 | *ramaddr = c; | |
db2f721f | 524 | |
55e33279 WD |
525 | memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; |
526 | *ramaddr = c; | |
db2f721f | 527 | |
55e33279 WD |
528 | /* |
529 | * Do it a second time for the second set of chips if the DIMM has | |
530 | * two chip selects (double sided). | |
531 | */ | |
532 | if (chipselects > 1) { | |
533 | ramaddr += sdram_size; | |
db2f721f | 534 | |
6d0f6bcf | 535 | memctl->memc_br3 = CONFIG_SYS_BR3_PRELIM + sdram_size; |
db2f721f WD |
536 | memctl->memc_or3 = or; |
537 | ||
538 | memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; | |
539 | *ramaddr = c; | |
540 | ||
541 | memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; | |
542 | for (i = 0; i < 8; i++) | |
543 | *ramaddr = c; | |
544 | ||
545 | memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; | |
546 | *ramaddr = c; | |
547 | ||
548 | memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; | |
549 | *ramaddr = c; | |
55e33279 | 550 | } |
db2f721f | 551 | |
db2f721f WD |
552 | /* print info */ |
553 | printf("SDRAM configuration read from SPD\n"); | |
554 | printf("\tSize per side = %dMB\n", sdram_size >> 20); | |
55e33279 WD |
555 | printf("\tOrganization: %d sides, %d banks, %d Columns, %d Rows, Data width = %d bits\n", |
556 | chipselects, 1 << (banks), cols, rows, data_width); | |
65bd0e28 | 557 | printf("\tRefresh rate = %d, CAS latency = %d", psrt, caslatency); |
55e33279 WD |
558 | #if (CONFIG_PBI == 0) /* bank-based interleaving */ |
559 | printf(", Using Bank Based Interleave\n"); | |
65bd0e28 | 560 | #else |
55e33279 | 561 | printf(", Using Page Based Interleave\n"); |
42d1f039 | 562 | #endif |
db2f721f WD |
563 | printf("\tTotal size: "); |
564 | ||
55e33279 WD |
565 | /* this delay only needed for original 16MB DIMM... |
566 | * Not needed for any other memory configuration */ | |
567 | if ((sdram_size * chipselects) == (16 * 1024 * 1024)) | |
568 | udelay(250000); | |
5d232d0e | 569 | |
55e33279 WD |
570 | return sdram_size * chipselects; |
571 | } | |
7a8e9bed | 572 | |
5d232d0e WD |
573 | #ifdef CONFIG_PCI |
574 | struct pci_controller hose; | |
575 | ||
576 | extern void pci_mpc8250_init(struct pci_controller *); | |
577 | ||
578 | void pci_init_board(void) | |
579 | { | |
580 | pci_mpc8250_init(&hose); | |
581 | } | |
582 | #endif |