nand_timings.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * Copyright (C) 2014 Free Electrons
  3. *
  4. * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/err.h>
  13. #include <linux/export.h>
  14. #include "internals.h"
  15. #define ONFI_DYN_TIMING_MAX U16_MAX
  16. static const struct nand_data_interface onfi_sdr_timings[] = {
  17. /* Mode 0 */
  18. {
  19. .type = NAND_SDR_IFACE,
  20. .timings.sdr = {
  21. .tCCS_min = 500000,
  22. .tR_max = 200000000,
  23. .tADL_min = 400000,
  24. .tALH_min = 20000,
  25. .tALS_min = 50000,
  26. .tAR_min = 25000,
  27. .tCEA_max = 100000,
  28. .tCEH_min = 20000,
  29. .tCH_min = 20000,
  30. .tCHZ_max = 100000,
  31. .tCLH_min = 20000,
  32. .tCLR_min = 20000,
  33. .tCLS_min = 50000,
  34. .tCOH_min = 0,
  35. .tCS_min = 70000,
  36. .tDH_min = 20000,
  37. .tDS_min = 40000,
  38. .tFEAT_max = 1000000,
  39. .tIR_min = 10000,
  40. .tITC_max = 1000000,
  41. .tRC_min = 100000,
  42. .tREA_max = 40000,
  43. .tREH_min = 30000,
  44. .tRHOH_min = 0,
  45. .tRHW_min = 200000,
  46. .tRHZ_max = 200000,
  47. .tRLOH_min = 0,
  48. .tRP_min = 50000,
  49. .tRR_min = 40000,
  50. .tRST_max = 250000000000ULL,
  51. .tWB_max = 200000,
  52. .tWC_min = 100000,
  53. .tWH_min = 30000,
  54. .tWHR_min = 120000,
  55. .tWP_min = 50000,
  56. .tWW_min = 100000,
  57. },
  58. },
  59. /* Mode 1 */
  60. {
  61. .type = NAND_SDR_IFACE,
  62. .timings.sdr = {
  63. .tCCS_min = 500000,
  64. .tR_max = 200000000,
  65. .tADL_min = 400000,
  66. .tALH_min = 10000,
  67. .tALS_min = 25000,
  68. .tAR_min = 10000,
  69. .tCEA_max = 45000,
  70. .tCEH_min = 20000,
  71. .tCH_min = 10000,
  72. .tCHZ_max = 50000,
  73. .tCLH_min = 10000,
  74. .tCLR_min = 10000,
  75. .tCLS_min = 25000,
  76. .tCOH_min = 15000,
  77. .tCS_min = 35000,
  78. .tDH_min = 10000,
  79. .tDS_min = 20000,
  80. .tFEAT_max = 1000000,
  81. .tIR_min = 0,
  82. .tITC_max = 1000000,
  83. .tRC_min = 50000,
  84. .tREA_max = 30000,
  85. .tREH_min = 15000,
  86. .tRHOH_min = 15000,
  87. .tRHW_min = 100000,
  88. .tRHZ_max = 100000,
  89. .tRLOH_min = 0,
  90. .tRP_min = 25000,
  91. .tRR_min = 20000,
  92. .tRST_max = 500000000,
  93. .tWB_max = 100000,
  94. .tWC_min = 45000,
  95. .tWH_min = 15000,
  96. .tWHR_min = 80000,
  97. .tWP_min = 25000,
  98. .tWW_min = 100000,
  99. },
  100. },
  101. /* Mode 2 */
  102. {
  103. .type = NAND_SDR_IFACE,
  104. .timings.sdr = {
  105. .tCCS_min = 500000,
  106. .tR_max = 200000000,
  107. .tADL_min = 400000,
  108. .tALH_min = 10000,
  109. .tALS_min = 15000,
  110. .tAR_min = 10000,
  111. .tCEA_max = 30000,
  112. .tCEH_min = 20000,
  113. .tCH_min = 10000,
  114. .tCHZ_max = 50000,
  115. .tCLH_min = 10000,
  116. .tCLR_min = 10000,
  117. .tCLS_min = 15000,
  118. .tCOH_min = 15000,
  119. .tCS_min = 25000,
  120. .tDH_min = 5000,
  121. .tDS_min = 15000,
  122. .tFEAT_max = 1000000,
  123. .tIR_min = 0,
  124. .tITC_max = 1000000,
  125. .tRC_min = 35000,
  126. .tREA_max = 25000,
  127. .tREH_min = 15000,
  128. .tRHOH_min = 15000,
  129. .tRHW_min = 100000,
  130. .tRHZ_max = 100000,
  131. .tRLOH_min = 0,
  132. .tRR_min = 20000,
  133. .tRST_max = 500000000,
  134. .tWB_max = 100000,
  135. .tRP_min = 17000,
  136. .tWC_min = 35000,
  137. .tWH_min = 15000,
  138. .tWHR_min = 80000,
  139. .tWP_min = 17000,
  140. .tWW_min = 100000,
  141. },
  142. },
  143. /* Mode 3 */
  144. {
  145. .type = NAND_SDR_IFACE,
  146. .timings.sdr = {
  147. .tCCS_min = 500000,
  148. .tR_max = 200000000,
  149. .tADL_min = 400000,
  150. .tALH_min = 5000,
  151. .tALS_min = 10000,
  152. .tAR_min = 10000,
  153. .tCEA_max = 25000,
  154. .tCEH_min = 20000,
  155. .tCH_min = 5000,
  156. .tCHZ_max = 50000,
  157. .tCLH_min = 5000,
  158. .tCLR_min = 10000,
  159. .tCLS_min = 10000,
  160. .tCOH_min = 15000,
  161. .tCS_min = 25000,
  162. .tDH_min = 5000,
  163. .tDS_min = 10000,
  164. .tFEAT_max = 1000000,
  165. .tIR_min = 0,
  166. .tITC_max = 1000000,
  167. .tRC_min = 30000,
  168. .tREA_max = 20000,
  169. .tREH_min = 10000,
  170. .tRHOH_min = 15000,
  171. .tRHW_min = 100000,
  172. .tRHZ_max = 100000,
  173. .tRLOH_min = 0,
  174. .tRP_min = 15000,
  175. .tRR_min = 20000,
  176. .tRST_max = 500000000,
  177. .tWB_max = 100000,
  178. .tWC_min = 30000,
  179. .tWH_min = 10000,
  180. .tWHR_min = 80000,
  181. .tWP_min = 15000,
  182. .tWW_min = 100000,
  183. },
  184. },
  185. /* Mode 4 */
  186. {
  187. .type = NAND_SDR_IFACE,
  188. .timings.sdr = {
  189. .tCCS_min = 500000,
  190. .tR_max = 200000000,
  191. .tADL_min = 400000,
  192. .tALH_min = 5000,
  193. .tALS_min = 10000,
  194. .tAR_min = 10000,
  195. .tCEA_max = 25000,
  196. .tCEH_min = 20000,
  197. .tCH_min = 5000,
  198. .tCHZ_max = 30000,
  199. .tCLH_min = 5000,
  200. .tCLR_min = 10000,
  201. .tCLS_min = 10000,
  202. .tCOH_min = 15000,
  203. .tCS_min = 20000,
  204. .tDH_min = 5000,
  205. .tDS_min = 10000,
  206. .tFEAT_max = 1000000,
  207. .tIR_min = 0,
  208. .tITC_max = 1000000,
  209. .tRC_min = 25000,
  210. .tREA_max = 20000,
  211. .tREH_min = 10000,
  212. .tRHOH_min = 15000,
  213. .tRHW_min = 100000,
  214. .tRHZ_max = 100000,
  215. .tRLOH_min = 5000,
  216. .tRP_min = 12000,
  217. .tRR_min = 20000,
  218. .tRST_max = 500000000,
  219. .tWB_max = 100000,
  220. .tWC_min = 25000,
  221. .tWH_min = 10000,
  222. .tWHR_min = 80000,
  223. .tWP_min = 12000,
  224. .tWW_min = 100000,
  225. },
  226. },
  227. /* Mode 5 */
  228. {
  229. .type = NAND_SDR_IFACE,
  230. .timings.sdr = {
  231. .tCCS_min = 500000,
  232. .tR_max = 200000000,
  233. .tADL_min = 400000,
  234. .tALH_min = 5000,
  235. .tALS_min = 10000,
  236. .tAR_min = 10000,
  237. .tCEA_max = 25000,
  238. .tCEH_min = 20000,
  239. .tCH_min = 5000,
  240. .tCHZ_max = 30000,
  241. .tCLH_min = 5000,
  242. .tCLR_min = 10000,
  243. .tCLS_min = 10000,
  244. .tCOH_min = 15000,
  245. .tCS_min = 15000,
  246. .tDH_min = 5000,
  247. .tDS_min = 7000,
  248. .tFEAT_max = 1000000,
  249. .tIR_min = 0,
  250. .tITC_max = 1000000,
  251. .tRC_min = 20000,
  252. .tREA_max = 16000,
  253. .tREH_min = 7000,
  254. .tRHOH_min = 15000,
  255. .tRHW_min = 100000,
  256. .tRHZ_max = 100000,
  257. .tRLOH_min = 5000,
  258. .tRP_min = 10000,
  259. .tRR_min = 20000,
  260. .tRST_max = 500000000,
  261. .tWB_max = 100000,
  262. .tWC_min = 20000,
  263. .tWH_min = 7000,
  264. .tWHR_min = 80000,
  265. .tWP_min = 10000,
  266. .tWW_min = 100000,
  267. },
  268. },
  269. };
  270. /**
  271. * onfi_fill_data_interface - [NAND Interface] Initialize a data interface from
  272. * given ONFI mode
  273. * @mode: The ONFI timing mode
  274. */
  275. int onfi_fill_data_interface(struct nand_chip *chip,
  276. enum nand_data_interface_type type,
  277. int timing_mode)
  278. {
  279. struct nand_data_interface *iface = &chip->data_interface;
  280. struct onfi_params *onfi = chip->parameters.onfi;
  281. if (type != NAND_SDR_IFACE)
  282. return -EINVAL;
  283. if (timing_mode < 0 || timing_mode >= ARRAY_SIZE(onfi_sdr_timings))
  284. return -EINVAL;
  285. *iface = onfi_sdr_timings[timing_mode];
  286. /*
  287. * Initialize timings that cannot be deduced from timing mode:
  288. * tPROG, tBERS, tR and tCCS.
  289. * These information are part of the ONFI parameter page.
  290. */
  291. if (onfi) {
  292. struct nand_sdr_timings *timings = &iface->timings.sdr;
  293. /* microseconds -> picoseconds */
  294. timings->tPROG_max = 1000000ULL * onfi->tPROG;
  295. timings->tBERS_max = 1000000ULL * onfi->tBERS;
  296. timings->tR_max = 1000000ULL * onfi->tR;
  297. /* nanoseconds -> picoseconds */
  298. timings->tCCS_min = 1000UL * onfi->tCCS;
  299. } else {
  300. struct nand_sdr_timings *timings = &iface->timings.sdr;
  301. /*
  302. * For non-ONFI chips we use the highest possible value for
  303. * tPROG and tBERS. tR and tCCS will take the default values
  304. * precised in the ONFI specification for timing mode 0,
  305. * respectively 200us and 500ns.
  306. */
  307. /* microseconds -> picoseconds */
  308. timings->tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX;
  309. timings->tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX;
  310. timings->tR_max = 1000000ULL * 200000000ULL;
  311. /* nanoseconds -> picoseconds */
  312. timings->tCCS_min = 1000UL * 500000;
  313. }
  314. return 0;
  315. }