0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/err.h>
0009 #include <linux/export.h>
0010
0011 #include "internals.h"
0012
0013 #define ONFI_DYN_TIMING_MAX U16_MAX
0014
0015
0016
0017
0018
0019
0020
0021
0022 static const struct nand_interface_config onfi_sdr_timings[] = {
0023
0024 {
0025 .type = NAND_SDR_IFACE,
0026 .timings.mode = 0,
0027 .timings.sdr = {
0028 .tCCS_min = 500000,
0029 .tR_max = 200000000,
0030 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0031 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0032 .tADL_min = 400000,
0033 .tALH_min = 20000,
0034 .tALS_min = 50000,
0035 .tAR_min = 25000,
0036 .tCEA_max = 100000,
0037 .tCEH_min = 20000,
0038 .tCH_min = 20000,
0039 .tCHZ_max = 100000,
0040 .tCLH_min = 20000,
0041 .tCLR_min = 20000,
0042 .tCLS_min = 50000,
0043 .tCOH_min = 0,
0044 .tCS_min = 70000,
0045 .tDH_min = 20000,
0046 .tDS_min = 40000,
0047 .tFEAT_max = 1000000,
0048 .tIR_min = 10000,
0049 .tITC_max = 1000000,
0050 .tRC_min = 100000,
0051 .tREA_max = 40000,
0052 .tREH_min = 30000,
0053 .tRHOH_min = 0,
0054 .tRHW_min = 200000,
0055 .tRHZ_max = 200000,
0056 .tRLOH_min = 0,
0057 .tRP_min = 50000,
0058 .tRR_min = 40000,
0059 .tRST_max = 250000000000ULL,
0060 .tWB_max = 200000,
0061 .tWC_min = 100000,
0062 .tWH_min = 30000,
0063 .tWHR_min = 120000,
0064 .tWP_min = 50000,
0065 .tWW_min = 100000,
0066 },
0067 },
0068
0069 {
0070 .type = NAND_SDR_IFACE,
0071 .timings.mode = 1,
0072 .timings.sdr = {
0073 .tCCS_min = 500000,
0074 .tR_max = 200000000,
0075 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0076 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0077 .tADL_min = 400000,
0078 .tALH_min = 10000,
0079 .tALS_min = 25000,
0080 .tAR_min = 10000,
0081 .tCEA_max = 45000,
0082 .tCEH_min = 20000,
0083 .tCH_min = 10000,
0084 .tCHZ_max = 50000,
0085 .tCLH_min = 10000,
0086 .tCLR_min = 10000,
0087 .tCLS_min = 25000,
0088 .tCOH_min = 15000,
0089 .tCS_min = 35000,
0090 .tDH_min = 10000,
0091 .tDS_min = 20000,
0092 .tFEAT_max = 1000000,
0093 .tIR_min = 0,
0094 .tITC_max = 1000000,
0095 .tRC_min = 50000,
0096 .tREA_max = 30000,
0097 .tREH_min = 15000,
0098 .tRHOH_min = 15000,
0099 .tRHW_min = 100000,
0100 .tRHZ_max = 100000,
0101 .tRLOH_min = 0,
0102 .tRP_min = 25000,
0103 .tRR_min = 20000,
0104 .tRST_max = 500000000,
0105 .tWB_max = 100000,
0106 .tWC_min = 45000,
0107 .tWH_min = 15000,
0108 .tWHR_min = 80000,
0109 .tWP_min = 25000,
0110 .tWW_min = 100000,
0111 },
0112 },
0113
0114 {
0115 .type = NAND_SDR_IFACE,
0116 .timings.mode = 2,
0117 .timings.sdr = {
0118 .tCCS_min = 500000,
0119 .tR_max = 200000000,
0120 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0121 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0122 .tADL_min = 400000,
0123 .tALH_min = 10000,
0124 .tALS_min = 15000,
0125 .tAR_min = 10000,
0126 .tCEA_max = 30000,
0127 .tCEH_min = 20000,
0128 .tCH_min = 10000,
0129 .tCHZ_max = 50000,
0130 .tCLH_min = 10000,
0131 .tCLR_min = 10000,
0132 .tCLS_min = 15000,
0133 .tCOH_min = 15000,
0134 .tCS_min = 25000,
0135 .tDH_min = 5000,
0136 .tDS_min = 15000,
0137 .tFEAT_max = 1000000,
0138 .tIR_min = 0,
0139 .tITC_max = 1000000,
0140 .tRC_min = 35000,
0141 .tREA_max = 25000,
0142 .tREH_min = 15000,
0143 .tRHOH_min = 15000,
0144 .tRHW_min = 100000,
0145 .tRHZ_max = 100000,
0146 .tRLOH_min = 0,
0147 .tRR_min = 20000,
0148 .tRST_max = 500000000,
0149 .tWB_max = 100000,
0150 .tRP_min = 17000,
0151 .tWC_min = 35000,
0152 .tWH_min = 15000,
0153 .tWHR_min = 80000,
0154 .tWP_min = 17000,
0155 .tWW_min = 100000,
0156 },
0157 },
0158
0159 {
0160 .type = NAND_SDR_IFACE,
0161 .timings.mode = 3,
0162 .timings.sdr = {
0163 .tCCS_min = 500000,
0164 .tR_max = 200000000,
0165 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0166 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0167 .tADL_min = 400000,
0168 .tALH_min = 5000,
0169 .tALS_min = 10000,
0170 .tAR_min = 10000,
0171 .tCEA_max = 25000,
0172 .tCEH_min = 20000,
0173 .tCH_min = 5000,
0174 .tCHZ_max = 50000,
0175 .tCLH_min = 5000,
0176 .tCLR_min = 10000,
0177 .tCLS_min = 10000,
0178 .tCOH_min = 15000,
0179 .tCS_min = 25000,
0180 .tDH_min = 5000,
0181 .tDS_min = 10000,
0182 .tFEAT_max = 1000000,
0183 .tIR_min = 0,
0184 .tITC_max = 1000000,
0185 .tRC_min = 30000,
0186 .tREA_max = 20000,
0187 .tREH_min = 10000,
0188 .tRHOH_min = 15000,
0189 .tRHW_min = 100000,
0190 .tRHZ_max = 100000,
0191 .tRLOH_min = 0,
0192 .tRP_min = 15000,
0193 .tRR_min = 20000,
0194 .tRST_max = 500000000,
0195 .tWB_max = 100000,
0196 .tWC_min = 30000,
0197 .tWH_min = 10000,
0198 .tWHR_min = 80000,
0199 .tWP_min = 15000,
0200 .tWW_min = 100000,
0201 },
0202 },
0203
0204 {
0205 .type = NAND_SDR_IFACE,
0206 .timings.mode = 4,
0207 .timings.sdr = {
0208 .tCCS_min = 500000,
0209 .tR_max = 200000000,
0210 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0211 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0212 .tADL_min = 400000,
0213 .tALH_min = 5000,
0214 .tALS_min = 10000,
0215 .tAR_min = 10000,
0216 .tCEA_max = 25000,
0217 .tCEH_min = 20000,
0218 .tCH_min = 5000,
0219 .tCHZ_max = 30000,
0220 .tCLH_min = 5000,
0221 .tCLR_min = 10000,
0222 .tCLS_min = 10000,
0223 .tCOH_min = 15000,
0224 .tCS_min = 20000,
0225 .tDH_min = 5000,
0226 .tDS_min = 10000,
0227 .tFEAT_max = 1000000,
0228 .tIR_min = 0,
0229 .tITC_max = 1000000,
0230 .tRC_min = 25000,
0231 .tREA_max = 20000,
0232 .tREH_min = 10000,
0233 .tRHOH_min = 15000,
0234 .tRHW_min = 100000,
0235 .tRHZ_max = 100000,
0236 .tRLOH_min = 5000,
0237 .tRP_min = 12000,
0238 .tRR_min = 20000,
0239 .tRST_max = 500000000,
0240 .tWB_max = 100000,
0241 .tWC_min = 25000,
0242 .tWH_min = 10000,
0243 .tWHR_min = 80000,
0244 .tWP_min = 12000,
0245 .tWW_min = 100000,
0246 },
0247 },
0248
0249 {
0250 .type = NAND_SDR_IFACE,
0251 .timings.mode = 5,
0252 .timings.sdr = {
0253 .tCCS_min = 500000,
0254 .tR_max = 200000000,
0255 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0256 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0257 .tADL_min = 400000,
0258 .tALH_min = 5000,
0259 .tALS_min = 10000,
0260 .tAR_min = 10000,
0261 .tCEA_max = 25000,
0262 .tCEH_min = 20000,
0263 .tCH_min = 5000,
0264 .tCHZ_max = 30000,
0265 .tCLH_min = 5000,
0266 .tCLR_min = 10000,
0267 .tCLS_min = 10000,
0268 .tCOH_min = 15000,
0269 .tCS_min = 15000,
0270 .tDH_min = 5000,
0271 .tDS_min = 7000,
0272 .tFEAT_max = 1000000,
0273 .tIR_min = 0,
0274 .tITC_max = 1000000,
0275 .tRC_min = 20000,
0276 .tREA_max = 16000,
0277 .tREH_min = 7000,
0278 .tRHOH_min = 15000,
0279 .tRHW_min = 100000,
0280 .tRHZ_max = 100000,
0281 .tRLOH_min = 5000,
0282 .tRP_min = 10000,
0283 .tRR_min = 20000,
0284 .tRST_max = 500000000,
0285 .tWB_max = 100000,
0286 .tWC_min = 20000,
0287 .tWH_min = 7000,
0288 .tWHR_min = 80000,
0289 .tWP_min = 10000,
0290 .tWW_min = 100000,
0291 },
0292 },
0293 };
0294
0295 static const struct nand_interface_config onfi_nvddr_timings[] = {
0296
0297 {
0298 .type = NAND_NVDDR_IFACE,
0299 .timings.mode = 0,
0300 .timings.nvddr = {
0301 .tCCS_min = 500000,
0302 .tR_max = 200000000,
0303 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0304 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0305 .tAC_min = 3000,
0306 .tAC_max = 25000,
0307 .tADL_min = 400000,
0308 .tCAD_min = 45000,
0309 .tCAH_min = 10000,
0310 .tCALH_min = 10000,
0311 .tCALS_min = 10000,
0312 .tCAS_min = 10000,
0313 .tCEH_min = 20000,
0314 .tCH_min = 10000,
0315 .tCK_min = 50000,
0316 .tCS_min = 35000,
0317 .tDH_min = 5000,
0318 .tDQSCK_min = 3000,
0319 .tDQSCK_max = 25000,
0320 .tDQSD_min = 0,
0321 .tDQSD_max = 18000,
0322 .tDQSHZ_max = 20000,
0323 .tDQSQ_max = 5000,
0324 .tDS_min = 5000,
0325 .tDSC_min = 50000,
0326 .tFEAT_max = 1000000,
0327 .tITC_max = 1000000,
0328 .tQHS_max = 6000,
0329 .tRHW_min = 100000,
0330 .tRR_min = 20000,
0331 .tRST_max = 500000000,
0332 .tWB_max = 100000,
0333 .tWHR_min = 80000,
0334 .tWRCK_min = 20000,
0335 .tWW_min = 100000,
0336 },
0337 },
0338
0339 {
0340 .type = NAND_NVDDR_IFACE,
0341 .timings.mode = 1,
0342 .timings.nvddr = {
0343 .tCCS_min = 500000,
0344 .tR_max = 200000000,
0345 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0346 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0347 .tAC_min = 3000,
0348 .tAC_max = 25000,
0349 .tADL_min = 400000,
0350 .tCAD_min = 45000,
0351 .tCAH_min = 5000,
0352 .tCALH_min = 5000,
0353 .tCALS_min = 5000,
0354 .tCAS_min = 5000,
0355 .tCEH_min = 20000,
0356 .tCH_min = 5000,
0357 .tCK_min = 30000,
0358 .tCS_min = 25000,
0359 .tDH_min = 2500,
0360 .tDQSCK_min = 3000,
0361 .tDQSCK_max = 25000,
0362 .tDQSD_min = 0,
0363 .tDQSD_max = 18000,
0364 .tDQSHZ_max = 20000,
0365 .tDQSQ_max = 2500,
0366 .tDS_min = 3000,
0367 .tDSC_min = 30000,
0368 .tFEAT_max = 1000000,
0369 .tITC_max = 1000000,
0370 .tQHS_max = 3000,
0371 .tRHW_min = 100000,
0372 .tRR_min = 20000,
0373 .tRST_max = 500000000,
0374 .tWB_max = 100000,
0375 .tWHR_min = 80000,
0376 .tWRCK_min = 20000,
0377 .tWW_min = 100000,
0378 },
0379 },
0380
0381 {
0382 .type = NAND_NVDDR_IFACE,
0383 .timings.mode = 2,
0384 .timings.nvddr = {
0385 .tCCS_min = 500000,
0386 .tR_max = 200000000,
0387 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0388 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0389 .tAC_min = 3000,
0390 .tAC_max = 25000,
0391 .tADL_min = 400000,
0392 .tCAD_min = 45000,
0393 .tCAH_min = 4000,
0394 .tCALH_min = 4000,
0395 .tCALS_min = 4000,
0396 .tCAS_min = 4000,
0397 .tCEH_min = 20000,
0398 .tCH_min = 4000,
0399 .tCK_min = 20000,
0400 .tCS_min = 15000,
0401 .tDH_min = 1700,
0402 .tDQSCK_min = 3000,
0403 .tDQSCK_max = 25000,
0404 .tDQSD_min = 0,
0405 .tDQSD_max = 18000,
0406 .tDQSHZ_max = 20000,
0407 .tDQSQ_max = 1700,
0408 .tDS_min = 2000,
0409 .tDSC_min = 20000,
0410 .tFEAT_max = 1000000,
0411 .tITC_max = 1000000,
0412 .tQHS_max = 2000,
0413 .tRHW_min = 100000,
0414 .tRR_min = 20000,
0415 .tRST_max = 500000000,
0416 .tWB_max = 100000,
0417 .tWHR_min = 80000,
0418 .tWRCK_min = 20000,
0419 .tWW_min = 100000,
0420 },
0421 },
0422
0423 {
0424 .type = NAND_NVDDR_IFACE,
0425 .timings.mode = 3,
0426 .timings.nvddr = {
0427 .tCCS_min = 500000,
0428 .tR_max = 200000000,
0429 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0430 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0431 .tAC_min = 3000,
0432 .tAC_max = 25000,
0433 .tADL_min = 400000,
0434 .tCAD_min = 45000,
0435 .tCAH_min = 3000,
0436 .tCALH_min = 3000,
0437 .tCALS_min = 3000,
0438 .tCAS_min = 3000,
0439 .tCEH_min = 20000,
0440 .tCH_min = 3000,
0441 .tCK_min = 15000,
0442 .tCS_min = 15000,
0443 .tDH_min = 1300,
0444 .tDQSCK_min = 3000,
0445 .tDQSCK_max = 25000,
0446 .tDQSD_min = 0,
0447 .tDQSD_max = 18000,
0448 .tDQSHZ_max = 20000,
0449 .tDQSQ_max = 1300,
0450 .tDS_min = 1500,
0451 .tDSC_min = 15000,
0452 .tFEAT_max = 1000000,
0453 .tITC_max = 1000000,
0454 .tQHS_max = 1500,
0455 .tRHW_min = 100000,
0456 .tRR_min = 20000,
0457 .tRST_max = 500000000,
0458 .tWB_max = 100000,
0459 .tWHR_min = 80000,
0460 .tWRCK_min = 20000,
0461 .tWW_min = 100000,
0462 },
0463 },
0464
0465 {
0466 .type = NAND_NVDDR_IFACE,
0467 .timings.mode = 4,
0468 .timings.nvddr = {
0469 .tCCS_min = 500000,
0470 .tR_max = 200000000,
0471 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0472 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0473 .tAC_min = 3000,
0474 .tAC_max = 25000,
0475 .tADL_min = 400000,
0476 .tCAD_min = 45000,
0477 .tCAH_min = 2500,
0478 .tCALH_min = 2500,
0479 .tCALS_min = 2500,
0480 .tCAS_min = 2500,
0481 .tCEH_min = 20000,
0482 .tCH_min = 2500,
0483 .tCK_min = 12000,
0484 .tCS_min = 15000,
0485 .tDH_min = 1100,
0486 .tDQSCK_min = 3000,
0487 .tDQSCK_max = 25000,
0488 .tDQSD_min = 0,
0489 .tDQSD_max = 18000,
0490 .tDQSHZ_max = 20000,
0491 .tDQSQ_max = 1000,
0492 .tDS_min = 1100,
0493 .tDSC_min = 12000,
0494 .tFEAT_max = 1000000,
0495 .tITC_max = 1000000,
0496 .tQHS_max = 1200,
0497 .tRHW_min = 100000,
0498 .tRR_min = 20000,
0499 .tRST_max = 500000000,
0500 .tWB_max = 100000,
0501 .tWHR_min = 80000,
0502 .tWRCK_min = 20000,
0503 .tWW_min = 100000,
0504 },
0505 },
0506
0507 {
0508 .type = NAND_NVDDR_IFACE,
0509 .timings.mode = 5,
0510 .timings.nvddr = {
0511 .tCCS_min = 500000,
0512 .tR_max = 200000000,
0513 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0514 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,
0515 .tAC_min = 3000,
0516 .tAC_max = 25000,
0517 .tADL_min = 400000,
0518 .tCAD_min = 45000,
0519 .tCAH_min = 2000,
0520 .tCALH_min = 2000,
0521 .tCALS_min = 2000,
0522 .tCAS_min = 2000,
0523 .tCEH_min = 20000,
0524 .tCH_min = 2000,
0525 .tCK_min = 10000,
0526 .tCS_min = 15000,
0527 .tDH_min = 900,
0528 .tDQSCK_min = 3000,
0529 .tDQSCK_max = 25000,
0530 .tDQSD_min = 0,
0531 .tDQSD_max = 18000,
0532 .tDQSHZ_max = 20000,
0533 .tDQSQ_max = 850,
0534 .tDS_min = 900,
0535 .tDSC_min = 10000,
0536 .tFEAT_max = 1000000,
0537 .tITC_max = 1000000,
0538 .tQHS_max = 1000,
0539 .tRHW_min = 100000,
0540 .tRR_min = 20000,
0541 .tRST_max = 500000000,
0542 .tWB_max = 100000,
0543 .tWHR_min = 80000,
0544 .tWRCK_min = 20000,
0545 .tWW_min = 100000,
0546 },
0547 },
0548 };
0549
0550
0551 const struct nand_interface_config *nand_get_reset_interface_config(void)
0552 {
0553 return &onfi_sdr_timings[0];
0554 }
0555
0556
0557
0558
0559
0560
0561 unsigned int
0562 onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings)
0563 {
0564 const struct nand_sdr_timings *onfi_timings;
0565 int mode;
0566
0567 for (mode = ARRAY_SIZE(onfi_sdr_timings) - 1; mode > 0; mode--) {
0568 onfi_timings = &onfi_sdr_timings[mode].timings.sdr;
0569
0570 if (spec_timings->tCCS_min <= onfi_timings->tCCS_min &&
0571 spec_timings->tADL_min <= onfi_timings->tADL_min &&
0572 spec_timings->tALH_min <= onfi_timings->tALH_min &&
0573 spec_timings->tALS_min <= onfi_timings->tALS_min &&
0574 spec_timings->tAR_min <= onfi_timings->tAR_min &&
0575 spec_timings->tCEH_min <= onfi_timings->tCEH_min &&
0576 spec_timings->tCH_min <= onfi_timings->tCH_min &&
0577 spec_timings->tCLH_min <= onfi_timings->tCLH_min &&
0578 spec_timings->tCLR_min <= onfi_timings->tCLR_min &&
0579 spec_timings->tCLS_min <= onfi_timings->tCLS_min &&
0580 spec_timings->tCOH_min <= onfi_timings->tCOH_min &&
0581 spec_timings->tCS_min <= onfi_timings->tCS_min &&
0582 spec_timings->tDH_min <= onfi_timings->tDH_min &&
0583 spec_timings->tDS_min <= onfi_timings->tDS_min &&
0584 spec_timings->tIR_min <= onfi_timings->tIR_min &&
0585 spec_timings->tRC_min <= onfi_timings->tRC_min &&
0586 spec_timings->tREH_min <= onfi_timings->tREH_min &&
0587 spec_timings->tRHOH_min <= onfi_timings->tRHOH_min &&
0588 spec_timings->tRHW_min <= onfi_timings->tRHW_min &&
0589 spec_timings->tRLOH_min <= onfi_timings->tRLOH_min &&
0590 spec_timings->tRP_min <= onfi_timings->tRP_min &&
0591 spec_timings->tRR_min <= onfi_timings->tRR_min &&
0592 spec_timings->tWC_min <= onfi_timings->tWC_min &&
0593 spec_timings->tWH_min <= onfi_timings->tWH_min &&
0594 spec_timings->tWHR_min <= onfi_timings->tWHR_min &&
0595 spec_timings->tWP_min <= onfi_timings->tWP_min &&
0596 spec_timings->tWW_min <= onfi_timings->tWW_min)
0597 return mode;
0598 }
0599
0600 return 0;
0601 }
0602
0603
0604
0605
0606
0607
0608 unsigned int
0609 onfi_find_closest_nvddr_mode(const struct nand_nvddr_timings *spec_timings)
0610 {
0611 const struct nand_nvddr_timings *onfi_timings;
0612 int mode;
0613
0614 for (mode = ARRAY_SIZE(onfi_nvddr_timings) - 1; mode > 0; mode--) {
0615 onfi_timings = &onfi_nvddr_timings[mode].timings.nvddr;
0616
0617 if (spec_timings->tCCS_min <= onfi_timings->tCCS_min &&
0618 spec_timings->tAC_min <= onfi_timings->tAC_min &&
0619 spec_timings->tADL_min <= onfi_timings->tADL_min &&
0620 spec_timings->tCAD_min <= onfi_timings->tCAD_min &&
0621 spec_timings->tCAH_min <= onfi_timings->tCAH_min &&
0622 spec_timings->tCALH_min <= onfi_timings->tCALH_min &&
0623 spec_timings->tCALS_min <= onfi_timings->tCALS_min &&
0624 spec_timings->tCAS_min <= onfi_timings->tCAS_min &&
0625 spec_timings->tCEH_min <= onfi_timings->tCEH_min &&
0626 spec_timings->tCH_min <= onfi_timings->tCH_min &&
0627 spec_timings->tCK_min <= onfi_timings->tCK_min &&
0628 spec_timings->tCS_min <= onfi_timings->tCS_min &&
0629 spec_timings->tDH_min <= onfi_timings->tDH_min &&
0630 spec_timings->tDQSCK_min <= onfi_timings->tDQSCK_min &&
0631 spec_timings->tDQSD_min <= onfi_timings->tDQSD_min &&
0632 spec_timings->tDS_min <= onfi_timings->tDS_min &&
0633 spec_timings->tDSC_min <= onfi_timings->tDSC_min &&
0634 spec_timings->tRHW_min <= onfi_timings->tRHW_min &&
0635 spec_timings->tRR_min <= onfi_timings->tRR_min &&
0636 spec_timings->tWHR_min <= onfi_timings->tWHR_min &&
0637 spec_timings->tWRCK_min <= onfi_timings->tWRCK_min &&
0638 spec_timings->tWW_min <= onfi_timings->tWW_min)
0639 return mode;
0640 }
0641
0642 return 0;
0643 }
0644
0645
0646
0647
0648
0649
0650
0651
0652 static void onfi_fill_sdr_interface_config(struct nand_chip *chip,
0653 struct nand_interface_config *iface,
0654 unsigned int timing_mode)
0655 {
0656 struct onfi_params *onfi = chip->parameters.onfi;
0657
0658 if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_sdr_timings)))
0659 return;
0660
0661 *iface = onfi_sdr_timings[timing_mode];
0662
0663
0664
0665
0666
0667
0668 if (onfi) {
0669 struct nand_sdr_timings *timings = &iface->timings.sdr;
0670
0671
0672 timings->tPROG_max = 1000000ULL * onfi->tPROG;
0673 timings->tBERS_max = 1000000ULL * onfi->tBERS;
0674 timings->tR_max = 1000000ULL * onfi->tR;
0675
0676
0677 timings->tCCS_min = 1000UL * onfi->tCCS;
0678 }
0679 }
0680
0681
0682
0683
0684
0685
0686
0687
0688 static void onfi_fill_nvddr_interface_config(struct nand_chip *chip,
0689 struct nand_interface_config *iface,
0690 unsigned int timing_mode)
0691 {
0692 struct onfi_params *onfi = chip->parameters.onfi;
0693
0694 if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_nvddr_timings)))
0695 return;
0696
0697 *iface = onfi_nvddr_timings[timing_mode];
0698
0699
0700
0701
0702
0703
0704 if (onfi) {
0705 struct nand_nvddr_timings *timings = &iface->timings.nvddr;
0706
0707
0708 timings->tPROG_max = 1000000ULL * onfi->tPROG;
0709 timings->tBERS_max = 1000000ULL * onfi->tBERS;
0710 timings->tR_max = 1000000ULL * onfi->tR;
0711
0712
0713 timings->tCCS_min = 1000UL * onfi->tCCS;
0714
0715 if (onfi->fast_tCAD)
0716 timings->tCAD_min = 25000;
0717 }
0718 }
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728 void onfi_fill_interface_config(struct nand_chip *chip,
0729 struct nand_interface_config *iface,
0730 enum nand_interface_type type,
0731 unsigned int timing_mode)
0732 {
0733 if (type == NAND_SDR_IFACE)
0734 return onfi_fill_sdr_interface_config(chip, iface, timing_mode);
0735 else
0736 return onfi_fill_nvddr_interface_config(chip, iface, timing_mode);
0737 }