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