1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2014 Free Electrons 4 * 5 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> 6 */ 7 #include <linux/kernel.h> 8 #include <linux/err.h> 9 #include <linux/export.h> 10 11 #include "internals.h" 12 13 #define ONFI_DYN_TIMING_MAX U16_MAX 14 15 /* 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. 19 * 20 * These four values are tweaked to be more accurate in the case of ONFI chips. 21 */ 22 static const struct nand_interface_config onfi_sdr_timings[] = { 23 /* Mode 0 */ 24 { 25 .type = NAND_SDR_IFACE, 26 .timings.mode = 0, 27 .timings.sdr = { 28 .tCCS_min = 500000, 29 .tR_max = 200000000, 30 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 31 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 32 .tADL_min = 400000, 33 .tALH_min = 20000, 34 .tALS_min = 50000, 35 .tAR_min = 25000, 36 .tCEA_max = 100000, 37 .tCEH_min = 20000, 38 .tCH_min = 20000, 39 .tCHZ_max = 100000, 40 .tCLH_min = 20000, 41 .tCLR_min = 20000, 42 .tCLS_min = 50000, 43 .tCOH_min = 0, 44 .tCS_min = 70000, 45 .tDH_min = 20000, 46 .tDS_min = 40000, 47 .tFEAT_max = 1000000, 48 .tIR_min = 10000, 49 .tITC_max = 1000000, 50 .tRC_min = 100000, 51 .tREA_max = 40000, 52 .tREH_min = 30000, 53 .tRHOH_min = 0, 54 .tRHW_min = 200000, 55 .tRHZ_max = 200000, 56 .tRLOH_min = 0, 57 .tRP_min = 50000, 58 .tRR_min = 40000, 59 .tRST_max = 250000000000ULL, 60 .tWB_max = 200000, 61 .tWC_min = 100000, 62 .tWH_min = 30000, 63 .tWHR_min = 120000, 64 .tWP_min = 50000, 65 .tWW_min = 100000, 66 }, 67 }, 68 /* Mode 1 */ 69 { 70 .type = NAND_SDR_IFACE, 71 .timings.mode = 1, 72 .timings.sdr = { 73 .tCCS_min = 500000, 74 .tR_max = 200000000, 75 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 76 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 77 .tADL_min = 400000, 78 .tALH_min = 10000, 79 .tALS_min = 25000, 80 .tAR_min = 10000, 81 .tCEA_max = 45000, 82 .tCEH_min = 20000, 83 .tCH_min = 10000, 84 .tCHZ_max = 50000, 85 .tCLH_min = 10000, 86 .tCLR_min = 10000, 87 .tCLS_min = 25000, 88 .tCOH_min = 15000, 89 .tCS_min = 35000, 90 .tDH_min = 10000, 91 .tDS_min = 20000, 92 .tFEAT_max = 1000000, 93 .tIR_min = 0, 94 .tITC_max = 1000000, 95 .tRC_min = 50000, 96 .tREA_max = 30000, 97 .tREH_min = 15000, 98 .tRHOH_min = 15000, 99 .tRHW_min = 100000, 100 .tRHZ_max = 100000, 101 .tRLOH_min = 0, 102 .tRP_min = 25000, 103 .tRR_min = 20000, 104 .tRST_max = 500000000, 105 .tWB_max = 100000, 106 .tWC_min = 45000, 107 .tWH_min = 15000, 108 .tWHR_min = 80000, 109 .tWP_min = 25000, 110 .tWW_min = 100000, 111 }, 112 }, 113 /* Mode 2 */ 114 { 115 .type = NAND_SDR_IFACE, 116 .timings.mode = 2, 117 .timings.sdr = { 118 .tCCS_min = 500000, 119 .tR_max = 200000000, 120 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 121 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 122 .tADL_min = 400000, 123 .tALH_min = 10000, 124 .tALS_min = 15000, 125 .tAR_min = 10000, 126 .tCEA_max = 30000, 127 .tCEH_min = 20000, 128 .tCH_min = 10000, 129 .tCHZ_max = 50000, 130 .tCLH_min = 10000, 131 .tCLR_min = 10000, 132 .tCLS_min = 15000, 133 .tCOH_min = 15000, 134 .tCS_min = 25000, 135 .tDH_min = 5000, 136 .tDS_min = 15000, 137 .tFEAT_max = 1000000, 138 .tIR_min = 0, 139 .tITC_max = 1000000, 140 .tRC_min = 35000, 141 .tREA_max = 25000, 142 .tREH_min = 15000, 143 .tRHOH_min = 15000, 144 .tRHW_min = 100000, 145 .tRHZ_max = 100000, 146 .tRLOH_min = 0, 147 .tRR_min = 20000, 148 .tRST_max = 500000000, 149 .tWB_max = 100000, 150 .tRP_min = 17000, 151 .tWC_min = 35000, 152 .tWH_min = 15000, 153 .tWHR_min = 80000, 154 .tWP_min = 17000, 155 .tWW_min = 100000, 156 }, 157 }, 158 /* Mode 3 */ 159 { 160 .type = NAND_SDR_IFACE, 161 .timings.mode = 3, 162 .timings.sdr = { 163 .tCCS_min = 500000, 164 .tR_max = 200000000, 165 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 166 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 167 .tADL_min = 400000, 168 .tALH_min = 5000, 169 .tALS_min = 10000, 170 .tAR_min = 10000, 171 .tCEA_max = 25000, 172 .tCEH_min = 20000, 173 .tCH_min = 5000, 174 .tCHZ_max = 50000, 175 .tCLH_min = 5000, 176 .tCLR_min = 10000, 177 .tCLS_min = 10000, 178 .tCOH_min = 15000, 179 .tCS_min = 25000, 180 .tDH_min = 5000, 181 .tDS_min = 10000, 182 .tFEAT_max = 1000000, 183 .tIR_min = 0, 184 .tITC_max = 1000000, 185 .tRC_min = 30000, 186 .tREA_max = 20000, 187 .tREH_min = 10000, 188 .tRHOH_min = 15000, 189 .tRHW_min = 100000, 190 .tRHZ_max = 100000, 191 .tRLOH_min = 0, 192 .tRP_min = 15000, 193 .tRR_min = 20000, 194 .tRST_max = 500000000, 195 .tWB_max = 100000, 196 .tWC_min = 30000, 197 .tWH_min = 10000, 198 .tWHR_min = 80000, 199 .tWP_min = 15000, 200 .tWW_min = 100000, 201 }, 202 }, 203 /* Mode 4 */ 204 { 205 .type = NAND_SDR_IFACE, 206 .timings.mode = 4, 207 .timings.sdr = { 208 .tCCS_min = 500000, 209 .tR_max = 200000000, 210 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 211 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 212 .tADL_min = 400000, 213 .tALH_min = 5000, 214 .tALS_min = 10000, 215 .tAR_min = 10000, 216 .tCEA_max = 25000, 217 .tCEH_min = 20000, 218 .tCH_min = 5000, 219 .tCHZ_max = 30000, 220 .tCLH_min = 5000, 221 .tCLR_min = 10000, 222 .tCLS_min = 10000, 223 .tCOH_min = 15000, 224 .tCS_min = 20000, 225 .tDH_min = 5000, 226 .tDS_min = 10000, 227 .tFEAT_max = 1000000, 228 .tIR_min = 0, 229 .tITC_max = 1000000, 230 .tRC_min = 25000, 231 .tREA_max = 20000, 232 .tREH_min = 10000, 233 .tRHOH_min = 15000, 234 .tRHW_min = 100000, 235 .tRHZ_max = 100000, 236 .tRLOH_min = 5000, 237 .tRP_min = 12000, 238 .tRR_min = 20000, 239 .tRST_max = 500000000, 240 .tWB_max = 100000, 241 .tWC_min = 25000, 242 .tWH_min = 10000, 243 .tWHR_min = 80000, 244 .tWP_min = 12000, 245 .tWW_min = 100000, 246 }, 247 }, 248 /* Mode 5 */ 249 { 250 .type = NAND_SDR_IFACE, 251 .timings.mode = 5, 252 .timings.sdr = { 253 .tCCS_min = 500000, 254 .tR_max = 200000000, 255 .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 256 .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, 257 .tADL_min = 400000, 258 .tALH_min = 5000, 259 .tALS_min = 10000, 260 .tAR_min = 10000, 261 .tCEA_max = 25000, 262 .tCEH_min = 20000, 263 .tCH_min = 5000, 264 .tCHZ_max = 30000, 265 .tCLH_min = 5000, 266 .tCLR_min = 10000, 267 .tCLS_min = 10000, 268 .tCOH_min = 15000, 269 .tCS_min = 15000, 270 .tDH_min = 5000, 271 .tDS_min = 7000, 272 .tFEAT_max = 1000000, 273 .tIR_min = 0, 274 .tITC_max = 1000000, 275 .tRC_min = 20000, 276 .tREA_max = 16000, 277 .tREH_min = 7000, 278 .tRHOH_min = 15000, 279 .tRHW_min = 100000, 280 .tRHZ_max = 100000, 281 .tRLOH_min = 5000, 282 .tRP_min = 10000, 283 .tRR_min = 20000, 284 .tRST_max = 500000000, 285 .tWB_max = 100000, 286 .tWC_min = 20000, 287 .tWH_min = 7000, 288 .tWHR_min = 80000, 289 .tWP_min = 10000, 290 .tWW_min = 100000, 291 }, 292 }, 293 }; 294 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) 297 { 298 return &onfi_sdr_timings[0]; 299 } 300 301 /** 302 * onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a 303 * set of timings 304 * @spec_timings: the timings to challenge 305 */ 306 unsigned int 307 onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings) 308 { 309 const struct nand_sdr_timings *onfi_timings; 310 int mode; 311 312 for (mode = ARRAY_SIZE(onfi_sdr_timings) - 1; mode > 0; mode--) { 313 onfi_timings = &onfi_sdr_timings[mode].timings.sdr; 314 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) 342 return mode; 343 } 344 345 return 0; 346 } 347 348 /** 349 * onfi_fill_interface_config - Initialize an interface config from a given 350 * ONFI mode 351 * @chip: The NAND chip 352 * @iface: The interface configuration to fill 353 * @type: The interface type 354 * @timing_mode: The ONFI timing mode 355 */ 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) 360 { 361 struct onfi_params *onfi = chip->parameters.onfi; 362 363 if (WARN_ON(type != NAND_SDR_IFACE)) 364 return; 365 366 if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_sdr_timings))) 367 return; 368 369 *iface = onfi_sdr_timings[timing_mode]; 370 371 /* 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. 375 */ 376 if (onfi) { 377 struct nand_sdr_timings *timings = &iface->timings.sdr; 378 379 /* microseconds -> picoseconds */ 380 timings->tPROG_max = 1000000ULL * onfi->tPROG; 381 timings->tBERS_max = 1000000ULL * onfi->tBERS; 382 timings->tR_max = 1000000ULL * onfi->tR; 383 384 /* nanoseconds -> picoseconds */ 385 timings->tCCS_min = 1000UL * onfi->tCCS; 386 } 387 } 388