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