162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2014 Free Electrons 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#include <linux/kernel.h> 862306a36Sopenharmony_ci#include <linux/err.h> 962306a36Sopenharmony_ci#include <linux/export.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "internals.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define ONFI_DYN_TIMING_MAX U16_MAX 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* 1662306a36Sopenharmony_ci * For non-ONFI chips we use the highest possible value for tPROG and tBERS. 1762306a36Sopenharmony_ci * tR and tCCS will take the default values precised in the ONFI specification 1862306a36Sopenharmony_ci * for timing mode 0, respectively 200us and 500ns. 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * These four values are tweaked to be more accurate in the case of ONFI chips. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_cistatic const struct nand_interface_config onfi_sdr_timings[] = { 2362306a36Sopenharmony_ci /* Mode 0 */ 2462306a36Sopenharmony_ci { 2562306a36Sopenharmony_ci .type = NAND_SDR_IFACE, 2662306a36Sopenharmony_ci .timings.mode = 0, 2762306a36Sopenharmony_ci .timings.sdr = { 2862306a36Sopenharmony_ci .tCCS_min = 500000, 2962306a36Sopenharmony_ci .tR_max = 200000000, 3062306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 3162306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 3262306a36Sopenharmony_ci .tADL_min = 400000, 3362306a36Sopenharmony_ci .tALH_min = 20000, 3462306a36Sopenharmony_ci .tALS_min = 50000, 3562306a36Sopenharmony_ci .tAR_min = 25000, 3662306a36Sopenharmony_ci .tCEA_max = 100000, 3762306a36Sopenharmony_ci .tCEH_min = 20000, 3862306a36Sopenharmony_ci .tCH_min = 20000, 3962306a36Sopenharmony_ci .tCHZ_max = 100000, 4062306a36Sopenharmony_ci .tCLH_min = 20000, 4162306a36Sopenharmony_ci .tCLR_min = 20000, 4262306a36Sopenharmony_ci .tCLS_min = 50000, 4362306a36Sopenharmony_ci .tCOH_min = 0, 4462306a36Sopenharmony_ci .tCS_min = 70000, 4562306a36Sopenharmony_ci .tDH_min = 20000, 4662306a36Sopenharmony_ci .tDS_min = 40000, 4762306a36Sopenharmony_ci .tFEAT_max = 1000000, 4862306a36Sopenharmony_ci .tIR_min = 10000, 4962306a36Sopenharmony_ci .tITC_max = 1000000, 5062306a36Sopenharmony_ci .tRC_min = 100000, 5162306a36Sopenharmony_ci .tREA_max = 40000, 5262306a36Sopenharmony_ci .tREH_min = 30000, 5362306a36Sopenharmony_ci .tRHOH_min = 0, 5462306a36Sopenharmony_ci .tRHW_min = 200000, 5562306a36Sopenharmony_ci .tRHZ_max = 200000, 5662306a36Sopenharmony_ci .tRLOH_min = 0, 5762306a36Sopenharmony_ci .tRP_min = 50000, 5862306a36Sopenharmony_ci .tRR_min = 40000, 5962306a36Sopenharmony_ci .tRST_max = 250000000000ULL, 6062306a36Sopenharmony_ci .tWB_max = 200000, 6162306a36Sopenharmony_ci .tWC_min = 100000, 6262306a36Sopenharmony_ci .tWH_min = 30000, 6362306a36Sopenharmony_ci .tWHR_min = 120000, 6462306a36Sopenharmony_ci .tWP_min = 50000, 6562306a36Sopenharmony_ci .tWW_min = 100000, 6662306a36Sopenharmony_ci }, 6762306a36Sopenharmony_ci }, 6862306a36Sopenharmony_ci /* Mode 1 */ 6962306a36Sopenharmony_ci { 7062306a36Sopenharmony_ci .type = NAND_SDR_IFACE, 7162306a36Sopenharmony_ci .timings.mode = 1, 7262306a36Sopenharmony_ci .timings.sdr = { 7362306a36Sopenharmony_ci .tCCS_min = 500000, 7462306a36Sopenharmony_ci .tR_max = 200000000, 7562306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 7662306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 7762306a36Sopenharmony_ci .tADL_min = 400000, 7862306a36Sopenharmony_ci .tALH_min = 10000, 7962306a36Sopenharmony_ci .tALS_min = 25000, 8062306a36Sopenharmony_ci .tAR_min = 10000, 8162306a36Sopenharmony_ci .tCEA_max = 45000, 8262306a36Sopenharmony_ci .tCEH_min = 20000, 8362306a36Sopenharmony_ci .tCH_min = 10000, 8462306a36Sopenharmony_ci .tCHZ_max = 50000, 8562306a36Sopenharmony_ci .tCLH_min = 10000, 8662306a36Sopenharmony_ci .tCLR_min = 10000, 8762306a36Sopenharmony_ci .tCLS_min = 25000, 8862306a36Sopenharmony_ci .tCOH_min = 15000, 8962306a36Sopenharmony_ci .tCS_min = 35000, 9062306a36Sopenharmony_ci .tDH_min = 10000, 9162306a36Sopenharmony_ci .tDS_min = 20000, 9262306a36Sopenharmony_ci .tFEAT_max = 1000000, 9362306a36Sopenharmony_ci .tIR_min = 0, 9462306a36Sopenharmony_ci .tITC_max = 1000000, 9562306a36Sopenharmony_ci .tRC_min = 50000, 9662306a36Sopenharmony_ci .tREA_max = 30000, 9762306a36Sopenharmony_ci .tREH_min = 15000, 9862306a36Sopenharmony_ci .tRHOH_min = 15000, 9962306a36Sopenharmony_ci .tRHW_min = 100000, 10062306a36Sopenharmony_ci .tRHZ_max = 100000, 10162306a36Sopenharmony_ci .tRLOH_min = 0, 10262306a36Sopenharmony_ci .tRP_min = 25000, 10362306a36Sopenharmony_ci .tRR_min = 20000, 10462306a36Sopenharmony_ci .tRST_max = 500000000, 10562306a36Sopenharmony_ci .tWB_max = 100000, 10662306a36Sopenharmony_ci .tWC_min = 45000, 10762306a36Sopenharmony_ci .tWH_min = 15000, 10862306a36Sopenharmony_ci .tWHR_min = 80000, 10962306a36Sopenharmony_ci .tWP_min = 25000, 11062306a36Sopenharmony_ci .tWW_min = 100000, 11162306a36Sopenharmony_ci }, 11262306a36Sopenharmony_ci }, 11362306a36Sopenharmony_ci /* Mode 2 */ 11462306a36Sopenharmony_ci { 11562306a36Sopenharmony_ci .type = NAND_SDR_IFACE, 11662306a36Sopenharmony_ci .timings.mode = 2, 11762306a36Sopenharmony_ci .timings.sdr = { 11862306a36Sopenharmony_ci .tCCS_min = 500000, 11962306a36Sopenharmony_ci .tR_max = 200000000, 12062306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 12162306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 12262306a36Sopenharmony_ci .tADL_min = 400000, 12362306a36Sopenharmony_ci .tALH_min = 10000, 12462306a36Sopenharmony_ci .tALS_min = 15000, 12562306a36Sopenharmony_ci .tAR_min = 10000, 12662306a36Sopenharmony_ci .tCEA_max = 30000, 12762306a36Sopenharmony_ci .tCEH_min = 20000, 12862306a36Sopenharmony_ci .tCH_min = 10000, 12962306a36Sopenharmony_ci .tCHZ_max = 50000, 13062306a36Sopenharmony_ci .tCLH_min = 10000, 13162306a36Sopenharmony_ci .tCLR_min = 10000, 13262306a36Sopenharmony_ci .tCLS_min = 15000, 13362306a36Sopenharmony_ci .tCOH_min = 15000, 13462306a36Sopenharmony_ci .tCS_min = 25000, 13562306a36Sopenharmony_ci .tDH_min = 5000, 13662306a36Sopenharmony_ci .tDS_min = 15000, 13762306a36Sopenharmony_ci .tFEAT_max = 1000000, 13862306a36Sopenharmony_ci .tIR_min = 0, 13962306a36Sopenharmony_ci .tITC_max = 1000000, 14062306a36Sopenharmony_ci .tRC_min = 35000, 14162306a36Sopenharmony_ci .tREA_max = 25000, 14262306a36Sopenharmony_ci .tREH_min = 15000, 14362306a36Sopenharmony_ci .tRHOH_min = 15000, 14462306a36Sopenharmony_ci .tRHW_min = 100000, 14562306a36Sopenharmony_ci .tRHZ_max = 100000, 14662306a36Sopenharmony_ci .tRLOH_min = 0, 14762306a36Sopenharmony_ci .tRR_min = 20000, 14862306a36Sopenharmony_ci .tRST_max = 500000000, 14962306a36Sopenharmony_ci .tWB_max = 100000, 15062306a36Sopenharmony_ci .tRP_min = 17000, 15162306a36Sopenharmony_ci .tWC_min = 35000, 15262306a36Sopenharmony_ci .tWH_min = 15000, 15362306a36Sopenharmony_ci .tWHR_min = 80000, 15462306a36Sopenharmony_ci .tWP_min = 17000, 15562306a36Sopenharmony_ci .tWW_min = 100000, 15662306a36Sopenharmony_ci }, 15762306a36Sopenharmony_ci }, 15862306a36Sopenharmony_ci /* Mode 3 */ 15962306a36Sopenharmony_ci { 16062306a36Sopenharmony_ci .type = NAND_SDR_IFACE, 16162306a36Sopenharmony_ci .timings.mode = 3, 16262306a36Sopenharmony_ci .timings.sdr = { 16362306a36Sopenharmony_ci .tCCS_min = 500000, 16462306a36Sopenharmony_ci .tR_max = 200000000, 16562306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 16662306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 16762306a36Sopenharmony_ci .tADL_min = 400000, 16862306a36Sopenharmony_ci .tALH_min = 5000, 16962306a36Sopenharmony_ci .tALS_min = 10000, 17062306a36Sopenharmony_ci .tAR_min = 10000, 17162306a36Sopenharmony_ci .tCEA_max = 25000, 17262306a36Sopenharmony_ci .tCEH_min = 20000, 17362306a36Sopenharmony_ci .tCH_min = 5000, 17462306a36Sopenharmony_ci .tCHZ_max = 50000, 17562306a36Sopenharmony_ci .tCLH_min = 5000, 17662306a36Sopenharmony_ci .tCLR_min = 10000, 17762306a36Sopenharmony_ci .tCLS_min = 10000, 17862306a36Sopenharmony_ci .tCOH_min = 15000, 17962306a36Sopenharmony_ci .tCS_min = 25000, 18062306a36Sopenharmony_ci .tDH_min = 5000, 18162306a36Sopenharmony_ci .tDS_min = 10000, 18262306a36Sopenharmony_ci .tFEAT_max = 1000000, 18362306a36Sopenharmony_ci .tIR_min = 0, 18462306a36Sopenharmony_ci .tITC_max = 1000000, 18562306a36Sopenharmony_ci .tRC_min = 30000, 18662306a36Sopenharmony_ci .tREA_max = 20000, 18762306a36Sopenharmony_ci .tREH_min = 10000, 18862306a36Sopenharmony_ci .tRHOH_min = 15000, 18962306a36Sopenharmony_ci .tRHW_min = 100000, 19062306a36Sopenharmony_ci .tRHZ_max = 100000, 19162306a36Sopenharmony_ci .tRLOH_min = 0, 19262306a36Sopenharmony_ci .tRP_min = 15000, 19362306a36Sopenharmony_ci .tRR_min = 20000, 19462306a36Sopenharmony_ci .tRST_max = 500000000, 19562306a36Sopenharmony_ci .tWB_max = 100000, 19662306a36Sopenharmony_ci .tWC_min = 30000, 19762306a36Sopenharmony_ci .tWH_min = 10000, 19862306a36Sopenharmony_ci .tWHR_min = 80000, 19962306a36Sopenharmony_ci .tWP_min = 15000, 20062306a36Sopenharmony_ci .tWW_min = 100000, 20162306a36Sopenharmony_ci }, 20262306a36Sopenharmony_ci }, 20362306a36Sopenharmony_ci /* Mode 4 */ 20462306a36Sopenharmony_ci { 20562306a36Sopenharmony_ci .type = NAND_SDR_IFACE, 20662306a36Sopenharmony_ci .timings.mode = 4, 20762306a36Sopenharmony_ci .timings.sdr = { 20862306a36Sopenharmony_ci .tCCS_min = 500000, 20962306a36Sopenharmony_ci .tR_max = 200000000, 21062306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 21162306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 21262306a36Sopenharmony_ci .tADL_min = 400000, 21362306a36Sopenharmony_ci .tALH_min = 5000, 21462306a36Sopenharmony_ci .tALS_min = 10000, 21562306a36Sopenharmony_ci .tAR_min = 10000, 21662306a36Sopenharmony_ci .tCEA_max = 25000, 21762306a36Sopenharmony_ci .tCEH_min = 20000, 21862306a36Sopenharmony_ci .tCH_min = 5000, 21962306a36Sopenharmony_ci .tCHZ_max = 30000, 22062306a36Sopenharmony_ci .tCLH_min = 5000, 22162306a36Sopenharmony_ci .tCLR_min = 10000, 22262306a36Sopenharmony_ci .tCLS_min = 10000, 22362306a36Sopenharmony_ci .tCOH_min = 15000, 22462306a36Sopenharmony_ci .tCS_min = 20000, 22562306a36Sopenharmony_ci .tDH_min = 5000, 22662306a36Sopenharmony_ci .tDS_min = 10000, 22762306a36Sopenharmony_ci .tFEAT_max = 1000000, 22862306a36Sopenharmony_ci .tIR_min = 0, 22962306a36Sopenharmony_ci .tITC_max = 1000000, 23062306a36Sopenharmony_ci .tRC_min = 25000, 23162306a36Sopenharmony_ci .tREA_max = 20000, 23262306a36Sopenharmony_ci .tREH_min = 10000, 23362306a36Sopenharmony_ci .tRHOH_min = 15000, 23462306a36Sopenharmony_ci .tRHW_min = 100000, 23562306a36Sopenharmony_ci .tRHZ_max = 100000, 23662306a36Sopenharmony_ci .tRLOH_min = 5000, 23762306a36Sopenharmony_ci .tRP_min = 12000, 23862306a36Sopenharmony_ci .tRR_min = 20000, 23962306a36Sopenharmony_ci .tRST_max = 500000000, 24062306a36Sopenharmony_ci .tWB_max = 100000, 24162306a36Sopenharmony_ci .tWC_min = 25000, 24262306a36Sopenharmony_ci .tWH_min = 10000, 24362306a36Sopenharmony_ci .tWHR_min = 80000, 24462306a36Sopenharmony_ci .tWP_min = 12000, 24562306a36Sopenharmony_ci .tWW_min = 100000, 24662306a36Sopenharmony_ci }, 24762306a36Sopenharmony_ci }, 24862306a36Sopenharmony_ci /* Mode 5 */ 24962306a36Sopenharmony_ci { 25062306a36Sopenharmony_ci .type = NAND_SDR_IFACE, 25162306a36Sopenharmony_ci .timings.mode = 5, 25262306a36Sopenharmony_ci .timings.sdr = { 25362306a36Sopenharmony_ci .tCCS_min = 500000, 25462306a36Sopenharmony_ci .tR_max = 200000000, 25562306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 25662306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 25762306a36Sopenharmony_ci .tADL_min = 400000, 25862306a36Sopenharmony_ci .tALH_min = 5000, 25962306a36Sopenharmony_ci .tALS_min = 10000, 26062306a36Sopenharmony_ci .tAR_min = 10000, 26162306a36Sopenharmony_ci .tCEA_max = 25000, 26262306a36Sopenharmony_ci .tCEH_min = 20000, 26362306a36Sopenharmony_ci .tCH_min = 5000, 26462306a36Sopenharmony_ci .tCHZ_max = 30000, 26562306a36Sopenharmony_ci .tCLH_min = 5000, 26662306a36Sopenharmony_ci .tCLR_min = 10000, 26762306a36Sopenharmony_ci .tCLS_min = 10000, 26862306a36Sopenharmony_ci .tCOH_min = 15000, 26962306a36Sopenharmony_ci .tCS_min = 15000, 27062306a36Sopenharmony_ci .tDH_min = 5000, 27162306a36Sopenharmony_ci .tDS_min = 7000, 27262306a36Sopenharmony_ci .tFEAT_max = 1000000, 27362306a36Sopenharmony_ci .tIR_min = 0, 27462306a36Sopenharmony_ci .tITC_max = 1000000, 27562306a36Sopenharmony_ci .tRC_min = 20000, 27662306a36Sopenharmony_ci .tREA_max = 16000, 27762306a36Sopenharmony_ci .tREH_min = 7000, 27862306a36Sopenharmony_ci .tRHOH_min = 15000, 27962306a36Sopenharmony_ci .tRHW_min = 100000, 28062306a36Sopenharmony_ci .tRHZ_max = 100000, 28162306a36Sopenharmony_ci .tRLOH_min = 5000, 28262306a36Sopenharmony_ci .tRP_min = 10000, 28362306a36Sopenharmony_ci .tRR_min = 20000, 28462306a36Sopenharmony_ci .tRST_max = 500000000, 28562306a36Sopenharmony_ci .tWB_max = 100000, 28662306a36Sopenharmony_ci .tWC_min = 20000, 28762306a36Sopenharmony_ci .tWH_min = 7000, 28862306a36Sopenharmony_ci .tWHR_min = 80000, 28962306a36Sopenharmony_ci .tWP_min = 10000, 29062306a36Sopenharmony_ci .tWW_min = 100000, 29162306a36Sopenharmony_ci }, 29262306a36Sopenharmony_ci }, 29362306a36Sopenharmony_ci}; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_cistatic const struct nand_interface_config onfi_nvddr_timings[] = { 29662306a36Sopenharmony_ci /* Mode 0 */ 29762306a36Sopenharmony_ci { 29862306a36Sopenharmony_ci .type = NAND_NVDDR_IFACE, 29962306a36Sopenharmony_ci .timings.mode = 0, 30062306a36Sopenharmony_ci .timings.nvddr = { 30162306a36Sopenharmony_ci .tCCS_min = 500000, 30262306a36Sopenharmony_ci .tR_max = 200000000, 30362306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 30462306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 30562306a36Sopenharmony_ci .tAC_min = 3000, 30662306a36Sopenharmony_ci .tAC_max = 25000, 30762306a36Sopenharmony_ci .tADL_min = 400000, 30862306a36Sopenharmony_ci .tCAD_min = 45000, 30962306a36Sopenharmony_ci .tCAH_min = 10000, 31062306a36Sopenharmony_ci .tCALH_min = 10000, 31162306a36Sopenharmony_ci .tCALS_min = 10000, 31262306a36Sopenharmony_ci .tCAS_min = 10000, 31362306a36Sopenharmony_ci .tCEH_min = 20000, 31462306a36Sopenharmony_ci .tCH_min = 10000, 31562306a36Sopenharmony_ci .tCK_min = 50000, 31662306a36Sopenharmony_ci .tCS_min = 35000, 31762306a36Sopenharmony_ci .tDH_min = 5000, 31862306a36Sopenharmony_ci .tDQSCK_min = 3000, 31962306a36Sopenharmony_ci .tDQSCK_max = 25000, 32062306a36Sopenharmony_ci .tDQSD_min = 0, 32162306a36Sopenharmony_ci .tDQSD_max = 18000, 32262306a36Sopenharmony_ci .tDQSHZ_max = 20000, 32362306a36Sopenharmony_ci .tDQSQ_max = 5000, 32462306a36Sopenharmony_ci .tDS_min = 5000, 32562306a36Sopenharmony_ci .tDSC_min = 50000, 32662306a36Sopenharmony_ci .tFEAT_max = 1000000, 32762306a36Sopenharmony_ci .tITC_max = 1000000, 32862306a36Sopenharmony_ci .tQHS_max = 6000, 32962306a36Sopenharmony_ci .tRHW_min = 100000, 33062306a36Sopenharmony_ci .tRR_min = 20000, 33162306a36Sopenharmony_ci .tRST_max = 500000000, 33262306a36Sopenharmony_ci .tWB_max = 100000, 33362306a36Sopenharmony_ci .tWHR_min = 80000, 33462306a36Sopenharmony_ci .tWRCK_min = 20000, 33562306a36Sopenharmony_ci .tWW_min = 100000, 33662306a36Sopenharmony_ci }, 33762306a36Sopenharmony_ci }, 33862306a36Sopenharmony_ci /* Mode 1 */ 33962306a36Sopenharmony_ci { 34062306a36Sopenharmony_ci .type = NAND_NVDDR_IFACE, 34162306a36Sopenharmony_ci .timings.mode = 1, 34262306a36Sopenharmony_ci .timings.nvddr = { 34362306a36Sopenharmony_ci .tCCS_min = 500000, 34462306a36Sopenharmony_ci .tR_max = 200000000, 34562306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 34662306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 34762306a36Sopenharmony_ci .tAC_min = 3000, 34862306a36Sopenharmony_ci .tAC_max = 25000, 34962306a36Sopenharmony_ci .tADL_min = 400000, 35062306a36Sopenharmony_ci .tCAD_min = 45000, 35162306a36Sopenharmony_ci .tCAH_min = 5000, 35262306a36Sopenharmony_ci .tCALH_min = 5000, 35362306a36Sopenharmony_ci .tCALS_min = 5000, 35462306a36Sopenharmony_ci .tCAS_min = 5000, 35562306a36Sopenharmony_ci .tCEH_min = 20000, 35662306a36Sopenharmony_ci .tCH_min = 5000, 35762306a36Sopenharmony_ci .tCK_min = 30000, 35862306a36Sopenharmony_ci .tCS_min = 25000, 35962306a36Sopenharmony_ci .tDH_min = 2500, 36062306a36Sopenharmony_ci .tDQSCK_min = 3000, 36162306a36Sopenharmony_ci .tDQSCK_max = 25000, 36262306a36Sopenharmony_ci .tDQSD_min = 0, 36362306a36Sopenharmony_ci .tDQSD_max = 18000, 36462306a36Sopenharmony_ci .tDQSHZ_max = 20000, 36562306a36Sopenharmony_ci .tDQSQ_max = 2500, 36662306a36Sopenharmony_ci .tDS_min = 3000, 36762306a36Sopenharmony_ci .tDSC_min = 30000, 36862306a36Sopenharmony_ci .tFEAT_max = 1000000, 36962306a36Sopenharmony_ci .tITC_max = 1000000, 37062306a36Sopenharmony_ci .tQHS_max = 3000, 37162306a36Sopenharmony_ci .tRHW_min = 100000, 37262306a36Sopenharmony_ci .tRR_min = 20000, 37362306a36Sopenharmony_ci .tRST_max = 500000000, 37462306a36Sopenharmony_ci .tWB_max = 100000, 37562306a36Sopenharmony_ci .tWHR_min = 80000, 37662306a36Sopenharmony_ci .tWRCK_min = 20000, 37762306a36Sopenharmony_ci .tWW_min = 100000, 37862306a36Sopenharmony_ci }, 37962306a36Sopenharmony_ci }, 38062306a36Sopenharmony_ci /* Mode 2 */ 38162306a36Sopenharmony_ci { 38262306a36Sopenharmony_ci .type = NAND_NVDDR_IFACE, 38362306a36Sopenharmony_ci .timings.mode = 2, 38462306a36Sopenharmony_ci .timings.nvddr = { 38562306a36Sopenharmony_ci .tCCS_min = 500000, 38662306a36Sopenharmony_ci .tR_max = 200000000, 38762306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 38862306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 38962306a36Sopenharmony_ci .tAC_min = 3000, 39062306a36Sopenharmony_ci .tAC_max = 25000, 39162306a36Sopenharmony_ci .tADL_min = 400000, 39262306a36Sopenharmony_ci .tCAD_min = 45000, 39362306a36Sopenharmony_ci .tCAH_min = 4000, 39462306a36Sopenharmony_ci .tCALH_min = 4000, 39562306a36Sopenharmony_ci .tCALS_min = 4000, 39662306a36Sopenharmony_ci .tCAS_min = 4000, 39762306a36Sopenharmony_ci .tCEH_min = 20000, 39862306a36Sopenharmony_ci .tCH_min = 4000, 39962306a36Sopenharmony_ci .tCK_min = 20000, 40062306a36Sopenharmony_ci .tCS_min = 15000, 40162306a36Sopenharmony_ci .tDH_min = 1700, 40262306a36Sopenharmony_ci .tDQSCK_min = 3000, 40362306a36Sopenharmony_ci .tDQSCK_max = 25000, 40462306a36Sopenharmony_ci .tDQSD_min = 0, 40562306a36Sopenharmony_ci .tDQSD_max = 18000, 40662306a36Sopenharmony_ci .tDQSHZ_max = 20000, 40762306a36Sopenharmony_ci .tDQSQ_max = 1700, 40862306a36Sopenharmony_ci .tDS_min = 2000, 40962306a36Sopenharmony_ci .tDSC_min = 20000, 41062306a36Sopenharmony_ci .tFEAT_max = 1000000, 41162306a36Sopenharmony_ci .tITC_max = 1000000, 41262306a36Sopenharmony_ci .tQHS_max = 2000, 41362306a36Sopenharmony_ci .tRHW_min = 100000, 41462306a36Sopenharmony_ci .tRR_min = 20000, 41562306a36Sopenharmony_ci .tRST_max = 500000000, 41662306a36Sopenharmony_ci .tWB_max = 100000, 41762306a36Sopenharmony_ci .tWHR_min = 80000, 41862306a36Sopenharmony_ci .tWRCK_min = 20000, 41962306a36Sopenharmony_ci .tWW_min = 100000, 42062306a36Sopenharmony_ci }, 42162306a36Sopenharmony_ci }, 42262306a36Sopenharmony_ci /* Mode 3 */ 42362306a36Sopenharmony_ci { 42462306a36Sopenharmony_ci .type = NAND_NVDDR_IFACE, 42562306a36Sopenharmony_ci .timings.mode = 3, 42662306a36Sopenharmony_ci .timings.nvddr = { 42762306a36Sopenharmony_ci .tCCS_min = 500000, 42862306a36Sopenharmony_ci .tR_max = 200000000, 42962306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 43062306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 43162306a36Sopenharmony_ci .tAC_min = 3000, 43262306a36Sopenharmony_ci .tAC_max = 25000, 43362306a36Sopenharmony_ci .tADL_min = 400000, 43462306a36Sopenharmony_ci .tCAD_min = 45000, 43562306a36Sopenharmony_ci .tCAH_min = 3000, 43662306a36Sopenharmony_ci .tCALH_min = 3000, 43762306a36Sopenharmony_ci .tCALS_min = 3000, 43862306a36Sopenharmony_ci .tCAS_min = 3000, 43962306a36Sopenharmony_ci .tCEH_min = 20000, 44062306a36Sopenharmony_ci .tCH_min = 3000, 44162306a36Sopenharmony_ci .tCK_min = 15000, 44262306a36Sopenharmony_ci .tCS_min = 15000, 44362306a36Sopenharmony_ci .tDH_min = 1300, 44462306a36Sopenharmony_ci .tDQSCK_min = 3000, 44562306a36Sopenharmony_ci .tDQSCK_max = 25000, 44662306a36Sopenharmony_ci .tDQSD_min = 0, 44762306a36Sopenharmony_ci .tDQSD_max = 18000, 44862306a36Sopenharmony_ci .tDQSHZ_max = 20000, 44962306a36Sopenharmony_ci .tDQSQ_max = 1300, 45062306a36Sopenharmony_ci .tDS_min = 1500, 45162306a36Sopenharmony_ci .tDSC_min = 15000, 45262306a36Sopenharmony_ci .tFEAT_max = 1000000, 45362306a36Sopenharmony_ci .tITC_max = 1000000, 45462306a36Sopenharmony_ci .tQHS_max = 1500, 45562306a36Sopenharmony_ci .tRHW_min = 100000, 45662306a36Sopenharmony_ci .tRR_min = 20000, 45762306a36Sopenharmony_ci .tRST_max = 500000000, 45862306a36Sopenharmony_ci .tWB_max = 100000, 45962306a36Sopenharmony_ci .tWHR_min = 80000, 46062306a36Sopenharmony_ci .tWRCK_min = 20000, 46162306a36Sopenharmony_ci .tWW_min = 100000, 46262306a36Sopenharmony_ci }, 46362306a36Sopenharmony_ci }, 46462306a36Sopenharmony_ci /* Mode 4 */ 46562306a36Sopenharmony_ci { 46662306a36Sopenharmony_ci .type = NAND_NVDDR_IFACE, 46762306a36Sopenharmony_ci .timings.mode = 4, 46862306a36Sopenharmony_ci .timings.nvddr = { 46962306a36Sopenharmony_ci .tCCS_min = 500000, 47062306a36Sopenharmony_ci .tR_max = 200000000, 47162306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 47262306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 47362306a36Sopenharmony_ci .tAC_min = 3000, 47462306a36Sopenharmony_ci .tAC_max = 25000, 47562306a36Sopenharmony_ci .tADL_min = 400000, 47662306a36Sopenharmony_ci .tCAD_min = 45000, 47762306a36Sopenharmony_ci .tCAH_min = 2500, 47862306a36Sopenharmony_ci .tCALH_min = 2500, 47962306a36Sopenharmony_ci .tCALS_min = 2500, 48062306a36Sopenharmony_ci .tCAS_min = 2500, 48162306a36Sopenharmony_ci .tCEH_min = 20000, 48262306a36Sopenharmony_ci .tCH_min = 2500, 48362306a36Sopenharmony_ci .tCK_min = 12000, 48462306a36Sopenharmony_ci .tCS_min = 15000, 48562306a36Sopenharmony_ci .tDH_min = 1100, 48662306a36Sopenharmony_ci .tDQSCK_min = 3000, 48762306a36Sopenharmony_ci .tDQSCK_max = 25000, 48862306a36Sopenharmony_ci .tDQSD_min = 0, 48962306a36Sopenharmony_ci .tDQSD_max = 18000, 49062306a36Sopenharmony_ci .tDQSHZ_max = 20000, 49162306a36Sopenharmony_ci .tDQSQ_max = 1000, 49262306a36Sopenharmony_ci .tDS_min = 1100, 49362306a36Sopenharmony_ci .tDSC_min = 12000, 49462306a36Sopenharmony_ci .tFEAT_max = 1000000, 49562306a36Sopenharmony_ci .tITC_max = 1000000, 49662306a36Sopenharmony_ci .tQHS_max = 1200, 49762306a36Sopenharmony_ci .tRHW_min = 100000, 49862306a36Sopenharmony_ci .tRR_min = 20000, 49962306a36Sopenharmony_ci .tRST_max = 500000000, 50062306a36Sopenharmony_ci .tWB_max = 100000, 50162306a36Sopenharmony_ci .tWHR_min = 80000, 50262306a36Sopenharmony_ci .tWRCK_min = 20000, 50362306a36Sopenharmony_ci .tWW_min = 100000, 50462306a36Sopenharmony_ci }, 50562306a36Sopenharmony_ci }, 50662306a36Sopenharmony_ci /* Mode 5 */ 50762306a36Sopenharmony_ci { 50862306a36Sopenharmony_ci .type = NAND_NVDDR_IFACE, 50962306a36Sopenharmony_ci .timings.mode = 5, 51062306a36Sopenharmony_ci .timings.nvddr = { 51162306a36Sopenharmony_ci .tCCS_min = 500000, 51262306a36Sopenharmony_ci .tR_max = 200000000, 51362306a36Sopenharmony_ci .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 51462306a36Sopenharmony_ci .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 51562306a36Sopenharmony_ci .tAC_min = 3000, 51662306a36Sopenharmony_ci .tAC_max = 25000, 51762306a36Sopenharmony_ci .tADL_min = 400000, 51862306a36Sopenharmony_ci .tCAD_min = 45000, 51962306a36Sopenharmony_ci .tCAH_min = 2000, 52062306a36Sopenharmony_ci .tCALH_min = 2000, 52162306a36Sopenharmony_ci .tCALS_min = 2000, 52262306a36Sopenharmony_ci .tCAS_min = 2000, 52362306a36Sopenharmony_ci .tCEH_min = 20000, 52462306a36Sopenharmony_ci .tCH_min = 2000, 52562306a36Sopenharmony_ci .tCK_min = 10000, 52662306a36Sopenharmony_ci .tCS_min = 15000, 52762306a36Sopenharmony_ci .tDH_min = 900, 52862306a36Sopenharmony_ci .tDQSCK_min = 3000, 52962306a36Sopenharmony_ci .tDQSCK_max = 25000, 53062306a36Sopenharmony_ci .tDQSD_min = 0, 53162306a36Sopenharmony_ci .tDQSD_max = 18000, 53262306a36Sopenharmony_ci .tDQSHZ_max = 20000, 53362306a36Sopenharmony_ci .tDQSQ_max = 850, 53462306a36Sopenharmony_ci .tDS_min = 900, 53562306a36Sopenharmony_ci .tDSC_min = 10000, 53662306a36Sopenharmony_ci .tFEAT_max = 1000000, 53762306a36Sopenharmony_ci .tITC_max = 1000000, 53862306a36Sopenharmony_ci .tQHS_max = 1000, 53962306a36Sopenharmony_ci .tRHW_min = 100000, 54062306a36Sopenharmony_ci .tRR_min = 20000, 54162306a36Sopenharmony_ci .tRST_max = 500000000, 54262306a36Sopenharmony_ci .tWB_max = 100000, 54362306a36Sopenharmony_ci .tWHR_min = 80000, 54462306a36Sopenharmony_ci .tWRCK_min = 20000, 54562306a36Sopenharmony_ci .tWW_min = 100000, 54662306a36Sopenharmony_ci }, 54762306a36Sopenharmony_ci }, 54862306a36Sopenharmony_ci}; 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci/* All NAND chips share the same reset data interface: SDR mode 0 */ 55162306a36Sopenharmony_ciconst struct nand_interface_config *nand_get_reset_interface_config(void) 55262306a36Sopenharmony_ci{ 55362306a36Sopenharmony_ci return &onfi_sdr_timings[0]; 55462306a36Sopenharmony_ci} 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci/** 55762306a36Sopenharmony_ci * onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a 55862306a36Sopenharmony_ci * set of timings 55962306a36Sopenharmony_ci * @spec_timings: the timings to challenge 56062306a36Sopenharmony_ci */ 56162306a36Sopenharmony_ciunsigned int 56262306a36Sopenharmony_cionfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings) 56362306a36Sopenharmony_ci{ 56462306a36Sopenharmony_ci const struct nand_sdr_timings *onfi_timings; 56562306a36Sopenharmony_ci int mode; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci for (mode = ARRAY_SIZE(onfi_sdr_timings) - 1; mode > 0; mode--) { 56862306a36Sopenharmony_ci onfi_timings = &onfi_sdr_timings[mode].timings.sdr; 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci if (spec_timings->tCCS_min <= onfi_timings->tCCS_min && 57162306a36Sopenharmony_ci spec_timings->tADL_min <= onfi_timings->tADL_min && 57262306a36Sopenharmony_ci spec_timings->tALH_min <= onfi_timings->tALH_min && 57362306a36Sopenharmony_ci spec_timings->tALS_min <= onfi_timings->tALS_min && 57462306a36Sopenharmony_ci spec_timings->tAR_min <= onfi_timings->tAR_min && 57562306a36Sopenharmony_ci spec_timings->tCEH_min <= onfi_timings->tCEH_min && 57662306a36Sopenharmony_ci spec_timings->tCH_min <= onfi_timings->tCH_min && 57762306a36Sopenharmony_ci spec_timings->tCLH_min <= onfi_timings->tCLH_min && 57862306a36Sopenharmony_ci spec_timings->tCLR_min <= onfi_timings->tCLR_min && 57962306a36Sopenharmony_ci spec_timings->tCLS_min <= onfi_timings->tCLS_min && 58062306a36Sopenharmony_ci spec_timings->tCOH_min <= onfi_timings->tCOH_min && 58162306a36Sopenharmony_ci spec_timings->tCS_min <= onfi_timings->tCS_min && 58262306a36Sopenharmony_ci spec_timings->tDH_min <= onfi_timings->tDH_min && 58362306a36Sopenharmony_ci spec_timings->tDS_min <= onfi_timings->tDS_min && 58462306a36Sopenharmony_ci spec_timings->tIR_min <= onfi_timings->tIR_min && 58562306a36Sopenharmony_ci spec_timings->tRC_min <= onfi_timings->tRC_min && 58662306a36Sopenharmony_ci spec_timings->tREH_min <= onfi_timings->tREH_min && 58762306a36Sopenharmony_ci spec_timings->tRHOH_min <= onfi_timings->tRHOH_min && 58862306a36Sopenharmony_ci spec_timings->tRHW_min <= onfi_timings->tRHW_min && 58962306a36Sopenharmony_ci spec_timings->tRLOH_min <= onfi_timings->tRLOH_min && 59062306a36Sopenharmony_ci spec_timings->tRP_min <= onfi_timings->tRP_min && 59162306a36Sopenharmony_ci spec_timings->tRR_min <= onfi_timings->tRR_min && 59262306a36Sopenharmony_ci spec_timings->tWC_min <= onfi_timings->tWC_min && 59362306a36Sopenharmony_ci spec_timings->tWH_min <= onfi_timings->tWH_min && 59462306a36Sopenharmony_ci spec_timings->tWHR_min <= onfi_timings->tWHR_min && 59562306a36Sopenharmony_ci spec_timings->tWP_min <= onfi_timings->tWP_min && 59662306a36Sopenharmony_ci spec_timings->tWW_min <= onfi_timings->tWW_min) 59762306a36Sopenharmony_ci return mode; 59862306a36Sopenharmony_ci } 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci return 0; 60162306a36Sopenharmony_ci} 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci/** 60462306a36Sopenharmony_ci * onfi_find_closest_nvddr_mode - Derive the closest ONFI NVDDR timing mode 60562306a36Sopenharmony_ci * given a set of timings 60662306a36Sopenharmony_ci * @spec_timings: the timings to challenge 60762306a36Sopenharmony_ci */ 60862306a36Sopenharmony_ciunsigned int 60962306a36Sopenharmony_cionfi_find_closest_nvddr_mode(const struct nand_nvddr_timings *spec_timings) 61062306a36Sopenharmony_ci{ 61162306a36Sopenharmony_ci const struct nand_nvddr_timings *onfi_timings; 61262306a36Sopenharmony_ci int mode; 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci for (mode = ARRAY_SIZE(onfi_nvddr_timings) - 1; mode > 0; mode--) { 61562306a36Sopenharmony_ci onfi_timings = &onfi_nvddr_timings[mode].timings.nvddr; 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci if (spec_timings->tCCS_min <= onfi_timings->tCCS_min && 61862306a36Sopenharmony_ci spec_timings->tAC_min <= onfi_timings->tAC_min && 61962306a36Sopenharmony_ci spec_timings->tADL_min <= onfi_timings->tADL_min && 62062306a36Sopenharmony_ci spec_timings->tCAD_min <= onfi_timings->tCAD_min && 62162306a36Sopenharmony_ci spec_timings->tCAH_min <= onfi_timings->tCAH_min && 62262306a36Sopenharmony_ci spec_timings->tCALH_min <= onfi_timings->tCALH_min && 62362306a36Sopenharmony_ci spec_timings->tCALS_min <= onfi_timings->tCALS_min && 62462306a36Sopenharmony_ci spec_timings->tCAS_min <= onfi_timings->tCAS_min && 62562306a36Sopenharmony_ci spec_timings->tCEH_min <= onfi_timings->tCEH_min && 62662306a36Sopenharmony_ci spec_timings->tCH_min <= onfi_timings->tCH_min && 62762306a36Sopenharmony_ci spec_timings->tCK_min <= onfi_timings->tCK_min && 62862306a36Sopenharmony_ci spec_timings->tCS_min <= onfi_timings->tCS_min && 62962306a36Sopenharmony_ci spec_timings->tDH_min <= onfi_timings->tDH_min && 63062306a36Sopenharmony_ci spec_timings->tDQSCK_min <= onfi_timings->tDQSCK_min && 63162306a36Sopenharmony_ci spec_timings->tDQSD_min <= onfi_timings->tDQSD_min && 63262306a36Sopenharmony_ci spec_timings->tDS_min <= onfi_timings->tDS_min && 63362306a36Sopenharmony_ci spec_timings->tDSC_min <= onfi_timings->tDSC_min && 63462306a36Sopenharmony_ci spec_timings->tRHW_min <= onfi_timings->tRHW_min && 63562306a36Sopenharmony_ci spec_timings->tRR_min <= onfi_timings->tRR_min && 63662306a36Sopenharmony_ci spec_timings->tWHR_min <= onfi_timings->tWHR_min && 63762306a36Sopenharmony_ci spec_timings->tWRCK_min <= onfi_timings->tWRCK_min && 63862306a36Sopenharmony_ci spec_timings->tWW_min <= onfi_timings->tWW_min) 63962306a36Sopenharmony_ci return mode; 64062306a36Sopenharmony_ci } 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_ci return 0; 64362306a36Sopenharmony_ci} 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci/* 64662306a36Sopenharmony_ci * onfi_fill_sdr_interface_config - Initialize a SDR interface config from a 64762306a36Sopenharmony_ci * given ONFI mode 64862306a36Sopenharmony_ci * @chip: The NAND chip 64962306a36Sopenharmony_ci * @iface: The interface configuration to fill 65062306a36Sopenharmony_ci * @timing_mode: The ONFI timing mode 65162306a36Sopenharmony_ci */ 65262306a36Sopenharmony_cistatic void onfi_fill_sdr_interface_config(struct nand_chip *chip, 65362306a36Sopenharmony_ci struct nand_interface_config *iface, 65462306a36Sopenharmony_ci unsigned int timing_mode) 65562306a36Sopenharmony_ci{ 65662306a36Sopenharmony_ci struct onfi_params *onfi = chip->parameters.onfi; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_sdr_timings))) 65962306a36Sopenharmony_ci return; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci *iface = onfi_sdr_timings[timing_mode]; 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci /* 66462306a36Sopenharmony_ci * Initialize timings that cannot be deduced from timing mode: 66562306a36Sopenharmony_ci * tPROG, tBERS, tR and tCCS. 66662306a36Sopenharmony_ci * These information are part of the ONFI parameter page. 66762306a36Sopenharmony_ci */ 66862306a36Sopenharmony_ci if (onfi) { 66962306a36Sopenharmony_ci struct nand_sdr_timings *timings = &iface->timings.sdr; 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci /* microseconds -> picoseconds */ 67262306a36Sopenharmony_ci timings->tPROG_max = 1000000ULL * onfi->tPROG; 67362306a36Sopenharmony_ci timings->tBERS_max = 1000000ULL * onfi->tBERS; 67462306a36Sopenharmony_ci timings->tR_max = 1000000ULL * onfi->tR; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci /* nanoseconds -> picoseconds */ 67762306a36Sopenharmony_ci timings->tCCS_min = 1000UL * onfi->tCCS; 67862306a36Sopenharmony_ci } 67962306a36Sopenharmony_ci} 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci/** 68262306a36Sopenharmony_ci * onfi_fill_nvddr_interface_config - Initialize a NVDDR interface config from a 68362306a36Sopenharmony_ci * given ONFI mode 68462306a36Sopenharmony_ci * @chip: The NAND chip 68562306a36Sopenharmony_ci * @iface: The interface configuration to fill 68662306a36Sopenharmony_ci * @timing_mode: The ONFI timing mode 68762306a36Sopenharmony_ci */ 68862306a36Sopenharmony_cistatic void onfi_fill_nvddr_interface_config(struct nand_chip *chip, 68962306a36Sopenharmony_ci struct nand_interface_config *iface, 69062306a36Sopenharmony_ci unsigned int timing_mode) 69162306a36Sopenharmony_ci{ 69262306a36Sopenharmony_ci struct onfi_params *onfi = chip->parameters.onfi; 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_nvddr_timings))) 69562306a36Sopenharmony_ci return; 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci *iface = onfi_nvddr_timings[timing_mode]; 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci /* 70062306a36Sopenharmony_ci * Initialize timings that cannot be deduced from timing mode: 70162306a36Sopenharmony_ci * tPROG, tBERS, tR, tCCS and tCAD. 70262306a36Sopenharmony_ci * These information are part of the ONFI parameter page. 70362306a36Sopenharmony_ci */ 70462306a36Sopenharmony_ci if (onfi) { 70562306a36Sopenharmony_ci struct nand_nvddr_timings *timings = &iface->timings.nvddr; 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_ci /* microseconds -> picoseconds */ 70862306a36Sopenharmony_ci timings->tPROG_max = 1000000ULL * onfi->tPROG; 70962306a36Sopenharmony_ci timings->tBERS_max = 1000000ULL * onfi->tBERS; 71062306a36Sopenharmony_ci timings->tR_max = 1000000ULL * onfi->tR; 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci /* nanoseconds -> picoseconds */ 71362306a36Sopenharmony_ci timings->tCCS_min = 1000UL * onfi->tCCS; 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci if (onfi->fast_tCAD) 71662306a36Sopenharmony_ci timings->tCAD_min = 25000; 71762306a36Sopenharmony_ci } 71862306a36Sopenharmony_ci} 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci/** 72162306a36Sopenharmony_ci * onfi_fill_interface_config - Initialize an interface config from a given 72262306a36Sopenharmony_ci * ONFI mode 72362306a36Sopenharmony_ci * @chip: The NAND chip 72462306a36Sopenharmony_ci * @iface: The interface configuration to fill 72562306a36Sopenharmony_ci * @type: The interface type 72662306a36Sopenharmony_ci * @timing_mode: The ONFI timing mode 72762306a36Sopenharmony_ci */ 72862306a36Sopenharmony_civoid onfi_fill_interface_config(struct nand_chip *chip, 72962306a36Sopenharmony_ci struct nand_interface_config *iface, 73062306a36Sopenharmony_ci enum nand_interface_type type, 73162306a36Sopenharmony_ci unsigned int timing_mode) 73262306a36Sopenharmony_ci{ 73362306a36Sopenharmony_ci if (type == NAND_SDR_IFACE) 73462306a36Sopenharmony_ci return onfi_fill_sdr_interface_config(chip, iface, timing_mode); 73562306a36Sopenharmony_ci else 73662306a36Sopenharmony_ci return onfi_fill_nvddr_interface_config(chip, iface, timing_mode); 73762306a36Sopenharmony_ci} 738