]>
Commit | Line | Data |
---|---|---|
fe8c2806 WD |
1 | /* |
2 | * (C) Copyright 2002 | |
3 | * Custom IDEAS, Inc. <www.cideas.com> | |
4 | * Gerald Van Baren <vanbaren@cideas.com> | |
5 | * | |
6 | * See file CREDITS for list of people who contributed to this | |
7 | * project. | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU General Public License as | |
11 | * published by the Free Software Foundation; either version 2 of | |
12 | * the License, or (at your option) any later version. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
22 | * MA 02111-1307 USA | |
23 | */ | |
24 | ||
fe8c2806 | 25 | #include <common.h> |
4ff170a8 | 26 | #include <asm/u-boot.h> |
fe8c2806 WD |
27 | #include <ioports.h> |
28 | #include <mpc8260.h> | |
fe8c2806 WD |
29 | #include <i2c.h> |
30 | #include <spi.h> | |
78137c3c | 31 | #include <command.h> |
fe8c2806 WD |
32 | |
33 | #ifdef CONFIG_SHOW_BOOT_PROGRESS | |
34 | #include <status_led.h> | |
35 | #endif | |
36 | ||
78137c3c WD |
37 | #ifdef CONFIG_ETHER_LOOPBACK_TEST |
38 | extern void eth_loopback_test(void); | |
39 | #endif /* CONFIG_ETHER_LOOPBACK_TEST */ | |
40 | ||
41 | extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); | |
42 | ||
fe8c2806 WD |
43 | #include "clkinit.h" |
44 | #include "ioconfig.h" /* I/O configuration table */ | |
45 | ||
46 | /* | |
47 | * PBI Page Based Interleaving | |
48 | * PSDMR_PBI page based interleaving | |
49 | * 0 bank based interleaving | |
50 | * External Address Multiplexing (EAMUX) adds a clock to address cycles | |
51 | * (this can help with marginal board layouts) | |
52 | * PSDMR_EAMUX adds a clock | |
53 | * 0 no extra clock | |
54 | * Buffer Command (BUFCMD) adds a clock to command cycles. | |
55 | * PSDMR_BUFCMD adds a clock | |
56 | * 0 no extra clock | |
57 | */ | |
58 | #define CONFIG_PBI PSDMR_PBI | |
59 | #define PESSIMISTIC_SDRAM 0 | |
60 | #define EAMUX 0 /* EST requires EAMUX */ | |
61 | #define BUFCMD 0 | |
62 | ||
63 | /* | |
64 | * ADC/DAC Defines: | |
65 | */ | |
66 | #define INITIAL_SAMPLE_RATE 10016 /* Initial Daq sample rate */ | |
67 | #define INITIAL_RIGHT_JUST 0 /* Initial DAC right justification */ | |
68 | #define INITIAL_MCLK_DIVIDE 0 /* Initial MCLK Divide */ | |
69 | #define INITIAL_SAMPLE_64X 1 /* Initial 64x clocking mode */ | |
70 | #define INITIAL_SAMPLE_128X 0 /* Initial 128x clocking mode */ | |
71 | ||
72 | /* | |
73 | * ADC Defines: | |
74 | */ | |
75 | #define I2C_ADC_1_ADDR 0x0E /* I2C Address of the ADC #1 */ | |
76 | #define I2C_ADC_2_ADDR 0x0F /* I2C Address of the ADC #2 */ | |
77 | ||
78 | #define ADC_SDATA1_MASK 0x00020000 /* PA14 - CH12SDATA_PU */ | |
79 | #define ADC_SDATA2_MASK 0x00010000 /* PA15 - CH34SDATA_PU */ | |
80 | ||
81 | #define ADC_VREF_CAP 100 /* VREF capacitor in uF */ | |
82 | #define ADC_INITIAL_DELAY (10 * ADC_VREF_CAP) /* 10 usec per uF, in usec */ | |
83 | #define ADC_SDATA_DELAY 100 /* ADC SDATA release delay in usec */ | |
84 | #define ADC_CAL_DELAY (1000000 / INITIAL_SAMPLE_RATE * 4500) | |
8bde7f77 | 85 | /* Wait at least 4100 LRCLK's */ |
fe8c2806 WD |
86 | |
87 | #define ADC_REG1_FRAME_START 0x80 /* Frame start */ | |
88 | #define ADC_REG1_GROUND_CAL 0x40 /* Ground calibration enable */ | |
89 | #define ADC_REG1_ANA_MOD_PDOWN 0x20 /* Analog modulator section in power down */ | |
90 | #define ADC_REG1_DIG_MOD_PDOWN 0x10 /* Digital modulator section in power down */ | |
91 | ||
92 | #define ADC_REG2_128x 0x80 /* Oversample at 128x */ | |
93 | #define ADC_REG2_CAL 0x40 /* System calibration enable */ | |
94 | #define ADC_REG2_CHANGE_SIGN 0x20 /* Change sign enable */ | |
95 | #define ADC_REG2_LR_DISABLE 0x10 /* Left/Right output disable */ | |
96 | #define ADC_REG2_HIGH_PASS_DIS 0x08 /* High pass filter disable */ | |
97 | #define ADC_REG2_SLAVE_MODE 0x04 /* Slave mode */ | |
98 | #define ADC_REG2_DFS 0x02 /* Digital format select */ | |
99 | #define ADC_REG2_MUTE 0x01 /* Mute */ | |
100 | ||
101 | #define ADC_REG7_ADDR_ENABLE 0x80 /* Address enable */ | |
102 | #define ADC_REG7_PEAK_ENABLE 0x40 /* Peak enable */ | |
103 | #define ADC_REG7_PEAK_UPDATE 0x20 /* Peak update */ | |
104 | #define ADC_REG7_PEAK_FORMAT 0x10 /* Peak display format */ | |
105 | #define ADC_REG7_DIG_FILT_PDOWN 0x04 /* Digital filter power down enable */ | |
106 | #define ADC_REG7_FIR2_IN_EN 0x02 /* External FIR2 input enable */ | |
107 | #define ADC_REG7_PSYCHO_EN 0x01 /* External pyscho filter input enable */ | |
108 | ||
109 | /* | |
110 | * DAC Defines: | |
111 | */ | |
112 | ||
113 | #define I2C_DAC_ADDR 0x11 /* I2C Address of the DAC */ | |
114 | ||
115 | #define DAC_RST_MASK 0x00008000 /* PA16 - DAC_RST* */ | |
116 | #define DAC_RESET_DELAY 100 /* DAC reset delay in usec */ | |
117 | #define DAC_INITIAL_DELAY 5000 /* DAC initialization delay in usec */ | |
118 | ||
119 | #define DAC_REG1_AMUTE 0x80 /* Auto-mute */ | |
120 | ||
121 | #define DAC_REG1_LEFT_JUST_24_BIT (0 << 4) /* Fmt 0: Left justified 24 bit */ | |
122 | #define DAC_REG1_I2S_24_BIT (1 << 4) /* Fmt 1: I2S up to 24 bit */ | |
123 | #define DAC_REG1_RIGHT_JUST_16BIT (2 << 4) /* Fmt 2: Right justified 16 bit */ | |
124 | #define DAC_REG1_RIGHT_JUST_24BIT (3 << 4) /* Fmt 3: Right justified 24 bit */ | |
125 | #define DAC_REG1_RIGHT_JUST_20BIT (4 << 4) /* Fmt 4: Right justified 20 bit */ | |
126 | #define DAC_REG1_RIGHT_JUST_18BIT (5 << 4) /* Fmt 5: Right justified 18 bit */ | |
127 | ||
128 | #define DAC_REG1_DEM_NO (0 << 2) /* No De-emphasis */ | |
129 | #define DAC_REG1_DEM_44KHZ (1 << 2) /* 44.1KHz De-emphasis */ | |
130 | #define DAC_REG1_DEM_48KHZ (2 << 2) /* 48KHz De-emphasis */ | |
131 | #define DAC_REG1_DEM_32KHZ (3 << 2) /* 32KHz De-emphasis */ | |
132 | ||
133 | #define DAC_REG1_SINGLE 0 /* 4- 50KHz sample rate */ | |
134 | #define DAC_REG1_DOUBLE 1 /* 50-100KHz sample rate */ | |
135 | #define DAC_REG1_QUAD 2 /* 100-200KHz sample rate */ | |
136 | #define DAC_REG1_DSD 3 /* Direct Stream Data, DSD */ | |
137 | ||
138 | #define DAC_REG5_INVERT_A 0x80 /* Invert channel A */ | |
139 | #define DAC_REG5_INVERT_B 0x40 /* Invert channel B */ | |
140 | #define DAC_REG5_I2C_MODE 0x20 /* Control port (I2C) mode */ | |
141 | #define DAC_REG5_POWER_DOWN 0x10 /* Power down mode */ | |
142 | #define DAC_REG5_MUTEC_A_B 0x08 /* Mutec A=B */ | |
143 | #define DAC_REG5_FREEZE 0x04 /* Freeze */ | |
144 | #define DAC_REG5_MCLK_DIV 0x02 /* MCLK divide by 2 */ | |
145 | #define DAC_REG5_RESERVED 0x01 /* Reserved */ | |
146 | ||
147 | /* ------------------------------------------------------------------------- */ | |
148 | ||
149 | /* | |
150 | * Check Board Identity: | |
151 | */ | |
152 | ||
153 | int checkboard(void) | |
154 | { | |
155 | printf ("SACSng\n"); | |
156 | ||
157 | return 0; | |
158 | } | |
159 | ||
160 | /* ------------------------------------------------------------------------- */ | |
161 | ||
9973e3c6 | 162 | phys_size_t initdram(int board_type) |
fe8c2806 | 163 | { |
6d0f6bcf | 164 | volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
fe8c2806 WD |
165 | volatile memctl8260_t *memctl = &immap->im_memctl; |
166 | volatile uchar c = 0; | |
6d0f6bcf JCPV |
167 | volatile uchar *ramaddr = (uchar *)(CONFIG_SYS_SDRAM_BASE + 0x8); |
168 | uint psdmr = CONFIG_SYS_PSDMR; | |
fe8c2806 WD |
169 | int i; |
170 | uint psrt = 14; /* for no SPD */ | |
171 | uint chipselects = 1; /* for no SPD */ | |
6d0f6bcf JCPV |
172 | uint sdram_size = CONFIG_SYS_SDRAM0_SIZE * 1024 * 1024; /* for no SPD */ |
173 | uint or = CONFIG_SYS_OR2_PRELIM; /* for no SPD */ | |
fe8c2806 WD |
174 | #ifdef SDRAM_SPD_ADDR |
175 | uint data_width; | |
176 | uint rows; | |
177 | uint banks; | |
178 | uint cols; | |
179 | uint caslatency; | |
180 | uint width; | |
181 | uint rowst; | |
182 | uint sdam; | |
183 | uint bsma; | |
184 | uint sda10; | |
185 | u_char spd_size; | |
186 | u_char data; | |
187 | u_char cksum; | |
188 | int j; | |
189 | #endif | |
190 | ||
191 | #ifdef SDRAM_SPD_ADDR | |
192 | /* Keep the compiler from complaining about potentially uninitialized vars */ | |
193 | data_width = chipselects = rows = banks = cols = caslatency = psrt = 0; | |
194 | ||
195 | /* | |
196 | * Read the SDRAM SPD EEPROM via I2C. | |
197 | */ | |
198 | i2c_read(SDRAM_SPD_ADDR, 0, 1, &data, 1); | |
199 | spd_size = data; | |
200 | cksum = data; | |
201 | for(j = 1; j < 64; j++) { /* read only the checksummed bytes */ | |
202 | /* note: the I2C address autoincrements when alen == 0 */ | |
203 | i2c_read(SDRAM_SPD_ADDR, 0, 0, &data, 1); | |
204 | if(j == 5) chipselects = data & 0x0F; | |
205 | else if(j == 6) data_width = data; | |
206 | else if(j == 7) data_width |= data << 8; | |
207 | else if(j == 3) rows = data & 0x0F; | |
208 | else if(j == 4) cols = data & 0x0F; | |
209 | else if(j == 12) { | |
210 | /* | |
8bde7f77 | 211 | * Refresh rate: this assumes the prescaler is set to |
fe8c2806 WD |
212 | * approximately 1uSec per tick. |
213 | */ | |
214 | switch(data & 0x7F) { | |
8bde7f77 WD |
215 | default: |
216 | case 0: psrt = 14 ; /* 15.625uS */ break; | |
217 | case 1: psrt = 2; /* 3.9uS */ break; | |
218 | case 2: psrt = 6; /* 7.8uS */ break; | |
219 | case 3: psrt = 29; /* 31.3uS */ break; | |
220 | case 4: psrt = 60; /* 62.5uS */ break; | |
221 | case 5: psrt = 120; /* 125uS */ break; | |
fe8c2806 WD |
222 | } |
223 | } | |
224 | else if(j == 17) banks = data; | |
225 | else if(j == 18) { | |
226 | caslatency = 3; /* default CL */ | |
227 | #if(PESSIMISTIC_SDRAM) | |
228 | if((data & 0x04) != 0) caslatency = 3; | |
229 | else if((data & 0x02) != 0) caslatency = 2; | |
230 | else if((data & 0x01) != 0) caslatency = 1; | |
231 | #else | |
232 | if((data & 0x01) != 0) caslatency = 1; | |
233 | else if((data & 0x02) != 0) caslatency = 2; | |
234 | else if((data & 0x04) != 0) caslatency = 3; | |
235 | #endif | |
236 | else { | |
237 | printf ("WARNING: Unknown CAS latency 0x%02X, using 3\n", | |
8bde7f77 | 238 | data); |
fe8c2806 WD |
239 | } |
240 | } | |
241 | else if(j == 63) { | |
242 | if(data != cksum) { | |
243 | printf ("WARNING: Configuration data checksum failure:" | |
8bde7f77 | 244 | " is 0x%02x, calculated 0x%02x\n", |
fe8c2806 WD |
245 | data, cksum); |
246 | } | |
247 | } | |
248 | cksum += data; | |
249 | } | |
250 | ||
251 | /* We don't trust CL less than 2 (only saw it on an old 16MByte DIMM) */ | |
252 | if(caslatency < 2) { | |
78137c3c | 253 | printf("WARNING: CL was %d, forcing to 2\n", caslatency); |
fe8c2806 WD |
254 | caslatency = 2; |
255 | } | |
256 | if(rows > 14) { | |
78137c3c | 257 | printf("WARNING: This doesn't look good, rows = %d, should be <= 14\n", rows); |
fe8c2806 WD |
258 | rows = 14; |
259 | } | |
260 | if(cols > 11) { | |
78137c3c | 261 | printf("WARNING: This doesn't look good, columns = %d, should be <= 11\n", cols); |
fe8c2806 WD |
262 | cols = 11; |
263 | } | |
264 | ||
265 | if((data_width != 64) && (data_width != 72)) | |
266 | { | |
267 | printf("WARNING: SDRAM width unsupported, is %d, expected 64 or 72.\n", | |
268 | data_width); | |
269 | } | |
270 | width = 3; /* 2^3 = 8 bytes = 64 bits wide */ | |
271 | /* | |
272 | * Convert banks into log2(banks) | |
273 | */ | |
274 | if (banks == 2) banks = 1; | |
275 | else if(banks == 4) banks = 2; | |
276 | else if(banks == 8) banks = 3; | |
277 | ||
278 | sdram_size = 1 << (rows + cols + banks + width); | |
279 | ||
280 | #if(CONFIG_PBI == 0) /* bank-based interleaving */ | |
281 | rowst = ((32 - 6) - (rows + cols + width)) * 2; | |
282 | #else | |
283 | rowst = 32 - (rows + banks + cols + width); | |
284 | #endif | |
285 | ||
286 | or = ~(sdram_size - 1) | /* SDAM address mask */ | |
287 | ((banks-1) << 13) | /* banks per device */ | |
288 | (rowst << 9) | /* rowst */ | |
289 | ((rows - 9) << 6); /* numr */ | |
290 | ||
291 | memctl->memc_or2 = or; | |
292 | ||
293 | /* | |
294 | * SDAM specifies the number of columns that are multiplexed | |
295 | * (reference AN2165/D), defined to be (columns - 6) for page | |
296 | * interleave, (columns - 8) for bank interleave. | |
297 | * | |
298 | * BSMA is 14 - max(rows, cols). The bank select lines come | |
299 | * into play above the highest "address" line going into the | |
300 | * the SDRAM. | |
301 | */ | |
302 | #if(CONFIG_PBI == 0) /* bank-based interleaving */ | |
303 | sdam = cols - 8; | |
304 | bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols); | |
305 | sda10 = sdam + 2; | |
306 | #else | |
307 | sdam = cols - 6; | |
308 | bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols); | |
309 | sda10 = sdam; | |
310 | #endif | |
311 | #if(PESSIMISTIC_SDRAM) | |
312 | psdmr = (CONFIG_PBI |\ | |
313 | PSDMR_RFEN |\ | |
314 | PSDMR_RFRC_16_CLK |\ | |
315 | PSDMR_PRETOACT_8W |\ | |
316 | PSDMR_ACTTORW_8W |\ | |
317 | PSDMR_WRC_4C |\ | |
318 | PSDMR_EAMUX |\ | |
8bde7f77 | 319 | PSDMR_BUFCMD) |\ |
fe8c2806 WD |
320 | caslatency |\ |
321 | ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \ | |
322 | (sdam << 24) |\ | |
323 | (bsma << 21) |\ | |
324 | (sda10 << 18); | |
325 | #else | |
326 | psdmr = (CONFIG_PBI |\ | |
327 | PSDMR_RFEN |\ | |
328 | PSDMR_RFRC_7_CLK |\ | |
329 | PSDMR_PRETOACT_3W | /* 1 for 7E parts (fast PC-133) */ \ | |
330 | PSDMR_ACTTORW_2W | /* 1 for 7E parts (fast PC-133) */ \ | |
331 | PSDMR_WRC_1C | /* 1 clock + 7nSec */ | |
332 | EAMUX |\ | |
8bde7f77 | 333 | BUFCMD) |\ |
fe8c2806 WD |
334 | caslatency |\ |
335 | ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \ | |
336 | (sdam << 24) |\ | |
337 | (bsma << 21) |\ | |
338 | (sda10 << 18); | |
339 | #endif | |
340 | #endif | |
341 | ||
342 | /* | |
343 | * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35): | |
344 | * | |
345 | * "At system reset, initialization software must set up the | |
346 | * programmable parameters in the memory controller banks registers | |
347 | * (ORx, BRx, P/LSDMR). After all memory parameters are configured, | |
348 | * system software should execute the following initialization sequence | |
349 | * for each SDRAM device. | |
350 | * | |
351 | * 1. Issue a PRECHARGE-ALL-BANKS command | |
352 | * 2. Issue eight CBR REFRESH commands | |
353 | * 3. Issue a MODE-SET command to initialize the mode register | |
354 | * | |
355 | * Quote from Micron MT48LC8M16A2 data sheet: | |
356 | * | |
357 | * "...the SDRAM requires a 100uS delay prior to issuing any | |
358 | * command other than a COMMAND INHIBIT or NOP. Starting at some | |
359 | * point during this 100uS period and continuing at least through | |
360 | * the end of this period, COMMAND INHIBIT or NOP commands should | |
361 | * be applied." | |
362 | * | |
363 | * "Once the 100uS delay has been satisfied with at least one COMMAND | |
364 | * INHIBIT or NOP command having been applied, a /PRECHARGE command/ | |
365 | * should be applied. All banks must then be precharged, thereby | |
366 | * placing the device in the all banks idle state." | |
367 | * | |
368 | * "Once in the idle state, /two/ AUTO REFRESH cycles must be | |
369 | * performed. After the AUTO REFRESH cycles are complete, the | |
370 | * SDRAM is ready for mode register programming." | |
371 | * | |
372 | * (/emphasis/ mine, gvb) | |
373 | * | |
374 | * The way I interpret this, Micron start up sequence is: | |
375 | * 1. Issue a PRECHARGE-BANK command (initial precharge) | |
376 | * 2. Issue a PRECHARGE-ALL-BANKS command ("all banks ... precharged") | |
377 | * 3. Issue two (presumably, doing eight is OK) CBR REFRESH commands | |
378 | * 4. Issue a MODE-SET command to initialize the mode register | |
379 | * | |
380 | * -------- | |
381 | * | |
382 | * The initial commands are executed by setting P/LSDMR[OP] and | |
383 | * accessing the SDRAM with a single-byte transaction." | |
384 | * | |
385 | * The appropriate BRx/ORx registers have already been set when we | |
6d0f6bcf | 386 | * get here. The SDRAM can be accessed at the address CONFIG_SYS_SDRAM_BASE. |
fe8c2806 WD |
387 | */ |
388 | ||
6d0f6bcf | 389 | memctl->memc_mptpr = CONFIG_SYS_MPTPR; |
fe8c2806 WD |
390 | memctl->memc_psrt = psrt; |
391 | ||
392 | memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; | |
393 | *ramaddr = c; | |
394 | ||
395 | memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; | |
396 | for (i = 0; i < 8; i++) | |
397 | *ramaddr = c; | |
398 | ||
399 | memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; | |
400 | *ramaddr = c; | |
401 | ||
402 | memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; | |
403 | *ramaddr = c; | |
404 | ||
405 | /* | |
406 | * Do it a second time for the second set of chips if the DIMM has | |
407 | * two chip selects (double sided). | |
408 | */ | |
409 | if(chipselects > 1) { | |
8bde7f77 | 410 | ramaddr += sdram_size; |
fe8c2806 | 411 | |
6d0f6bcf | 412 | memctl->memc_br3 = CONFIG_SYS_BR3_PRELIM + sdram_size; |
fe8c2806 WD |
413 | memctl->memc_or3 = or; |
414 | ||
415 | memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; | |
416 | *ramaddr = c; | |
417 | ||
418 | memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; | |
419 | for (i = 0; i < 8; i++) | |
420 | *ramaddr = c; | |
421 | ||
422 | memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; | |
423 | *ramaddr = c; | |
424 | ||
425 | memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; | |
426 | *ramaddr = c; | |
427 | } | |
428 | ||
429 | /* return total ram size */ | |
430 | return (sdram_size * chipselects); | |
431 | } | |
432 | ||
433 | /*----------------------------------------------------------------------- | |
434 | * Board Control Functions | |
435 | */ | |
436 | void board_poweroff (void) | |
437 | { | |
438 | while (1); /* hang forever */ | |
439 | } | |
440 | ||
441 | ||
442 | #ifdef CONFIG_MISC_INIT_R | |
443 | /* ------------------------------------------------------------------------- */ | |
444 | int misc_init_r(void) | |
445 | { | |
446 | /* | |
447 | * Note: iop is used by the I2C macros, and iopa by the ADC/DAC initialization. | |
448 | */ | |
6d0f6bcf JCPV |
449 | volatile ioport_t *iopa = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 0 /* port A */); |
450 | volatile ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT); | |
fe8c2806 WD |
451 | |
452 | int reg; /* I2C register value */ | |
453 | char *ep; /* Environment pointer */ | |
454 | char str_buf[12] ; /* sprintf output buffer */ | |
455 | int sample_rate; /* ADC/DAC sample rate */ | |
456 | int sample_64x; /* Use 64/4 clocking for the ADC/DAC */ | |
457 | int sample_128x; /* Use 128/4 clocking for the ADC/DAC */ | |
458 | int right_just; /* Is the data to the DAC right justified? */ | |
459 | int mclk_divide; /* MCLK Divide */ | |
78137c3c WD |
460 | int quiet; /* Quiet or minimal output mode */ |
461 | ||
462 | quiet = 0; | |
463 | if ((ep = getenv("quiet")) != NULL) { | |
464 | quiet = simple_strtol(ep, NULL, 10); | |
465 | } | |
466 | else { | |
467 | setenv("quiet", "0"); | |
468 | } | |
fe8c2806 WD |
469 | |
470 | /* | |
471 | * SACSng custom initialization: | |
472 | * Start the ADC and DAC clocks, since the Crystal parts do not | |
473 | * work on the I2C bus until the clocks are running. | |
474 | */ | |
475 | ||
476 | sample_rate = INITIAL_SAMPLE_RATE; | |
477 | if ((ep = getenv("DaqSampleRate")) != NULL) { | |
8bde7f77 | 478 | sample_rate = simple_strtol(ep, NULL, 10); |
fe8c2806 WD |
479 | } |
480 | ||
481 | sample_64x = INITIAL_SAMPLE_64X; | |
482 | sample_128x = INITIAL_SAMPLE_128X; | |
483 | if ((ep = getenv("Daq64xSampling")) != NULL) { | |
8bde7f77 | 484 | sample_64x = simple_strtol(ep, NULL, 10); |
fe8c2806 WD |
485 | if (sample_64x) { |
486 | sample_128x = 0; | |
487 | } | |
488 | else { | |
489 | sample_128x = 1; | |
490 | } | |
491 | } | |
492 | else { | |
8bde7f77 | 493 | if ((ep = getenv("Daq128xSampling")) != NULL) { |
fe8c2806 WD |
494 | sample_128x = simple_strtol(ep, NULL, 10); |
495 | if (sample_128x) { | |
8bde7f77 | 496 | sample_64x = 0; |
fe8c2806 WD |
497 | } |
498 | else { | |
8bde7f77 | 499 | sample_64x = 1; |
fe8c2806 WD |
500 | } |
501 | } | |
502 | } | |
503 | ||
8bde7f77 | 504 | /* |
eb9401e3 WD |
505 | * Stop the clocks and wait for at least 1 LRCLK period |
506 | * to make sure the clocking has really stopped. | |
507 | */ | |
508 | Daq_Stop_Clocks(); | |
509 | udelay((1000000 / sample_rate) * NUM_LRCLKS_TO_STABILIZE); | |
510 | ||
511 | /* | |
512 | * Initialize the clocks with the new rates | |
513 | */ | |
fe8c2806 WD |
514 | Daq_Init_Clocks(sample_rate, sample_64x); |
515 | sample_rate = Daq_Get_SampleRate(); | |
eb9401e3 WD |
516 | |
517 | /* | |
518 | * Start the clocks and wait for at least 1 LRCLK period | |
519 | * to make sure the clocking has become stable. | |
520 | */ | |
fe8c2806 | 521 | Daq_Start_Clocks(sample_rate); |
eb9401e3 | 522 | udelay((1000000 / sample_rate) * NUM_LRCLKS_TO_STABILIZE); |
fe8c2806 WD |
523 | |
524 | sprintf(str_buf, "%d", sample_rate); | |
525 | setenv("DaqSampleRate", str_buf); | |
526 | ||
527 | if (sample_64x) { | |
8bde7f77 WD |
528 | setenv("Daq64xSampling", "1"); |
529 | setenv("Daq128xSampling", NULL); | |
fe8c2806 WD |
530 | } |
531 | else { | |
8bde7f77 WD |
532 | setenv("Daq64xSampling", NULL); |
533 | setenv("Daq128xSampling", "1"); | |
fe8c2806 WD |
534 | } |
535 | ||
42d1f039 WD |
536 | /* |
537 | * Display the ADC/DAC clocking information | |
78137c3c WD |
538 | */ |
539 | if (!quiet) { | |
42d1f039 | 540 | Daq_Display_Clocks(); |
78137c3c | 541 | } |
fe8c2806 WD |
542 | |
543 | /* | |
544 | * Determine the DAC data justification | |
545 | */ | |
546 | ||
547 | right_just = INITIAL_RIGHT_JUST; | |
548 | if ((ep = getenv("DaqDACRightJustified")) != NULL) { | |
8bde7f77 | 549 | right_just = simple_strtol(ep, NULL, 10); |
fe8c2806 WD |
550 | } |
551 | ||
552 | sprintf(str_buf, "%d", right_just); | |
553 | setenv("DaqDACRightJustified", str_buf); | |
554 | ||
555 | /* | |
556 | * Determine the DAC MCLK Divide | |
557 | */ | |
558 | ||
559 | mclk_divide = INITIAL_MCLK_DIVIDE; | |
560 | if ((ep = getenv("DaqDACMClockDivide")) != NULL) { | |
8bde7f77 | 561 | mclk_divide = simple_strtol(ep, NULL, 10); |
fe8c2806 WD |
562 | } |
563 | ||
564 | sprintf(str_buf, "%d", mclk_divide); | |
565 | setenv("DaqDACMClockDivide", str_buf); | |
566 | ||
567 | /* | |
568 | * Initializing the I2C address in the Crystal A/Ds: | |
569 | * | |
570 | * 1) Wait for VREF cap to settle (10uSec per uF) | |
571 | * 2) Release pullup on SDATA | |
572 | * 3) Write the I2C address to register 6 | |
573 | * 4) Enable address matching by setting the MSB in register 7 | |
574 | */ | |
42d1f039 | 575 | |
78137c3c | 576 | if (!quiet) { |
42d1f039 | 577 | printf("Initializing the ADC...\n"); |
78137c3c | 578 | } |
fe8c2806 WD |
579 | udelay(ADC_INITIAL_DELAY); /* 10uSec per uF of VREF cap */ |
580 | ||
581 | iopa->pdat &= ~ADC_SDATA1_MASK; /* release SDATA1 */ | |
582 | udelay(ADC_SDATA_DELAY); /* arbitrary settling time */ | |
583 | ||
584 | i2c_reg_write(0x00, 0x06, I2C_ADC_1_ADDR); /* set address */ | |
585 | i2c_reg_write(I2C_ADC_1_ADDR, 0x07, /* turn on ADDREN */ | |
586 | ADC_REG7_ADDR_ENABLE); | |
587 | ||
588 | i2c_reg_write(I2C_ADC_1_ADDR, 0x02, /* 128x, slave mode, !HPEN */ | |
589 | (sample_64x ? 0 : ADC_REG2_128x) | | |
590 | ADC_REG2_HIGH_PASS_DIS | | |
591 | ADC_REG2_SLAVE_MODE); | |
592 | ||
593 | reg = i2c_reg_read(I2C_ADC_1_ADDR, 0x06) & 0x7F; | |
594 | if(reg != I2C_ADC_1_ADDR) | |
595 | printf("Init of ADC U10 failed: address is 0x%02X should be 0x%02X\n", | |
596 | reg, I2C_ADC_1_ADDR); | |
597 | ||
598 | iopa->pdat &= ~ADC_SDATA2_MASK; /* release SDATA2 */ | |
599 | udelay(ADC_SDATA_DELAY); /* arbitrary settling time */ | |
600 | ||
601 | i2c_reg_write(0x00, 0x06, I2C_ADC_2_ADDR); /* set address (do not set ADDREN yet) */ | |
602 | ||
603 | i2c_reg_write(I2C_ADC_2_ADDR, 0x02, /* 64x, slave mode, !HPEN */ | |
604 | (sample_64x ? 0 : ADC_REG2_128x) | | |
605 | ADC_REG2_HIGH_PASS_DIS | | |
606 | ADC_REG2_SLAVE_MODE); | |
607 | ||
608 | reg = i2c_reg_read(I2C_ADC_2_ADDR, 0x06) & 0x7F; | |
609 | if(reg != I2C_ADC_2_ADDR) | |
610 | printf("Init of ADC U15 failed: address is 0x%02X should be 0x%02X\n", | |
611 | reg, I2C_ADC_2_ADDR); | |
612 | ||
613 | i2c_reg_write(I2C_ADC_1_ADDR, 0x01, /* set FSTART and GNDCAL */ | |
614 | ADC_REG1_FRAME_START | | |
615 | ADC_REG1_GROUND_CAL); | |
616 | ||
617 | i2c_reg_write(I2C_ADC_1_ADDR, 0x02, /* Start calibration */ | |
618 | (sample_64x ? 0 : ADC_REG2_128x) | | |
619 | ADC_REG2_CAL | | |
620 | ADC_REG2_HIGH_PASS_DIS | | |
621 | ADC_REG2_SLAVE_MODE); | |
622 | ||
623 | udelay(ADC_CAL_DELAY); /* a minimum of 4100 LRCLKs */ | |
624 | i2c_reg_write(I2C_ADC_1_ADDR, 0x01, 0x00); /* remove GNDCAL */ | |
625 | ||
626 | /* | |
627 | * Now that we have synchronized the ADC's, enable address | |
628 | * selection on the second ADC as well as the first. | |
629 | */ | |
630 | i2c_reg_write(I2C_ADC_2_ADDR, 0x07, ADC_REG7_ADDR_ENABLE); | |
631 | ||
632 | /* | |
633 | * Initialize the Crystal DAC | |
634 | * | |
635 | * Two of the config lines are used for I2C so we have to set them | |
636 | * to the proper initialization state without inadvertantly | |
637 | * sending an I2C "start" sequence. When we bring the I2C back to | |
638 | * the normal state, we send an I2C "stop" sequence. | |
639 | */ | |
78137c3c WD |
640 | if (!quiet) { |
641 | printf("Initializing the DAC...\n"); | |
642 | } | |
fe8c2806 WD |
643 | |
644 | /* | |
645 | * Bring the I2C clock and data lines low for initialization | |
646 | */ | |
647 | I2C_SCL(0); | |
648 | I2C_DELAY; | |
649 | I2C_SDA(0); | |
650 | I2C_ACTIVE; | |
651 | I2C_DELAY; | |
652 | ||
653 | /* Reset the DAC */ | |
654 | iopa->pdat &= ~DAC_RST_MASK; | |
655 | udelay(DAC_RESET_DELAY); | |
656 | ||
657 | /* Release the DAC reset */ | |
658 | iopa->pdat |= DAC_RST_MASK; | |
659 | udelay(DAC_INITIAL_DELAY); | |
660 | ||
661 | /* | |
662 | * Cause the DAC to: | |
663 | * Enable control port (I2C mode) | |
664 | * Going into power down | |
665 | */ | |
666 | i2c_reg_write(I2C_DAC_ADDR, 0x05, | |
667 | DAC_REG5_I2C_MODE | | |
668 | DAC_REG5_POWER_DOWN); | |
669 | ||
670 | /* | |
671 | * Cause the DAC to: | |
672 | * Enable control port (I2C mode) | |
673 | * Going into power down | |
674 | * . MCLK divide by 1 | |
675 | * . MCLK divide by 2 | |
676 | */ | |
677 | i2c_reg_write(I2C_DAC_ADDR, 0x05, | |
678 | DAC_REG5_I2C_MODE | | |
679 | DAC_REG5_POWER_DOWN | | |
680 | (mclk_divide ? DAC_REG5_MCLK_DIV : 0)); | |
681 | ||
682 | /* | |
683 | * Cause the DAC to: | |
684 | * Auto-mute disabled | |
685 | * . Format 0, left justified 24 bits | |
686 | * . Format 3, right justified 24 bits | |
687 | * No de-emphasis | |
688 | * . Single speed mode | |
689 | * . Double speed mode | |
690 | */ | |
691 | i2c_reg_write(I2C_DAC_ADDR, 0x01, | |
692 | (right_just ? DAC_REG1_RIGHT_JUST_24BIT : | |
8bde7f77 | 693 | DAC_REG1_LEFT_JUST_24_BIT) | |
fe8c2806 WD |
694 | DAC_REG1_DEM_NO | |
695 | (sample_rate >= 50000 ? DAC_REG1_DOUBLE : DAC_REG1_SINGLE)); | |
696 | ||
697 | sprintf(str_buf, "%d", | |
698 | sample_rate >= 50000 ? DAC_REG1_DOUBLE : DAC_REG1_SINGLE); | |
699 | setenv("DaqDACFunctionalMode", str_buf); | |
700 | ||
701 | /* | |
702 | * Cause the DAC to: | |
703 | * Enable control port (I2C mode) | |
704 | * Remove power down | |
705 | * . MCLK divide by 1 | |
706 | * . MCLK divide by 2 | |
707 | */ | |
708 | i2c_reg_write(I2C_DAC_ADDR, 0x05, | |
709 | DAC_REG5_I2C_MODE | | |
710 | (mclk_divide ? DAC_REG5_MCLK_DIV : 0)); | |
711 | ||
712 | /* | |
713 | * Create a I2C stop condition: | |
714 | * low->high on data while clock is high. | |
715 | */ | |
716 | I2C_SCL(1); | |
717 | I2C_DELAY; | |
718 | I2C_SDA(1); | |
719 | I2C_DELAY; | |
720 | I2C_TRISTATE; | |
721 | ||
78137c3c | 722 | if (!quiet) { |
42d1f039 | 723 | printf("\n"); |
78137c3c WD |
724 | } |
725 | ||
726 | #ifdef CONFIG_ETHER_LOOPBACK_TEST | |
727 | /* | |
728 | * Run the Ethernet loopback test | |
729 | */ | |
730 | eth_loopback_test (); | |
731 | #endif /* CONFIG_ETHER_LOOPBACK_TEST */ | |
fe8c2806 WD |
732 | |
733 | #ifdef CONFIG_SHOW_BOOT_PROGRESS | |
734 | /* | |
735 | * Turn off the RED fail LED now that we are up and running. | |
736 | */ | |
737 | status_led_set(STATUS_LED_RED, STATUS_LED_OFF); | |
738 | #endif | |
739 | ||
740 | return 0; | |
741 | } | |
742 | ||
743 | #ifdef CONFIG_SHOW_BOOT_PROGRESS | |
744 | /* | |
745 | * Show boot status: flash the LED if something goes wrong, indicating | |
746 | * that last thing that worked and thus, by implication, what is broken. | |
747 | * | |
748 | * This stores the last OK value in RAM so this will not work properly | |
749 | * before RAM is initialized. Since it is being used for indicating | |
750 | * boot status (i.e. after RAM is initialized), that is OK. | |
751 | */ | |
752 | static void flash_code(uchar number, uchar modulo, uchar digits) | |
753 | { | |
754 | int j; | |
755 | ||
756 | /* | |
757 | * Recursively do upper digits. | |
758 | */ | |
759 | if(digits > 1) { | |
8bde7f77 | 760 | flash_code(number / modulo, modulo, digits - 1); |
fe8c2806 WD |
761 | } |
762 | ||
763 | number = number % modulo; | |
764 | ||
765 | /* | |
766 | * Zero is indicated by one long flash (dash). | |
767 | */ | |
768 | if(number == 0) { | |
8bde7f77 WD |
769 | status_led_set(STATUS_LED_BOOT, STATUS_LED_ON); |
770 | udelay(1000000); | |
771 | status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); | |
772 | udelay(200000); | |
fe8c2806 | 773 | } else { |
8bde7f77 WD |
774 | /* |
775 | * Non-zero is indicated by short flashes, one per count. | |
776 | */ | |
777 | for(j = 0; j < number; j++) { | |
778 | status_led_set(STATUS_LED_BOOT, STATUS_LED_ON); | |
779 | udelay(100000); | |
780 | status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); | |
781 | udelay(200000); | |
782 | } | |
fe8c2806 WD |
783 | } |
784 | /* | |
785 | * Inter-digit pause: we've already waited 200 mSec, wait 1 sec total | |
786 | */ | |
787 | udelay(700000); | |
788 | } | |
789 | ||
790 | static int last_boot_progress; | |
791 | ||
792 | void show_boot_progress (int status) | |
793 | { | |
78137c3c WD |
794 | int i,j; |
795 | if(status > 0) { | |
8bde7f77 | 796 | last_boot_progress = status; |
fe8c2806 | 797 | } else { |
42d1f039 | 798 | /* |
78137c3c WD |
799 | * If a specific failure code is given, flash this code |
800 | * else just use the last success code we've seen | |
801 | */ | |
802 | if(status < -1) | |
803 | last_boot_progress = -status; | |
42d1f039 WD |
804 | |
805 | /* | |
78137c3c WD |
806 | * Flash this code 5 times |
807 | */ | |
808 | for(j=0; j<5; j++) { | |
809 | /* | |
810 | * Houston, we have a problem. | |
811 | * Blink the last OK status which indicates where things failed. | |
812 | */ | |
813 | status_led_set(STATUS_LED_RED, STATUS_LED_ON); | |
814 | flash_code(last_boot_progress, 5, 3); | |
815 | ||
42d1f039 WD |
816 | /* |
817 | * Delay 5 seconds between repetitions, | |
818 | * with the fault LED blinking | |
78137c3c WD |
819 | */ |
820 | for(i=0; i<5; i++) { | |
42d1f039 WD |
821 | status_led_set(STATUS_LED_RED, STATUS_LED_OFF); |
822 | udelay(500000); | |
823 | status_led_set(STATUS_LED_RED, STATUS_LED_ON); | |
824 | udelay(500000); | |
78137c3c WD |
825 | } |
826 | } | |
827 | ||
8bde7f77 | 828 | /* |
78137c3c | 829 | * Reset the board to retry initialization. |
8bde7f77 | 830 | */ |
78137c3c | 831 | do_reset (NULL, 0, 0, NULL); |
fe8c2806 WD |
832 | } |
833 | } | |
834 | #endif /* CONFIG_SHOW_BOOT_PROGRESS */ | |
835 | ||
836 | ||
837 | /* | |
838 | * The following are used to control the SPI chip selects for the SPI command. | |
839 | */ | |
ab3abcba | 840 | #if defined(CONFIG_CMD_SPI) |
fe8c2806 WD |
841 | |
842 | #define SPI_ADC_CS_MASK 0x00000800 | |
843 | #define SPI_DAC_CS_MASK 0x00001000 | |
844 | ||
d255bb0e HS |
845 | static const u32 cs_mask[] = { |
846 | SPI_ADC_CS_MASK, | |
847 | SPI_DAC_CS_MASK, | |
848 | }; | |
849 | ||
850 | int spi_cs_is_valid(unsigned int bus, unsigned int cs) | |
851 | { | |
852 | return bus == 0 && cs < sizeof(cs_mask) / sizeof(cs_mask[0]); | |
853 | } | |
854 | ||
855 | void spi_cs_activate(struct spi_slave *slave) | |
fe8c2806 | 856 | { |
6d0f6bcf | 857 | volatile ioport_t *iopd = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3 /* port D */); |
fe8c2806 | 858 | |
d255bb0e | 859 | iopd->pdat &= ~cs_mask[slave->cs]; |
fe8c2806 WD |
860 | } |
861 | ||
d255bb0e | 862 | void spi_cs_deactivate(struct spi_slave *slave) |
fe8c2806 | 863 | { |
6d0f6bcf | 864 | volatile ioport_t *iopd = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3 /* port D */); |
fe8c2806 | 865 | |
d255bb0e | 866 | iopd->pdat |= cs_mask[slave->cs]; |
fe8c2806 WD |
867 | } |
868 | ||
d39b5741 | 869 | #endif |
fe8c2806 WD |
870 | |
871 | #endif /* CONFIG_MISC_INIT_R */ | |
8564acf9 WD |
872 | |
873 | #ifdef CONFIG_POST | |
945af8d7 | 874 | /* |
8564acf9 WD |
875 | * Returns 1 if keys pressed to start the power-on long-running tests |
876 | * Called from board_init_f(). | |
877 | */ | |
878 | int post_hotkeys_pressed(void) | |
879 | { | |
880 | return 0; /* No hotkeys supported */ | |
881 | } | |
882 | ||
883 | #endif |