Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux-2.6-microblaze.git] / drivers / mtd / nand / raw / nand_timings.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  Copyright (C) 2014 Free Electrons
4  *
5  *  Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
6  */
7 #include <linux/kernel.h>
8 #include <linux/err.h>
9 #include <linux/export.h>
10
11 #include "internals.h"
12
13 #define ONFI_DYN_TIMING_MAX U16_MAX
14
15 /*
16  * For non-ONFI chips we use the highest possible value for tPROG and tBERS.
17  * tR and tCCS will take the default values precised in the ONFI specification
18  * for timing mode 0, respectively 200us and 500ns.
19  *
20  * These four values are tweaked to be more accurate in the case of ONFI chips.
21  */
22 static const struct nand_interface_config onfi_sdr_timings[] = {
23         /* Mode 0 */
24         {
25                 .type = NAND_SDR_IFACE,
26                 .timings.mode = 0,
27                 .timings.sdr = {
28                         .tCCS_min = 500000,
29                         .tR_max = 200000000,
30                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
31                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
32                         .tADL_min = 400000,
33                         .tALH_min = 20000,
34                         .tALS_min = 50000,
35                         .tAR_min = 25000,
36                         .tCEA_max = 100000,
37                         .tCEH_min = 20000,
38                         .tCH_min = 20000,
39                         .tCHZ_max = 100000,
40                         .tCLH_min = 20000,
41                         .tCLR_min = 20000,
42                         .tCLS_min = 50000,
43                         .tCOH_min = 0,
44                         .tCS_min = 70000,
45                         .tDH_min = 20000,
46                         .tDS_min = 40000,
47                         .tFEAT_max = 1000000,
48                         .tIR_min = 10000,
49                         .tITC_max = 1000000,
50                         .tRC_min = 100000,
51                         .tREA_max = 40000,
52                         .tREH_min = 30000,
53                         .tRHOH_min = 0,
54                         .tRHW_min = 200000,
55                         .tRHZ_max = 200000,
56                         .tRLOH_min = 0,
57                         .tRP_min = 50000,
58                         .tRR_min = 40000,
59                         .tRST_max = 250000000000ULL,
60                         .tWB_max = 200000,
61                         .tWC_min = 100000,
62                         .tWH_min = 30000,
63                         .tWHR_min = 120000,
64                         .tWP_min = 50000,
65                         .tWW_min = 100000,
66                 },
67         },
68         /* Mode 1 */
69         {
70                 .type = NAND_SDR_IFACE,
71                 .timings.mode = 1,
72                 .timings.sdr = {
73                         .tCCS_min = 500000,
74                         .tR_max = 200000000,
75                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
76                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
77                         .tADL_min = 400000,
78                         .tALH_min = 10000,
79                         .tALS_min = 25000,
80                         .tAR_min = 10000,
81                         .tCEA_max = 45000,
82                         .tCEH_min = 20000,
83                         .tCH_min = 10000,
84                         .tCHZ_max = 50000,
85                         .tCLH_min = 10000,
86                         .tCLR_min = 10000,
87                         .tCLS_min = 25000,
88                         .tCOH_min = 15000,
89                         .tCS_min = 35000,
90                         .tDH_min = 10000,
91                         .tDS_min = 20000,
92                         .tFEAT_max = 1000000,
93                         .tIR_min = 0,
94                         .tITC_max = 1000000,
95                         .tRC_min = 50000,
96                         .tREA_max = 30000,
97                         .tREH_min = 15000,
98                         .tRHOH_min = 15000,
99                         .tRHW_min = 100000,
100                         .tRHZ_max = 100000,
101                         .tRLOH_min = 0,
102                         .tRP_min = 25000,
103                         .tRR_min = 20000,
104                         .tRST_max = 500000000,
105                         .tWB_max = 100000,
106                         .tWC_min = 45000,
107                         .tWH_min = 15000,
108                         .tWHR_min = 80000,
109                         .tWP_min = 25000,
110                         .tWW_min = 100000,
111                 },
112         },
113         /* Mode 2 */
114         {
115                 .type = NAND_SDR_IFACE,
116                 .timings.mode = 2,
117                 .timings.sdr = {
118                         .tCCS_min = 500000,
119                         .tR_max = 200000000,
120                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
121                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
122                         .tADL_min = 400000,
123                         .tALH_min = 10000,
124                         .tALS_min = 15000,
125                         .tAR_min = 10000,
126                         .tCEA_max = 30000,
127                         .tCEH_min = 20000,
128                         .tCH_min = 10000,
129                         .tCHZ_max = 50000,
130                         .tCLH_min = 10000,
131                         .tCLR_min = 10000,
132                         .tCLS_min = 15000,
133                         .tCOH_min = 15000,
134                         .tCS_min = 25000,
135                         .tDH_min = 5000,
136                         .tDS_min = 15000,
137                         .tFEAT_max = 1000000,
138                         .tIR_min = 0,
139                         .tITC_max = 1000000,
140                         .tRC_min = 35000,
141                         .tREA_max = 25000,
142                         .tREH_min = 15000,
143                         .tRHOH_min = 15000,
144                         .tRHW_min = 100000,
145                         .tRHZ_max = 100000,
146                         .tRLOH_min = 0,
147                         .tRR_min = 20000,
148                         .tRST_max = 500000000,
149                         .tWB_max = 100000,
150                         .tRP_min = 17000,
151                         .tWC_min = 35000,
152                         .tWH_min = 15000,
153                         .tWHR_min = 80000,
154                         .tWP_min = 17000,
155                         .tWW_min = 100000,
156                 },
157         },
158         /* Mode 3 */
159         {
160                 .type = NAND_SDR_IFACE,
161                 .timings.mode = 3,
162                 .timings.sdr = {
163                         .tCCS_min = 500000,
164                         .tR_max = 200000000,
165                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
166                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
167                         .tADL_min = 400000,
168                         .tALH_min = 5000,
169                         .tALS_min = 10000,
170                         .tAR_min = 10000,
171                         .tCEA_max = 25000,
172                         .tCEH_min = 20000,
173                         .tCH_min = 5000,
174                         .tCHZ_max = 50000,
175                         .tCLH_min = 5000,
176                         .tCLR_min = 10000,
177                         .tCLS_min = 10000,
178                         .tCOH_min = 15000,
179                         .tCS_min = 25000,
180                         .tDH_min = 5000,
181                         .tDS_min = 10000,
182                         .tFEAT_max = 1000000,
183                         .tIR_min = 0,
184                         .tITC_max = 1000000,
185                         .tRC_min = 30000,
186                         .tREA_max = 20000,
187                         .tREH_min = 10000,
188                         .tRHOH_min = 15000,
189                         .tRHW_min = 100000,
190                         .tRHZ_max = 100000,
191                         .tRLOH_min = 0,
192                         .tRP_min = 15000,
193                         .tRR_min = 20000,
194                         .tRST_max = 500000000,
195                         .tWB_max = 100000,
196                         .tWC_min = 30000,
197                         .tWH_min = 10000,
198                         .tWHR_min = 80000,
199                         .tWP_min = 15000,
200                         .tWW_min = 100000,
201                 },
202         },
203         /* Mode 4 */
204         {
205                 .type = NAND_SDR_IFACE,
206                 .timings.mode = 4,
207                 .timings.sdr = {
208                         .tCCS_min = 500000,
209                         .tR_max = 200000000,
210                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
211                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
212                         .tADL_min = 400000,
213                         .tALH_min = 5000,
214                         .tALS_min = 10000,
215                         .tAR_min = 10000,
216                         .tCEA_max = 25000,
217                         .tCEH_min = 20000,
218                         .tCH_min = 5000,
219                         .tCHZ_max = 30000,
220                         .tCLH_min = 5000,
221                         .tCLR_min = 10000,
222                         .tCLS_min = 10000,
223                         .tCOH_min = 15000,
224                         .tCS_min = 20000,
225                         .tDH_min = 5000,
226                         .tDS_min = 10000,
227                         .tFEAT_max = 1000000,
228                         .tIR_min = 0,
229                         .tITC_max = 1000000,
230                         .tRC_min = 25000,
231                         .tREA_max = 20000,
232                         .tREH_min = 10000,
233                         .tRHOH_min = 15000,
234                         .tRHW_min = 100000,
235                         .tRHZ_max = 100000,
236                         .tRLOH_min = 5000,
237                         .tRP_min = 12000,
238                         .tRR_min = 20000,
239                         .tRST_max = 500000000,
240                         .tWB_max = 100000,
241                         .tWC_min = 25000,
242                         .tWH_min = 10000,
243                         .tWHR_min = 80000,
244                         .tWP_min = 12000,
245                         .tWW_min = 100000,
246                 },
247         },
248         /* Mode 5 */
249         {
250                 .type = NAND_SDR_IFACE,
251                 .timings.mode = 5,
252                 .timings.sdr = {
253                         .tCCS_min = 500000,
254                         .tR_max = 200000000,
255                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
256                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
257                         .tADL_min = 400000,
258                         .tALH_min = 5000,
259                         .tALS_min = 10000,
260                         .tAR_min = 10000,
261                         .tCEA_max = 25000,
262                         .tCEH_min = 20000,
263                         .tCH_min = 5000,
264                         .tCHZ_max = 30000,
265                         .tCLH_min = 5000,
266                         .tCLR_min = 10000,
267                         .tCLS_min = 10000,
268                         .tCOH_min = 15000,
269                         .tCS_min = 15000,
270                         .tDH_min = 5000,
271                         .tDS_min = 7000,
272                         .tFEAT_max = 1000000,
273                         .tIR_min = 0,
274                         .tITC_max = 1000000,
275                         .tRC_min = 20000,
276                         .tREA_max = 16000,
277                         .tREH_min = 7000,
278                         .tRHOH_min = 15000,
279                         .tRHW_min = 100000,
280                         .tRHZ_max = 100000,
281                         .tRLOH_min = 5000,
282                         .tRP_min = 10000,
283                         .tRR_min = 20000,
284                         .tRST_max = 500000000,
285                         .tWB_max = 100000,
286                         .tWC_min = 20000,
287                         .tWH_min = 7000,
288                         .tWHR_min = 80000,
289                         .tWP_min = 10000,
290                         .tWW_min = 100000,
291                 },
292         },
293 };
294
295 static const struct nand_interface_config onfi_nvddr_timings[] = {
296         /* Mode 0 */
297         {
298                 .type = NAND_NVDDR_IFACE,
299                 .timings.mode = 0,
300                 .timings.nvddr = {
301                         .tCCS_min = 500000,
302                         .tR_max = 200000000,
303                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
304                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
305                         .tAC_min = 3000,
306                         .tAC_max = 25000,
307                         .tADL_min = 400000,
308                         .tCAD_min = 45000,
309                         .tCAH_min = 10000,
310                         .tCALH_min = 10000,
311                         .tCALS_min = 10000,
312                         .tCAS_min = 10000,
313                         .tCEH_min = 20000,
314                         .tCH_min = 10000,
315                         .tCK_min = 50000,
316                         .tCS_min = 35000,
317                         .tDH_min = 5000,
318                         .tDQSCK_min = 3000,
319                         .tDQSCK_max = 25000,
320                         .tDQSD_min = 0,
321                         .tDQSD_max = 18000,
322                         .tDQSHZ_max = 20000,
323                         .tDQSQ_max = 5000,
324                         .tDS_min = 5000,
325                         .tDSC_min = 50000,
326                         .tFEAT_max = 1000000,
327                         .tITC_max = 1000000,
328                         .tQHS_max = 6000,
329                         .tRHW_min = 100000,
330                         .tRR_min = 20000,
331                         .tRST_max = 500000000,
332                         .tWB_max = 100000,
333                         .tWHR_min = 80000,
334                         .tWRCK_min = 20000,
335                         .tWW_min = 100000,
336                 },
337         },
338         /* Mode 1 */
339         {
340                 .type = NAND_NVDDR_IFACE,
341                 .timings.mode = 1,
342                 .timings.nvddr = {
343                         .tCCS_min = 500000,
344                         .tR_max = 200000000,
345                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
346                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
347                         .tAC_min = 3000,
348                         .tAC_max = 25000,
349                         .tADL_min = 400000,
350                         .tCAD_min = 45000,
351                         .tCAH_min = 5000,
352                         .tCALH_min = 5000,
353                         .tCALS_min = 5000,
354                         .tCAS_min = 5000,
355                         .tCEH_min = 20000,
356                         .tCH_min = 5000,
357                         .tCK_min = 30000,
358                         .tCS_min = 25000,
359                         .tDH_min = 2500,
360                         .tDQSCK_min = 3000,
361                         .tDQSCK_max = 25000,
362                         .tDQSD_min = 0,
363                         .tDQSD_max = 18000,
364                         .tDQSHZ_max = 20000,
365                         .tDQSQ_max = 2500,
366                         .tDS_min = 3000,
367                         .tDSC_min = 30000,
368                         .tFEAT_max = 1000000,
369                         .tITC_max = 1000000,
370                         .tQHS_max = 3000,
371                         .tRHW_min = 100000,
372                         .tRR_min = 20000,
373                         .tRST_max = 500000000,
374                         .tWB_max = 100000,
375                         .tWHR_min = 80000,
376                         .tWRCK_min = 20000,
377                         .tWW_min = 100000,
378                 },
379         },
380         /* Mode 2 */
381         {
382                 .type = NAND_NVDDR_IFACE,
383                 .timings.mode = 2,
384                 .timings.nvddr = {
385                         .tCCS_min = 500000,
386                         .tR_max = 200000000,
387                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
388                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
389                         .tAC_min = 3000,
390                         .tAC_max = 25000,
391                         .tADL_min = 400000,
392                         .tCAD_min = 45000,
393                         .tCAH_min = 4000,
394                         .tCALH_min = 4000,
395                         .tCALS_min = 4000,
396                         .tCAS_min = 4000,
397                         .tCEH_min = 20000,
398                         .tCH_min = 4000,
399                         .tCK_min = 20000,
400                         .tCS_min = 15000,
401                         .tDH_min = 1700,
402                         .tDQSCK_min = 3000,
403                         .tDQSCK_max = 25000,
404                         .tDQSD_min = 0,
405                         .tDQSD_max = 18000,
406                         .tDQSHZ_max = 20000,
407                         .tDQSQ_max = 1700,
408                         .tDS_min = 2000,
409                         .tDSC_min = 20000,
410                         .tFEAT_max = 1000000,
411                         .tITC_max = 1000000,
412                         .tQHS_max = 2000,
413                         .tRHW_min = 100000,
414                         .tRR_min = 20000,
415                         .tRST_max = 500000000,
416                         .tWB_max = 100000,
417                         .tWHR_min = 80000,
418                         .tWRCK_min = 20000,
419                         .tWW_min = 100000,
420                 },
421         },
422         /* Mode 3 */
423         {
424                 .type = NAND_NVDDR_IFACE,
425                 .timings.mode = 3,
426                 .timings.nvddr = {
427                         .tCCS_min = 500000,
428                         .tR_max = 200000000,
429                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
430                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
431                         .tAC_min = 3000,
432                         .tAC_max = 25000,
433                         .tADL_min = 400000,
434                         .tCAD_min = 45000,
435                         .tCAH_min = 3000,
436                         .tCALH_min = 3000,
437                         .tCALS_min = 3000,
438                         .tCAS_min = 3000,
439                         .tCEH_min = 20000,
440                         .tCH_min = 3000,
441                         .tCK_min = 15000,
442                         .tCS_min = 15000,
443                         .tDH_min = 1300,
444                         .tDQSCK_min = 3000,
445                         .tDQSCK_max = 25000,
446                         .tDQSD_min = 0,
447                         .tDQSD_max = 18000,
448                         .tDQSHZ_max = 20000,
449                         .tDQSQ_max = 1300,
450                         .tDS_min = 1500,
451                         .tDSC_min = 15000,
452                         .tFEAT_max = 1000000,
453                         .tITC_max = 1000000,
454                         .tQHS_max = 1500,
455                         .tRHW_min = 100000,
456                         .tRR_min = 20000,
457                         .tRST_max = 500000000,
458                         .tWB_max = 100000,
459                         .tWHR_min = 80000,
460                         .tWRCK_min = 20000,
461                         .tWW_min = 100000,
462                 },
463         },
464         /* Mode 4 */
465         {
466                 .type = NAND_NVDDR_IFACE,
467                 .timings.mode = 4,
468                 .timings.nvddr = {
469                         .tCCS_min = 500000,
470                         .tR_max = 200000000,
471                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
472                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
473                         .tAC_min = 3000,
474                         .tAC_max = 25000,
475                         .tADL_min = 400000,
476                         .tCAD_min = 45000,
477                         .tCAH_min = 2500,
478                         .tCALH_min = 2500,
479                         .tCALS_min = 2500,
480                         .tCAS_min = 2500,
481                         .tCEH_min = 20000,
482                         .tCH_min = 2500,
483                         .tCK_min = 12000,
484                         .tCS_min = 15000,
485                         .tDH_min = 1100,
486                         .tDQSCK_min = 3000,
487                         .tDQSCK_max = 25000,
488                         .tDQSD_min = 0,
489                         .tDQSD_max = 18000,
490                         .tDQSHZ_max = 20000,
491                         .tDQSQ_max = 1000,
492                         .tDS_min = 1100,
493                         .tDSC_min = 12000,
494                         .tFEAT_max = 1000000,
495                         .tITC_max = 1000000,
496                         .tQHS_max = 1200,
497                         .tRHW_min = 100000,
498                         .tRR_min = 20000,
499                         .tRST_max = 500000000,
500                         .tWB_max = 100000,
501                         .tWHR_min = 80000,
502                         .tWRCK_min = 20000,
503                         .tWW_min = 100000,
504                 },
505         },
506         /* Mode 5 */
507         {
508                 .type = NAND_NVDDR_IFACE,
509                 .timings.mode = 5,
510                 .timings.nvddr = {
511                         .tCCS_min = 500000,
512                         .tR_max = 200000000,
513                         .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
514                         .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
515                         .tAC_min = 3000,
516                         .tAC_max = 25000,
517                         .tADL_min = 400000,
518                         .tCAD_min = 45000,
519                         .tCAH_min = 2000,
520                         .tCALH_min = 2000,
521                         .tCALS_min = 2000,
522                         .tCAS_min = 2000,
523                         .tCEH_min = 20000,
524                         .tCH_min = 2000,
525                         .tCK_min = 10000,
526                         .tCS_min = 15000,
527                         .tDH_min = 900,
528                         .tDQSCK_min = 3000,
529                         .tDQSCK_max = 25000,
530                         .tDQSD_min = 0,
531                         .tDQSD_max = 18000,
532                         .tDQSHZ_max = 20000,
533                         .tDQSQ_max = 850,
534                         .tDS_min = 900,
535                         .tDSC_min = 10000,
536                         .tFEAT_max = 1000000,
537                         .tITC_max = 1000000,
538                         .tQHS_max = 1000,
539                         .tRHW_min = 100000,
540                         .tRR_min = 20000,
541                         .tRST_max = 500000000,
542                         .tWB_max = 100000,
543                         .tWHR_min = 80000,
544                         .tWRCK_min = 20000,
545                         .tWW_min = 100000,
546                 },
547         },
548 };
549
550 /* All NAND chips share the same reset data interface: SDR mode 0 */
551 const struct nand_interface_config *nand_get_reset_interface_config(void)
552 {
553         return &onfi_sdr_timings[0];
554 }
555
556 /**
557  * onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a
558  *                              set of timings
559  * @spec_timings: the timings to challenge
560  */
561 unsigned int
562 onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings)
563 {
564         const struct nand_sdr_timings *onfi_timings;
565         int mode;
566
567         for (mode = ARRAY_SIZE(onfi_sdr_timings) - 1; mode > 0; mode--) {
568                 onfi_timings = &onfi_sdr_timings[mode].timings.sdr;
569
570                 if (spec_timings->tCCS_min <= onfi_timings->tCCS_min &&
571                     spec_timings->tADL_min <= onfi_timings->tADL_min &&
572                     spec_timings->tALH_min <= onfi_timings->tALH_min &&
573                     spec_timings->tALS_min <= onfi_timings->tALS_min &&
574                     spec_timings->tAR_min <= onfi_timings->tAR_min &&
575                     spec_timings->tCEH_min <= onfi_timings->tCEH_min &&
576                     spec_timings->tCH_min <= onfi_timings->tCH_min &&
577                     spec_timings->tCLH_min <= onfi_timings->tCLH_min &&
578                     spec_timings->tCLR_min <= onfi_timings->tCLR_min &&
579                     spec_timings->tCLS_min <= onfi_timings->tCLS_min &&
580                     spec_timings->tCOH_min <= onfi_timings->tCOH_min &&
581                     spec_timings->tCS_min <= onfi_timings->tCS_min &&
582                     spec_timings->tDH_min <= onfi_timings->tDH_min &&
583                     spec_timings->tDS_min <= onfi_timings->tDS_min &&
584                     spec_timings->tIR_min <= onfi_timings->tIR_min &&
585                     spec_timings->tRC_min <= onfi_timings->tRC_min &&
586                     spec_timings->tREH_min <= onfi_timings->tREH_min &&
587                     spec_timings->tRHOH_min <= onfi_timings->tRHOH_min &&
588                     spec_timings->tRHW_min <= onfi_timings->tRHW_min &&
589                     spec_timings->tRLOH_min <= onfi_timings->tRLOH_min &&
590                     spec_timings->tRP_min <= onfi_timings->tRP_min &&
591                     spec_timings->tRR_min <= onfi_timings->tRR_min &&
592                     spec_timings->tWC_min <= onfi_timings->tWC_min &&
593                     spec_timings->tWH_min <= onfi_timings->tWH_min &&
594                     spec_timings->tWHR_min <= onfi_timings->tWHR_min &&
595                     spec_timings->tWP_min <= onfi_timings->tWP_min &&
596                     spec_timings->tWW_min <= onfi_timings->tWW_min)
597                         return mode;
598         }
599
600         return 0;
601 }
602
603 /**
604  * onfi_find_closest_nvddr_mode - Derive the closest ONFI NVDDR timing mode
605  *                                given a set of timings
606  * @spec_timings: the timings to challenge
607  */
608 unsigned int
609 onfi_find_closest_nvddr_mode(const struct nand_nvddr_timings *spec_timings)
610 {
611         const struct nand_nvddr_timings *onfi_timings;
612         int mode;
613
614         for (mode = ARRAY_SIZE(onfi_nvddr_timings) - 1; mode > 0; mode--) {
615                 onfi_timings = &onfi_nvddr_timings[mode].timings.nvddr;
616
617                 if (spec_timings->tCCS_min <= onfi_timings->tCCS_min &&
618                     spec_timings->tAC_min <= onfi_timings->tAC_min &&
619                     spec_timings->tADL_min <= onfi_timings->tADL_min &&
620                     spec_timings->tCAD_min <= onfi_timings->tCAD_min &&
621                     spec_timings->tCAH_min <= onfi_timings->tCAH_min &&
622                     spec_timings->tCALH_min <= onfi_timings->tCALH_min &&
623                     spec_timings->tCALS_min <= onfi_timings->tCALS_min &&
624                     spec_timings->tCAS_min <= onfi_timings->tCAS_min &&
625                     spec_timings->tCEH_min <= onfi_timings->tCEH_min &&
626                     spec_timings->tCH_min <= onfi_timings->tCH_min &&
627                     spec_timings->tCK_min <= onfi_timings->tCK_min &&
628                     spec_timings->tCS_min <= onfi_timings->tCS_min &&
629                     spec_timings->tDH_min <= onfi_timings->tDH_min &&
630                     spec_timings->tDQSCK_min <= onfi_timings->tDQSCK_min &&
631                     spec_timings->tDQSD_min <= onfi_timings->tDQSD_min &&
632                     spec_timings->tDS_min <= onfi_timings->tDS_min &&
633                     spec_timings->tDSC_min <= onfi_timings->tDSC_min &&
634                     spec_timings->tRHW_min <= onfi_timings->tRHW_min &&
635                     spec_timings->tRR_min <= onfi_timings->tRR_min &&
636                     spec_timings->tWHR_min <= onfi_timings->tWHR_min &&
637                     spec_timings->tWRCK_min <= onfi_timings->tWRCK_min &&
638                     spec_timings->tWW_min <= onfi_timings->tWW_min)
639                         return mode;
640         }
641
642         return 0;
643 }
644
645 /*
646  * onfi_fill_sdr_interface_config - Initialize a SDR interface config from a
647  *                                  given ONFI mode
648  * @chip: The NAND chip
649  * @iface: The interface configuration to fill
650  * @timing_mode: The ONFI timing mode
651  */
652 static void onfi_fill_sdr_interface_config(struct nand_chip *chip,
653                                            struct nand_interface_config *iface,
654                                            unsigned int timing_mode)
655 {
656         struct onfi_params *onfi = chip->parameters.onfi;
657
658         if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_sdr_timings)))
659                 return;
660
661         *iface = onfi_sdr_timings[timing_mode];
662
663         /*
664          * Initialize timings that cannot be deduced from timing mode:
665          * tPROG, tBERS, tR and tCCS.
666          * These information are part of the ONFI parameter page.
667          */
668         if (onfi) {
669                 struct nand_sdr_timings *timings = &iface->timings.sdr;
670
671                 /* microseconds -> picoseconds */
672                 timings->tPROG_max = 1000000ULL * onfi->tPROG;
673                 timings->tBERS_max = 1000000ULL * onfi->tBERS;
674                 timings->tR_max = 1000000ULL * onfi->tR;
675
676                 /* nanoseconds -> picoseconds */
677                 timings->tCCS_min = 1000UL * onfi->tCCS;
678         }
679 }
680
681 /**
682  * onfi_fill_nvddr_interface_config - Initialize a NVDDR interface config from a
683  *                                    given ONFI mode
684  * @chip: The NAND chip
685  * @iface: The interface configuration to fill
686  * @timing_mode: The ONFI timing mode
687  */
688 static void onfi_fill_nvddr_interface_config(struct nand_chip *chip,
689                                              struct nand_interface_config *iface,
690                                              unsigned int timing_mode)
691 {
692         struct onfi_params *onfi = chip->parameters.onfi;
693
694         if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_nvddr_timings)))
695                 return;
696
697         *iface = onfi_nvddr_timings[timing_mode];
698
699         /*
700          * Initialize timings that cannot be deduced from timing mode:
701          * tPROG, tBERS, tR, tCCS and tCAD.
702          * These information are part of the ONFI parameter page.
703          */
704         if (onfi) {
705                 struct nand_nvddr_timings *timings = &iface->timings.nvddr;
706
707                 /* microseconds -> picoseconds */
708                 timings->tPROG_max = 1000000ULL * onfi->tPROG;
709                 timings->tBERS_max = 1000000ULL * onfi->tBERS;
710                 timings->tR_max = 1000000ULL * onfi->tR;
711
712                 /* nanoseconds -> picoseconds */
713                 timings->tCCS_min = 1000UL * onfi->tCCS;
714
715                 if (onfi->fast_tCAD)
716                         timings->tCAD_min = 25000;
717         }
718 }
719
720 /**
721  * onfi_fill_interface_config - Initialize an interface config from a given
722  *                              ONFI mode
723  * @chip: The NAND chip
724  * @iface: The interface configuration to fill
725  * @type: The interface type
726  * @timing_mode: The ONFI timing mode
727  */
728 void onfi_fill_interface_config(struct nand_chip *chip,
729                                 struct nand_interface_config *iface,
730                                 enum nand_interface_type type,
731                                 unsigned int timing_mode)
732 {
733         if (type == NAND_SDR_IFACE)
734                 return onfi_fill_sdr_interface_config(chip, iface, timing_mode);
735         else
736                 return onfi_fill_nvddr_interface_config(chip, iface, timing_mode);
737 }