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