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