1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2974647eaSBoris BREZILLON /* 3974647eaSBoris BREZILLON * Copyright (C) 2014 Free Electrons 4974647eaSBoris BREZILLON * 5974647eaSBoris BREZILLON * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> 6974647eaSBoris BREZILLON */ 7974647eaSBoris BREZILLON #include <linux/kernel.h> 8974647eaSBoris BREZILLON #include <linux/err.h> 9974647eaSBoris BREZILLON #include <linux/export.h> 10348d56a8SBoris Brezillon 11348d56a8SBoris Brezillon #include "internals.h" 12974647eaSBoris BREZILLON 136a943386SMiquel Raynal #define ONFI_DYN_TIMING_MAX U16_MAX 146a943386SMiquel Raynal 15d1bfe1e3SMiquel Raynal /* 16d1bfe1e3SMiquel Raynal * For non-ONFI chips we use the highest possible value for tPROG and tBERS. 17d1bfe1e3SMiquel Raynal * tR and tCCS will take the default values precised in the ONFI specification 18d1bfe1e3SMiquel Raynal * for timing mode 0, respectively 200us and 500ns. 19d1bfe1e3SMiquel Raynal * 20d1bfe1e3SMiquel Raynal * These four values are tweaked to be more accurate in the case of ONFI chips. 21d1bfe1e3SMiquel Raynal */ 224c46667bSMiquel Raynal static const struct nand_interface_config onfi_sdr_timings[] = { 23974647eaSBoris BREZILLON /* Mode 0 */ 24974647eaSBoris BREZILLON { 25b1dd3ca2SSascha Hauer .type = NAND_SDR_IFACE, 2683c411c2SMiquel Raynal .timings.mode = 0, 27b1dd3ca2SSascha Hauer .timings.sdr = { 28204e7ecdSBoris Brezillon .tCCS_min = 500000, 29204e7ecdSBoris Brezillon .tR_max = 200000000, 30d1bfe1e3SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 31d1bfe1e3SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 3274a332e7SBoris Brezillon .tADL_min = 400000, 33974647eaSBoris BREZILLON .tALH_min = 20000, 34974647eaSBoris BREZILLON .tALS_min = 50000, 35974647eaSBoris BREZILLON .tAR_min = 25000, 36974647eaSBoris BREZILLON .tCEA_max = 100000, 37974647eaSBoris BREZILLON .tCEH_min = 20000, 38974647eaSBoris BREZILLON .tCH_min = 20000, 39974647eaSBoris BREZILLON .tCHZ_max = 100000, 40974647eaSBoris BREZILLON .tCLH_min = 20000, 41974647eaSBoris BREZILLON .tCLR_min = 20000, 42974647eaSBoris BREZILLON .tCLS_min = 50000, 43974647eaSBoris BREZILLON .tCOH_min = 0, 44974647eaSBoris BREZILLON .tCS_min = 70000, 45974647eaSBoris BREZILLON .tDH_min = 20000, 46974647eaSBoris BREZILLON .tDS_min = 40000, 47974647eaSBoris BREZILLON .tFEAT_max = 1000000, 48974647eaSBoris BREZILLON .tIR_min = 10000, 49974647eaSBoris BREZILLON .tITC_max = 1000000, 50974647eaSBoris BREZILLON .tRC_min = 100000, 51974647eaSBoris BREZILLON .tREA_max = 40000, 52974647eaSBoris BREZILLON .tREH_min = 30000, 53974647eaSBoris BREZILLON .tRHOH_min = 0, 54974647eaSBoris BREZILLON .tRHW_min = 200000, 55974647eaSBoris BREZILLON .tRHZ_max = 200000, 56974647eaSBoris BREZILLON .tRLOH_min = 0, 57974647eaSBoris BREZILLON .tRP_min = 50000, 5857d419a4SBoris Brezillon .tRR_min = 40000, 59bd8898dbSGeert Uytterhoeven .tRST_max = 250000000000ULL, 60974647eaSBoris BREZILLON .tWB_max = 200000, 61974647eaSBoris BREZILLON .tWC_min = 100000, 62974647eaSBoris BREZILLON .tWH_min = 30000, 63974647eaSBoris BREZILLON .tWHR_min = 120000, 64974647eaSBoris BREZILLON .tWP_min = 50000, 65974647eaSBoris BREZILLON .tWW_min = 100000, 66974647eaSBoris BREZILLON }, 67b1dd3ca2SSascha Hauer }, 68974647eaSBoris BREZILLON /* Mode 1 */ 69974647eaSBoris BREZILLON { 70b1dd3ca2SSascha Hauer .type = NAND_SDR_IFACE, 7183c411c2SMiquel Raynal .timings.mode = 1, 72b1dd3ca2SSascha Hauer .timings.sdr = { 73204e7ecdSBoris Brezillon .tCCS_min = 500000, 74204e7ecdSBoris Brezillon .tR_max = 200000000, 75d1bfe1e3SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 76d1bfe1e3SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 7774a332e7SBoris Brezillon .tADL_min = 400000, 78974647eaSBoris BREZILLON .tALH_min = 10000, 79974647eaSBoris BREZILLON .tALS_min = 25000, 80974647eaSBoris BREZILLON .tAR_min = 10000, 81974647eaSBoris BREZILLON .tCEA_max = 45000, 82974647eaSBoris BREZILLON .tCEH_min = 20000, 83974647eaSBoris BREZILLON .tCH_min = 10000, 84974647eaSBoris BREZILLON .tCHZ_max = 50000, 85974647eaSBoris BREZILLON .tCLH_min = 10000, 86974647eaSBoris BREZILLON .tCLR_min = 10000, 87974647eaSBoris BREZILLON .tCLS_min = 25000, 88974647eaSBoris BREZILLON .tCOH_min = 15000, 89974647eaSBoris BREZILLON .tCS_min = 35000, 90974647eaSBoris BREZILLON .tDH_min = 10000, 91974647eaSBoris BREZILLON .tDS_min = 20000, 92974647eaSBoris BREZILLON .tFEAT_max = 1000000, 93974647eaSBoris BREZILLON .tIR_min = 0, 94974647eaSBoris BREZILLON .tITC_max = 1000000, 95974647eaSBoris BREZILLON .tRC_min = 50000, 96974647eaSBoris BREZILLON .tREA_max = 30000, 97974647eaSBoris BREZILLON .tREH_min = 15000, 98974647eaSBoris BREZILLON .tRHOH_min = 15000, 99974647eaSBoris BREZILLON .tRHW_min = 100000, 100974647eaSBoris BREZILLON .tRHZ_max = 100000, 101974647eaSBoris BREZILLON .tRLOH_min = 0, 102974647eaSBoris BREZILLON .tRP_min = 25000, 103974647eaSBoris BREZILLON .tRR_min = 20000, 104974647eaSBoris BREZILLON .tRST_max = 500000000, 105974647eaSBoris BREZILLON .tWB_max = 100000, 106974647eaSBoris BREZILLON .tWC_min = 45000, 107974647eaSBoris BREZILLON .tWH_min = 15000, 108974647eaSBoris BREZILLON .tWHR_min = 80000, 109974647eaSBoris BREZILLON .tWP_min = 25000, 110974647eaSBoris BREZILLON .tWW_min = 100000, 111974647eaSBoris BREZILLON }, 112b1dd3ca2SSascha Hauer }, 113974647eaSBoris BREZILLON /* Mode 2 */ 114974647eaSBoris BREZILLON { 115b1dd3ca2SSascha Hauer .type = NAND_SDR_IFACE, 11683c411c2SMiquel Raynal .timings.mode = 2, 117b1dd3ca2SSascha Hauer .timings.sdr = { 118204e7ecdSBoris Brezillon .tCCS_min = 500000, 119204e7ecdSBoris Brezillon .tR_max = 200000000, 120d1bfe1e3SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 121d1bfe1e3SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 12274a332e7SBoris Brezillon .tADL_min = 400000, 123974647eaSBoris BREZILLON .tALH_min = 10000, 124974647eaSBoris BREZILLON .tALS_min = 15000, 125974647eaSBoris BREZILLON .tAR_min = 10000, 126974647eaSBoris BREZILLON .tCEA_max = 30000, 127974647eaSBoris BREZILLON .tCEH_min = 20000, 128974647eaSBoris BREZILLON .tCH_min = 10000, 129974647eaSBoris BREZILLON .tCHZ_max = 50000, 130974647eaSBoris BREZILLON .tCLH_min = 10000, 131974647eaSBoris BREZILLON .tCLR_min = 10000, 132974647eaSBoris BREZILLON .tCLS_min = 15000, 133974647eaSBoris BREZILLON .tCOH_min = 15000, 134974647eaSBoris BREZILLON .tCS_min = 25000, 135974647eaSBoris BREZILLON .tDH_min = 5000, 136974647eaSBoris BREZILLON .tDS_min = 15000, 137974647eaSBoris BREZILLON .tFEAT_max = 1000000, 138974647eaSBoris BREZILLON .tIR_min = 0, 139974647eaSBoris BREZILLON .tITC_max = 1000000, 140974647eaSBoris BREZILLON .tRC_min = 35000, 141974647eaSBoris BREZILLON .tREA_max = 25000, 142974647eaSBoris BREZILLON .tREH_min = 15000, 143974647eaSBoris BREZILLON .tRHOH_min = 15000, 144974647eaSBoris BREZILLON .tRHW_min = 100000, 145974647eaSBoris BREZILLON .tRHZ_max = 100000, 146974647eaSBoris BREZILLON .tRLOH_min = 0, 147974647eaSBoris BREZILLON .tRR_min = 20000, 148974647eaSBoris BREZILLON .tRST_max = 500000000, 149974647eaSBoris BREZILLON .tWB_max = 100000, 150974647eaSBoris BREZILLON .tRP_min = 17000, 151974647eaSBoris BREZILLON .tWC_min = 35000, 152974647eaSBoris BREZILLON .tWH_min = 15000, 153974647eaSBoris BREZILLON .tWHR_min = 80000, 154974647eaSBoris BREZILLON .tWP_min = 17000, 155974647eaSBoris BREZILLON .tWW_min = 100000, 156974647eaSBoris BREZILLON }, 157b1dd3ca2SSascha Hauer }, 158974647eaSBoris BREZILLON /* Mode 3 */ 159974647eaSBoris BREZILLON { 160b1dd3ca2SSascha Hauer .type = NAND_SDR_IFACE, 16183c411c2SMiquel Raynal .timings.mode = 3, 162b1dd3ca2SSascha Hauer .timings.sdr = { 163204e7ecdSBoris Brezillon .tCCS_min = 500000, 164204e7ecdSBoris Brezillon .tR_max = 200000000, 165d1bfe1e3SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 166d1bfe1e3SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 16774a332e7SBoris Brezillon .tADL_min = 400000, 168974647eaSBoris BREZILLON .tALH_min = 5000, 169974647eaSBoris BREZILLON .tALS_min = 10000, 170974647eaSBoris BREZILLON .tAR_min = 10000, 171974647eaSBoris BREZILLON .tCEA_max = 25000, 172974647eaSBoris BREZILLON .tCEH_min = 20000, 173974647eaSBoris BREZILLON .tCH_min = 5000, 174974647eaSBoris BREZILLON .tCHZ_max = 50000, 175974647eaSBoris BREZILLON .tCLH_min = 5000, 176974647eaSBoris BREZILLON .tCLR_min = 10000, 177974647eaSBoris BREZILLON .tCLS_min = 10000, 178974647eaSBoris BREZILLON .tCOH_min = 15000, 179974647eaSBoris BREZILLON .tCS_min = 25000, 180974647eaSBoris BREZILLON .tDH_min = 5000, 181974647eaSBoris BREZILLON .tDS_min = 10000, 182974647eaSBoris BREZILLON .tFEAT_max = 1000000, 183974647eaSBoris BREZILLON .tIR_min = 0, 184974647eaSBoris BREZILLON .tITC_max = 1000000, 185974647eaSBoris BREZILLON .tRC_min = 30000, 186974647eaSBoris BREZILLON .tREA_max = 20000, 187974647eaSBoris BREZILLON .tREH_min = 10000, 188974647eaSBoris BREZILLON .tRHOH_min = 15000, 189974647eaSBoris BREZILLON .tRHW_min = 100000, 190974647eaSBoris BREZILLON .tRHZ_max = 100000, 191974647eaSBoris BREZILLON .tRLOH_min = 0, 192974647eaSBoris BREZILLON .tRP_min = 15000, 193974647eaSBoris BREZILLON .tRR_min = 20000, 194974647eaSBoris BREZILLON .tRST_max = 500000000, 195974647eaSBoris BREZILLON .tWB_max = 100000, 196974647eaSBoris BREZILLON .tWC_min = 30000, 197974647eaSBoris BREZILLON .tWH_min = 10000, 198974647eaSBoris BREZILLON .tWHR_min = 80000, 199974647eaSBoris BREZILLON .tWP_min = 15000, 200974647eaSBoris BREZILLON .tWW_min = 100000, 201974647eaSBoris BREZILLON }, 202b1dd3ca2SSascha Hauer }, 203974647eaSBoris BREZILLON /* Mode 4 */ 204974647eaSBoris BREZILLON { 205b1dd3ca2SSascha Hauer .type = NAND_SDR_IFACE, 20683c411c2SMiquel Raynal .timings.mode = 4, 207b1dd3ca2SSascha Hauer .timings.sdr = { 208204e7ecdSBoris Brezillon .tCCS_min = 500000, 209204e7ecdSBoris Brezillon .tR_max = 200000000, 210d1bfe1e3SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 211d1bfe1e3SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 21274a332e7SBoris Brezillon .tADL_min = 400000, 213974647eaSBoris BREZILLON .tALH_min = 5000, 214974647eaSBoris BREZILLON .tALS_min = 10000, 215974647eaSBoris BREZILLON .tAR_min = 10000, 216974647eaSBoris BREZILLON .tCEA_max = 25000, 217974647eaSBoris BREZILLON .tCEH_min = 20000, 218974647eaSBoris BREZILLON .tCH_min = 5000, 219974647eaSBoris BREZILLON .tCHZ_max = 30000, 220974647eaSBoris BREZILLON .tCLH_min = 5000, 221974647eaSBoris BREZILLON .tCLR_min = 10000, 222974647eaSBoris BREZILLON .tCLS_min = 10000, 223974647eaSBoris BREZILLON .tCOH_min = 15000, 224974647eaSBoris BREZILLON .tCS_min = 20000, 225974647eaSBoris BREZILLON .tDH_min = 5000, 226974647eaSBoris BREZILLON .tDS_min = 10000, 227974647eaSBoris BREZILLON .tFEAT_max = 1000000, 228974647eaSBoris BREZILLON .tIR_min = 0, 229974647eaSBoris BREZILLON .tITC_max = 1000000, 230974647eaSBoris BREZILLON .tRC_min = 25000, 231974647eaSBoris BREZILLON .tREA_max = 20000, 232974647eaSBoris BREZILLON .tREH_min = 10000, 233974647eaSBoris BREZILLON .tRHOH_min = 15000, 234974647eaSBoris BREZILLON .tRHW_min = 100000, 235974647eaSBoris BREZILLON .tRHZ_max = 100000, 236974647eaSBoris BREZILLON .tRLOH_min = 5000, 237974647eaSBoris BREZILLON .tRP_min = 12000, 238974647eaSBoris BREZILLON .tRR_min = 20000, 239974647eaSBoris BREZILLON .tRST_max = 500000000, 240974647eaSBoris BREZILLON .tWB_max = 100000, 241974647eaSBoris BREZILLON .tWC_min = 25000, 242974647eaSBoris BREZILLON .tWH_min = 10000, 243974647eaSBoris BREZILLON .tWHR_min = 80000, 244974647eaSBoris BREZILLON .tWP_min = 12000, 245974647eaSBoris BREZILLON .tWW_min = 100000, 246974647eaSBoris BREZILLON }, 247b1dd3ca2SSascha Hauer }, 248974647eaSBoris BREZILLON /* Mode 5 */ 249974647eaSBoris BREZILLON { 250b1dd3ca2SSascha Hauer .type = NAND_SDR_IFACE, 25183c411c2SMiquel Raynal .timings.mode = 5, 252b1dd3ca2SSascha Hauer .timings.sdr = { 253204e7ecdSBoris Brezillon .tCCS_min = 500000, 254204e7ecdSBoris Brezillon .tR_max = 200000000, 255d1bfe1e3SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 256d1bfe1e3SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 25774a332e7SBoris Brezillon .tADL_min = 400000, 258974647eaSBoris BREZILLON .tALH_min = 5000, 259974647eaSBoris BREZILLON .tALS_min = 10000, 260974647eaSBoris BREZILLON .tAR_min = 10000, 261974647eaSBoris BREZILLON .tCEA_max = 25000, 262974647eaSBoris BREZILLON .tCEH_min = 20000, 263974647eaSBoris BREZILLON .tCH_min = 5000, 264974647eaSBoris BREZILLON .tCHZ_max = 30000, 265974647eaSBoris BREZILLON .tCLH_min = 5000, 266974647eaSBoris BREZILLON .tCLR_min = 10000, 267974647eaSBoris BREZILLON .tCLS_min = 10000, 268974647eaSBoris BREZILLON .tCOH_min = 15000, 269974647eaSBoris BREZILLON .tCS_min = 15000, 270974647eaSBoris BREZILLON .tDH_min = 5000, 271974647eaSBoris BREZILLON .tDS_min = 7000, 272974647eaSBoris BREZILLON .tFEAT_max = 1000000, 273974647eaSBoris BREZILLON .tIR_min = 0, 274974647eaSBoris BREZILLON .tITC_max = 1000000, 275974647eaSBoris BREZILLON .tRC_min = 20000, 276974647eaSBoris BREZILLON .tREA_max = 16000, 277974647eaSBoris BREZILLON .tREH_min = 7000, 278974647eaSBoris BREZILLON .tRHOH_min = 15000, 279974647eaSBoris BREZILLON .tRHW_min = 100000, 280974647eaSBoris BREZILLON .tRHZ_max = 100000, 281974647eaSBoris BREZILLON .tRLOH_min = 5000, 282974647eaSBoris BREZILLON .tRP_min = 10000, 283974647eaSBoris BREZILLON .tRR_min = 20000, 284974647eaSBoris BREZILLON .tRST_max = 500000000, 285974647eaSBoris BREZILLON .tWB_max = 100000, 286974647eaSBoris BREZILLON .tWC_min = 20000, 287974647eaSBoris BREZILLON .tWH_min = 7000, 288974647eaSBoris BREZILLON .tWHR_min = 80000, 289974647eaSBoris BREZILLON .tWP_min = 10000, 290974647eaSBoris BREZILLON .tWW_min = 100000, 291974647eaSBoris BREZILLON }, 292b1dd3ca2SSascha Hauer }, 293974647eaSBoris BREZILLON }; 294974647eaSBoris BREZILLON 2951666b815SMiquel Raynal static const struct nand_interface_config onfi_nvddr_timings[] = { 2961666b815SMiquel Raynal /* Mode 0 */ 2971666b815SMiquel Raynal { 2981666b815SMiquel Raynal .type = NAND_NVDDR_IFACE, 2991666b815SMiquel Raynal .timings.mode = 0, 3001666b815SMiquel Raynal .timings.nvddr = { 3011666b815SMiquel Raynal .tCCS_min = 500000, 3021666b815SMiquel Raynal .tR_max = 200000000, 3031666b815SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 3041666b815SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 3051666b815SMiquel Raynal .tAC_min = 3000, 3061666b815SMiquel Raynal .tAC_max = 25000, 3071666b815SMiquel Raynal .tADL_min = 400000, 3081666b815SMiquel Raynal .tCAD_min = 45000, 3091666b815SMiquel Raynal .tCAH_min = 10000, 3101666b815SMiquel Raynal .tCALH_min = 10000, 3111666b815SMiquel Raynal .tCALS_min = 10000, 3121666b815SMiquel Raynal .tCAS_min = 10000, 3131666b815SMiquel Raynal .tCEH_min = 20000, 3141666b815SMiquel Raynal .tCH_min = 10000, 3151666b815SMiquel Raynal .tCK_min = 50000, 3161666b815SMiquel Raynal .tCS_min = 35000, 3171666b815SMiquel Raynal .tDH_min = 5000, 3181666b815SMiquel Raynal .tDQSCK_min = 3000, 3191666b815SMiquel Raynal .tDQSCK_max = 25000, 3201666b815SMiquel Raynal .tDQSD_min = 0, 3211666b815SMiquel Raynal .tDQSD_max = 18000, 3221666b815SMiquel Raynal .tDQSHZ_max = 20000, 3231666b815SMiquel Raynal .tDQSQ_max = 5000, 3241666b815SMiquel Raynal .tDS_min = 5000, 3251666b815SMiquel Raynal .tDSC_min = 50000, 3261666b815SMiquel Raynal .tFEAT_max = 1000000, 3271666b815SMiquel Raynal .tITC_max = 1000000, 3281666b815SMiquel Raynal .tQHS_max = 6000, 3291666b815SMiquel Raynal .tRHW_min = 100000, 3301666b815SMiquel Raynal .tRR_min = 20000, 3311666b815SMiquel Raynal .tRST_max = 500000000, 3321666b815SMiquel Raynal .tWB_max = 100000, 3331666b815SMiquel Raynal .tWHR_min = 80000, 3341666b815SMiquel Raynal .tWRCK_min = 20000, 3351666b815SMiquel Raynal .tWW_min = 100000, 3361666b815SMiquel Raynal }, 3371666b815SMiquel Raynal }, 3381666b815SMiquel Raynal /* Mode 1 */ 3391666b815SMiquel Raynal { 3401666b815SMiquel Raynal .type = NAND_NVDDR_IFACE, 3411666b815SMiquel Raynal .timings.mode = 1, 3421666b815SMiquel Raynal .timings.nvddr = { 3431666b815SMiquel Raynal .tCCS_min = 500000, 3441666b815SMiquel Raynal .tR_max = 200000000, 3451666b815SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 3461666b815SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 3471666b815SMiquel Raynal .tAC_min = 3000, 3481666b815SMiquel Raynal .tAC_max = 25000, 3491666b815SMiquel Raynal .tADL_min = 400000, 3501666b815SMiquel Raynal .tCAD_min = 45000, 3511666b815SMiquel Raynal .tCAH_min = 5000, 3521666b815SMiquel Raynal .tCALH_min = 5000, 3531666b815SMiquel Raynal .tCALS_min = 5000, 3541666b815SMiquel Raynal .tCAS_min = 5000, 3551666b815SMiquel Raynal .tCEH_min = 20000, 3561666b815SMiquel Raynal .tCH_min = 5000, 3571666b815SMiquel Raynal .tCK_min = 30000, 3581666b815SMiquel Raynal .tCS_min = 25000, 3591666b815SMiquel Raynal .tDH_min = 2500, 3601666b815SMiquel Raynal .tDQSCK_min = 3000, 3611666b815SMiquel Raynal .tDQSCK_max = 25000, 3621666b815SMiquel Raynal .tDQSD_min = 0, 3631666b815SMiquel Raynal .tDQSD_max = 18000, 3641666b815SMiquel Raynal .tDQSHZ_max = 20000, 3651666b815SMiquel Raynal .tDQSQ_max = 2500, 3661666b815SMiquel Raynal .tDS_min = 3000, 3671666b815SMiquel Raynal .tDSC_min = 30000, 3681666b815SMiquel Raynal .tFEAT_max = 1000000, 3691666b815SMiquel Raynal .tITC_max = 1000000, 3701666b815SMiquel Raynal .tQHS_max = 3000, 3711666b815SMiquel Raynal .tRHW_min = 100000, 3721666b815SMiquel Raynal .tRR_min = 20000, 3731666b815SMiquel Raynal .tRST_max = 500000000, 3741666b815SMiquel Raynal .tWB_max = 100000, 3751666b815SMiquel Raynal .tWHR_min = 80000, 3761666b815SMiquel Raynal .tWRCK_min = 20000, 3771666b815SMiquel Raynal .tWW_min = 100000, 3781666b815SMiquel Raynal }, 3791666b815SMiquel Raynal }, 3801666b815SMiquel Raynal /* Mode 2 */ 3811666b815SMiquel Raynal { 3821666b815SMiquel Raynal .type = NAND_NVDDR_IFACE, 3831666b815SMiquel Raynal .timings.mode = 2, 3841666b815SMiquel Raynal .timings.nvddr = { 3851666b815SMiquel Raynal .tCCS_min = 500000, 3861666b815SMiquel Raynal .tR_max = 200000000, 3871666b815SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 3881666b815SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 3891666b815SMiquel Raynal .tAC_min = 3000, 3901666b815SMiquel Raynal .tAC_max = 25000, 3911666b815SMiquel Raynal .tADL_min = 400000, 3921666b815SMiquel Raynal .tCAD_min = 45000, 3931666b815SMiquel Raynal .tCAH_min = 4000, 3941666b815SMiquel Raynal .tCALH_min = 4000, 3951666b815SMiquel Raynal .tCALS_min = 4000, 3961666b815SMiquel Raynal .tCAS_min = 4000, 3971666b815SMiquel Raynal .tCEH_min = 20000, 3981666b815SMiquel Raynal .tCH_min = 4000, 3991666b815SMiquel Raynal .tCK_min = 20000, 4001666b815SMiquel Raynal .tCS_min = 15000, 4011666b815SMiquel Raynal .tDH_min = 1700, 4021666b815SMiquel Raynal .tDQSCK_min = 3000, 4031666b815SMiquel Raynal .tDQSCK_max = 25000, 4041666b815SMiquel Raynal .tDQSD_min = 0, 4051666b815SMiquel Raynal .tDQSD_max = 18000, 4061666b815SMiquel Raynal .tDQSHZ_max = 20000, 4071666b815SMiquel Raynal .tDQSQ_max = 1700, 4081666b815SMiquel Raynal .tDS_min = 2000, 4091666b815SMiquel Raynal .tDSC_min = 20000, 4101666b815SMiquel Raynal .tFEAT_max = 1000000, 4111666b815SMiquel Raynal .tITC_max = 1000000, 4121666b815SMiquel Raynal .tQHS_max = 2000, 4131666b815SMiquel Raynal .tRHW_min = 100000, 4141666b815SMiquel Raynal .tRR_min = 20000, 4151666b815SMiquel Raynal .tRST_max = 500000000, 4161666b815SMiquel Raynal .tWB_max = 100000, 4171666b815SMiquel Raynal .tWHR_min = 80000, 4181666b815SMiquel Raynal .tWRCK_min = 20000, 4191666b815SMiquel Raynal .tWW_min = 100000, 4201666b815SMiquel Raynal }, 4211666b815SMiquel Raynal }, 4221666b815SMiquel Raynal /* Mode 3 */ 4231666b815SMiquel Raynal { 4241666b815SMiquel Raynal .type = NAND_NVDDR_IFACE, 4251666b815SMiquel Raynal .timings.mode = 3, 4261666b815SMiquel Raynal .timings.nvddr = { 4271666b815SMiquel Raynal .tCCS_min = 500000, 4281666b815SMiquel Raynal .tR_max = 200000000, 4291666b815SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 4301666b815SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 4311666b815SMiquel Raynal .tAC_min = 3000, 4321666b815SMiquel Raynal .tAC_max = 25000, 4331666b815SMiquel Raynal .tADL_min = 400000, 4341666b815SMiquel Raynal .tCAD_min = 45000, 4351666b815SMiquel Raynal .tCAH_min = 3000, 4361666b815SMiquel Raynal .tCALH_min = 3000, 4371666b815SMiquel Raynal .tCALS_min = 3000, 4381666b815SMiquel Raynal .tCAS_min = 3000, 4391666b815SMiquel Raynal .tCEH_min = 20000, 4401666b815SMiquel Raynal .tCH_min = 3000, 4411666b815SMiquel Raynal .tCK_min = 15000, 4421666b815SMiquel Raynal .tCS_min = 15000, 4431666b815SMiquel Raynal .tDH_min = 1300, 4441666b815SMiquel Raynal .tDQSCK_min = 3000, 4451666b815SMiquel Raynal .tDQSCK_max = 25000, 4461666b815SMiquel Raynal .tDQSD_min = 0, 4471666b815SMiquel Raynal .tDQSD_max = 18000, 4481666b815SMiquel Raynal .tDQSHZ_max = 20000, 4491666b815SMiquel Raynal .tDQSQ_max = 1300, 4501666b815SMiquel Raynal .tDS_min = 1500, 4511666b815SMiquel Raynal .tDSC_min = 15000, 4521666b815SMiquel Raynal .tFEAT_max = 1000000, 4531666b815SMiquel Raynal .tITC_max = 1000000, 4541666b815SMiquel Raynal .tQHS_max = 1500, 4551666b815SMiquel Raynal .tRHW_min = 100000, 4561666b815SMiquel Raynal .tRR_min = 20000, 4571666b815SMiquel Raynal .tRST_max = 500000000, 4581666b815SMiquel Raynal .tWB_max = 100000, 4591666b815SMiquel Raynal .tWHR_min = 80000, 4601666b815SMiquel Raynal .tWRCK_min = 20000, 4611666b815SMiquel Raynal .tWW_min = 100000, 4621666b815SMiquel Raynal }, 4631666b815SMiquel Raynal }, 4641666b815SMiquel Raynal /* Mode 4 */ 4651666b815SMiquel Raynal { 4661666b815SMiquel Raynal .type = NAND_NVDDR_IFACE, 4671666b815SMiquel Raynal .timings.mode = 4, 4681666b815SMiquel Raynal .timings.nvddr = { 4691666b815SMiquel Raynal .tCCS_min = 500000, 4701666b815SMiquel Raynal .tR_max = 200000000, 4711666b815SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 4721666b815SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 4731666b815SMiquel Raynal .tAC_min = 3000, 4741666b815SMiquel Raynal .tAC_max = 25000, 4751666b815SMiquel Raynal .tADL_min = 400000, 4761666b815SMiquel Raynal .tCAD_min = 45000, 4771666b815SMiquel Raynal .tCAH_min = 2500, 4781666b815SMiquel Raynal .tCALH_min = 2500, 4791666b815SMiquel Raynal .tCALS_min = 2500, 4801666b815SMiquel Raynal .tCAS_min = 2500, 4811666b815SMiquel Raynal .tCEH_min = 20000, 4821666b815SMiquel Raynal .tCH_min = 2500, 4831666b815SMiquel Raynal .tCK_min = 12000, 4841666b815SMiquel Raynal .tCS_min = 15000, 4851666b815SMiquel Raynal .tDH_min = 1100, 4861666b815SMiquel Raynal .tDQSCK_min = 3000, 4871666b815SMiquel Raynal .tDQSCK_max = 25000, 4881666b815SMiquel Raynal .tDQSD_min = 0, 4891666b815SMiquel Raynal .tDQSD_max = 18000, 4901666b815SMiquel Raynal .tDQSHZ_max = 20000, 4911666b815SMiquel Raynal .tDQSQ_max = 1000, 4921666b815SMiquel Raynal .tDS_min = 1100, 4931666b815SMiquel Raynal .tDSC_min = 12000, 4941666b815SMiquel Raynal .tFEAT_max = 1000000, 4951666b815SMiquel Raynal .tITC_max = 1000000, 4961666b815SMiquel Raynal .tQHS_max = 1200, 4971666b815SMiquel Raynal .tRHW_min = 100000, 4981666b815SMiquel Raynal .tRR_min = 20000, 4991666b815SMiquel Raynal .tRST_max = 500000000, 5001666b815SMiquel Raynal .tWB_max = 100000, 5011666b815SMiquel Raynal .tWHR_min = 80000, 5021666b815SMiquel Raynal .tWRCK_min = 20000, 5031666b815SMiquel Raynal .tWW_min = 100000, 5041666b815SMiquel Raynal }, 5051666b815SMiquel Raynal }, 5061666b815SMiquel Raynal /* Mode 5 */ 5071666b815SMiquel Raynal { 5081666b815SMiquel Raynal .type = NAND_NVDDR_IFACE, 5091666b815SMiquel Raynal .timings.mode = 5, 5101666b815SMiquel Raynal .timings.nvddr = { 5111666b815SMiquel Raynal .tCCS_min = 500000, 5121666b815SMiquel Raynal .tR_max = 200000000, 5131666b815SMiquel Raynal .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 5141666b815SMiquel Raynal .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 5151666b815SMiquel Raynal .tAC_min = 3000, 5161666b815SMiquel Raynal .tAC_max = 25000, 5171666b815SMiquel Raynal .tADL_min = 400000, 5181666b815SMiquel Raynal .tCAD_min = 45000, 5191666b815SMiquel Raynal .tCAH_min = 2000, 5201666b815SMiquel Raynal .tCALH_min = 2000, 5211666b815SMiquel Raynal .tCALS_min = 2000, 5221666b815SMiquel Raynal .tCAS_min = 2000, 5231666b815SMiquel Raynal .tCEH_min = 20000, 5241666b815SMiquel Raynal .tCH_min = 2000, 5251666b815SMiquel Raynal .tCK_min = 10000, 5261666b815SMiquel Raynal .tCS_min = 15000, 5271666b815SMiquel Raynal .tDH_min = 900, 5281666b815SMiquel Raynal .tDQSCK_min = 3000, 5291666b815SMiquel Raynal .tDQSCK_max = 25000, 5301666b815SMiquel Raynal .tDQSD_min = 0, 5311666b815SMiquel Raynal .tDQSD_max = 18000, 5321666b815SMiquel Raynal .tDQSHZ_max = 20000, 5331666b815SMiquel Raynal .tDQSQ_max = 850, 5341666b815SMiquel Raynal .tDS_min = 900, 5351666b815SMiquel Raynal .tDSC_min = 10000, 5361666b815SMiquel Raynal .tFEAT_max = 1000000, 5371666b815SMiquel Raynal .tITC_max = 1000000, 5381666b815SMiquel Raynal .tQHS_max = 1000, 5391666b815SMiquel Raynal .tRHW_min = 100000, 5401666b815SMiquel Raynal .tRR_min = 20000, 5411666b815SMiquel Raynal .tRST_max = 500000000, 5421666b815SMiquel Raynal .tWB_max = 100000, 5431666b815SMiquel Raynal .tWHR_min = 80000, 5441666b815SMiquel Raynal .tWRCK_min = 20000, 5451666b815SMiquel Raynal .tWW_min = 100000, 5461666b815SMiquel Raynal }, 5471666b815SMiquel Raynal }, 5481666b815SMiquel Raynal }; 5491666b815SMiquel Raynal 55035b6bcc9SMiquel Raynal /* All NAND chips share the same reset data interface: SDR mode 0 */ 55135b6bcc9SMiquel Raynal const struct nand_interface_config *nand_get_reset_interface_config(void) 55235b6bcc9SMiquel Raynal { 55335b6bcc9SMiquel Raynal return &onfi_sdr_timings[0]; 55435b6bcc9SMiquel Raynal } 55535b6bcc9SMiquel Raynal 556974647eaSBoris BREZILLON /** 55798d6979aSMiquel Raynal * onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a 55898d6979aSMiquel Raynal * set of timings 55998d6979aSMiquel Raynal * @spec_timings: the timings to challenge 56098d6979aSMiquel Raynal */ 56198d6979aSMiquel Raynal unsigned int 56298d6979aSMiquel Raynal onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings) 56398d6979aSMiquel Raynal { 56498d6979aSMiquel Raynal const struct nand_sdr_timings *onfi_timings; 56598d6979aSMiquel Raynal int mode; 56698d6979aSMiquel Raynal 56798d6979aSMiquel Raynal for (mode = ARRAY_SIZE(onfi_sdr_timings) - 1; mode > 0; mode--) { 56898d6979aSMiquel Raynal onfi_timings = &onfi_sdr_timings[mode].timings.sdr; 56998d6979aSMiquel Raynal 57098d6979aSMiquel Raynal if (spec_timings->tCCS_min <= onfi_timings->tCCS_min && 57198d6979aSMiquel Raynal spec_timings->tADL_min <= onfi_timings->tADL_min && 57298d6979aSMiquel Raynal spec_timings->tALH_min <= onfi_timings->tALH_min && 57398d6979aSMiquel Raynal spec_timings->tALS_min <= onfi_timings->tALS_min && 57498d6979aSMiquel Raynal spec_timings->tAR_min <= onfi_timings->tAR_min && 57598d6979aSMiquel Raynal spec_timings->tCEH_min <= onfi_timings->tCEH_min && 57698d6979aSMiquel Raynal spec_timings->tCH_min <= onfi_timings->tCH_min && 57798d6979aSMiquel Raynal spec_timings->tCLH_min <= onfi_timings->tCLH_min && 57898d6979aSMiquel Raynal spec_timings->tCLR_min <= onfi_timings->tCLR_min && 57998d6979aSMiquel Raynal spec_timings->tCLS_min <= onfi_timings->tCLS_min && 58098d6979aSMiquel Raynal spec_timings->tCOH_min <= onfi_timings->tCOH_min && 58198d6979aSMiquel Raynal spec_timings->tCS_min <= onfi_timings->tCS_min && 58298d6979aSMiquel Raynal spec_timings->tDH_min <= onfi_timings->tDH_min && 58398d6979aSMiquel Raynal spec_timings->tDS_min <= onfi_timings->tDS_min && 58498d6979aSMiquel Raynal spec_timings->tIR_min <= onfi_timings->tIR_min && 58598d6979aSMiquel Raynal spec_timings->tRC_min <= onfi_timings->tRC_min && 58698d6979aSMiquel Raynal spec_timings->tREH_min <= onfi_timings->tREH_min && 58798d6979aSMiquel Raynal spec_timings->tRHOH_min <= onfi_timings->tRHOH_min && 58898d6979aSMiquel Raynal spec_timings->tRHW_min <= onfi_timings->tRHW_min && 58998d6979aSMiquel Raynal spec_timings->tRLOH_min <= onfi_timings->tRLOH_min && 59098d6979aSMiquel Raynal spec_timings->tRP_min <= onfi_timings->tRP_min && 59198d6979aSMiquel Raynal spec_timings->tRR_min <= onfi_timings->tRR_min && 59298d6979aSMiquel Raynal spec_timings->tWC_min <= onfi_timings->tWC_min && 59398d6979aSMiquel Raynal spec_timings->tWH_min <= onfi_timings->tWH_min && 59498d6979aSMiquel Raynal spec_timings->tWHR_min <= onfi_timings->tWHR_min && 59598d6979aSMiquel Raynal spec_timings->tWP_min <= onfi_timings->tWP_min && 59698d6979aSMiquel Raynal spec_timings->tWW_min <= onfi_timings->tWW_min) 59798d6979aSMiquel Raynal return mode; 59898d6979aSMiquel Raynal } 59998d6979aSMiquel Raynal 60098d6979aSMiquel Raynal return 0; 60198d6979aSMiquel Raynal } 60298d6979aSMiquel Raynal 60398d6979aSMiquel Raynal /** 604*e32df79fSMiquel Raynal * onfi_find_closest_nvddr_mode - Derive the closest ONFI NVDDR timing mode 605*e32df79fSMiquel Raynal * given a set of timings 606*e32df79fSMiquel Raynal * @spec_timings: the timings to challenge 607*e32df79fSMiquel Raynal */ 608*e32df79fSMiquel Raynal unsigned int 609*e32df79fSMiquel Raynal onfi_find_closest_nvddr_mode(const struct nand_nvddr_timings *spec_timings) 610*e32df79fSMiquel Raynal { 611*e32df79fSMiquel Raynal const struct nand_nvddr_timings *onfi_timings; 612*e32df79fSMiquel Raynal int mode; 613*e32df79fSMiquel Raynal 614*e32df79fSMiquel Raynal for (mode = ARRAY_SIZE(onfi_nvddr_timings) - 1; mode > 0; mode--) { 615*e32df79fSMiquel Raynal onfi_timings = &onfi_nvddr_timings[mode].timings.nvddr; 616*e32df79fSMiquel Raynal 617*e32df79fSMiquel Raynal if (spec_timings->tCCS_min <= onfi_timings->tCCS_min && 618*e32df79fSMiquel Raynal spec_timings->tAC_min <= onfi_timings->tAC_min && 619*e32df79fSMiquel Raynal spec_timings->tADL_min <= onfi_timings->tADL_min && 620*e32df79fSMiquel Raynal spec_timings->tCAD_min <= onfi_timings->tCAD_min && 621*e32df79fSMiquel Raynal spec_timings->tCAH_min <= onfi_timings->tCAH_min && 622*e32df79fSMiquel Raynal spec_timings->tCALH_min <= onfi_timings->tCALH_min && 623*e32df79fSMiquel Raynal spec_timings->tCALS_min <= onfi_timings->tCALS_min && 624*e32df79fSMiquel Raynal spec_timings->tCAS_min <= onfi_timings->tCAS_min && 625*e32df79fSMiquel Raynal spec_timings->tCEH_min <= onfi_timings->tCEH_min && 626*e32df79fSMiquel Raynal spec_timings->tCH_min <= onfi_timings->tCH_min && 627*e32df79fSMiquel Raynal spec_timings->tCK_min <= onfi_timings->tCK_min && 628*e32df79fSMiquel Raynal spec_timings->tCS_min <= onfi_timings->tCS_min && 629*e32df79fSMiquel Raynal spec_timings->tDH_min <= onfi_timings->tDH_min && 630*e32df79fSMiquel Raynal spec_timings->tDQSCK_min <= onfi_timings->tDQSCK_min && 631*e32df79fSMiquel Raynal spec_timings->tDQSD_min <= onfi_timings->tDQSD_min && 632*e32df79fSMiquel Raynal spec_timings->tDS_min <= onfi_timings->tDS_min && 633*e32df79fSMiquel Raynal spec_timings->tDSC_min <= onfi_timings->tDSC_min && 634*e32df79fSMiquel Raynal spec_timings->tRHW_min <= onfi_timings->tRHW_min && 635*e32df79fSMiquel Raynal spec_timings->tRR_min <= onfi_timings->tRR_min && 636*e32df79fSMiquel Raynal spec_timings->tWHR_min <= onfi_timings->tWHR_min && 637*e32df79fSMiquel Raynal spec_timings->tWRCK_min <= onfi_timings->tWRCK_min && 638*e32df79fSMiquel Raynal spec_timings->tWW_min <= onfi_timings->tWW_min) 639*e32df79fSMiquel Raynal return mode; 640*e32df79fSMiquel Raynal } 641*e32df79fSMiquel Raynal 642*e32df79fSMiquel Raynal return 0; 643*e32df79fSMiquel Raynal } 644*e32df79fSMiquel Raynal 645*e32df79fSMiquel Raynal /* 64694c8ce8eSMiquel Raynal * onfi_fill_sdr_interface_config - Initialize a SDR interface config from a 64794c8ce8eSMiquel Raynal * given ONFI mode 648844cc464SMiquel Raynal * @chip: The NAND chip 6494c46667bSMiquel Raynal * @iface: The interface configuration to fill 650844cc464SMiquel Raynal * @timing_mode: The ONFI timing mode 651b88730adSSascha Hauer */ 65294c8ce8eSMiquel Raynal static void onfi_fill_sdr_interface_config(struct nand_chip *chip, 6534c46667bSMiquel Raynal struct nand_interface_config *iface, 654fcaab3b2SMiquel Raynal unsigned int timing_mode) 655b88730adSSascha Hauer { 6563d3fe3c0SMiquel Raynal struct onfi_params *onfi = chip->parameters.onfi; 65717fa8044SMiquel Raynal 65842a9ad05SMiquel Raynal if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_sdr_timings))) 65942a9ad05SMiquel Raynal return; 660b88730adSSascha Hauer 661b88730adSSascha Hauer *iface = onfi_sdr_timings[timing_mode]; 662b88730adSSascha Hauer 663b88730adSSascha Hauer /* 664204e7ecdSBoris Brezillon * Initialize timings that cannot be deduced from timing mode: 6656a943386SMiquel Raynal * tPROG, tBERS, tR and tCCS. 666b88730adSSascha Hauer * These information are part of the ONFI parameter page. 667b88730adSSascha Hauer */ 6683d3fe3c0SMiquel Raynal if (onfi) { 669204e7ecdSBoris Brezillon struct nand_sdr_timings *timings = &iface->timings.sdr; 670204e7ecdSBoris Brezillon 671204e7ecdSBoris Brezillon /* microseconds -> picoseconds */ 6723d3fe3c0SMiquel Raynal timings->tPROG_max = 1000000ULL * onfi->tPROG; 6733d3fe3c0SMiquel Raynal timings->tBERS_max = 1000000ULL * onfi->tBERS; 6743d3fe3c0SMiquel Raynal timings->tR_max = 1000000ULL * onfi->tR; 675204e7ecdSBoris Brezillon 676204e7ecdSBoris Brezillon /* nanoseconds -> picoseconds */ 6773d3fe3c0SMiquel Raynal timings->tCCS_min = 1000UL * onfi->tCCS; 678204e7ecdSBoris Brezillon } 679b88730adSSascha Hauer } 68094c8ce8eSMiquel Raynal 68194c8ce8eSMiquel Raynal /** 68245606518SMiquel Raynal * onfi_fill_nvddr_interface_config - Initialize a NVDDR interface config from a 68345606518SMiquel Raynal * given ONFI mode 68445606518SMiquel Raynal * @chip: The NAND chip 68545606518SMiquel Raynal * @iface: The interface configuration to fill 68645606518SMiquel Raynal * @timing_mode: The ONFI timing mode 68745606518SMiquel Raynal */ 68845606518SMiquel Raynal static void onfi_fill_nvddr_interface_config(struct nand_chip *chip, 68945606518SMiquel Raynal struct nand_interface_config *iface, 69045606518SMiquel Raynal unsigned int timing_mode) 69145606518SMiquel Raynal { 69245606518SMiquel Raynal struct onfi_params *onfi = chip->parameters.onfi; 69345606518SMiquel Raynal 69445606518SMiquel Raynal if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_nvddr_timings))) 69545606518SMiquel Raynal return; 69645606518SMiquel Raynal 69745606518SMiquel Raynal *iface = onfi_nvddr_timings[timing_mode]; 69845606518SMiquel Raynal 69945606518SMiquel Raynal /* 70045606518SMiquel Raynal * Initialize timings that cannot be deduced from timing mode: 70145606518SMiquel Raynal * tPROG, tBERS, tR, tCCS and tCAD. 70245606518SMiquel Raynal * These information are part of the ONFI parameter page. 70345606518SMiquel Raynal */ 70445606518SMiquel Raynal if (onfi) { 70545606518SMiquel Raynal struct nand_nvddr_timings *timings = &iface->timings.nvddr; 70645606518SMiquel Raynal 70745606518SMiquel Raynal /* microseconds -> picoseconds */ 70845606518SMiquel Raynal timings->tPROG_max = 1000000ULL * onfi->tPROG; 70945606518SMiquel Raynal timings->tBERS_max = 1000000ULL * onfi->tBERS; 71045606518SMiquel Raynal timings->tR_max = 1000000ULL * onfi->tR; 71145606518SMiquel Raynal 71245606518SMiquel Raynal /* nanoseconds -> picoseconds */ 71345606518SMiquel Raynal timings->tCCS_min = 1000UL * onfi->tCCS; 71445606518SMiquel Raynal 71545606518SMiquel Raynal if (onfi->fast_tCAD) 71645606518SMiquel Raynal timings->tCAD_min = 25000; 71745606518SMiquel Raynal } 71845606518SMiquel Raynal } 71945606518SMiquel Raynal 72045606518SMiquel Raynal /** 72194c8ce8eSMiquel Raynal * onfi_fill_interface_config - Initialize an interface config from a given 72294c8ce8eSMiquel Raynal * ONFI mode 72394c8ce8eSMiquel Raynal * @chip: The NAND chip 72494c8ce8eSMiquel Raynal * @iface: The interface configuration to fill 72594c8ce8eSMiquel Raynal * @type: The interface type 72694c8ce8eSMiquel Raynal * @timing_mode: The ONFI timing mode 72794c8ce8eSMiquel Raynal */ 72894c8ce8eSMiquel Raynal void onfi_fill_interface_config(struct nand_chip *chip, 72994c8ce8eSMiquel Raynal struct nand_interface_config *iface, 73094c8ce8eSMiquel Raynal enum nand_interface_type type, 73194c8ce8eSMiquel Raynal unsigned int timing_mode) 73294c8ce8eSMiquel Raynal { 73394c8ce8eSMiquel Raynal if (type == NAND_SDR_IFACE) 73494c8ce8eSMiquel Raynal return onfi_fill_sdr_interface_config(chip, iface, timing_mode); 73545606518SMiquel Raynal else 73645606518SMiquel Raynal return onfi_fill_nvddr_interface_config(chip, iface, timing_mode); 73794c8ce8eSMiquel Raynal } 738