diff options
Diffstat (limited to 'drivers/mtd/nand/gpmi-nand/gpmi-nand.h')
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h new file mode 100644 index 000000000000..e023bccb7781 --- /dev/null +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * Freescale GPMI NAND Flash Driver | ||
3 | * | ||
4 | * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. | ||
5 | * Copyright (C) 2008 Embedded Alley Solutions, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | #ifndef __DRIVERS_MTD_NAND_GPMI_NAND_H | ||
18 | #define __DRIVERS_MTD_NAND_GPMI_NAND_H | ||
19 | |||
20 | #include <linux/mtd/nand.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/dma-mapping.h> | ||
23 | #include <mach/dma.h> | ||
24 | |||
25 | struct resources { | ||
26 | void *gpmi_regs; | ||
27 | void *bch_regs; | ||
28 | unsigned int bch_low_interrupt; | ||
29 | unsigned int bch_high_interrupt; | ||
30 | unsigned int dma_low_channel; | ||
31 | unsigned int dma_high_channel; | ||
32 | struct clk *clock; | ||
33 | }; | ||
34 | |||
35 | /** | ||
36 | * struct bch_geometry - BCH geometry description. | ||
37 | * @gf_len: The length of Galois Field. (e.g., 13 or 14) | ||
38 | * @ecc_strength: A number that describes the strength of the ECC | ||
39 | * algorithm. | ||
40 | * @page_size: The size, in bytes, of a physical page, including | ||
41 | * both data and OOB. | ||
42 | * @metadata_size: The size, in bytes, of the metadata. | ||
43 | * @ecc_chunk_size: The size, in bytes, of a single ECC chunk. Note | ||
44 | * the first chunk in the page includes both data and | ||
45 | * metadata, so it's a bit larger than this value. | ||
46 | * @ecc_chunk_count: The number of ECC chunks in the page, | ||
47 | * @payload_size: The size, in bytes, of the payload buffer. | ||
48 | * @auxiliary_size: The size, in bytes, of the auxiliary buffer. | ||
49 | * @auxiliary_status_offset: The offset into the auxiliary buffer at which | ||
50 | * the ECC status appears. | ||
51 | * @block_mark_byte_offset: The byte offset in the ECC-based page view at | ||
52 | * which the underlying physical block mark appears. | ||
53 | * @block_mark_bit_offset: The bit offset into the ECC-based page view at | ||
54 | * which the underlying physical block mark appears. | ||
55 | */ | ||
56 | struct bch_geometry { | ||
57 | unsigned int gf_len; | ||
58 | unsigned int ecc_strength; | ||
59 | unsigned int page_size; | ||
60 | unsigned int metadata_size; | ||
61 | unsigned int ecc_chunk_size; | ||
62 | unsigned int ecc_chunk_count; | ||
63 | unsigned int payload_size; | ||
64 | unsigned int auxiliary_size; | ||
65 | unsigned int auxiliary_status_offset; | ||
66 | unsigned int block_mark_byte_offset; | ||
67 | unsigned int block_mark_bit_offset; | ||
68 | }; | ||
69 | |||
70 | /** | ||
71 | * struct boot_rom_geometry - Boot ROM geometry description. | ||
72 | * @stride_size_in_pages: The size of a boot block stride, in pages. | ||
73 | * @search_area_stride_exponent: The logarithm to base 2 of the size of a | ||
74 | * search area in boot block strides. | ||
75 | */ | ||
76 | struct boot_rom_geometry { | ||
77 | unsigned int stride_size_in_pages; | ||
78 | unsigned int search_area_stride_exponent; | ||
79 | }; | ||
80 | |||
81 | /* DMA operations types */ | ||
82 | enum dma_ops_type { | ||
83 | DMA_FOR_COMMAND = 1, | ||
84 | DMA_FOR_READ_DATA, | ||
85 | DMA_FOR_WRITE_DATA, | ||
86 | DMA_FOR_READ_ECC_PAGE, | ||
87 | DMA_FOR_WRITE_ECC_PAGE | ||
88 | }; | ||
89 | |||
90 | /** | ||
91 | * struct nand_timing - Fundamental timing attributes for NAND. | ||
92 | * @data_setup_in_ns: The data setup time, in nanoseconds. Usually the | ||
93 | * maximum of tDS and tWP. A negative value | ||
94 | * indicates this characteristic isn't known. | ||
95 | * @data_hold_in_ns: The data hold time, in nanoseconds. Usually the | ||
96 | * maximum of tDH, tWH and tREH. A negative value | ||
97 | * indicates this characteristic isn't known. | ||
98 | * @address_setup_in_ns: The address setup time, in nanoseconds. Usually | ||
99 | * the maximum of tCLS, tCS and tALS. A negative | ||
100 | * value indicates this characteristic isn't known. | ||
101 | * @gpmi_sample_delay_in_ns: A GPMI-specific timing parameter. A negative value | ||
102 | * indicates this characteristic isn't known. | ||
103 | * @tREA_in_ns: tREA, in nanoseconds, from the data sheet. A | ||
104 | * negative value indicates this characteristic isn't | ||
105 | * known. | ||
106 | * @tRLOH_in_ns: tRLOH, in nanoseconds, from the data sheet. A | ||
107 | * negative value indicates this characteristic isn't | ||
108 | * known. | ||
109 | * @tRHOH_in_ns: tRHOH, in nanoseconds, from the data sheet. A | ||
110 | * negative value indicates this characteristic isn't | ||
111 | * known. | ||
112 | */ | ||
113 | struct nand_timing { | ||
114 | int8_t data_setup_in_ns; | ||
115 | int8_t data_hold_in_ns; | ||
116 | int8_t address_setup_in_ns; | ||
117 | int8_t gpmi_sample_delay_in_ns; | ||
118 | int8_t tREA_in_ns; | ||
119 | int8_t tRLOH_in_ns; | ||
120 | int8_t tRHOH_in_ns; | ||
121 | }; | ||
122 | |||
123 | struct gpmi_nand_data { | ||
124 | /* System Interface */ | ||
125 | struct device *dev; | ||
126 | struct platform_device *pdev; | ||
127 | struct gpmi_nand_platform_data *pdata; | ||
128 | |||
129 | /* Resources */ | ||
130 | struct resources resources; | ||
131 | |||
132 | /* Flash Hardware */ | ||
133 | struct nand_timing timing; | ||
134 | |||
135 | /* BCH */ | ||
136 | struct bch_geometry bch_geometry; | ||
137 | struct completion bch_done; | ||
138 | |||
139 | /* NAND Boot issue */ | ||
140 | bool swap_block_mark; | ||
141 | struct boot_rom_geometry rom_geometry; | ||
142 | |||
143 | /* MTD / NAND */ | ||
144 | struct nand_chip nand; | ||
145 | struct mtd_info mtd; | ||
146 | |||
147 | /* General-use Variables */ | ||
148 | int current_chip; | ||
149 | unsigned int command_length; | ||
150 | |||
151 | /* passed from upper layer */ | ||
152 | uint8_t *upper_buf; | ||
153 | int upper_len; | ||
154 | |||
155 | /* for DMA operations */ | ||
156 | bool direct_dma_map_ok; | ||
157 | |||
158 | struct scatterlist cmd_sgl; | ||
159 | char *cmd_buffer; | ||
160 | |||
161 | struct scatterlist data_sgl; | ||
162 | char *data_buffer_dma; | ||
163 | |||
164 | void *page_buffer_virt; | ||
165 | dma_addr_t page_buffer_phys; | ||
166 | unsigned int page_buffer_size; | ||
167 | |||
168 | void *payload_virt; | ||
169 | dma_addr_t payload_phys; | ||
170 | |||
171 | void *auxiliary_virt; | ||
172 | dma_addr_t auxiliary_phys; | ||
173 | |||
174 | /* DMA channels */ | ||
175 | #define DMA_CHANS 8 | ||
176 | struct dma_chan *dma_chans[DMA_CHANS]; | ||
177 | struct mxs_dma_data dma_data; | ||
178 | enum dma_ops_type last_dma_type; | ||
179 | enum dma_ops_type dma_type; | ||
180 | struct completion dma_done; | ||
181 | |||
182 | /* private */ | ||
183 | void *private; | ||
184 | }; | ||
185 | |||
186 | /** | ||
187 | * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters. | ||
188 | * @data_setup_in_cycles: The data setup time, in cycles. | ||
189 | * @data_hold_in_cycles: The data hold time, in cycles. | ||
190 | * @address_setup_in_cycles: The address setup time, in cycles. | ||
191 | * @use_half_periods: Indicates the clock is running slowly, so the | ||
192 | * NFC DLL should use half-periods. | ||
193 | * @sample_delay_factor: The sample delay factor. | ||
194 | */ | ||
195 | struct gpmi_nfc_hardware_timing { | ||
196 | uint8_t data_setup_in_cycles; | ||
197 | uint8_t data_hold_in_cycles; | ||
198 | uint8_t address_setup_in_cycles; | ||
199 | bool use_half_periods; | ||
200 | uint8_t sample_delay_factor; | ||
201 | }; | ||
202 | |||
203 | /** | ||
204 | * struct timing_threshod - Timing threshold | ||
205 | * @max_data_setup_cycles: The maximum number of data setup cycles that | ||
206 | * can be expressed in the hardware. | ||
207 | * @internal_data_setup_in_ns: The time, in ns, that the NFC hardware requires | ||
208 | * for data read internal setup. In the Reference | ||
209 | * Manual, see the chapter "High-Speed NAND | ||
210 | * Timing" for more details. | ||
211 | * @max_sample_delay_factor: The maximum sample delay factor that can be | ||
212 | * expressed in the hardware. | ||
213 | * @max_dll_clock_period_in_ns: The maximum period of the GPMI clock that the | ||
214 | * sample delay DLL hardware can possibly work | ||
215 | * with (the DLL is unusable with longer periods). | ||
216 | * If the full-cycle period is greater than HALF | ||
217 | * this value, the DLL must be configured to use | ||
218 | * half-periods. | ||
219 | * @max_dll_delay_in_ns: The maximum amount of delay, in ns, that the | ||
220 | * DLL can implement. | ||
221 | * @clock_frequency_in_hz: The clock frequency, in Hz, during the current | ||
222 | * I/O transaction. If no I/O transaction is in | ||
223 | * progress, this is the clock frequency during | ||
224 | * the most recent I/O transaction. | ||
225 | */ | ||
226 | struct timing_threshod { | ||
227 | const unsigned int max_chip_count; | ||
228 | const unsigned int max_data_setup_cycles; | ||
229 | const unsigned int internal_data_setup_in_ns; | ||
230 | const unsigned int max_sample_delay_factor; | ||
231 | const unsigned int max_dll_clock_period_in_ns; | ||
232 | const unsigned int max_dll_delay_in_ns; | ||
233 | unsigned long clock_frequency_in_hz; | ||
234 | |||
235 | }; | ||
236 | |||
237 | /* Common Services */ | ||
238 | extern int common_nfc_set_geometry(struct gpmi_nand_data *); | ||
239 | extern struct dma_chan *get_dma_chan(struct gpmi_nand_data *); | ||
240 | extern void prepare_data_dma(struct gpmi_nand_data *, | ||
241 | enum dma_data_direction dr); | ||
242 | extern int start_dma_without_bch_irq(struct gpmi_nand_data *, | ||
243 | struct dma_async_tx_descriptor *); | ||
244 | extern int start_dma_with_bch_irq(struct gpmi_nand_data *, | ||
245 | struct dma_async_tx_descriptor *); | ||
246 | |||
247 | /* GPMI-NAND helper function library */ | ||
248 | extern int gpmi_init(struct gpmi_nand_data *); | ||
249 | extern void gpmi_clear_bch(struct gpmi_nand_data *); | ||
250 | extern void gpmi_dump_info(struct gpmi_nand_data *); | ||
251 | extern int bch_set_geometry(struct gpmi_nand_data *); | ||
252 | extern int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip); | ||
253 | extern int gpmi_send_command(struct gpmi_nand_data *); | ||
254 | extern void gpmi_begin(struct gpmi_nand_data *); | ||
255 | extern void gpmi_end(struct gpmi_nand_data *); | ||
256 | extern int gpmi_read_data(struct gpmi_nand_data *); | ||
257 | extern int gpmi_send_data(struct gpmi_nand_data *); | ||
258 | extern int gpmi_send_page(struct gpmi_nand_data *, | ||
259 | dma_addr_t payload, dma_addr_t auxiliary); | ||
260 | extern int gpmi_read_page(struct gpmi_nand_data *, | ||
261 | dma_addr_t payload, dma_addr_t auxiliary); | ||
262 | |||
263 | /* BCH : Status Block Completion Codes */ | ||
264 | #define STATUS_GOOD 0x00 | ||
265 | #define STATUS_ERASED 0xff | ||
266 | #define STATUS_UNCORRECTABLE 0xfe | ||
267 | |||
268 | /* Use the platform_id to distinguish different Archs. */ | ||
269 | #define IS_MX23 0x1 | ||
270 | #define IS_MX28 0x2 | ||
271 | #define GPMI_IS_MX23(x) ((x)->pdev->id_entry->driver_data == IS_MX23) | ||
272 | #define GPMI_IS_MX28(x) ((x)->pdev->id_entry->driver_data == IS_MX28) | ||
273 | #endif | ||