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