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 */
22static 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
295static 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 */
551const 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 */
561unsigned int
562onfi_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 */
608unsigned int
609onfi_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 */
652static 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 */
688static 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 */
728void 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}
738