1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2014 Free Electrons
5 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
7 #include <linux/kernel.h>
9 #include <linux/export.h>
11 #include "internals.h"
13 #define ONFI_DYN_TIMING_MAX U16_MAX
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.
20 * These four values are tweaked to be more accurate in the case of ONFI chips.
22 static const struct nand_interface_config onfi_sdr_timings
[] = {
25 .type
= NAND_SDR_IFACE
,
30 .tPROG_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
31 .tBERS_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
59 .tRST_max
= 250000000000ULL,
70 .type
= NAND_SDR_IFACE
,
75 .tPROG_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
76 .tBERS_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
104 .tRST_max
= 500000000,
115 .type
= NAND_SDR_IFACE
,
120 .tPROG_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
121 .tBERS_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
137 .tFEAT_max
= 1000000,
148 .tRST_max
= 500000000,
160 .type
= NAND_SDR_IFACE
,
165 .tPROG_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
166 .tBERS_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
182 .tFEAT_max
= 1000000,
194 .tRST_max
= 500000000,
205 .type
= NAND_SDR_IFACE
,
210 .tPROG_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
211 .tBERS_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
227 .tFEAT_max
= 1000000,
239 .tRST_max
= 500000000,
250 .type
= NAND_SDR_IFACE
,
255 .tPROG_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
256 .tBERS_max
= 1000000ULL * ONFI_DYN_TIMING_MAX
,
272 .tFEAT_max
= 1000000,
284 .tRST_max
= 500000000,
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)
298 return &onfi_sdr_timings
[0];
302 * onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a
304 * @spec_timings: the timings to challenge
307 onfi_find_closest_sdr_mode(const struct nand_sdr_timings
*spec_timings
)
309 const struct nand_sdr_timings
*onfi_timings
;
312 for (mode
= ARRAY_SIZE(onfi_sdr_timings
) - 1; mode
> 0; mode
--) {
313 onfi_timings
= &onfi_sdr_timings
[mode
].timings
.sdr
;
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
)
349 * onfi_fill_interface_config - Initialize an interface config from a given
351 * @chip: The NAND chip
352 * @iface: The interface configuration to fill
353 * @type: The interface type
354 * @timing_mode: The ONFI timing mode
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
)
361 struct onfi_params
*onfi
= chip
->parameters
.onfi
;
363 if (WARN_ON(type
!= NAND_SDR_IFACE
))
366 if (WARN_ON(timing_mode
>= ARRAY_SIZE(onfi_sdr_timings
)))
369 *iface
= onfi_sdr_timings
[timing_mode
];
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.
377 struct nand_sdr_timings
*timings
= &iface
->timings
.sdr
;
379 /* microseconds -> picoseconds */
380 timings
->tPROG_max
= 1000000ULL * onfi
->tPROG
;
381 timings
->tBERS_max
= 1000000ULL * onfi
->tBERS
;
382 timings
->tR_max
= 1000000ULL * onfi
->tR
;
384 /* nanoseconds -> picoseconds */
385 timings
->tCCS_min
= 1000UL * onfi
->tCCS
;