Merge tag 'sfi-removal-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[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 /* All NAND chips share the same reset data interface: SDR mode 0 */
296 const struct nand_interface_config *nand_get_reset_interface_config(void)
297 {
298         return &onfi_sdr_timings[0];
299 }
300
301 /**
302  * onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a
303  *                              set of timings
304  * @spec_timings: the timings to challenge
305  */
306 unsigned int
307 onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings)
308 {
309         const struct nand_sdr_timings *onfi_timings;
310         int mode;
311
312         for (mode = ARRAY_SIZE(onfi_sdr_timings) - 1; mode > 0; mode--) {
313                 onfi_timings = &onfi_sdr_timings[mode].timings.sdr;
314
315                 if (spec_timings->tCCS_min <= onfi_timings->tCCS_min &&
316                     spec_timings->tADL_min <= onfi_timings->tADL_min &&
317                     spec_timings->tALH_min <= onfi_timings->tALH_min &&
318                     spec_timings->tALS_min <= onfi_timings->tALS_min &&
319                     spec_timings->tAR_min <= onfi_timings->tAR_min &&
320                     spec_timings->tCEH_min <= onfi_timings->tCEH_min &&
321                     spec_timings->tCH_min <= onfi_timings->tCH_min &&
322                     spec_timings->tCLH_min <= onfi_timings->tCLH_min &&
323                     spec_timings->tCLR_min <= onfi_timings->tCLR_min &&
324                     spec_timings->tCLS_min <= onfi_timings->tCLS_min &&
325                     spec_timings->tCOH_min <= onfi_timings->tCOH_min &&
326                     spec_timings->tCS_min <= onfi_timings->tCS_min &&
327                     spec_timings->tDH_min <= onfi_timings->tDH_min &&
328                     spec_timings->tDS_min <= onfi_timings->tDS_min &&
329                     spec_timings->tIR_min <= onfi_timings->tIR_min &&
330                     spec_timings->tRC_min <= onfi_timings->tRC_min &&
331                     spec_timings->tREH_min <= onfi_timings->tREH_min &&
332                     spec_timings->tRHOH_min <= onfi_timings->tRHOH_min &&
333                     spec_timings->tRHW_min <= onfi_timings->tRHW_min &&
334                     spec_timings->tRLOH_min <= onfi_timings->tRLOH_min &&
335                     spec_timings->tRP_min <= onfi_timings->tRP_min &&
336                     spec_timings->tRR_min <= onfi_timings->tRR_min &&
337                     spec_timings->tWC_min <= onfi_timings->tWC_min &&
338                     spec_timings->tWH_min <= onfi_timings->tWH_min &&
339                     spec_timings->tWHR_min <= onfi_timings->tWHR_min &&
340                     spec_timings->tWP_min <= onfi_timings->tWP_min &&
341                     spec_timings->tWW_min <= onfi_timings->tWW_min)
342                         return mode;
343         }
344
345         return 0;
346 }
347
348 /**
349  * onfi_fill_interface_config - Initialize an interface config from a given
350  *                              ONFI mode
351  * @chip: The NAND chip
352  * @iface: The interface configuration to fill
353  * @type: The interface type
354  * @timing_mode: The ONFI timing mode
355  */
356 void onfi_fill_interface_config(struct nand_chip *chip,
357                                 struct nand_interface_config *iface,
358                                 enum nand_interface_type type,
359                                 unsigned int timing_mode)
360 {
361         struct onfi_params *onfi = chip->parameters.onfi;
362
363         if (WARN_ON(type != NAND_SDR_IFACE))
364                 return;
365
366         if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_sdr_timings)))
367                 return;
368
369         *iface = onfi_sdr_timings[timing_mode];
370
371         /*
372          * Initialize timings that cannot be deduced from timing mode:
373          * tPROG, tBERS, tR and tCCS.
374          * These information are part of the ONFI parameter page.
375          */
376         if (onfi) {
377                 struct nand_sdr_timings *timings = &iface->timings.sdr;
378
379                 /* microseconds -> picoseconds */
380                 timings->tPROG_max = 1000000ULL * onfi->tPROG;
381                 timings->tBERS_max = 1000000ULL * onfi->tBERS;
382                 timings->tR_max = 1000000ULL * onfi->tR;
383
384                 /* nanoseconds -> picoseconds */
385                 timings->tCCS_min = 1000UL * onfi->tCCS;
386         }
387 }