]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/contrib/octeon-sdk/cvmx-nand.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / contrib / octeon-sdk / cvmx-nand.c
1 /***********************license start***************
2  *  Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
3  *  reserved.
4  *
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions are
8  *  met:
9  *
10  *      * Redistributions of source code must retain the above copyright
11  *        notice, this list of conditions and the following disclaimer.
12  *
13  *      * Redistributions in binary form must reproduce the above
14  *        copyright notice, this list of conditions and the following
15  *        disclaimer in the documentation and/or other materials provided
16  *        with the distribution.
17  *
18  *      * Neither the name of Cavium Networks nor the names of
19  *        its contributors may be used to endorse or promote products
20  *        derived from this software without specific prior written
21  *        permission.
22  *
23  *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24  *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25  *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26  *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27  *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28  *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29  *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30  *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31  *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
32  *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
33  *
34  *
35  *  For any questions regarding licensing please contact marketing@caviumnetworks.com
36  *
37  ***********************license end**************************************/
38
39
40 /**
41  * @file
42  *
43  * Interface to the NAND flash controller.
44  * See cvmx-nand.h for usage documentation and notes.
45  *
46  * <hr>$Revision: 35726 $<hr>
47  */
48
49 #include "cvmx.h"
50 #include "cvmx-nand.h"
51 #include "cvmx-swap.h"
52 #include "cvmx-bootmem.h"
53
54 #define NAND_COMMAND_READ_ID            0x90
55 #define NAND_COMMAND_READ_PARAM_PAGE    0xec
56 #define NAND_COMMAND_RESET              0xff
57 #define NAND_COMMAND_STATUS             0x70
58 #define NAND_COMMAND_READ               0x00
59 #define NAND_COMMAND_READ_FIN           0x30
60 #define NAND_COMMAND_ERASE              0x60
61 #define NAND_COMMAND_ERASE_FIN          0xd0
62 #define NAND_COMMAND_PROGRAM            0x80
63 #define NAND_COMMAND_PROGRAM_FIN        0x10
64 #define NAND_TIMEOUT_USECS              1000000
65
66 #define CVMX_NAND_ROUNDUP(_Dividend, _Divisor) (((_Dividend)+(_Divisor-1))/(_Divisor))
67 #undef min
68 #define min(X, Y)                               \
69         ({ typeof (X) __x = (X), __y = (Y);     \
70                 (__x < __y) ? __x : __y; })
71
72 #undef max
73 #define max(X, Y)                               \
74         ({ typeof (X) __x = (X), __y = (Y);     \
75                 (__x > __y) ? __x : __y; })
76
77
78 /* Structure to store the parameters that we care about that
79 ** describe the ONFI speed modes.  This is used to configure
80 ** the flash timing to match what is reported in the 
81 ** parameter page of the ONFI flash chip. */
82 typedef struct
83 {
84     int twp;
85     int twh;
86     int twc;
87     int tclh;
88     int tals;
89 } onfi_speed_mode_desc_t;
90 static const onfi_speed_mode_desc_t onfi_speed_modes[] =
91 {
92
93     {50,30,100,20,50},  /* Mode 0 */
94     {25,15, 45,10,25},  /* Mode 1 */
95     {17,15, 35,10,15},  /* Mode 2 */
96     {15,10, 30, 5,10},  /* Mode 3 */
97     {12,10, 25, 5,10},  /* Mode 4, requires EDO timings */
98     {10, 7, 20, 5,10},  /* Mode 5, requries EDO timings */
99 };
100
101 /**
102  * Structure used to store data about the NAND devices hooked
103  * to the bootbus.
104  */
105 typedef struct
106 {
107     int page_size;
108     int oob_size;
109     int pages_per_block;
110     int blocks;
111     int tim_mult;
112     int tim_par[8];
113     int clen[4];
114     int alen[4];
115     int rdn[4];
116     int wrn[2];
117     int onfi_timing;
118 } cvmx_nand_state_t;
119
120 /**
121  * Array indexed by bootbus chip select with information
122  * about NAND devices.
123  */
124 #if defined(CVMX_BUILD_FOR_UBOOT) && CONFIG_OCTEON_NAND_STAGE2
125 /* For u-boot nand boot we need to play some tricks to be able
126 ** to use this early in boot.  We put them in a special section that is merged
127 ** with the text segment.  (Using the text segment directly results in an assembler warning.)
128 */
129 #define USE_DATA_IN_TEXT
130 #endif
131
132 #ifdef USE_DATA_IN_TEXT
133 static uint8_t cvmx_nand_buffer[4096] __attribute__((aligned(8)))  __attribute__ ((section (".data_in_text")));
134 static cvmx_nand_state_t cvmx_nand_state[8] __attribute__ ((section (".data_in_text")));
135 static cvmx_nand_initialize_flags_t cvmx_nand_flags __attribute__ ((section (".data_in_text")));
136 static int debug_indent __attribute__ ((section (".data_in_text")));
137 #else
138 static CVMX_SHARED cvmx_nand_state_t cvmx_nand_state[8];
139 static CVMX_SHARED cvmx_nand_initialize_flags_t cvmx_nand_flags;
140 static CVMX_SHARED uint8_t *cvmx_nand_buffer = NULL;
141 static int debug_indent = 0;
142 #endif
143
144 static CVMX_SHARED const char *cvmx_nand_opcode_labels[] =
145 {
146     "NOP",                      /* 0 */
147     "Timing",                   /* 1 */
148     "Wait",                     /* 2 */
149     "Chip Enable / Disable",    /* 3 */
150     "CLE",                      /* 4 */
151     "ALE",                      /* 5 */
152     "6 - Unknown",              /* 6 */
153     "7 - Unknown",              /* 7 */
154     "Write",                    /* 8 */
155     "Read",                     /* 9 */
156     "Read EDO",                 /* 10 */
157     "Wait Status",              /* 11 */
158     "12 - Unknown",             /* 12 */
159     "13 - Unknown",             /* 13 */
160     "14 - Unknown",             /* 14 */
161     "Bus Aquire / Release"      /* 15 */
162 };
163
164 #define ULL unsigned long long
165 /* This macro logs out whenever a function is called if debugging is on */
166 #define CVMX_NAND_LOG_CALLED() \
167     if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG)) \
168         cvmx_dprintf("%*s%s: called\n", 2*debug_indent++, "", __FUNCTION__);
169
170 /* This macro logs out each function parameter if debugging is on */
171 #define CVMX_NAND_LOG_PARAM(format, param) \
172     if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG)) \
173         cvmx_dprintf("%*s%s: param %s = " format "\n", 2*debug_indent, "", __FUNCTION__, #param, param);
174
175 /* This macro logs out when a function returns a value */
176 #define CVMX_NAND_RETURN(v)                                              \
177     do {                                                                \
178         typeof(v) r = v;                                                \
179         if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))         \
180             cvmx_dprintf("%*s%s: returned %s(%d)\n", 2*--debug_indent, "", __FUNCTION__, #v, r); \
181         return r;                                                       \
182     } while (0);
183
184 /* This macro logs out when a function doesn't return a value */
185 #define CVMX_NAND_RETURN_NOTHING()                                      \
186     do {                                                                \
187         if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))         \
188             cvmx_dprintf("%*s%s: returned\n", 2*--debug_indent, "", __FUNCTION__); \
189         return;                                                         \
190     } while (0);
191
192
193
194
195
196
197 /* Compute the CRC for the ONFI parameter page.  Adapted from sample code
198 ** in the specification.
199 */
200 static uint16_t __onfi_parameter_crc_compute(uint8_t *data)
201 {
202     const int order = 16;                     // Order of the CRC-16
203     unsigned long i, j, c, bit;
204     unsigned long crc = 0x4F4E;              // Initialize the shift register with 0x4F4E
205     unsigned long crcmask = ((((unsigned long)1<<(order-1))-1)<<1)|1;
206     unsigned long crchighbit = (unsigned long)1<<(order-1);
207
208     for (i = 0; i < 254; i++)
209     {
210         c = (unsigned long)data[i];
211         for (j = 0x80; j; j >>= 1) {
212               bit = crc & crchighbit;
213               crc <<= 1;
214               if (c & j)
215                   bit ^= crchighbit;
216               if (bit)
217                    crc ^= 0x8005;
218         }
219         crc &= crcmask;
220     }
221     return(crc);
222 }
223
224
225 /**
226  * Validate the ONFI parameter page and return a pointer to
227  * the config values.
228  *
229  * @param param_page Pointer to the raw NAND data returned after a parameter page read. It will
230  *                   contain at least 4 copies of the parameter structure.
231  *
232  * @return Pointer to a validated paramter page, or NULL if one couldn't be found.
233  */
234 static cvmx_nand_onfi_param_page_t *__cvmx_nand_onfi_process(cvmx_nand_onfi_param_page_t param_page[4])
235 {
236     int index;
237
238     for (index=0; index<4; index++)
239     {
240         uint16_t crc = __onfi_parameter_crc_compute((void *)&param_page[index]);
241         if (crc == cvmx_le16_to_cpu(param_page[index].crc))
242             break;
243         if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
244             cvmx_dprintf("%s: Paramter page %d is corrupt. (Expected CRC: 0x%04x, computed: 0x%04x)\n",
245                           __FUNCTION__, index, cvmx_le16_to_cpu(param_page[index].crc), crc);
246     }
247
248     if (index == 4)
249     {
250         if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
251             cvmx_dprintf("%s: All parameter pages fail CRC check.  Checking to see if any look sane.\n", __FUNCTION__);
252
253         if (!memcmp(param_page, param_page + 1, 256))
254         {
255             /* First and second copies match, now check some values */
256             if (param_page[0].pages_per_block != 0 && param_page[0].pages_per_block != 0xFFFFFFFF
257                 && param_page[0].page_data_bytes != 0 && param_page[0].page_data_bytes != 0xFFFFFFFF
258                 && param_page[0].page_spare_bytes != 0 && param_page[0].page_spare_bytes != 0xFFFF
259                 && param_page[0].blocks_per_lun != 0 && param_page[0].blocks_per_lun != 0xFFFFFFFF
260                 && param_page[0].timing_mode != 0 && param_page[0].timing_mode != 0xFFFF)
261             {
262                 /* Looks like we have enough values to use */
263                 if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
264                     cvmx_dprintf("%s: Page 0 looks sane, using even though CRC fails.\n", __FUNCTION__);
265                 index = 0;
266             }
267         }
268     }
269
270     if (index == 4)
271     {
272         cvmx_dprintf("%s: No valid ONFI parameter pages found.\n", __FUNCTION__);
273         return NULL;
274     }
275
276     if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
277     {
278         cvmx_dprintf("%*sONFI Information\n", 2*debug_indent, "");
279         debug_indent++;
280         cvmx_dprintf("%*sonfi = %c%c%c%c\n", 2*debug_indent, "", param_page[index].onfi[0], param_page[index].onfi[1],
281             param_page[index].onfi[2], param_page[index].onfi[3]);
282         cvmx_dprintf("%*srevision_number = 0x%x\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].revision_number));
283         cvmx_dprintf("%*sfeatures = 0x%x\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].features));
284         cvmx_dprintf("%*soptional_commands = 0x%x\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].optional_commands));
285
286         cvmx_dprintf("%*smanufacturer = %12.12s\n", 2*debug_indent, "", param_page[index].manufacturer);
287         cvmx_dprintf("%*smodel = %20.20s\n", 2*debug_indent, "", param_page[index].model);
288         cvmx_dprintf("%*sjedec_id = 0x%x\n", 2*debug_indent, "", param_page[index].jedec_id);
289         cvmx_dprintf("%*sdate_code = 0x%x\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].date_code));
290
291         cvmx_dprintf("%*spage_data_bytes = %u\n", 2*debug_indent, "", (int)cvmx_le32_to_cpu(param_page[index].page_data_bytes));
292         cvmx_dprintf("%*spage_spare_bytes = %u\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].page_spare_bytes));
293         cvmx_dprintf("%*spartial_page_data_bytes = %u\n", 2*debug_indent, "", (int)cvmx_le32_to_cpu(param_page[index].partial_page_data_bytes));
294         cvmx_dprintf("%*spartial_page_spare_bytes = %u\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].partial_page_spare_bytes));
295         cvmx_dprintf("%*spages_per_block = %u\n", 2*debug_indent, "", (int)cvmx_le32_to_cpu(param_page[index].pages_per_block));
296         cvmx_dprintf("%*sblocks_per_lun = %u\n", 2*debug_indent, "", (int)cvmx_le32_to_cpu(param_page[index].blocks_per_lun));
297         cvmx_dprintf("%*snumber_lun = %u\n", 2*debug_indent, "", param_page[index].number_lun);
298         cvmx_dprintf("%*saddress_cycles = 0x%x\n", 2*debug_indent, "", param_page[index].address_cycles);
299         cvmx_dprintf("%*sbits_per_cell = %u\n", 2*debug_indent, "", param_page[index].bits_per_cell);
300         cvmx_dprintf("%*sbad_block_per_lun = %u\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].bad_block_per_lun));
301         cvmx_dprintf("%*sblock_endurance = %u\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].block_endurance));
302         cvmx_dprintf("%*sgood_blocks = %u\n", 2*debug_indent, "", param_page[index].good_blocks);
303         cvmx_dprintf("%*sgood_block_endurance = %u\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].good_block_endurance));
304         cvmx_dprintf("%*sprograms_per_page = %u\n", 2*debug_indent, "", param_page[index].programs_per_page);
305         cvmx_dprintf("%*spartial_program_attrib = 0x%x\n", 2*debug_indent, "", param_page[index].partial_program_attrib);
306         cvmx_dprintf("%*sbits_ecc = %u\n", 2*debug_indent, "", param_page[index].bits_ecc);
307         cvmx_dprintf("%*sinterleaved_address_bits = 0x%x\n", 2*debug_indent, "", param_page[index].interleaved_address_bits);
308         cvmx_dprintf("%*sinterleaved_attrib = 0x%x\n", 2*debug_indent, "", param_page[index].interleaved_attrib);
309
310         cvmx_dprintf("%*spin_capacitance = %u\n", 2*debug_indent, "", param_page[index].pin_capacitance);
311         cvmx_dprintf("%*stiming_mode = 0x%x\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].timing_mode));
312         cvmx_dprintf("%*scache_timing_mode = 0x%x\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].cache_timing_mode));
313         cvmx_dprintf("%*st_prog = %d us\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].t_prog));
314         cvmx_dprintf("%*st_bers = %u us\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].t_bers));
315         cvmx_dprintf("%*st_r = %u us\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].t_r));
316         cvmx_dprintf("%*st_ccs = %u ns\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].t_ccs));
317         cvmx_dprintf("%*svendor_revision = 0x%x\n", 2*debug_indent, "", cvmx_le16_to_cpu(param_page[index].vendor_revision));
318         //uint8_t vendor_specific[88];    /**< Byte 166-253: Vendor specific */
319         cvmx_dprintf("%*scrc = 0x%x\n", 2*debug_indent, "", param_page[index].crc);
320         debug_indent--;
321     }
322     return param_page + index;
323 }
324
325 void __set_onfi_timing_mode(int *tim_par, int clocks_us, int mode)
326 {
327     const onfi_speed_mode_desc_t *mp = &onfi_speed_modes[mode];  /* use shorter name to fill in timing array */
328     int margin;
329     int pulse_adjust;
330
331     if (mode > 5)
332     {
333         cvmx_dprintf("%s: invalid ONFI timing mode: %d\n", __FUNCTION__, mode);
334         return;
335     }
336
337     /* Adjust the read/write pulse duty cycle to make it more even.  The cycle time
338     ** requirement is longer than the sum of the high low times, so we exend both the high
339     ** and low times to meet the cycle time requirement.
340     */
341     pulse_adjust = ((mp->twc - mp->twh - mp->twp)/2 + 1) * clocks_us;
342
343     /* Add a small margin to all timings. */
344     margin = 2 * clocks_us;
345     /* Update timing parameters based on supported mode */
346     tim_par[1] = CVMX_NAND_ROUNDUP(mp->twp * clocks_us + margin + pulse_adjust, 1000); /* Twp, WE# pulse width */
347     tim_par[2] = CVMX_NAND_ROUNDUP(max(mp->twh, mp->twc - mp->twp) * clocks_us + margin + pulse_adjust, 1000); /* Tw, WE# pulse width high */
348     tim_par[3] = CVMX_NAND_ROUNDUP(mp->tclh * clocks_us + margin, 1000); /* Tclh, CLE hold time */
349     tim_par[4] = CVMX_NAND_ROUNDUP(mp->tals * clocks_us + margin, 1000); /* Tals, ALE setup time */
350     tim_par[5] = tim_par[3]; /* Talh, ALE hold time */
351     tim_par[6] = tim_par[1]; /* Trp, RE# pulse width*/
352     tim_par[7] = tim_par[2]; /* Treh, RE# high hold time */
353
354 }
355
356 /**
357  * Called to initialize the NAND controller for use. Note that
358  * you must be running out of L2 or memory and not NAND before
359  * calling this function.
360  *
361  * @param flags  Optional initialization flags
362  * @param active_chips
363  *               Each bit in this parameter represents a chip select that might
364  *               contain NAND flash. Any chip select present in this bitmask may
365  *               be connected to NAND. It is normally safe to pass 0xff here and
366  *               let the API probe all 8 chip selects.
367  *
368  * @return Zero on success, a negative cvmx_nand_status_t error code on failure
369  */
370 cvmx_nand_status_t cvmx_nand_initialize(cvmx_nand_initialize_flags_t flags, int active_chips)
371 {
372     int chip;
373     int start_chip;
374     int stop_chip;
375     uint64_t clocks_us;
376     cvmx_ndf_misc_t ndf_misc;
377
378     cvmx_nand_flags = flags;
379     CVMX_NAND_LOG_CALLED();
380     CVMX_NAND_LOG_PARAM("0x%x", flags);
381
382     memset(&cvmx_nand_state,  0,  sizeof(cvmx_nand_state));
383
384 #ifndef USE_DATA_IN_TEXT
385     if (!cvmx_nand_buffer)
386         cvmx_nand_buffer = cvmx_bootmem_alloc(4096, 128);
387 #endif
388     if (!cvmx_nand_buffer)
389         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
390
391     /* Disable boot mode and reset the fifo */
392     ndf_misc.u64 = cvmx_read_csr(CVMX_NDF_MISC);
393     ndf_misc.s.rd_cmd = 0;
394     ndf_misc.s.bt_dma = 0;
395     ndf_misc.s.bt_dis = 1;
396     ndf_misc.s.ex_dis = 0;
397     ndf_misc.s.rst_ff = 1;
398     cvmx_write_csr(CVMX_NDF_MISC, ndf_misc.u64);
399     cvmx_read_csr(CVMX_NDF_MISC);
400
401     /* Bring the fifo out of reset */
402     cvmx_wait_usec(1);
403     ndf_misc.s.rst_ff = 0;
404     cvmx_write_csr(CVMX_NDF_MISC, ndf_misc.u64);
405     cvmx_read_csr(CVMX_NDF_MISC);
406     cvmx_wait_usec(1);
407
408     /* Clear the ECC counter */
409     //cvmx_write_csr(CVMX_NDF_ECC_CNT, cvmx_read_csr(CVMX_NDF_ECC_CNT));
410
411     /* Clear the interrupt state */
412     cvmx_write_csr(CVMX_NDF_INT, cvmx_read_csr(CVMX_NDF_INT));
413     cvmx_write_csr(CVMX_NDF_INT_EN, 0);
414     cvmx_write_csr(CVMX_MIO_NDF_DMA_INT, cvmx_read_csr(CVMX_MIO_NDF_DMA_INT));
415     cvmx_write_csr(CVMX_MIO_NDF_DMA_INT_EN, 0);
416
417     if (cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DONT_PROBE)
418         CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
419
420     /* The simulator crashes if you access non existant devices. Assume
421         only chip select 1 is connected to NAND */
422     if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
423     {
424         start_chip = 1;
425         stop_chip = 2;
426     }
427     else
428     {
429         start_chip = 0;
430         stop_chip = 8;
431     }
432
433     /* Figure out how many clocks are in one microsecond, rounding up */
434     clocks_us = CVMX_NAND_ROUNDUP(cvmx_sysinfo_get()->cpu_clock_hz, 1000000);
435
436     /* Probe and see what NAND flash we can find */
437     for (chip=start_chip; chip<stop_chip; chip++)
438     {
439         cvmx_mio_boot_reg_cfgx_t mio_boot_reg_cfg;
440         cvmx_nand_onfi_param_page_t *onfi_param_page;
441
442         /* Skip chip selects that the caller didn't supply in the active chip bits */
443         if (((1<<chip) & active_chips) == 0)
444             continue;
445
446         mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(chip));
447         /* Enabled regions can't be connected to NAND flash */
448         if (mio_boot_reg_cfg.s.en)
449             continue;
450
451         /* Start out with some sane, but slow, defaults */
452         cvmx_nand_state[chip].page_size = 0;
453         cvmx_nand_state[chip].oob_size = 64;
454         cvmx_nand_state[chip].pages_per_block = 64;
455         cvmx_nand_state[chip].blocks = 100;
456         cvmx_nand_state[chip].tim_mult = 0; /* Don't use a multiplier. Values are in cycles */
457
458
459         /* Set timing mode to ONFI mode 0 for initial accesses */
460         __set_onfi_timing_mode(cvmx_nand_state[chip].tim_par, clocks_us, 0);
461
462         /* Put the index of which timing parameter to use.  The indexes are into the tim_par
463         ** which match the indexes of the 8 timing parameters that the hardware supports.
464         ** Index 0 is not software controlled, and is fixed by hardware. */
465         cvmx_nand_state[chip].clen[0] = 0; /* Command doesn't need to be held before WE */
466         cvmx_nand_state[chip].clen[1] = 1; /* Twp, WE# pulse width */
467         cvmx_nand_state[chip].clen[2] = 3; /* Tclh, CLE hold time */
468         cvmx_nand_state[chip].clen[3] = 1;
469
470         cvmx_nand_state[chip].alen[0] = 4; /* Tals, ALE setup time */
471         cvmx_nand_state[chip].alen[1] = 1; /* Twp, WE# pulse width */
472         cvmx_nand_state[chip].alen[2] = 2; /* Twh, WE# pulse width high */
473         cvmx_nand_state[chip].alen[3] = 5; /* Talh, ALE hold time */
474
475         cvmx_nand_state[chip].rdn[0] = 0;
476         cvmx_nand_state[chip].rdn[1] = 6; /* Trp, RE# pulse width*/
477         cvmx_nand_state[chip].rdn[2] = 7; /* Treh, RE# high hold time */
478         cvmx_nand_state[chip].rdn[3] = 0;
479
480         cvmx_nand_state[chip].wrn[0] = 1; /* Twp, WE# pulse width */
481         cvmx_nand_state[chip].wrn[1] = 2; /* Twh, WE# pulse width high */
482
483         /* Probe and see if we get an answer */
484         memset(cvmx_nand_buffer, 0xff, 8);
485         if (cvmx_nand_read_id(chip, 0x0, cvmx_ptr_to_phys(cvmx_nand_buffer), 8) < 4)
486         {
487             if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
488                 cvmx_dprintf("%s: Failed to probe chip %d\n", __FUNCTION__, chip);
489             continue;
490         }
491         if (*(uint32_t*)cvmx_nand_buffer == 0xffffffff)
492         {
493             if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
494                 cvmx_dprintf("%s: Probe returned nothing for chip %d\n", __FUNCTION__, chip);
495             continue;
496         }
497
498         if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
499             cvmx_dprintf("%s: NAND chip %d has ID 0x%08llx\n", __FUNCTION__, chip, (unsigned long long int)*(uint64_t*)cvmx_nand_buffer);
500
501         if (cvmx_nand_read_id(chip, 0x20, cvmx_ptr_to_phys(cvmx_nand_buffer), 4) < 4)
502         {
503             if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
504                 cvmx_dprintf("%s: Failed to probe chip %d\n", __FUNCTION__, chip);
505             continue;
506         }
507
508         if (!((cvmx_nand_buffer[0] == 'O') && (cvmx_nand_buffer[1] == 'N') &&
509             (cvmx_nand_buffer[2] == 'F') && (cvmx_nand_buffer[3] == 'I')))
510         {
511             /* FIXME: This is where non ONFI NAND devices need to be handled */
512             if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
513                 cvmx_dprintf("%s: Chip %d doesn't support ONFI, skipping\n", __FUNCTION__, chip);
514             continue;
515         }
516
517         cvmx_nand_read_param_page(chip, cvmx_ptr_to_phys(cvmx_nand_buffer), 1024);
518         onfi_param_page = __cvmx_nand_onfi_process((cvmx_nand_onfi_param_page_t *)cvmx_nand_buffer);
519         if (onfi_param_page)
520         {
521             /* ONFI NAND parts are described by a parameter page.  Here we extract the configuration values
522             ** from the parameter page that we need to access the chip. */
523             cvmx_nand_state[chip].page_size = cvmx_le32_to_cpu(onfi_param_page->page_data_bytes);
524             cvmx_nand_state[chip].oob_size = cvmx_le16_to_cpu(onfi_param_page->page_spare_bytes);
525             cvmx_nand_state[chip].pages_per_block = cvmx_le32_to_cpu(onfi_param_page->pages_per_block);
526             cvmx_nand_state[chip].blocks = cvmx_le32_to_cpu(onfi_param_page->blocks_per_lun) * onfi_param_page->number_lun;
527
528             if (cvmx_le16_to_cpu(onfi_param_page->timing_mode) <= 0x3f)
529             {
530                 int mode_mask = cvmx_le16_to_cpu(onfi_param_page->timing_mode);
531                 int mode = 0;
532                 int i;
533                 for (i = 0; i < 6;i++)
534                 {
535                     if (mode_mask & (1 << i))
536                         mode = i;
537                 }
538                 cvmx_nand_state[chip].onfi_timing = mode;
539             }
540             else
541             {
542                 cvmx_dprintf("%s: Invalid timing mode (%d) in ONFI parameter page, ignoring\n", __FUNCTION__, cvmx_nand_state[chip].onfi_timing);
543                 cvmx_nand_state[chip].onfi_timing = 0;
544
545             }
546             if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
547                 cvmx_dprintf("%s: Using ONFI timing mode: %d\n", __FUNCTION__, cvmx_nand_state[chip].onfi_timing);
548             __set_onfi_timing_mode(cvmx_nand_state[chip].tim_par, clocks_us, cvmx_nand_state[chip].onfi_timing);
549         }
550         else
551         {
552             /* We did not find a valid parameter page in the FLASH part.  This means that the part
553             ** does not provide the parameter page that ONFI requires.  In this case, hard coded defaults
554             ** can be used, but they _must_ be updated to match the flash used.
555             */
556             /* Enable this code to force a configuration for NAND chip that doesn't have a proper parameter page.
557             ** ONFI requires a parameter page, so this should not be needed for compliant chips */
558
559             /* The default values below are for the Numonyx NAND08GW3B2CN6E part */
560 #define NAND_SIZE_BITS  (8*1024*1024*1024ULL)
561             cvmx_nand_state[chip].page_size = 2048;  /* NAND page size in bytes */
562             cvmx_nand_state[chip].oob_size = 64;     /* NAND OOB (spare) size in bytes (per page) */
563             cvmx_nand_state[chip].pages_per_block = 64;
564             cvmx_nand_state[chip].blocks = (NAND_SIZE_BITS)/(8ULL*cvmx_nand_state[chip].page_size*cvmx_nand_state[chip].pages_per_block);
565             cvmx_nand_state[chip].onfi_timing = 2;
566             cvmx_dprintf("%s: WARNING: No valid ONFI parameter page found, using fixed defaults.\n", __FUNCTION__);
567             cvmx_dprintf("%s: Defaults: page size: %d, OOB size: %d, pages per block %d, part size: %d MBytes, timing mode: %d\n",
568                          __FUNCTION__, cvmx_nand_state[chip].page_size, cvmx_nand_state[chip].oob_size, cvmx_nand_state[chip].pages_per_block,
569                          (int)(NAND_SIZE_BITS/(8*1024*1024)), cvmx_nand_state[chip].onfi_timing);
570
571             __set_onfi_timing_mode(cvmx_nand_state[chip].tim_par, clocks_us, cvmx_nand_state[chip].onfi_timing);
572         }
573
574
575     }
576
577     CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
578 }
579
580
581 /**
582  * Call to shutdown the NAND controller after all transactions
583  * are done. In most setups this will never be called.
584  *
585  * @return Zero on success, a negative cvmx_nand_status_t error code on failure
586  */
587 cvmx_nand_status_t cvmx_nand_shutdown(void)
588 {
589     CVMX_NAND_LOG_CALLED();
590     memset(&cvmx_nand_state,  0,  sizeof(cvmx_nand_state));
591     CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
592 }
593
594
595 /**
596  * Returns a bitmask representing the chip selects that are
597  * connected to NAND chips. This can be called after the
598  * initialize to determine the actual number of NAND chips
599  * found. Each bit in the response coresponds to a chip select.
600  *
601  * @return Zero if no NAND chips were found. Otherwise a bit is set for
602  *         each chip select (1<<chip).
603  */
604 int cvmx_nand_get_active_chips(void)
605 {
606     int chip;
607     int result = 0;
608     for (chip=0; chip<8; chip++)
609     {
610         if (cvmx_nand_state[chip].page_size)
611             result |= 1<<chip;
612     }
613     return result;
614 }
615
616
617 /**
618  * Override the timing parameters for a NAND chip
619  *
620  * @param chip     Chip select to override
621  * @param tim_mult
622  * @param tim_par
623  * @param clen
624  * @param alen
625  * @param rdn
626  * @param wrn
627  *
628  * @return Zero on success, a negative cvmx_nand_status_t error code on failure
629  */
630 cvmx_nand_status_t cvmx_nand_set_timing(int chip, int tim_mult, int tim_par[8], int clen[4], int alen[4], int rdn[4], int wrn[2])
631 {
632     int i;
633     CVMX_NAND_LOG_CALLED();
634
635     if ((chip < 0) || (chip > 7))
636         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
637     if (!cvmx_nand_state[chip].page_size)
638         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
639
640     cvmx_nand_state[chip].tim_mult = tim_mult;
641     for (i=0;i<8;i++)
642         cvmx_nand_state[chip].tim_par[i] = tim_par[i];
643     for (i=0;i<4;i++)
644         cvmx_nand_state[chip].clen[i] = clen[i];
645     for (i=0;i<4;i++)
646         cvmx_nand_state[chip].alen[i] = alen[i];
647     for (i=0;i<4;i++)
648         cvmx_nand_state[chip].rdn[i] = rdn[i];
649     for (i=0;i<2;i++)
650         cvmx_nand_state[chip].wrn[i] = wrn[i];
651
652     CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
653 }
654
655
656 /**
657  * @INTERNAL
658  * Get the number of free bytes in the NAND command queue
659  *
660  * @return Number of bytes in queue
661  */
662 static inline int __cvmx_nand_get_free_cmd_bytes(void)
663 {
664     cvmx_ndf_misc_t ndf_misc;
665     CVMX_NAND_LOG_CALLED();
666     ndf_misc.u64 = cvmx_read_csr(CVMX_NDF_MISC);
667     CVMX_NAND_RETURN((int)ndf_misc.s.fr_byt);
668 }
669
670
671 /**
672  * Submit a command to the NAND command queue. Generally this
673  * will not be used directly. Instead most programs will use the other
674  * higher level NAND functions.
675  *
676  * @param cmd    Command to submit
677  *
678  * @return Zero on success, a negative cvmx_nand_status_t error code on failure
679  */
680 cvmx_nand_status_t cvmx_nand_submit(cvmx_nand_cmd_t cmd)
681 {
682     CVMX_NAND_LOG_CALLED();
683     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)cmd.u64[0]);
684     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)cmd.u64[1]);
685     CVMX_NAND_LOG_PARAM("%s", cvmx_nand_opcode_labels[cmd.s.op_code]);
686     switch (cmd.s.op_code)
687     {
688         /* All these commands fit in one 64bit word */
689         case 0: /* NOP */
690         case 1: /* Timing */
691         case 2: /* WAIT */
692         case 3: /* Chip Enable/Disable */
693         case 4: /* CLE */
694         case 8: /* Write */
695         case 9: /* Read */
696         case 10: /* Read EDO */
697         case 15: /* Bus Aquire/Release */
698             if (__cvmx_nand_get_free_cmd_bytes() < 8)
699                 CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
700             cvmx_write_csr(CVMX_NDF_CMD, cmd.u64[1]);
701             CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
702
703         case 5: /* ALE commands take either one or two 64bit words */
704             if (cmd.ale.adr_byte_num < 5)
705             {
706                 if (__cvmx_nand_get_free_cmd_bytes() < 8)
707                     CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
708                 cvmx_write_csr(CVMX_NDF_CMD, cmd.u64[1]);
709                 CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
710             }
711             else
712             {
713                 if (__cvmx_nand_get_free_cmd_bytes() < 16)
714                     CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
715                 cvmx_write_csr(CVMX_NDF_CMD, cmd.u64[1]);
716                 cvmx_write_csr(CVMX_NDF_CMD, cmd.u64[0]);
717                 CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
718             }
719
720         case 11: /* Wait status commands take two 64bit words */
721             if (__cvmx_nand_get_free_cmd_bytes() < 16)
722                 CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
723             cvmx_write_csr(CVMX_NDF_CMD, cmd.u64[1]);
724             cvmx_write_csr(CVMX_NDF_CMD, cmd.u64[0]);
725             CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
726
727         default:
728             CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
729     }
730 }
731
732
733 /**
734  * @INTERNAL
735  * Get the number of bits required to encode the column bits. This
736  * does not include padding to align on a byte boundary.
737  *
738  * @param chip   NAND chip to get data for
739  *
740  * @return Number of column bits
741  */
742 static inline int __cvmx_nand_get_column_bits(int chip)
743 {
744     return cvmx_pop(cvmx_nand_state[chip].page_size - 1);
745 }
746
747
748 /**
749  * @INTERNAL
750  * Get the number of bits required to encode the row bits. This
751  * does not include padding to align on a byte boundary.
752  *
753  * @param chip   NAND chip to get data for
754  *
755  * @return Number of row bits
756  */
757 static inline int __cvmx_nand_get_row_bits(int chip)
758 {
759     return cvmx_pop(cvmx_nand_state[chip].blocks-1) + cvmx_pop(cvmx_nand_state[chip].pages_per_block-1);
760 }
761
762
763 /**
764  * @INTERNAL
765  * Get the number of address cycles required for this NAND part.
766  * This include column bits, padding, page bits, and block bits.
767  *
768  * @param chip   NAND chip to get data for
769  *
770  * @return Number of address cycles on the bus
771  */
772 static inline int __cvmx_nand_get_address_cycles(int chip)
773 {
774     int address_bits = ((__cvmx_nand_get_column_bits(chip) + 7) >> 3) << 3;
775     address_bits += ((__cvmx_nand_get_row_bits(chip) + 7) >> 3) << 3;
776     return (address_bits + 7) >> 3;
777 }
778
779
780 /**
781  * @INTERNAL
782  * Build the set of command common to most transactions
783  * @param chip      NAND chip to program
784  * @param cmd_data  NAND comamnd for CLE cycle 1
785  * @param num_address_cycles
786  *                  Number of address cycles to put on the bus
787  * @param nand_address
788  *                  Data to be put on the bus. It is translated according to
789  *                  the rules in the file information section.
790  *
791  * @param cmd_data2 If non zero, adds a second CLE cycle used by a number of NAND
792  *                  transactions.
793  *
794  * @return Zero on success, a negative cvmx_nand_status_t error code on failure
795  */
796 static inline cvmx_nand_status_t __cvmx_nand_build_pre_cmd(int chip, int cmd_data, int num_address_cycles, uint64_t nand_address, int cmd_data2)
797 {
798     cvmx_nand_status_t result;
799     cvmx_nand_cmd_t cmd;
800
801     CVMX_NAND_LOG_CALLED();
802
803     /* Send timing parameters */
804     memset(&cmd,  0,  sizeof(cmd));
805     cmd.set_tm_par.one = 1;
806     cmd.set_tm_par.tim_mult = cvmx_nand_state[chip].tim_mult;
807     /* tim_par[0] unused */
808     cmd.set_tm_par.tim_par1 = cvmx_nand_state[chip].tim_par[1];
809     cmd.set_tm_par.tim_par2 = cvmx_nand_state[chip].tim_par[2];
810     cmd.set_tm_par.tim_par3 = cvmx_nand_state[chip].tim_par[3];
811     cmd.set_tm_par.tim_par4 = cvmx_nand_state[chip].tim_par[4];
812     cmd.set_tm_par.tim_par5 = cvmx_nand_state[chip].tim_par[5];
813     cmd.set_tm_par.tim_par6 = cvmx_nand_state[chip].tim_par[6];
814     cmd.set_tm_par.tim_par7 = cvmx_nand_state[chip].tim_par[7];
815     result = cvmx_nand_submit(cmd);
816     if (result)
817         CVMX_NAND_RETURN(result);
818
819     /* Send bus select */
820     memset(&cmd,  0,  sizeof(cmd));
821     cmd.bus_acq.fifteen = 15;
822     cmd.bus_acq.one = 1;
823     result = cvmx_nand_submit(cmd);
824     if (result)
825         CVMX_NAND_RETURN(result);
826
827     /* Send chip select */
828     memset(&cmd,  0,  sizeof(cmd));
829     cmd.chip_en.chip = chip;
830     cmd.chip_en.one = 1;
831     cmd.chip_en.three = 3;
832     cmd.chip_en.width = (cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_16BIT) ? 2 : 1;
833     result = cvmx_nand_submit(cmd);
834     if (result)
835         CVMX_NAND_RETURN(result);
836
837     /* Send wait, fixed time
838     ** This meets chip enable to command latch enable timing.
839     ** This is tCS - tCLS from the ONFI spec.
840     ** Use tWP as a proxy, as this is adequate for
841     ** all ONFI 1.0 timing modes. */
842     memset(&cmd,  0,  sizeof(cmd));
843     cmd.wait.two = 2;
844     cmd.wait.n = 1;
845     if (cvmx_nand_submit(cmd))
846         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
847
848     /* Send CLE */
849     memset(&cmd,  0,  sizeof(cmd));
850     cmd.cle.cmd_data = cmd_data;
851     cmd.cle.clen1 = cvmx_nand_state[chip].clen[0];
852     cmd.cle.clen2 = cvmx_nand_state[chip].clen[1];
853     cmd.cle.clen3 = cvmx_nand_state[chip].clen[2];
854     cmd.cle.four = 4;
855     result = cvmx_nand_submit(cmd);
856     if (result)
857         CVMX_NAND_RETURN(result);
858
859     /* Send ALE */
860     if (num_address_cycles)
861     {
862         memset(&cmd,  0,  sizeof(cmd));
863         cmd.ale.adr_byte_num = num_address_cycles;
864         if (num_address_cycles < __cvmx_nand_get_address_cycles(chip))
865         {
866             cmd.ale.adr_bytes_l = nand_address;
867             cmd.ale.adr_bytes_h = nand_address >> 32;
868         }
869         else
870         {
871             int column_bits = __cvmx_nand_get_column_bits(chip);
872             int column_shift = ((column_bits + 7) >> 3) << 3;
873             int column = nand_address & (cvmx_nand_state[chip].page_size-1);
874             int row = nand_address >> column_bits;
875             cmd.ale.adr_bytes_l = column + (row << column_shift);
876             cmd.ale.adr_bytes_h = row >> (32 - column_shift);
877         }
878         cmd.ale.alen1 = cvmx_nand_state[chip].alen[0];
879         cmd.ale.alen2 = cvmx_nand_state[chip].alen[1];
880         cmd.ale.alen3 = cvmx_nand_state[chip].alen[2];
881         cmd.ale.alen4 = cvmx_nand_state[chip].alen[3];
882         cmd.ale.five = 5;
883         result = cvmx_nand_submit(cmd);
884         if (result)
885             CVMX_NAND_RETURN(result);
886     }
887
888     /* Send CLE 2 */
889     if (cmd_data2)
890     {
891         memset(&cmd,  0,  sizeof(cmd));
892         cmd.cle.cmd_data = cmd_data2;
893         cmd.cle.clen1 = cvmx_nand_state[chip].clen[0];
894         cmd.cle.clen2 = cvmx_nand_state[chip].clen[1];
895         cmd.cle.clen3 = cvmx_nand_state[chip].clen[2];
896         cmd.cle.four = 4;
897         result = cvmx_nand_submit(cmd);
898         if (result)
899             CVMX_NAND_RETURN(result);
900     }
901
902     CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
903 }
904
905
906 /**
907  * @INTERNAL
908  * Build the set of command common to most transactions
909  * @return Zero on success, a negative cvmx_nand_status_t error code on failure
910  */
911 static inline cvmx_nand_status_t __cvmx_nand_build_post_cmd(void)
912 {
913     cvmx_nand_status_t result;
914     cvmx_nand_cmd_t cmd;
915
916     CVMX_NAND_LOG_CALLED();
917
918     /* Send chip deselect */
919     memset(&cmd,  0,  sizeof(cmd));
920     cmd.chip_dis.three = 3;
921     result = cvmx_nand_submit(cmd);
922     if (result)
923         CVMX_NAND_RETURN(result);
924
925     /* Send bus release */
926     memset(&cmd,  0,  sizeof(cmd));
927     cmd.bus_rel.fifteen = 15;
928     result = cvmx_nand_submit(cmd);
929     if (result)
930         CVMX_NAND_RETURN(result);
931
932     /* Ring the doorbell */
933     cvmx_write_csr(CVMX_NDF_DRBELL, 1);
934     CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
935 }
936
937
938 /**
939  * @INTERNAL
940  * Setup the NAND DMA engine for a transfer
941  *
942  * @param chip     Chip select for NAND flash
943  * @param is_write Non zero if this is a write
944  * @param buffer_address
945  *                 Physical memory address to DMA to/from
946  * @param buffer_length
947  *                 Length of the DMA in bytes
948  */
949 static inline void __cvmx_nand_setup_dma(int chip, int is_write, uint64_t buffer_address, int buffer_length)
950 {
951     cvmx_mio_ndf_dma_cfg_t ndf_dma_cfg;
952     CVMX_NAND_LOG_CALLED();
953     CVMX_NAND_LOG_PARAM("%d", chip);
954     CVMX_NAND_LOG_PARAM("%d", is_write);
955     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)buffer_address);
956     CVMX_NAND_LOG_PARAM("%d", buffer_length);
957     ndf_dma_cfg.u64 = 0;
958     ndf_dma_cfg.s.en = 1;
959     ndf_dma_cfg.s.rw = is_write; /* One means DMA reads from memory and writes to flash */
960     ndf_dma_cfg.s.clr = 0;
961     ndf_dma_cfg.s.size = ((buffer_length + 7) >> 3) - 1;
962     ndf_dma_cfg.s.adr = buffer_address;
963     CVMX_SYNCWS;
964     cvmx_write_csr(CVMX_MIO_NDF_DMA_CFG, ndf_dma_cfg.u64);
965     CVMX_NAND_RETURN_NOTHING();
966 }
967
968
969 /**
970  * Dump a buffer out in hex for debug
971  *
972  * @param buffer_address
973  *               Starting physical address
974  * @param buffer_length
975  *               Number of bytes to display
976  */
977 static void __cvmx_nand_hex_dump(uint64_t buffer_address, int buffer_length)
978 {
979     uint8_t *buffer = cvmx_phys_to_ptr(buffer_address);
980     int offset = 0;
981     while (offset < buffer_length)
982     {
983         int i;
984         cvmx_dprintf("%*s%04x:",  2*debug_indent, "", offset);
985         for (i=0; i<32; i++)
986         {
987             if ((i&3) == 0)
988                 cvmx_dprintf(" ");
989             if (offset+i < buffer_length)
990                 cvmx_dprintf("%02x", 0xff & buffer[offset+i]);
991             else
992                 cvmx_dprintf("  ");
993         }
994         cvmx_dprintf("\n");
995         offset += 32;
996     }
997 }
998
999 /**
1000  * @INTERNAL
1001  * Perform a low level NAND read command
1002  *
1003  * @param chip   Chip to read from
1004  * @param nand_command1
1005  *               First command cycle value
1006  * @param address_cycles
1007  *               Number of address cycles after comand 1
1008  * @param nand_address
1009  *               NAND address to use for address cycles
1010  * @param nand_command2
1011  *               NAND comamnd cycle 2 if not zero
1012  * @param buffer_address
1013  *               Physical address to DMA into
1014  * @param buffer_length
1015  *               Length of the transfer in bytes
1016  *
1017  * @return Number of bytes transfered or a negative error code
1018  */
1019 static inline int __cvmx_nand_low_level_read(int chip, int nand_command1, int address_cycles, uint64_t nand_address, int nand_command2, uint64_t buffer_address, int buffer_length)
1020 {
1021     cvmx_nand_cmd_t cmd;
1022     cvmx_mio_ndf_dma_cfg_t ndf_dma_cfg;
1023     int bytes;
1024
1025     CVMX_NAND_LOG_CALLED();
1026     CVMX_NAND_LOG_PARAM("%d", chip);
1027     CVMX_NAND_LOG_PARAM("0x%x", nand_command1);
1028     CVMX_NAND_LOG_PARAM("%d", address_cycles);
1029     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)nand_address);
1030     CVMX_NAND_LOG_PARAM("0x%x", nand_command2);
1031     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)buffer_address);
1032     CVMX_NAND_LOG_PARAM("%d", buffer_length);
1033
1034     if ((chip < 0) || (chip > 7))
1035         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1036     if (!buffer_address)
1037         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1038     if (buffer_address & 7)
1039         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1040     if (!buffer_length)
1041         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1042
1043     /* Build the command and address cycles */
1044     if (__cvmx_nand_build_pre_cmd(chip, nand_command1, address_cycles, nand_address, nand_command2))
1045         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1046
1047     /* Send WAIT.  This waits for some time, then
1048     ** waits for busy to be de-asserted. */
1049     memset(&cmd,  0,  sizeof(cmd));
1050     cmd.wait.two = 2;
1051     cmd.wait.r_b=1;
1052     cmd.wait.n = 1;
1053     if (cvmx_nand_submit(cmd))
1054         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1055
1056     /* Wait for tRR after busy de-asserts.
1057     ** Use 2* tALS as proxy.  This is overkill in
1058     ** the slow modes, but not bad in the faster ones. */
1059     cmd.wait.r_b=0;
1060     cmd.wait.n=4;
1061     if (cvmx_nand_submit(cmd))
1062         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1063     if (cvmx_nand_submit(cmd))
1064         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1065
1066     /* Send READ */
1067     memset(&cmd,  0,  sizeof(cmd));
1068     cmd.rd.data_bytes = buffer_length;
1069     if (cvmx_nand_state[chip].onfi_timing >= 4)
1070         cmd.rd.nine = 10;  /* READ_EDO command is required for ONFI timing modes 4 and 5 */
1071     else
1072         cmd.rd.nine = 9;
1073     cmd.rd.rdn1 = cvmx_nand_state[chip].rdn[0];
1074     cmd.rd.rdn2 = cvmx_nand_state[chip].rdn[1];
1075     cmd.rd.rdn3 = cvmx_nand_state[chip].rdn[2];
1076     cmd.rd.rdn4 = cvmx_nand_state[chip].rdn[3];
1077     if (cvmx_nand_submit(cmd))
1078         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1079
1080     __cvmx_nand_setup_dma(chip, 0, buffer_address, buffer_length);
1081
1082     if (__cvmx_nand_build_post_cmd())
1083         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1084
1085     /* Wait for the DMA to complete */
1086     if (CVMX_WAIT_FOR_FIELD64(CVMX_MIO_NDF_DMA_CFG, cvmx_mio_ndf_dma_cfg_t, en, ==, 0, NAND_TIMEOUT_USECS))
1087         CVMX_NAND_RETURN(CVMX_NAND_TIMEOUT);
1088
1089     /* Return the number of bytes transfered */
1090     ndf_dma_cfg.u64 = cvmx_read_csr(CVMX_MIO_NDF_DMA_CFG);
1091     bytes = ndf_dma_cfg.s.adr - buffer_address;
1092
1093     if (cvmx_unlikely(cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_DEBUG))
1094         __cvmx_nand_hex_dump(buffer_address, bytes);
1095
1096     CVMX_NAND_RETURN(bytes);
1097 }
1098
1099
1100 /**
1101  * Read a page from NAND. If the buffer has room, the out of band
1102  * data will be included.
1103  *
1104  * @param chip   Chip select for NAND flash
1105  * @param nand_address
1106  *               Location in NAND to read. See description in file comment
1107  * @param buffer_address
1108  *               Physical address to store the result at
1109  * @param buffer_length
1110  *               Number of bytes to read
1111  *
1112  * @return Bytes read on success, a negative cvmx_nand_status_t error code on failure
1113  */
1114 int cvmx_nand_page_read(int chip, uint64_t nand_address, uint64_t buffer_address, int buffer_length)
1115 {
1116     int bytes;
1117
1118     CVMX_NAND_LOG_CALLED();
1119     CVMX_NAND_LOG_PARAM("%d", chip);
1120     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)nand_address);
1121     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)buffer_address);
1122     CVMX_NAND_LOG_PARAM("%d", buffer_length);
1123
1124     if ((chip < 0) || (chip > 7))
1125         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1126     if (!cvmx_nand_state[chip].page_size)
1127         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1128     if (!buffer_address)
1129         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1130     if (buffer_address & 7)
1131         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1132     if (!buffer_length)
1133         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1134
1135     bytes = __cvmx_nand_low_level_read(chip, NAND_COMMAND_READ, __cvmx_nand_get_address_cycles(chip), nand_address, NAND_COMMAND_READ_FIN, buffer_address, buffer_length);
1136     CVMX_NAND_RETURN(bytes);
1137 }
1138
1139
1140 /**
1141  * Write a page to NAND. The buffer must contain the entire page
1142  * including the out of band data.
1143  *
1144  * @param chip   Chip select for NAND flash
1145  * @param nand_address
1146  *               Location in NAND to write. See description in file comment
1147  * @param buffer_address
1148  *               Physical address to read the data from
1149  *
1150  * @return Zero on success, a negative cvmx_nand_status_t error code on failure
1151  */
1152 cvmx_nand_status_t cvmx_nand_page_write(int chip, uint64_t nand_address, uint64_t buffer_address)
1153 {
1154     cvmx_nand_cmd_t cmd;
1155     int buffer_length;
1156
1157     CVMX_NAND_LOG_CALLED();
1158     CVMX_NAND_LOG_PARAM("%d", chip);
1159     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)nand_address);
1160     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)buffer_address);
1161
1162     if ((chip < 0) || (chip > 7))
1163         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1164     if (!cvmx_nand_state[chip].page_size)
1165         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1166     if (!buffer_address)
1167         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1168     if (buffer_address & 7)
1169         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1170
1171     buffer_length = cvmx_nand_state[chip].page_size + cvmx_nand_state[chip].oob_size;
1172
1173     /* Build the command and address cycles */
1174     if (__cvmx_nand_build_pre_cmd(chip, NAND_COMMAND_PROGRAM, __cvmx_nand_get_address_cycles(chip), nand_address, 0))
1175         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1176
1177     /* Send WRITE */
1178     memset(&cmd,  0,  sizeof(cmd));
1179     cmd.wr.data_bytes = buffer_length;
1180     cmd.wr.eight = 8;
1181     cmd.wr.wrn1 = cvmx_nand_state[chip].wrn[0];
1182     cmd.wr.wrn2 = cvmx_nand_state[chip].wrn[1];
1183     if (cvmx_nand_submit(cmd))
1184         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1185
1186     /* Send WRITE command */
1187     memset(&cmd,  0,  sizeof(cmd));
1188     cmd.cle.cmd_data = NAND_COMMAND_PROGRAM_FIN;
1189     cmd.cle.clen1 = cvmx_nand_state[chip].clen[0];
1190     cmd.cle.clen2 = cvmx_nand_state[chip].clen[1];
1191     cmd.cle.clen3 = cvmx_nand_state[chip].clen[2];
1192     cmd.cle.four = 4;
1193     if (cvmx_nand_submit(cmd))
1194         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1195
1196     __cvmx_nand_setup_dma(chip, 1, buffer_address, buffer_length);
1197
1198     /* WAIT for R_B to signal program is complete  */
1199     memset(&cmd,  0,  sizeof(cmd));
1200     cmd.wait.two = 2;
1201     cmd.wait.r_b=1;
1202     cmd.wait.n = 1;
1203     if (cvmx_nand_submit(cmd))
1204         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1205
1206     if (__cvmx_nand_build_post_cmd())
1207         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1208
1209     /* Wait for the DMA to complete */
1210     if (CVMX_WAIT_FOR_FIELD64(CVMX_MIO_NDF_DMA_CFG, cvmx_mio_ndf_dma_cfg_t, en, ==, 0, NAND_TIMEOUT_USECS))
1211         CVMX_NAND_RETURN(CVMX_NAND_TIMEOUT);
1212
1213     CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
1214 }
1215
1216
1217 /**
1218  * Erase a NAND block. A single block contains multiple pages.
1219  *
1220  * @param chip   Chip select for NAND flash
1221  * @param nand_address
1222  *               Location in NAND to erase. See description in file comment
1223  *
1224  * @return Zero on success, a negative cvmx_nand_status_t error code on failure
1225  */
1226 cvmx_nand_status_t cvmx_nand_block_erase(int chip, uint64_t nand_address)
1227 {
1228     cvmx_nand_cmd_t cmd;
1229
1230     CVMX_NAND_LOG_CALLED();
1231     CVMX_NAND_LOG_PARAM("%d", chip);
1232     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)nand_address);
1233
1234     if ((chip < 0) || (chip > 7))
1235         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1236     if (!cvmx_nand_state[chip].page_size)
1237         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1238
1239     /* Build the command and address cycles */
1240     if (__cvmx_nand_build_pre_cmd(chip, NAND_COMMAND_ERASE,
1241                                   (__cvmx_nand_get_row_bits(chip)+7) >> 3,
1242                                   nand_address >> __cvmx_nand_get_column_bits(chip),
1243                                   NAND_COMMAND_ERASE_FIN))
1244         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1245
1246     /* WAIT for R_B to signal erase is complete  */
1247     memset(&cmd,  0,  sizeof(cmd));
1248     cmd.wait.two = 2;
1249     cmd.wait.r_b=1;
1250     cmd.wait.n = 1;
1251     if (cvmx_nand_submit(cmd))
1252         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1253
1254     if (__cvmx_nand_build_post_cmd())
1255         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1256
1257     /* Wait for the command queue to be idle, which means the wait is done */
1258     if (CVMX_WAIT_FOR_FIELD64(CVMX_NDF_ST_REG, cvmx_ndf_st_reg_t, exe_idle, ==, 1, NAND_TIMEOUT_USECS))
1259         CVMX_NAND_RETURN(CVMX_NAND_TIMEOUT);
1260
1261     CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
1262 }
1263
1264
1265 /**
1266  * Read the NAND ID information
1267  *
1268  * @param chip   Chip select for NAND flash
1269  * @param nand_address
1270  *               NAND address to read ID from. Usually this is either 0x0 or 0x20.
1271  * @param buffer_address
1272  *               Physical address to store data in
1273  * @param buffer_length
1274  *               Length of the buffer. Usually this is 4 bytes
1275  *
1276  * @return Bytes read on success, a negative cvmx_nand_status_t error code on failure
1277  */
1278 int cvmx_nand_read_id(int chip, uint64_t nand_address, uint64_t buffer_address, int buffer_length)
1279 {
1280     int bytes;
1281
1282     CVMX_NAND_LOG_CALLED();
1283     CVMX_NAND_LOG_PARAM("%d", chip);
1284     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)nand_address);
1285     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)buffer_address);
1286     CVMX_NAND_LOG_PARAM("%d", buffer_length);
1287
1288     if ((chip < 0) || (chip > 7))
1289         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1290     if (!buffer_address)
1291         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1292     if (buffer_address & 7)
1293         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1294     if (!buffer_length)
1295         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1296
1297     bytes = __cvmx_nand_low_level_read(chip, NAND_COMMAND_READ_ID, 1, nand_address, 0, buffer_address, buffer_length);
1298     CVMX_NAND_RETURN(bytes);
1299 }
1300
1301
1302 /**
1303  * Read the NAND parameter page
1304  *
1305  * @param chip   Chip select for NAND flash
1306  * @param buffer_address
1307  *               Physical address to store data in
1308  * @param buffer_length
1309  *               Length of the buffer. Usually this is 4 bytes
1310  *
1311  * @return Bytes read on success, a negative cvmx_nand_status_t error code on failure
1312  */
1313 int cvmx_nand_read_param_page(int chip, uint64_t buffer_address, int buffer_length)
1314 {
1315     int bytes;
1316
1317     CVMX_NAND_LOG_CALLED();
1318     CVMX_NAND_LOG_PARAM("%d", chip);
1319     CVMX_NAND_LOG_PARAM("0x%llx", (ULL)buffer_address);
1320     CVMX_NAND_LOG_PARAM("%d", buffer_length);
1321
1322     if ((chip < 0) || (chip > 7))
1323         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1324     if (!buffer_address)
1325         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1326     if (buffer_address & 7)
1327         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1328     if (!buffer_length)
1329         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1330
1331     bytes = __cvmx_nand_low_level_read(chip, NAND_COMMAND_READ_PARAM_PAGE, 1, 0x0, 0, buffer_address, buffer_length);
1332     CVMX_NAND_RETURN(bytes);
1333 }
1334
1335
1336 /**
1337  * Get the status of the NAND flash
1338  *
1339  * @param chip   Chip select for NAND flash
1340  *
1341  * @return NAND status or a negative cvmx_nand_status_t error code on failure
1342  */
1343 int cvmx_nand_get_status(int chip)
1344 {
1345     int status;
1346
1347     CVMX_NAND_LOG_CALLED();
1348     CVMX_NAND_LOG_PARAM("%d", chip);
1349
1350     if ((chip < 0) || (chip > 7))
1351         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1352
1353     *(uint8_t*)cvmx_nand_buffer = 0xff;
1354     status = __cvmx_nand_low_level_read(chip, NAND_COMMAND_STATUS, 0, 0, 0, cvmx_ptr_to_phys(cvmx_nand_buffer), (cvmx_nand_flags & CVMX_NAND_INITIALIZE_FLAGS_16BIT) ? 2 : 1);
1355     if (status > 0)
1356         status = *(uint8_t*)cvmx_nand_buffer;
1357
1358     CVMX_NAND_RETURN(status);
1359 }
1360
1361
1362 /**
1363  * Get the page size, excluding out of band data. This  function
1364  * will return zero for chip selects not connected to NAND.
1365  *
1366  * @param chip   Chip select for NAND flash
1367  *
1368  * @return Page size in bytes or a negative cvmx_nand_status_t error code on failure
1369  */
1370 int cvmx_nand_get_page_size(int chip)
1371 {
1372     CVMX_NAND_LOG_CALLED();
1373     CVMX_NAND_LOG_PARAM("%d", chip);
1374
1375     if ((chip < 0) || (chip > 7))
1376         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1377
1378     CVMX_NAND_RETURN(cvmx_nand_state[chip].page_size);
1379 }
1380
1381
1382 /**
1383  * Get the OOB size.
1384  *
1385  * @param chip   Chip select for NAND flash
1386  *
1387  * @return OOB in bytes or a negative cvmx_nand_status_t error code on failure
1388  */
1389 int cvmx_nand_get_oob_size(int chip)
1390 {
1391     CVMX_NAND_LOG_CALLED();
1392     CVMX_NAND_LOG_PARAM("%d", chip);
1393
1394     if ((chip < 0) || (chip > 7))
1395         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1396
1397     CVMX_NAND_RETURN(cvmx_nand_state[chip].oob_size);
1398 }
1399
1400
1401 /**
1402  * Get the number of pages per NAND block
1403  *
1404  * @param chip   Chip select for NAND flash
1405  *
1406  * @return Number of pages in each block or a negative cvmx_nand_status_t error
1407  *         code on failure
1408  */
1409 int cvmx_nand_get_pages_per_block(int chip)
1410 {
1411     CVMX_NAND_LOG_CALLED();
1412     CVMX_NAND_LOG_PARAM("%d", chip);
1413
1414     if ((chip < 0) || (chip > 7))
1415         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1416
1417     CVMX_NAND_RETURN(cvmx_nand_state[chip].pages_per_block);
1418 }
1419
1420
1421 /**
1422  * Get the number of blocks in the NAND flash
1423  *
1424  * @param chip   Chip select for NAND flash
1425  *
1426  * @return Number of blocks or a negative cvmx_nand_status_t error code on failure
1427  */
1428 int cvmx_nand_get_blocks(int chip)
1429 {
1430     CVMX_NAND_LOG_CALLED();
1431     CVMX_NAND_LOG_PARAM("%d", chip);
1432
1433     if ((chip < 0) || (chip > 7))
1434         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1435
1436     CVMX_NAND_RETURN(cvmx_nand_state[chip].blocks);
1437 }
1438
1439
1440 /**
1441  * Reset the NAND flash
1442  *
1443  * @param chip   Chip select for NAND flash
1444  *
1445  * @return Zero on success, a negative cvmx_nand_status_t error code on failure
1446  */
1447 cvmx_nand_status_t cvmx_nand_reset(int chip)
1448 {
1449     cvmx_nand_cmd_t cmd;
1450
1451     CVMX_NAND_LOG_CALLED();
1452     CVMX_NAND_LOG_PARAM("%d", chip);
1453
1454     if ((chip < 0) || (chip > 7))
1455         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1456     if (!cvmx_nand_state[chip].page_size)
1457         CVMX_NAND_RETURN(CVMX_NAND_INVALID_PARAM);
1458
1459     if (__cvmx_nand_build_pre_cmd(chip, NAND_COMMAND_RESET, 0, 0, 0))
1460         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1461
1462     /* WAIT for R_B to signal reset is complete  */
1463     memset(&cmd,  0,  sizeof(cmd));
1464     cmd.wait.two = 2;
1465     cmd.wait.r_b=1;
1466     cmd.wait.n = 1;
1467     if (cvmx_nand_submit(cmd))
1468         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1469
1470     if (__cvmx_nand_build_post_cmd())
1471         CVMX_NAND_RETURN(CVMX_NAND_NO_MEMORY);
1472
1473     CVMX_NAND_RETURN(CVMX_NAND_SUCCESS);
1474 }
1475
1476
1477
1478
1479 /**
1480  * This function computes the Octeon specific ECC data used by the NAND boot
1481  * feature.
1482  * 
1483  * @param block  pointer to 256 bytes of data
1484  * @param eccp   pointer to where 8 bytes of ECC data will be stored
1485  */
1486 void cvmx_nand_compute_boot_ecc(unsigned char *block, unsigned char *eccp)
1487 {
1488         unsigned char pd0, pd1, pd2;
1489         int i, j;
1490
1491         pd0 = pd1 = pd2 = 0;
1492
1493         for (i = 0; i < 256; i++)       /* PD0<0> */
1494                 pd0 ^= (block[i] ^ (block[i] >> 2) ^ (block[i] >> 4) ^ (block[i] >> 6)) & 1;
1495         for (i = 0; i < 256; i++)       /* PD0<1> */
1496                 pd0 ^= ((block[i] ^ (block[i] >> 1) ^ (block[i] >> 4) ^ (block[i] >> 5)) & 1) << 1;
1497         for (i = 0; i < 256; i++)       /* PD0<2> */
1498                 pd0 ^= ((block[i] ^ (block[i] >> 1) ^ (block[i] >> 2) ^ (block[i] >> 3)) & 1) << 2;
1499         for (i = 0; i < 128; i++)       /* PD0<3> */
1500                 pd0 ^= ((block[2*i] ^ (block[2*i] >> 1) ^ (block[2*i] >> 2) ^
1501                         (block[2*i] >> 3) ^ (block[2*i] >> 4) ^ (block[2*i] >> 5) ^
1502                         (block[2*i] >> 6) ^ (block[2*i] >> 7)) & 1) << 3;
1503         for (i = 0; i < 64; i++)        /* PD0<4> */
1504                 for (j = 0; j < 2; j++)
1505                         pd0 ^= ((block[4*i+j] ^ (block[4*i+j] >> 1) ^ (block[4*i+j] >> 2) ^
1506                                 (block[4*i+j] >> 3) ^ (block[4*i+j] >> 4) ^ (block[4*i+j] >> 5) ^
1507                                 (block[4*i+j] >> 6) ^ (block[4*i+j] >> 7)) & 1) << 4;
1508         for (i = 0; i < 32; i++)        /* PD0<5> */
1509                 for (j = 0; j < 4; j++)
1510                         pd0 ^= ((block[8*i+j] ^ (block[8*i+j] >> 1) ^ (block[8*i+j] >> 2) ^
1511                                 (block[8*i+j] >> 3) ^ (block[8*i+j] >> 4) ^ (block[8*i+j] >> 5) ^
1512                                 (block[8*i+j] >> 6) ^ (block[8*i+j] >> 7)) & 1) << 5;
1513         for (i = 0; i < 16; i++)        /* PD0<6> */
1514                 for (j = 0; j < 8; j++)
1515                         pd0 ^= ((block[16*i+j] ^ (block[16*i+j] >> 1) ^ (block[16*i+j] >> 2) ^
1516                                 (block[16*i+j] >> 3) ^ (block[16*i+j] >> 4) ^ (block[16*i+j] >> 5) ^
1517                                 (block[16*i+j] >> 6) ^ (block[16*i+j] >> 7)) & 1) << 6;
1518         for (i = 0; i < 8; i++)         /* PD0<7> */
1519                 for (j = 0; j < 16; j++)
1520                         pd0 ^= ((block[32*i+j] ^ (block[32*i+j] >> 1) ^ (block[32*i+j] >> 2) ^
1521                                 (block[32*i+j] >> 3) ^ (block[32*i+j] >> 4) ^ (block[32*i+j] >> 5) ^
1522                                 (block[32*i+j] >> 6) ^ (block[32*i+j] >> 7)) & 1) << 7;
1523         for (i = 0; i < 4; i++)         /* PD1<0> */
1524                 for (j = 0; j < 32; j++)
1525                         pd1 ^= ((block[64*i+j] ^ (block[64*i+j] >> 1) ^ (block[64*i+j] >> 2) ^
1526                                 (block[64*i+j] >> 3) ^ (block[64*i+j] >> 4) ^ (block[64*i+j] >> 5) ^
1527                                 (block[64*i+j] >> 6) ^ (block[64*i+j] >> 7)) & 1) << 0;
1528         for (i = 0; i < 2; i++)         /* PD1<1> */
1529                 for (j = 0; j < 64; j++)
1530                         pd1 ^= ((block[128*i+j] ^ (block[128*i+j] >> 1) ^ (block[128*i+j] >> 2) ^
1531                                 (block[128*i+j] >> 3) ^ (block[128*i+j] >> 4) ^ (block[128*i+j] >> 5) ^
1532                                 (block[128*i+j] >> 6) ^ (block[128*i+j] >> 7)) & 1) << 1;
1533         for (i = 0; i < 128; i++)       /* PD1<2> */
1534                 pd1 ^= ((block[i] ^ (block[i] >> 1) ^ (block[i] >> 2) ^
1535                         (block[i] >> 3) ^ (block[i] >> 4) ^ (block[i] >> 5) ^
1536                         (block[i] >> 6) ^ (block[i] >> 7)) & 1) << 2;
1537         /* PD1<3> */
1538         /* PD1<4> */
1539         for (i = 0; i < 256; i++)       /* PD1<5> */
1540                 pd1 ^= (((block[i] >> 1) ^ (block[i] >> 3) ^ (block[i] >> 5) ^ (block[i] >> 7)) & 1) << 5;
1541         for (i = 0; i < 256; i++)       /* PD1<6> */
1542                 pd1 ^= (((block[i] >> 2) ^ (block[i] >> 3) ^ (block[i] >> 6) ^ (block[i] >> 7)) & 1) << 6;
1543         for (i = 0; i < 256; i++)       /* PD1<7> */
1544                 pd1 ^= (((block[i] >> 4) ^ (block[i] >> 5) ^ (block[i] >> 6) ^ (block[i] >> 7)) & 1) << 7;
1545         for (i = 0; i < 128; i++)       /* PD2<0> */
1546                 pd2 ^= ((block[2*i+1] ^ (block[2*i+1] >> 1) ^ (block[2*i+1] >> 2) ^
1547                         (block[2*i+1] >> 3) ^ (block[2*i+1] >> 4) ^ (block[2*i+1] >> 5) ^
1548                         (block[2*i+1] >> 6) ^ (block[2*i+1] >> 7)) & 1) << 0;
1549         for (i = 0; i < 64; i++)        /* PD2<1> */
1550                 for (j = 2; j < 4; j++)
1551                         pd2 ^= ((block[4*i+j] ^ (block[4*i+j] >> 1) ^ (block[4*i+j] >> 2) ^
1552                                 (block[4*i+j] >> 3) ^ (block[4*i+j] >> 4) ^ (block[4*i+j] >> 5) ^
1553                                 (block[4*i+j] >> 6) ^ (block[4*i+j] >> 7)) & 1) << 1;
1554         for (i = 0; i < 32; i++)        /* PD2<2> */
1555                 for (j = 4; j < 8; j++)
1556                         pd2 ^= ((block[8*i+j] ^ (block[8*i+j] >> 1) ^ (block[8*i+j] >> 2) ^
1557                                 (block[8*i+j] >> 3) ^ (block[8*i+j] >> 4) ^ (block[8*i+j] >> 5) ^
1558                                 (block[8*i+j] >> 6) ^ (block[8*i+j] >> 7)) & 1) << 2;
1559         for (i = 0; i < 16; i++)        /* PD2<3> */
1560                 for (j = 8; j < 16; j++)
1561                         pd2 ^= ((block[16*i+j] ^ (block[16*i+j] >> 1) ^ (block[16*i+j] >> 2) ^
1562                                 (block[16*i+j] >> 3) ^ (block[16*i+j] >> 4) ^ (block[16*i+j] >> 5) ^
1563                                 (block[16*i+j] >> 6) ^ (block[16*i+j] >> 7)) & 1) << 3;
1564         for (i = 0; i < 8; i++)         /* PD2<4> */
1565                 for (j = 16; j < 32; j++)
1566                         pd2 ^= ((block[32*i+j] ^ (block[32*i+j] >> 1) ^ (block[32*i+j] >> 2) ^
1567                                 (block[32*i+j] >> 3) ^ (block[32*i+j] >> 4) ^ (block[32*i+j] >> 5) ^
1568                                 (block[32*i+j] >> 6) ^ (block[32*i+j] >> 7)) & 1) << 4;
1569         for (i = 0; i < 4; i++)         /* PD2<5> */
1570                 for (j = 32; j < 64; j++)
1571                         pd2 ^= ((block[64*i+j] ^ (block[64*i+j] >> 1) ^ (block[64*i+j] >> 2) ^
1572                                 (block[64*i+j] >> 3) ^ (block[64*i+j] >> 4) ^ (block[64*i+j] >> 5) ^
1573                                 (block[64*i+j] >> 6) ^ (block[64*i+j] >> 7)) & 1) << 5;
1574         for (i = 0; i < 2; i++)         /* PD2<6> */
1575                 for (j = 64; j < 128; j++)
1576                         pd2 ^= ((block[128*i+j] ^ (block[128*i+j] >> 1) ^ (block[128*i+j] >> 2) ^
1577                                 (block[128*i+j] >> 3) ^ (block[128*i+j] >> 4) ^ (block[128*i+j] >> 5) ^
1578                                 (block[128*i+j] >> 6) ^ (block[128*i+j] >> 7)) & 1) << 6;
1579         for (i = 128; i < 256; i++)     /* PD2<7> */
1580                 pd2 ^= ((block[i] ^ (block[i] >> 1) ^ (block[i] >> 2) ^
1581                         (block[i] >> 3) ^ (block[i] >> 4) ^ (block[i] >> 5) ^
1582                         (block[i] >> 6) ^ (block[i] >> 7)) & 1) << 7;
1583
1584         eccp[0] = pd0;
1585         eccp[1] = pd1;
1586         eccp[2] = pd2;
1587 }
1588
1589 /**
1590  * Check an Octeon ECC block, fixing errors if possible
1591  *
1592  * @param block  Pointer to block to check
1593  *
1594  * @return Zero if block has no errors, one if errors were corrected, two
1595  *         if the errors could not be corrected.
1596  */
1597 int cvmx_nand_correct_boot_ecc(uint8_t *block)
1598 {
1599     unsigned char pd0, pd1, pd2;
1600     int i, j;
1601     unsigned char xorpd0, xorpd1, xorpd2;
1602     int xor_num;
1603     unsigned int check;
1604
1605     asm volatile ("pref 0,0(%0);pref 0,128(%0);pref 0,256(%0)\n" :: "r" (block));
1606
1607     pd0 = pd1 = pd2 = 0;
1608
1609     for (i = 0; i < 256; i++)   /* PD0<0> */
1610         pd0 ^= (block[i] ^ (block[i] >> 2) ^ (block[i] >> 4) ^ (block[i] >> 6)) & 1;
1611     for (i = 0; i < 256; i++)   /* PD0<1> */
1612         pd0 ^= ((block[i] ^ (block[i] >> 1) ^ (block[i] >> 4) ^ (block[i] >> 5)) & 1) << 1;
1613     for (i = 0; i < 256; i++)   /* PD0<2> */
1614         pd0 ^= ((block[i] ^ (block[i] >> 1) ^ (block[i] >> 2) ^ (block[i] >> 3)) & 1) << 2;
1615     for (i = 0; i < 128; i++)   /* PD0<3> */
1616         pd0 ^= ((block[2*i] ^ (block[2*i] >> 1) ^ (block[2*i] >> 2) ^
1617                  (block[2*i] >> 3) ^ (block[2*i] >> 4) ^ (block[2*i] >> 5) ^
1618                  (block[2*i] >> 6) ^ (block[2*i] >> 7)) & 1) << 3;
1619     for (i = 0; i < 64; i++)    /* PD0<4> */
1620         for (j = 0; j < 2; j++)
1621             pd0 ^= ((block[4*i+j] ^ (block[4*i+j] >> 1) ^ (block[4*i+j] >> 2) ^
1622                      (block[4*i+j] >> 3) ^ (block[4*i+j] >> 4) ^ (block[4*i+j] >> 5) ^
1623                      (block[4*i+j] >> 6) ^ (block[4*i+j] >> 7)) & 1) << 4;
1624     for (i = 0; i < 32; i++)    /* PD0<5> */
1625         for (j = 0; j < 4; j++)
1626             pd0 ^= ((block[8*i+j] ^ (block[8*i+j] >> 1) ^ (block[8*i+j] >> 2) ^
1627                      (block[8*i+j] >> 3) ^ (block[8*i+j] >> 4) ^ (block[8*i+j] >> 5) ^
1628                      (block[8*i+j] >> 6) ^ (block[8*i+j] >> 7)) & 1) << 5;
1629     for (i = 0; i < 16; i++)    /* PD0<6> */
1630         for (j = 0; j < 8; j++)
1631             pd0 ^= ((block[16*i+j] ^ (block[16*i+j] >> 1) ^ (block[16*i+j] >> 2) ^
1632                      (block[16*i+j] >> 3) ^ (block[16*i+j] >> 4) ^ (block[16*i+j] >> 5) ^
1633                      (block[16*i+j] >> 6) ^ (block[16*i+j] >> 7)) & 1) << 6;
1634     for (i = 0; i < 8; i++)     /* PD0<7> */
1635         for (j = 0; j < 16; j++)
1636             pd0 ^= ((block[32*i+j] ^ (block[32*i+j] >> 1) ^ (block[32*i+j] >> 2) ^
1637                      (block[32*i+j] >> 3) ^ (block[32*i+j] >> 4) ^ (block[32*i+j] >> 5) ^
1638                      (block[32*i+j] >> 6) ^ (block[32*i+j] >> 7)) & 1) << 7;
1639     for (i = 0; i < 4; i++)     /* PD1<0> */
1640         for (j = 0; j < 32; j++)
1641             pd1 ^= ((block[64*i+j] ^ (block[64*i+j] >> 1) ^ (block[64*i+j] >> 2) ^
1642                      (block[64*i+j] >> 3) ^ (block[64*i+j] >> 4) ^ (block[64*i+j] >> 5) ^
1643                      (block[64*i+j] >> 6) ^ (block[64*i+j] >> 7)) & 1) << 0;
1644     for (i = 0; i < 2; i++)     /* PD1<1> */
1645         for (j = 0; j < 64; j++)
1646             pd1 ^= ((block[128*i+j] ^ (block[128*i+j] >> 1) ^ (block[128*i+j] >> 2) ^
1647                      (block[128*i+j] >> 3) ^ (block[128*i+j] >> 4) ^ (block[128*i+j] >> 5) ^
1648                      (block[128*i+j] >> 6) ^ (block[128*i+j] >> 7)) & 1) << 1;
1649     for (i = 0; i < 128; i++)   /* PD1<2> */
1650         pd1 ^= ((block[i] ^ (block[i] >> 1) ^ (block[i] >> 2) ^
1651                  (block[i] >> 3) ^ (block[i] >> 4) ^ (block[i] >> 5) ^
1652                  (block[i] >> 6) ^ (block[i] >> 7)) & 1) << 2;
1653     /* PD1<3> */
1654     /* PD1<4> */
1655     for (i = 0; i < 256; i++)   /* PD1<5> */
1656         pd1 ^= (((block[i] >> 1) ^ (block[i] >> 3) ^ (block[i] >> 5) ^ (block[i] >> 7)) & 1) << 5;
1657     for (i = 0; i < 256; i++)   /* PD1<6> */
1658         pd1 ^= (((block[i] >> 2) ^ (block[i] >> 3) ^ (block[i] >> 6) ^ (block[i] >> 7)) & 1) << 6;
1659     for (i = 0; i < 256; i++)   /* PD1<7> */
1660         pd1 ^= (((block[i] >> 4) ^ (block[i] >> 5) ^ (block[i] >> 6) ^ (block[i] >> 7)) & 1) << 7;
1661     for (i = 0; i < 128; i++)   /* PD2<0> */
1662         pd2 ^= ((block[2*i+1] ^ (block[2*i+1] >> 1) ^ (block[2*i+1] >> 2) ^
1663                  (block[2*i+1] >> 3) ^ (block[2*i+1] >> 4) ^ (block[2*i+1] >> 5) ^
1664                  (block[2*i+1] >> 6) ^ (block[2*i+1] >> 7)) & 1) << 0;
1665     for (i = 0; i < 64; i++)    /* PD2<1> */
1666         for (j = 2; j < 4; j++)
1667             pd2 ^= ((block[4*i+j] ^ (block[4*i+j] >> 1) ^ (block[4*i+j] >> 2) ^
1668                      (block[4*i+j] >> 3) ^ (block[4*i+j] >> 4) ^ (block[4*i+j] >> 5) ^
1669                      (block[4*i+j] >> 6) ^ (block[4*i+j] >> 7)) & 1) << 1;
1670     for (i = 0; i < 32; i++)    /* PD2<2> */
1671         for (j = 4; j < 8; j++)
1672             pd2 ^= ((block[8*i+j] ^ (block[8*i+j] >> 1) ^ (block[8*i+j] >> 2) ^
1673                      (block[8*i+j] >> 3) ^ (block[8*i+j] >> 4) ^ (block[8*i+j] >> 5) ^
1674                      (block[8*i+j] >> 6) ^ (block[8*i+j] >> 7)) & 1) << 2;
1675     for (i = 0; i < 16; i++)    /* PD2<3> */
1676         for (j = 8; j < 16; j++)
1677             pd2 ^= ((block[16*i+j] ^ (block[16*i+j] >> 1) ^ (block[16*i+j] >> 2) ^
1678                      (block[16*i+j] >> 3) ^ (block[16*i+j] >> 4) ^ (block[16*i+j] >> 5) ^
1679                      (block[16*i+j] >> 6) ^ (block[16*i+j] >> 7)) & 1) << 3;
1680     for (i = 0; i < 8; i++)     /* PD2<4> */
1681         for (j = 16; j < 32; j++)
1682             pd2 ^= ((block[32*i+j] ^ (block[32*i+j] >> 1) ^ (block[32*i+j] >> 2) ^
1683                      (block[32*i+j] >> 3) ^ (block[32*i+j] >> 4) ^ (block[32*i+j] >> 5) ^
1684                      (block[32*i+j] >> 6) ^ (block[32*i+j] >> 7)) & 1) << 4;
1685     for (i = 0; i < 4; i++)     /* PD2<5> */
1686         for (j = 32; j < 64; j++)
1687             pd2 ^= ((block[64*i+j] ^ (block[64*i+j] >> 1) ^ (block[64*i+j] >> 2) ^
1688                      (block[64*i+j] >> 3) ^ (block[64*i+j] >> 4) ^ (block[64*i+j] >> 5) ^
1689                      (block[64*i+j] >> 6) ^ (block[64*i+j] >> 7)) & 1) << 5;
1690     for (i = 0; i < 2; i++)     /* PD2<6> */
1691         for (j = 64; j < 128; j++)
1692             pd2 ^= ((block[128*i+j] ^ (block[128*i+j] >> 1) ^ (block[128*i+j] >> 2) ^
1693                      (block[128*i+j] >> 3) ^ (block[128*i+j] >> 4) ^ (block[128*i+j] >> 5) ^
1694                      (block[128*i+j] >> 6) ^ (block[128*i+j] >> 7)) & 1) << 6;
1695     for (i = 128; i < 256; i++) /* PD2<7> */
1696         pd2 ^= ((block[i] ^ (block[i] >> 1) ^ (block[i] >> 2) ^
1697                  (block[i] >> 3) ^ (block[i] >> 4) ^ (block[i] >> 5) ^
1698                  (block[i] >> 6) ^ (block[i] >> 7)) & 1) << 7;
1699
1700     xorpd0 = pd0 ^ block[256];
1701     xorpd1 = pd1 ^ block[257];
1702     xorpd2 = pd2 ^ block[258];
1703
1704     xor_num = __builtin_popcount((xorpd0 << 16) | (xorpd1 << 8) | xorpd2);
1705     check = (((xorpd1 & 7) << 8) | xorpd0) ^ ((xorpd2 << 3) | (xorpd1 >> 5));
1706
1707     if (xor_num == 0)
1708         return 0;
1709     else if ((xor_num > 1) && (check != 0x7FF))
1710         return 2;
1711
1712     if (check == 0x7FF)
1713     {
1714         /* Correct the error */
1715         block[xorpd2] ^= 1 << (xorpd1 >> 5);
1716     }
1717
1718     return 1;
1719 }