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