mtd: nand: Expose data interface for ONFI mode 0
[oweals/u-boot.git] / drivers / mtd / nand / nand_timings.c
1 /*
2  *  Copyright (C) 2014 Free Electrons
3  *
4  *  Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  */
11 #include <common.h>
12 #include <linux/kernel.h>
13 #include <linux/mtd/nand.h>
14
15 static const struct nand_data_interface onfi_sdr_timings[] = {
16         /* Mode 0 */
17         {
18                 .type = NAND_SDR_IFACE,
19                 .timings.sdr = {
20                         .tADL_min = 400000,
21                         .tALH_min = 20000,
22                         .tALS_min = 50000,
23                         .tAR_min = 25000,
24                         .tCEA_max = 100000,
25                         .tCEH_min = 20000,
26                         .tCH_min = 20000,
27                         .tCHZ_max = 100000,
28                         .tCLH_min = 20000,
29                         .tCLR_min = 20000,
30                         .tCLS_min = 50000,
31                         .tCOH_min = 0,
32                         .tCS_min = 70000,
33                         .tDH_min = 20000,
34                         .tDS_min = 40000,
35                         .tFEAT_max = 1000000,
36                         .tIR_min = 10000,
37                         .tITC_max = 1000000,
38                         .tRC_min = 100000,
39                         .tREA_max = 40000,
40                         .tREH_min = 30000,
41                         .tRHOH_min = 0,
42                         .tRHW_min = 200000,
43                         .tRHZ_max = 200000,
44                         .tRLOH_min = 0,
45                         .tRP_min = 50000,
46                         .tRR_min = 40000,
47                         .tRST_max = 250000000000ULL,
48                         .tWB_max = 200000,
49                         .tWC_min = 100000,
50                         .tWH_min = 30000,
51                         .tWHR_min = 120000,
52                         .tWP_min = 50000,
53                         .tWW_min = 100000,
54                 },
55         },
56         /* Mode 1 */
57         {
58                 .type = NAND_SDR_IFACE,
59                 .timings.sdr = {
60                         .tADL_min = 400000,
61                         .tALH_min = 10000,
62                         .tALS_min = 25000,
63                         .tAR_min = 10000,
64                         .tCEA_max = 45000,
65                         .tCEH_min = 20000,
66                         .tCH_min = 10000,
67                         .tCHZ_max = 50000,
68                         .tCLH_min = 10000,
69                         .tCLR_min = 10000,
70                         .tCLS_min = 25000,
71                         .tCOH_min = 15000,
72                         .tCS_min = 35000,
73                         .tDH_min = 10000,
74                         .tDS_min = 20000,
75                         .tFEAT_max = 1000000,
76                         .tIR_min = 0,
77                         .tITC_max = 1000000,
78                         .tRC_min = 50000,
79                         .tREA_max = 30000,
80                         .tREH_min = 15000,
81                         .tRHOH_min = 15000,
82                         .tRHW_min = 100000,
83                         .tRHZ_max = 100000,
84                         .tRLOH_min = 0,
85                         .tRP_min = 25000,
86                         .tRR_min = 20000,
87                         .tRST_max = 500000000,
88                         .tWB_max = 100000,
89                         .tWC_min = 45000,
90                         .tWH_min = 15000,
91                         .tWHR_min = 80000,
92                         .tWP_min = 25000,
93                         .tWW_min = 100000,
94                 },
95         },
96         /* Mode 2 */
97         {
98                 .type = NAND_SDR_IFACE,
99                 .timings.sdr = {
100                         .tADL_min = 400000,
101                         .tALH_min = 10000,
102                         .tALS_min = 15000,
103                         .tAR_min = 10000,
104                         .tCEA_max = 30000,
105                         .tCEH_min = 20000,
106                         .tCH_min = 10000,
107                         .tCHZ_max = 50000,
108                         .tCLH_min = 10000,
109                         .tCLR_min = 10000,
110                         .tCLS_min = 15000,
111                         .tCOH_min = 15000,
112                         .tCS_min = 25000,
113                         .tDH_min = 5000,
114                         .tDS_min = 15000,
115                         .tFEAT_max = 1000000,
116                         .tIR_min = 0,
117                         .tITC_max = 1000000,
118                         .tRC_min = 35000,
119                         .tREA_max = 25000,
120                         .tREH_min = 15000,
121                         .tRHOH_min = 15000,
122                         .tRHW_min = 100000,
123                         .tRHZ_max = 100000,
124                         .tRLOH_min = 0,
125                         .tRR_min = 20000,
126                         .tRST_max = 500000000,
127                         .tWB_max = 100000,
128                         .tRP_min = 17000,
129                         .tWC_min = 35000,
130                         .tWH_min = 15000,
131                         .tWHR_min = 80000,
132                         .tWP_min = 17000,
133                         .tWW_min = 100000,
134                 },
135         },
136         /* Mode 3 */
137         {
138                 .type = NAND_SDR_IFACE,
139                 .timings.sdr = {
140                         .tADL_min = 400000,
141                         .tALH_min = 5000,
142                         .tALS_min = 10000,
143                         .tAR_min = 10000,
144                         .tCEA_max = 25000,
145                         .tCEH_min = 20000,
146                         .tCH_min = 5000,
147                         .tCHZ_max = 50000,
148                         .tCLH_min = 5000,
149                         .tCLR_min = 10000,
150                         .tCLS_min = 10000,
151                         .tCOH_min = 15000,
152                         .tCS_min = 25000,
153                         .tDH_min = 5000,
154                         .tDS_min = 10000,
155                         .tFEAT_max = 1000000,
156                         .tIR_min = 0,
157                         .tITC_max = 1000000,
158                         .tRC_min = 30000,
159                         .tREA_max = 20000,
160                         .tREH_min = 10000,
161                         .tRHOH_min = 15000,
162                         .tRHW_min = 100000,
163                         .tRHZ_max = 100000,
164                         .tRLOH_min = 0,
165                         .tRP_min = 15000,
166                         .tRR_min = 20000,
167                         .tRST_max = 500000000,
168                         .tWB_max = 100000,
169                         .tWC_min = 30000,
170                         .tWH_min = 10000,
171                         .tWHR_min = 80000,
172                         .tWP_min = 15000,
173                         .tWW_min = 100000,
174                 },
175         },
176         /* Mode 4 */
177         {
178                 .type = NAND_SDR_IFACE,
179                 .timings.sdr = {
180                         .tADL_min = 400000,
181                         .tALH_min = 5000,
182                         .tALS_min = 10000,
183                         .tAR_min = 10000,
184                         .tCEA_max = 25000,
185                         .tCEH_min = 20000,
186                         .tCH_min = 5000,
187                         .tCHZ_max = 30000,
188                         .tCLH_min = 5000,
189                         .tCLR_min = 10000,
190                         .tCLS_min = 10000,
191                         .tCOH_min = 15000,
192                         .tCS_min = 20000,
193                         .tDH_min = 5000,
194                         .tDS_min = 10000,
195                         .tFEAT_max = 1000000,
196                         .tIR_min = 0,
197                         .tITC_max = 1000000,
198                         .tRC_min = 25000,
199                         .tREA_max = 20000,
200                         .tREH_min = 10000,
201                         .tRHOH_min = 15000,
202                         .tRHW_min = 100000,
203                         .tRHZ_max = 100000,
204                         .tRLOH_min = 5000,
205                         .tRP_min = 12000,
206                         .tRR_min = 20000,
207                         .tRST_max = 500000000,
208                         .tWB_max = 100000,
209                         .tWC_min = 25000,
210                         .tWH_min = 10000,
211                         .tWHR_min = 80000,
212                         .tWP_min = 12000,
213                         .tWW_min = 100000,
214                 },
215         },
216         /* Mode 5 */
217         {
218                 .type = NAND_SDR_IFACE,
219                 .timings.sdr = {
220                         .tADL_min = 400000,
221                         .tALH_min = 5000,
222                         .tALS_min = 10000,
223                         .tAR_min = 10000,
224                         .tCEA_max = 25000,
225                         .tCEH_min = 20000,
226                         .tCH_min = 5000,
227                         .tCHZ_max = 30000,
228                         .tCLH_min = 5000,
229                         .tCLR_min = 10000,
230                         .tCLS_min = 10000,
231                         .tCOH_min = 15000,
232                         .tCS_min = 15000,
233                         .tDH_min = 5000,
234                         .tDS_min = 7000,
235                         .tFEAT_max = 1000000,
236                         .tIR_min = 0,
237                         .tITC_max = 1000000,
238                         .tRC_min = 20000,
239                         .tREA_max = 16000,
240                         .tREH_min = 7000,
241                         .tRHOH_min = 15000,
242                         .tRHW_min = 100000,
243                         .tRHZ_max = 100000,
244                         .tRLOH_min = 5000,
245                         .tRP_min = 10000,
246                         .tRR_min = 20000,
247                         .tRST_max = 500000000,
248                         .tWB_max = 100000,
249                         .tWC_min = 20000,
250                         .tWH_min = 7000,
251                         .tWHR_min = 80000,
252                         .tWP_min = 10000,
253                         .tWW_min = 100000,
254                 },
255         },
256 };
257
258 /**
259  * onfi_async_timing_mode_to_sdr_timings - [NAND Interface] Retrieve NAND
260  * timings according to the given ONFI timing mode
261  * @mode: ONFI timing mode
262  */
263 const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode)
264 {
265         if (mode < 0 || mode >= ARRAY_SIZE(onfi_sdr_timings))
266                 return ERR_PTR(-EINVAL);
267
268         return &onfi_sdr_timings[mode].timings.sdr;
269 }
270 EXPORT_SYMBOL(onfi_async_timing_mode_to_sdr_timings);
271
272 /**
273  * onfi_init_data_interface - [NAND Interface] Initialize a data interface from
274  * given ONFI mode
275  * @iface: The data interface to be initialized
276  * @mode: The ONFI timing mode
277  */
278 int onfi_init_data_interface(struct nand_chip *chip,
279                              struct nand_data_interface *iface,
280                              enum nand_data_interface_type type,
281                              int timing_mode)
282 {
283         if (type != NAND_SDR_IFACE)
284                 return -EINVAL;
285
286         if (timing_mode < 0 || timing_mode >= ARRAY_SIZE(onfi_sdr_timings))
287                 return -EINVAL;
288
289         *iface = onfi_sdr_timings[timing_mode];
290
291         /*
292          * TODO: initialize timings that cannot be deduced from timing mode:
293          * tR, tPROG, tCCS, ...
294          * These information are part of the ONFI parameter page.
295          */
296
297         return 0;
298 }
299 EXPORT_SYMBOL(onfi_init_data_interface);
300
301 /**
302  * nand_get_default_data_interface - [NAND Interface] Retrieve NAND
303  * data interface for mode 0. This is used as default timing after
304  * reset.
305  */
306 const struct nand_data_interface *nand_get_default_data_interface(void)
307 {
308         return &onfi_sdr_timings[0];
309 }
310 EXPORT_SYMBOL(nand_get_default_data_interface);