1210284Sjmallett/***********************license start***************
2232812Sjmallett * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights
3215990Sjmallett * reserved.
4210284Sjmallett *
5210284Sjmallett *
6215990Sjmallett * Redistribution and use in source and binary forms, with or without
7215990Sjmallett * modification, are permitted provided that the following conditions are
8215990Sjmallett * met:
9210284Sjmallett *
10215990Sjmallett *   * Redistributions of source code must retain the above copyright
11215990Sjmallett *     notice, this list of conditions and the following disclaimer.
12210284Sjmallett *
13215990Sjmallett *   * Redistributions in binary form must reproduce the above
14215990Sjmallett *     copyright notice, this list of conditions and the following
15215990Sjmallett *     disclaimer in the documentation and/or other materials provided
16215990Sjmallett *     with the distribution.
17215990Sjmallett
18232812Sjmallett *   * Neither the name of Cavium Inc. nor the names of
19215990Sjmallett *     its contributors may be used to endorse or promote products
20215990Sjmallett *     derived from this software without specific prior written
21215990Sjmallett *     permission.
22215990Sjmallett
23215990Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24215990Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25215990Sjmallett * regulations, and may be subject to export or import  regulations in other
26215990Sjmallett * countries.
27215990Sjmallett
28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29232812Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38210284Sjmallett ***********************license end**************************************/
39210284Sjmallett
40210284Sjmallett
41210284Sjmallett
42210284Sjmallett
43210284Sjmallett
44210284Sjmallett
45215990Sjmallett
46210284Sjmallett/**
47210284Sjmallett * @file
48210284Sjmallett *
49210284Sjmallett * This header defines the CVMX interface to the NAND flash controller. The
50210284Sjmallett * basic operations common to all NAND devices are supported by this API, but
51210284Sjmallett * many more advanced functions are not support. The low level hardware supports
52210284Sjmallett * all types of transactions, but this API only implements the must commonly
53210284Sjmallett * used operations. This API performs no locking, so it is the responsibility of
54210284Sjmallett * the caller to make sure only one thread of execution is accessing the NAND
55210284Sjmallett * controller at a time. Most applications should not use this API directly but
56210284Sjmallett * instead use a flash logical layer supplied through a secondary system. For
57210284Sjmallett * example, the Linux MTD layer provides a driver for running JFFS2 on top of
58210284Sjmallett * NAND flash.
59210284Sjmallett *
60210284Sjmallett * <h2>Selecting the NAND Chip</h2>
61210284Sjmallett *
62210284Sjmallett * Octeon's NAND controller assumes a single NAND chip is connected to a boot
63210284Sjmallett * bus chip select. Throughout this API, NAND chips are referred to by the chip
64210284Sjmallett * select they are connected to (0-7). Chip select 0 will only be a NAND chip
65210284Sjmallett * when you are booting from NAND flash.
66210284Sjmallett *
67210284Sjmallett * <h2>NAND Addressing</h2>
68210284Sjmallett *
69210284Sjmallett * Various functions in cvmx-nand use addresses to index into NAND flash. All
70210284Sjmallett * functions us a uniform address translation scheme to map the passed address
71210284Sjmallett * into a NAND block, page, and column. In NAND flash a page represents the
72210284Sjmallett * basic unit of reads and writes. Each page contains a power of two number of
73210284Sjmallett * bytes and some number of extra out of band (OOB) bytes. A fixed number of
74210284Sjmallett * pages fit into each NAND block. Here is the mapping of bits in the cvmx-nand
75210284Sjmallett * address to the NAND hardware:
76210284Sjmallett * <pre>
77210284Sjmallett * 63     56      48      40      32      24      16       8      0
78210284Sjmallett * +-------+-------+-------+-------+-------+-------+-------+------+
79210284Sjmallett * |                                 64 bit cvmx-nand nand_address|
80210284Sjmallett * +------------------------------------------------+----+--------+
81210284Sjmallett * |                                          block |page| column |
82210284Sjmallett * +-------+-------+-------+-------+-------+--------+----+--------+
83210284Sjmallett * 63     56      48      40      32      24      16       8      0
84210284Sjmallett * </pre>
85210284Sjmallett * Basically the block, page, and column addresses are packet together. Before
86210284Sjmallett * being sent out the NAND pins for addressing the column is padded out to an
87210284Sjmallett * even number of bytes. This means that column address are 2 bytes, or 2
88210284Sjmallett * address cycles, for page sizes between 512 and 65536 bytes. Page sizes
89210284Sjmallett * between 128KB and 16MB would use 3 column address cycles. NAND device
90210284Sjmallett * normally either have 32 or 64 pages per block, needing either 5 or 6 address
91210284Sjmallett * bits respectively. This means you have 10 bits for block address using 4
92210284Sjmallett * address cycles, or 18 for 5 address cycles. Using the cvmx-nand addressing
93210284Sjmallett * scheme, it is not possible to directly index the OOB data. Instead you can
94210284Sjmallett * access it by reading or writing more data than the normal page size would
95210284Sjmallett * allow. Logically the OOB data is appended onto the the page data. For
96210284Sjmallett * example, this means that a read of 65 bytes from a column address of 0x7ff
97210284Sjmallett * would yield byte 2047 of the page and then 64 bytes of OOB data.
98210284Sjmallett *
99210284Sjmallett * <hr>$Revision: 35726 $<hr>
100210284Sjmallett */
101210284Sjmallett
102210284Sjmallett#ifndef __CVMX_NAND_H__
103210284Sjmallett#define __CVMX_NAND_H__
104210284Sjmallett
105210284Sjmallett#ifdef	__cplusplus
106210284Sjmallettextern "C" {
107210284Sjmallett#endif
108210284Sjmallett
109215990Sjmallett/* Maxium PAGE + OOB size supported.  This is used to size
110215990Sjmallett** buffers, some that must be statically allocated. */
111215990Sjmallett#define CVMX_NAND_MAX_PAGE_AND_OOB_SIZE      (4096 + 256)
112210284Sjmallett
113215990Sjmallett
114210284Sjmallett/* Block size for boot ECC */
115210284Sjmallett#define CVMX_NAND_BOOT_ECC_BLOCK_SIZE    (256)
116210284Sjmallett/* ECC bytes for each block */
117210284Sjmallett#define CVMX_NAND_BOOT_ECC_ECC_SIZE      (8)
118210284Sjmallett
119210284Sjmallett/**
120210284Sjmallett * Flags to be passed to the initialize function
121210284Sjmallett */
122210284Sjmalletttypedef enum
123210284Sjmallett{
124210284Sjmallett    CVMX_NAND_INITIALIZE_FLAGS_16BIT = 1<<0,
125210284Sjmallett    CVMX_NAND_INITIALIZE_FLAGS_DONT_PROBE = 1<<1,
126210284Sjmallett    CVMX_NAND_INITIALIZE_FLAGS_DEBUG = 1<<15,
127210284Sjmallett} cvmx_nand_initialize_flags_t;
128210284Sjmallett
129210284Sjmallett/**
130210284Sjmallett * Return codes from NAND functions
131210284Sjmallett */
132210284Sjmalletttypedef enum
133210284Sjmallett{
134210284Sjmallett    CVMX_NAND_SUCCESS = 0,
135210284Sjmallett    CVMX_NAND_NO_MEMORY = -1,
136210284Sjmallett    CVMX_NAND_BUSY = -2,
137210284Sjmallett    CVMX_NAND_INVALID_PARAM = -3,
138210284Sjmallett    CVMX_NAND_TIMEOUT = -4,
139215990Sjmallett    CVMX_NAND_ERROR = -5,
140232812Sjmallett    CVMX_NAND_NO_DEVICE = -6,
141210284Sjmallett} cvmx_nand_status_t;
142210284Sjmallett
143210284Sjmallett/**
144210284Sjmallett * NAND NOP command definition
145210284Sjmallett */
146210284Sjmalletttypedef struct
147210284Sjmallett{
148210284Sjmallett    uint64_t reserved_64_127    : 64;
149210284Sjmallett    uint64_t reserved_4_63      : 60;
150210284Sjmallett    uint64_t zero               : 4;
151210284Sjmallett} cvmx_nand_cmd_nop_t;
152210284Sjmallett
153210284Sjmallett/**
154210284Sjmallett * NAND SET_TM_PAR command definition
155210284Sjmallett */
156210284Sjmalletttypedef struct
157210284Sjmallett{
158210284Sjmallett    uint64_t reserved_64_127    : 64;
159210284Sjmallett    uint64_t tim_par7           : 8;
160210284Sjmallett    uint64_t tim_par6           : 8;
161210284Sjmallett    uint64_t tim_par5           : 8;
162210284Sjmallett    uint64_t tim_par4           : 8;
163210284Sjmallett    uint64_t tim_par3           : 8;
164210284Sjmallett    uint64_t tim_par2           : 8;
165210284Sjmallett    uint64_t tim_par1           : 8;
166210284Sjmallett    uint64_t tim_mult           : 4;
167210284Sjmallett    uint64_t one                : 4;
168210284Sjmallett} cvmx_nand_cmd_set_tm_par_t;
169210284Sjmallett
170210284Sjmallett/**
171210284Sjmallett * NAND WAIT command definition
172210284Sjmallett */
173210284Sjmalletttypedef struct
174210284Sjmallett{
175210284Sjmallett    uint64_t reserved_64_127    : 64;
176210284Sjmallett    uint64_t reserved_11_63     : 53;
177210284Sjmallett    uint64_t n                  : 3;
178210284Sjmallett    uint64_t reserved_5_7       : 3;
179210284Sjmallett    uint64_t r_b                : 1;
180210284Sjmallett    uint64_t two                : 4;
181210284Sjmallett} cvmx_nand_cmd_wait_t;
182210284Sjmallett
183210284Sjmallett/**
184210284Sjmallett * NAND CHIP_EN command definition
185210284Sjmallett */
186210284Sjmalletttypedef struct
187210284Sjmallett{
188210284Sjmallett    uint64_t reserved_64_127    : 64;
189210284Sjmallett    uint64_t reserved_10_63     : 54;
190210284Sjmallett    uint64_t width              : 2;
191210284Sjmallett    uint64_t one                : 1;
192210284Sjmallett    uint64_t chip               : 3;
193210284Sjmallett    uint64_t three              : 4;
194210284Sjmallett} cvmx_nand_cmd_chip_en_t;
195210284Sjmallett
196210284Sjmallett/**
197210284Sjmallett * NAND CHIP_DIS command definition
198210284Sjmallett */
199210284Sjmalletttypedef struct
200210284Sjmallett{
201210284Sjmallett    uint64_t reserved_64_127    : 64;
202210284Sjmallett    uint64_t reserved_4_63      : 60;
203210284Sjmallett    uint64_t three              : 4;
204210284Sjmallett} cvmx_nand_cmd_chip_dis_t;
205210284Sjmallett
206210284Sjmallett/**
207210284Sjmallett * NAND CLE command definition
208210284Sjmallett */
209210284Sjmalletttypedef struct
210210284Sjmallett{
211210284Sjmallett    uint64_t reserved_64_127    : 64;
212210284Sjmallett    uint64_t reserved_25_63     : 39;
213210284Sjmallett    uint64_t clen3              : 3;
214210284Sjmallett    uint64_t clen2              : 3;
215210284Sjmallett    uint64_t clen1              : 3;
216210284Sjmallett    uint64_t cmd_data           : 8;
217210284Sjmallett    uint64_t reserved_4_7       : 4;
218210284Sjmallett    uint64_t four               : 4;
219210284Sjmallett} cvmx_nand_cmd_cle_t;
220210284Sjmallett
221210284Sjmallett/**
222210284Sjmallett * NAND ALE command definition
223210284Sjmallett */
224210284Sjmalletttypedef struct
225210284Sjmallett{
226210284Sjmallett    uint64_t reserved_96_127    : 32;
227210284Sjmallett    uint64_t adr_bytes_h        : 32;
228210284Sjmallett    uint64_t adr_bytes_l        : 32;
229210284Sjmallett    uint64_t reserved_28_31     : 4;
230210284Sjmallett    uint64_t alen4              : 3;
231210284Sjmallett    uint64_t alen3              : 3;
232210284Sjmallett    uint64_t alen2              : 3;
233210284Sjmallett    uint64_t alen1              : 3;
234210284Sjmallett    uint64_t reserved_12_15     : 4;
235210284Sjmallett    uint64_t adr_byte_num       : 4;
236210284Sjmallett    uint64_t reserved_4_7       : 4;
237210284Sjmallett    uint64_t five               : 4;
238210284Sjmallett} cvmx_nand_cmd_ale_t;
239210284Sjmallett
240210284Sjmallett/**
241210284Sjmallett * NAND WR command definition
242210284Sjmallett */
243210284Sjmalletttypedef struct
244210284Sjmallett{
245210284Sjmallett    uint64_t reserved_64_127    : 64;
246210284Sjmallett    uint64_t reserved_31_63     : 34;
247210284Sjmallett    uint64_t wrn2               : 3;
248210284Sjmallett    uint64_t wrn1               : 3;
249210284Sjmallett    uint64_t reserved_20_24     : 4;
250210284Sjmallett    uint64_t data_bytes         : 16;
251210284Sjmallett    uint64_t eight              : 4;
252210284Sjmallett} cvmx_nand_cmd_wr_t;
253210284Sjmallett
254210284Sjmallett/**
255210284Sjmallett * NAND RD command definition
256210284Sjmallett */
257210284Sjmalletttypedef struct
258210284Sjmallett{
259210284Sjmallett    uint64_t reserved_64_127    : 64;
260210284Sjmallett    uint64_t reserved_32_63     : 32;
261210284Sjmallett    uint64_t rdn4               : 3;
262210284Sjmallett    uint64_t rdn3               : 3;
263210284Sjmallett    uint64_t rdn2               : 3;
264210284Sjmallett    uint64_t rdn1               : 3;
265210284Sjmallett    uint64_t data_bytes         : 16;
266210284Sjmallett    uint64_t nine               : 4;
267210284Sjmallett} cvmx_nand_cmd_rd_t;
268210284Sjmallett
269210284Sjmallett/**
270210284Sjmallett * NAND RD_EDO command definition
271210284Sjmallett */
272210284Sjmalletttypedef struct
273210284Sjmallett{
274210284Sjmallett    uint64_t reserved_64_127    : 64;
275210284Sjmallett    uint64_t reserved_32_63     : 32;
276210284Sjmallett    uint64_t rdn4               : 3;
277210284Sjmallett    uint64_t rdn3               : 3;
278210284Sjmallett    uint64_t rdn2               : 3;
279210284Sjmallett    uint64_t rdn1               : 3;
280210284Sjmallett    uint64_t data_bytes         : 16;
281210284Sjmallett    uint64_t ten                : 4;
282210284Sjmallett} cvmx_nand_cmd_rd_edo_t;
283210284Sjmallett
284210284Sjmallett/**
285210284Sjmallett * NAND WAIT_STATUS command definition
286210284Sjmallett */
287210284Sjmalletttypedef struct
288210284Sjmallett{
289210284Sjmallett    uint64_t rdn4               : 3;
290210284Sjmallett    uint64_t rdn3               : 3;
291210284Sjmallett    uint64_t rdn2               : 3;
292210284Sjmallett    uint64_t rdn1               : 3;
293210284Sjmallett    uint64_t comp_byte          : 8;
294210284Sjmallett    uint64_t and_mask           : 8;
295210284Sjmallett    uint64_t nine               : 4;
296210284Sjmallett    uint64_t reserved_28_95     : 64;
297210284Sjmallett    uint64_t clen4              : 3;
298210284Sjmallett    uint64_t clen3              : 3;
299210284Sjmallett    uint64_t clen2              : 3;
300210284Sjmallett    uint64_t clen1              : 3;
301210284Sjmallett    uint64_t data               : 8;
302210284Sjmallett    uint64_t reserved_4_7       : 4;
303210284Sjmallett    uint64_t eleven             : 4;
304210284Sjmallett} cvmx_nand_cmd_wait_status_t;
305210284Sjmallett
306210284Sjmallett/**
307210284Sjmallett * NAND WAIT_STATUS_ALE command definition
308210284Sjmallett */
309210284Sjmalletttypedef struct
310210284Sjmallett{
311210284Sjmallett    uint64_t rdn4               : 3;
312210284Sjmallett    uint64_t rdn3               : 3;
313210284Sjmallett    uint64_t rdn2               : 3;
314210284Sjmallett    uint64_t rdn1               : 3;
315210284Sjmallett    uint64_t comp_byte          : 8;
316210284Sjmallett    uint64_t and_mask           : 8;
317210284Sjmallett    uint64_t nine               : 4;
318210284Sjmallett    uint64_t adr_bytes          : 32;
319210284Sjmallett    uint64_t reserved_60_63     : 4;
320210284Sjmallett    uint64_t alen4              : 3;
321210284Sjmallett    uint64_t alen3              : 3;
322210284Sjmallett    uint64_t alen2              : 3;
323210284Sjmallett    uint64_t alen1              : 3;
324210284Sjmallett    uint64_t reserved_44_47     : 4;
325210284Sjmallett    uint64_t adr_byte_num       : 4;
326210284Sjmallett    uint64_t five               : 4;
327210284Sjmallett    uint64_t reserved_25_31     : 7;
328210284Sjmallett    uint64_t clen3              : 3;
329210284Sjmallett    uint64_t clen2              : 3;
330210284Sjmallett    uint64_t clen1              : 3;
331210284Sjmallett    uint64_t data               : 8;
332210284Sjmallett    uint64_t reserved_4_7       : 4;
333210284Sjmallett    uint64_t eleven             : 4;
334210284Sjmallett} cvmx_nand_cmd_wait_status_ale_t;
335210284Sjmallett
336210284Sjmallett/**
337210284Sjmallett * NAND BUS_ACQ command definition
338210284Sjmallett */
339210284Sjmalletttypedef struct
340210284Sjmallett{
341210284Sjmallett    uint64_t reserved_64_127    : 64;
342210284Sjmallett    uint64_t reserved_8_63      : 56;
343210284Sjmallett    uint64_t one                : 4;
344210284Sjmallett    uint64_t fifteen            : 4;
345210284Sjmallett} cvmx_nand_cmd_bus_acq_t;
346210284Sjmallett
347210284Sjmallett/**
348210284Sjmallett * NAND BUS_REL command definition
349210284Sjmallett */
350210284Sjmalletttypedef struct
351210284Sjmallett{
352210284Sjmallett    uint64_t reserved_64_127    : 64;
353210284Sjmallett    uint64_t reserved_8_63      : 56;
354210284Sjmallett    uint64_t zero               : 4;
355210284Sjmallett    uint64_t fifteen            : 4;
356210284Sjmallett} cvmx_nand_cmd_bus_rel_t;
357210284Sjmallett
358210284Sjmallett/**
359210284Sjmallett * NAND command union of all possible commands
360210284Sjmallett */
361210284Sjmalletttypedef union
362210284Sjmallett{
363210284Sjmallett    uint64_t u64[2];
364210284Sjmallett    cvmx_nand_cmd_nop_t             nop;
365210284Sjmallett    cvmx_nand_cmd_set_tm_par_t      set_tm_par;
366210284Sjmallett    cvmx_nand_cmd_wait_t            wait;
367210284Sjmallett    cvmx_nand_cmd_chip_en_t         chip_en;
368210284Sjmallett    cvmx_nand_cmd_chip_dis_t        chip_dis;
369210284Sjmallett    cvmx_nand_cmd_cle_t             cle;
370210284Sjmallett    cvmx_nand_cmd_ale_t             ale;
371210284Sjmallett    cvmx_nand_cmd_rd_t              rd;
372210284Sjmallett    cvmx_nand_cmd_rd_edo_t          rd_edo;
373210284Sjmallett    cvmx_nand_cmd_wr_t              wr;
374210284Sjmallett    cvmx_nand_cmd_wait_status_t     wait_status;
375210284Sjmallett    cvmx_nand_cmd_wait_status_ale_t wait_status_ale;
376210284Sjmallett    cvmx_nand_cmd_bus_acq_t         bus_acq;
377210284Sjmallett    cvmx_nand_cmd_bus_rel_t         bus_rel;
378210284Sjmallett    struct
379210284Sjmallett    {
380210284Sjmallett        uint64_t reserved_64_127: 64;
381210284Sjmallett        uint64_t reserved_4_63  : 60;
382210284Sjmallett        uint64_t op_code        : 4;
383210284Sjmallett    } s;
384210284Sjmallett} cvmx_nand_cmd_t;
385210284Sjmallett
386210284Sjmallett
387210284Sjmalletttypedef struct __attribute__ ((packed))
388210284Sjmallett{
389210284Sjmallett    char onfi[4];                   /**< Bytes 0-3: The ASCII characters 'O', 'N', 'F', 'I' */
390210284Sjmallett    uint16_t revision_number;       /**< Bytes 4-5: ONFI revision number
391210284Sjmallett                                        - 2-15 Reserved (0)
392210284Sjmallett                                        - 1    1 = supports ONFI version 1.0
393210284Sjmallett                                        - 0    Reserved (0) */
394210284Sjmallett    uint16_t features;              /**< Bytes 6-7: Features supported
395210284Sjmallett                                        - 5-15    Reserved (0)
396210284Sjmallett                                        - 4       1 = supports odd to even page Copyback
397210284Sjmallett                                        - 3       1 = supports interleaved operations
398210284Sjmallett                                        - 2       1 = supports non-sequential page programming
399210284Sjmallett                                        - 1       1 = supports multiple LUN operations
400210284Sjmallett                                        - 0       1 = supports 16-bit data bus width */
401210284Sjmallett    uint16_t optional_commands;     /**< Bytes 8-9: Optional commands supported
402210284Sjmallett                                        - 6-15   Reserved (0)
403210284Sjmallett                                        - 5      1 = supports Read Unique ID
404210284Sjmallett                                        - 4      1 = supports Copyback
405210284Sjmallett                                        - 3      1 = supports Read Status Enhanced
406210284Sjmallett                                        - 2      1 = supports Get Features and Set Features
407210284Sjmallett                                        - 1      1 = supports Read Cache commands
408210284Sjmallett                                        - 0      1 = supports Page Cache Program command */
409210284Sjmallett    uint8_t reserved_10_31[22];     /**< Bytes 10-31: Reserved */
410210284Sjmallett
411210284Sjmallett    char manufacturer[12];          /**< Bytes 32-43: Device manufacturer (12 ASCII characters) */
412210284Sjmallett    char model[20];                 /**< Bytes 40-63: Device model (20 ASCII characters) */
413210284Sjmallett    uint8_t jedec_id;               /**< Byte 64: JEDEC manufacturer ID */
414210284Sjmallett    uint16_t date_code;             /**< Byte 65-66: Date code */
415210284Sjmallett    uint8_t reserved_67_79[13];     /**< Bytes 67-79: Reserved */
416210284Sjmallett
417210284Sjmallett    uint32_t page_data_bytes;       /**< Bytes 80-83: Number of data bytes per page */
418210284Sjmallett    uint16_t page_spare_bytes;      /**< Bytes 84-85: Number of spare bytes per page */
419210284Sjmallett    uint32_t partial_page_data_bytes; /**< Bytes 86-89: Number of data bytes per partial page */
420210284Sjmallett    uint16_t partial_page_spare_bytes; /**< Bytes 90-91: Number of spare bytes per partial page */
421210284Sjmallett    uint32_t pages_per_block;       /**< Bytes 92-95: Number of pages per block */
422210284Sjmallett    uint32_t blocks_per_lun;        /**< Bytes 96-99: Number of blocks per logical unit (LUN) */
423210284Sjmallett    uint8_t number_lun;             /**< Byte 100: Number of logical units (LUNs) */
424210284Sjmallett    uint8_t address_cycles;         /**< Byte 101: Number of address cycles
425210284Sjmallett                                        - 4-7     Column address cycles
426210284Sjmallett                                        - 0-3     Row address cycles */
427210284Sjmallett    uint8_t bits_per_cell;          /**< Byte 102: Number of bits per cell */
428210284Sjmallett    uint16_t bad_block_per_lun;     /**< Bytes 103-104: Bad blocks maximum per LUN */
429210284Sjmallett    uint16_t block_endurance;       /**< Bytes 105-106: Block endurance */
430210284Sjmallett    uint8_t good_blocks;            /**< Byte 107: Guaranteed valid blocks at beginning of target */
431210284Sjmallett    uint16_t good_block_endurance;  /**< Bytes 108-109: Block endurance for guaranteed valid blocks */
432210284Sjmallett    uint8_t programs_per_page;      /**< Byte 110: Number of programs per page */
433210284Sjmallett    uint8_t partial_program_attrib; /**< Byte 111: Partial programming attributes
434210284Sjmallett                                        - 5-7    Reserved
435210284Sjmallett                                        - 4      1 = partial page layout is partial page data followed by partial page spare
436210284Sjmallett                                        - 1-3    Reserved
437210284Sjmallett                                        - 0      1 = partial page programming has constraints */
438210284Sjmallett    uint8_t bits_ecc;               /**< Byte 112: Number of bits ECC correctability */
439210284Sjmallett    uint8_t interleaved_address_bits;   /**< Byte 113: Number of interleaved address bits
440210284Sjmallett                                            - 4-7    Reserved (0)
441210284Sjmallett                                            - 0-3    Number of interleaved address bits */
442210284Sjmallett    uint8_t interleaved_attrib;     /**< Byte 114: Interleaved operation attributes
443210284Sjmallett                                        - 4-7    Reserved (0)
444210284Sjmallett                                        - 3      Address restrictions for program cache
445210284Sjmallett                                        - 2      1 = program cache supported
446210284Sjmallett                                        - 1      1 = no block address restrictions
447210284Sjmallett                                        - 0      Overlapped / concurrent interleaving support */
448210284Sjmallett    uint8_t reserved_115_127[13];   /**< Bytes 115-127: Reserved (0) */
449210284Sjmallett
450210284Sjmallett    uint8_t pin_capacitance;        /**< Byte 128: I/O pin capacitance */
451210284Sjmallett    uint16_t timing_mode;           /**< Byte 129-130: Timing mode support
452210284Sjmallett                                        - 6-15   Reserved (0)
453210284Sjmallett                                        - 5      1 = supports timing mode 5
454210284Sjmallett                                        - 4      1 = supports timing mode 4
455210284Sjmallett                                        - 3      1 = supports timing mode 3
456210284Sjmallett                                        - 2      1 = supports timing mode 2
457210284Sjmallett                                        - 1      1 = supports timing mode 1
458210284Sjmallett                                        - 0      1 = supports timing mode 0, shall be 1 */
459210284Sjmallett    uint16_t cache_timing_mode;     /**< Byte 131-132: Program cache timing mode support
460210284Sjmallett                                        - 6-15   Reserved (0)
461210284Sjmallett                                        - 5      1 = supports timing mode 5
462210284Sjmallett                                        - 4      1 = supports timing mode 4
463210284Sjmallett                                        - 3      1 = supports timing mode 3
464210284Sjmallett                                        - 2      1 = supports timing mode 2
465210284Sjmallett                                        - 1      1 = supports timing mode 1
466210284Sjmallett                                        - 0      1 = supports timing mode 0 */
467210284Sjmallett    uint16_t t_prog;                /**< Byte 133-134: Maximum page program time (us) */
468210284Sjmallett    uint16_t t_bers;                /**< Byte 135-136: Maximum block erase time (us) */
469210284Sjmallett    uint16_t t_r;                   /**< Byte 137-148: Maximum page read time (us) */
470210284Sjmallett    uint16_t t_ccs;                 /**< Byte 139-140: Minimum change column setup time (ns) */
471210284Sjmallett    uint8_t reserved_141_163[23];   /**< Byte 141-163: Reserved (0) */
472210284Sjmallett
473210284Sjmallett    uint16_t vendor_revision;       /**< Byte 164-165: Vendor specific Revision number */
474210284Sjmallett    uint8_t vendor_specific[88];    /**< Byte 166-253: Vendor specific */
475210284Sjmallett    uint16_t crc;                   /**< Byte 254-255: Integrity CRC */
476210284Sjmallett} cvmx_nand_onfi_param_page_t;
477210284Sjmallett
478210284Sjmallett
479210284Sjmallett/**
480210284Sjmallett * Called to initialize the NAND controller for use. Note that
481210284Sjmallett * you must be running out of L2 or memory and not NAND before
482210284Sjmallett * calling this function.
483215990Sjmallett * When probing for NAND chips, this function attempts to autoconfigure based on the NAND parts detected.
484215990Sjmallett * It currently supports autodetection for ONFI parts (with valid parameter pages), and some Samsung NAND
485215990Sjmallett * parts (decoding ID bits.)  If autoconfiguration fails, the defaults set with __set_chip_defaults()
486215990Sjmallett * prior to calling cvmx_nand_initialize() are used.
487215990Sjmallett * If defaults are set and the CVMX_NAND_INITIALIZE_FLAGS_DONT_PROBE flag is provided, the defaults are used
488215990Sjmallett * for all chips in the active_chips mask.
489210284Sjmallett *
490210284Sjmallett * @param flags  Optional initialization flags
491215990Sjmallett *               If the CVMX_NAND_INITIALIZE_FLAGS_DONT_PROBE flag is passed, chips are not probed,
492215990Sjmallett *               and the default parameters (if set with cvmx_nand_set_defaults) are used for all chips
493215990Sjmallett *               in the active_chips mask.
494210284Sjmallett * @param active_chips
495210284Sjmallett *               Each bit in this parameter represents a chip select that might
496210284Sjmallett *               contain NAND flash. Any chip select present in this bitmask may
497210284Sjmallett *               be connected to NAND. It is normally safe to pass 0xff here and
498210284Sjmallett *               let the API probe all 8 chip selects.
499210284Sjmallett *
500210284Sjmallett * @return Zero on success, a negative cvmx_nand_status_t error code on failure
501210284Sjmallett */
502210284Sjmallettextern cvmx_nand_status_t cvmx_nand_initialize(cvmx_nand_initialize_flags_t flags, int active_chips);
503210284Sjmallett
504210284Sjmallett
505215990Sjmallett
506210284Sjmallett/**
507215990Sjmallett * This function may be called before cvmx_nand_initialize to set default values that will be used
508215990Sjmallett * for NAND chips that do not identify themselves in a way that allows autoconfiguration. (ONFI chip with
509215990Sjmallett * missing parameter page, for example.)
510215990Sjmallett * The parameters set by this function will be used by _all_ non-autoconfigured NAND chips.
511215990Sjmallett *
512215990Sjmallett *
513215990Sjmallett *   NOTE:  This function signature is _NOT_ stable, and will change in the future as required to support
514215990Sjmallett *          various NAND chips.
515215990Sjmallett *
516215990Sjmallett * @param page_size page size in bytes
517215990Sjmallett * @param oob_size  Out of band size in bytes (per page)
518215990Sjmallett * @param pages_per_block
519215990Sjmallett *                  number of pages per block
520215990Sjmallett * @param blocks    Total number of blocks in device
521215990Sjmallett * @param onfi_timing_mode
522215990Sjmallett *                  ONFI timing mode
523215990Sjmallett *
524215990Sjmallett * @return Zero on success, a negative cvmx_nand_status_t error code on failure
525215990Sjmallett */
526215990Sjmallettextern cvmx_nand_status_t cvmx_nand_set_defaults(int page_size, int oob_size, int pages_per_block, int blocks, int onfi_timing_mode);
527215990Sjmallett
528215990Sjmallett
529215990Sjmallett/**
530210284Sjmallett * Call to shutdown the NAND controller after all transactions
531210284Sjmallett * are done. In most setups this will never be called.
532210284Sjmallett *
533210284Sjmallett * @return Zero on success, a negative cvmx_nand_status_t error code on failure
534210284Sjmallett */
535210284Sjmallettextern cvmx_nand_status_t cvmx_nand_shutdown(void);
536210284Sjmallett
537210284Sjmallett
538210284Sjmallett/**
539210284Sjmallett * Returns a bitmask representing the chip selects that are
540210284Sjmallett * connected to NAND chips. This can be called after the
541210284Sjmallett * initialize to determine the actual number of NAND chips
542210284Sjmallett * found. Each bit in the response coresponds to a chip select.
543210284Sjmallett *
544210284Sjmallett * @return Zero if no NAND chips were found. Otherwise a bit is set for
545210284Sjmallett *         each chip select (1<<chip).
546210284Sjmallett */
547210284Sjmallettextern int cvmx_nand_get_active_chips(void);
548210284Sjmallett
549210284Sjmallett
550210284Sjmallett/**
551210284Sjmallett * Override the timing parameters for a NAND chip
552210284Sjmallett *
553210284Sjmallett * @param chip     Chip select to override
554210284Sjmallett * @param tim_mult
555210284Sjmallett * @param tim_par
556210284Sjmallett * @param clen
557210284Sjmallett * @param alen
558210284Sjmallett * @param rdn
559210284Sjmallett * @param wrn
560210284Sjmallett *
561210284Sjmallett * @return Zero on success, a negative cvmx_nand_status_t error code on failure
562210284Sjmallett */
563210284Sjmallettextern cvmx_nand_status_t cvmx_nand_set_timing(int chip, int tim_mult, int tim_par[7], int clen[4], int alen[4], int rdn[4], int wrn[2]);
564210284Sjmallett
565210284Sjmallett
566210284Sjmallett/**
567210284Sjmallett * Submit a command to the NAND command queue. Generally this
568210284Sjmallett * will not be used directly. Instead most programs will use the other
569210284Sjmallett * higher level NAND functions.
570210284Sjmallett *
571210284Sjmallett * @param cmd    Command to submit
572210284Sjmallett *
573210284Sjmallett * @return Zero on success, a negative cvmx_nand_status_t error code on failure
574210284Sjmallett */
575210284Sjmallettextern cvmx_nand_status_t cvmx_nand_submit(cvmx_nand_cmd_t cmd);
576210284Sjmallett
577210284Sjmallett/**
578210284Sjmallett * Read a page from NAND. If the buffer has room, the out of band
579210284Sjmallett * data will be included.
580210284Sjmallett *
581210284Sjmallett * @param chip   Chip select for NAND flash
582210284Sjmallett * @param nand_address
583210284Sjmallett *               Location in NAND to read. See description in file comment
584210284Sjmallett * @param buffer_address
585210284Sjmallett *               Physical address to store the result at
586210284Sjmallett * @param buffer_length
587210284Sjmallett *               Number of bytes to read
588210284Sjmallett *
589210284Sjmallett * @return Bytes read on success, a negative cvmx_nand_status_t error code on failure
590210284Sjmallett */
591210284Sjmallettextern int cvmx_nand_page_read(int chip, uint64_t nand_address, uint64_t buffer_address, int buffer_length);
592210284Sjmallett
593210284Sjmallett/**
594210284Sjmallett * Write a page to NAND. The buffer must contain the entire page
595210284Sjmallett * including the out of band data.
596210284Sjmallett *
597210284Sjmallett * @param chip   Chip select for NAND flash
598210284Sjmallett * @param nand_address
599210284Sjmallett *               Location in NAND to write. See description in file comment
600210284Sjmallett * @param buffer_address
601210284Sjmallett *               Physical address to read the data from
602210284Sjmallett *
603210284Sjmallett * @return Zero on success, a negative cvmx_nand_status_t error code on failure
604210284Sjmallett */
605210284Sjmallettextern cvmx_nand_status_t cvmx_nand_page_write(int chip, uint64_t nand_address, uint64_t buffer_address);
606210284Sjmallett
607210284Sjmallett/**
608210284Sjmallett * Erase a NAND block. A single block contains multiple pages.
609210284Sjmallett *
610210284Sjmallett * @param chip   Chip select for NAND flash
611210284Sjmallett * @param nand_address
612210284Sjmallett *               Location in NAND to erase. See description in file comment
613210284Sjmallett *
614210284Sjmallett * @return Zero on success, a negative cvmx_nand_status_t error code on failure
615210284Sjmallett */
616210284Sjmallettextern cvmx_nand_status_t cvmx_nand_block_erase(int chip, uint64_t nand_address);
617210284Sjmallett
618210284Sjmallett/**
619210284Sjmallett * Read the NAND ID information
620210284Sjmallett *
621210284Sjmallett * @param chip   Chip select for NAND flash
622210284Sjmallett * @param nand_address
623210284Sjmallett *               NAND address to read ID from. Usually this is either 0x0 or 0x20.
624210284Sjmallett * @param buffer_address
625210284Sjmallett *               Physical address to store data in
626210284Sjmallett * @param buffer_length
627210284Sjmallett *               Length of the buffer. Usually this is 4 bytes
628210284Sjmallett *
629210284Sjmallett * @return Bytes read on success, a negative cvmx_nand_status_t error code on failure
630210284Sjmallett */
631210284Sjmallettextern int cvmx_nand_read_id(int chip, uint64_t nand_address, uint64_t buffer_address, int buffer_length);
632210284Sjmallett
633210284Sjmallett/**
634210284Sjmallett * Read the NAND parameter page
635210284Sjmallett *
636210284Sjmallett * @param chip   Chip select for NAND flash
637210284Sjmallett * @param buffer_address
638210284Sjmallett *               Physical address to store data in
639210284Sjmallett * @param buffer_length
640210284Sjmallett *               Length of the buffer. Usually this is 4 bytes
641210284Sjmallett *
642210284Sjmallett * @return Bytes read on success, a negative cvmx_nand_status_t error code on failure
643210284Sjmallett */
644210284Sjmallettextern int cvmx_nand_read_param_page(int chip, uint64_t buffer_address, int buffer_length);
645210284Sjmallett
646210284Sjmallett/**
647210284Sjmallett * Get the status of the NAND flash
648210284Sjmallett *
649210284Sjmallett * @param chip   Chip select for NAND flash
650210284Sjmallett *
651210284Sjmallett * @return NAND status or a negative cvmx_nand_status_t error code on failure
652210284Sjmallett */
653210284Sjmallettextern int cvmx_nand_get_status(int chip);
654210284Sjmallett
655210284Sjmallett/**
656210284Sjmallett * Get the page size, excluding out of band data. This  function
657210284Sjmallett * will return zero for chip selects not connected to NAND.
658210284Sjmallett *
659210284Sjmallett * @param chip   Chip select for NAND flash
660210284Sjmallett *
661210284Sjmallett * @return Page size in bytes or a negative cvmx_nand_status_t error code on failure
662210284Sjmallett */
663210284Sjmallettextern int cvmx_nand_get_page_size(int chip);
664210284Sjmallett
665210284Sjmallett/**
666210284Sjmallett * Get the OOB size.
667210284Sjmallett *
668210284Sjmallett * @param chip   Chip select for NAND flash
669210284Sjmallett *
670210284Sjmallett * @return OOB in bytes or a negative cvmx_nand_status_t error code on failure
671210284Sjmallett */
672210284Sjmallettextern int cvmx_nand_get_oob_size(int chip);
673210284Sjmallett
674210284Sjmallett/**
675210284Sjmallett * Get the number of pages per NAND block
676210284Sjmallett *
677210284Sjmallett * @param chip   Chip select for NAND flash
678210284Sjmallett *
679210284Sjmallett * @return Numboer of pages in each block or a negative cvmx_nand_status_t error code on failure
680210284Sjmallett */
681210284Sjmallettextern int cvmx_nand_get_pages_per_block(int chip);
682210284Sjmallett
683210284Sjmallett/**
684210284Sjmallett * Get the number of blocks in the NAND flash
685210284Sjmallett *
686210284Sjmallett * @param chip   Chip select for NAND flash
687210284Sjmallett *
688210284Sjmallett * @return Number of blocks or a negative cvmx_nand_status_t error code on failure
689210284Sjmallett */
690210284Sjmallettextern int cvmx_nand_get_blocks(int chip);
691210284Sjmallett
692210284Sjmallett/**
693210284Sjmallett * Reset the NAND flash
694210284Sjmallett *
695210284Sjmallett * @param chip   Chip select for NAND flash
696210284Sjmallett *
697210284Sjmallett * @return Zero on success, a negative cvmx_nand_status_t error code on failure
698210284Sjmallett */
699210284Sjmallettextern cvmx_nand_status_t cvmx_nand_reset(int chip);
700210284Sjmallett
701210284Sjmallett/**
702210284Sjmallett * This function computes the Octeon specific ECC data used by the NAND boot
703210284Sjmallett * feature.
704215990Sjmallett *
705210284Sjmallett * @param block  pointer to 256 bytes of data
706210284Sjmallett * @param eccp   pointer to where 8 bytes of ECC data will be stored
707210284Sjmallett */
708210284Sjmallettextern void cvmx_nand_compute_boot_ecc(unsigned char *block, unsigned char *eccp);
709210284Sjmallett
710210284Sjmallett
711210284Sjmallettextern int cvmx_nand_correct_boot_ecc(uint8_t *block);
712210284Sjmallett#ifdef	__cplusplus
713210284Sjmallett}
714210284Sjmallett#endif
715210284Sjmallett
716210284Sjmallett#endif /* __CVMX_NAND_H__ */
717