mtk_nand_ops.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <string.h>
  32. #include <config.h>
  33. #include <malloc.h>
  34. #include <printf.h>
  35. #include <platform/mt_typedefs.h>
  36. #include <platform/mtk_nand.h>
  37. #include <partition.h>
  38. #include "partition_define.h"
  39. #include "cust_nand.h"
  40. #include <arch/ops.h>
  41. #include <kernel/event.h>
  42. #include <platform/mt_irq.h>
  43. #include "mtk_nand.h"
  44. #include <platform/mtk_nand_ops.h>
  45. #include <platform/bmt.h>
  46. struct mtk_nand_data_info *data_info;
  47. #define ERR_RTN_SUCCESS 1
  48. #define ERR_RTN_FAIL 0
  49. #define ERR_RTN_BCH_FAIL -1
  50. #define ALL_SLC_BUFFER 1
  51. static bool are_on_diff_planes(unsigned int block0,
  52. unsigned int block1)
  53. {
  54. return (block0 + block1) & 0x1;
  55. }
  56. static void add_work_list(struct worklist_ctrl *list_ctrl, struct nand_work *work)
  57. {
  58. struct nand_work *idx;
  59. if (list_ctrl->head == NULL) {
  60. list_ctrl->head = work;
  61. list_ctrl->total_num++;
  62. return;
  63. }
  64. idx = list_ctrl->head;
  65. while (idx->next != NULL)
  66. idx = idx->next;
  67. idx->next = work;
  68. list_ctrl->total_num++;
  69. }
  70. static void free_multi_write_work(struct worklist_ctrl *list_ctrl, int count)
  71. {
  72. int i;
  73. struct nand_work *work = list_ctrl->head;
  74. struct nand_work *temp;
  75. for (i = 0; i < count; i++) {
  76. temp = work;
  77. work = work->next;
  78. list_ctrl->total_num--;
  79. free(temp);
  80. }
  81. list_ctrl->head = work;
  82. }
  83. static void mtk_nand_dump_partition_info(
  84. struct nand_ftl_partition_info *partition_info)
  85. {
  86. nand_debug("nand_ftl_partition_info dump info here");
  87. nand_debug("start_block:0x%x", partition_info->start_block);
  88. nand_debug("total_block:0x%x", partition_info->total_block);
  89. nand_debug("slc_ratio:%d", partition_info->slc_ratio);
  90. nand_debug("slc_block:%d", partition_info->slc_block);
  91. }
  92. static void mtk_chip_info_init(struct mtk_nand_chip_info *chip_info)
  93. {
  94. unsigned int page_per_block;
  95. page_per_block = devinfo.blocksize*1024/devinfo.pagesize;
  96. chip_info->log_block_num = data_info->partition_info.total_block
  97. *data_info->partition_info.slc_ratio/100;
  98. chip_info->data_page_num = page_per_block;
  99. chip_info->data_page_size = devinfo.pagesize;
  100. chip_info->data_block_size = devinfo.blocksize*1024;
  101. chip_info->log_page_size = devinfo.pagesize;
  102. if (devinfo.NAND_FLASH_TYPE == MTK_NAND_FLASH_TLC) {
  103. chip_info->log_page_num =
  104. page_per_block/MTK_TLC_DIV;
  105. chip_info->log_block_size =
  106. chip_info->data_block_size/MTK_TLC_DIV;
  107. } else {
  108. chip_info->log_page_num =
  109. page_per_block/MTK_MLC_DIV;
  110. chip_info->log_block_size =
  111. chip_info->data_block_size/MTK_MLC_DIV;
  112. }
  113. if (devinfo.advancedmode & MULTI_PLANE) {
  114. chip_info->log_block_num >>= 1;
  115. chip_info->log_block_num <<= 1;
  116. }
  117. chip_info->data_block_num =
  118. data_info->partition_info.total_block - chip_info->log_block_num;
  119. if (devinfo.advancedmode & MULTI_PLANE) {
  120. chip_info->data_block_num >>= 1;
  121. chip_info->data_block_num <<= 1;
  122. }
  123. chip_info->data_oob_size = (devinfo.pagesize >> g_nand_chip.sector_shift)
  124. * g_nand_chip.nand_fdm_size;
  125. chip_info->log_oob_size = chip_info->data_oob_size;
  126. chip_info->slc_ratio = data_info->partition_info.slc_ratio;
  127. chip_info->start_block = data_info->partition_info.start_block;
  128. chip_info->sector_size_shift = 10;
  129. if (devinfo.NAND_FLASH_TYPE == MTK_NAND_FLASH_TLC)
  130. chip_info->max_keep_pages = (devinfo.advancedmode & MULTI_PLANE)?18:9;
  131. else
  132. chip_info->max_keep_pages = (devinfo.advancedmode & MULTI_PLANE)?2:1;
  133. if (devinfo.NAND_FLASH_TYPE == MTK_NAND_FLASH_TLC)
  134. chip_info->types = MTK_NAND_FLASH_TLC;
  135. else
  136. chip_info->types = MTK_NAND_FLASH_MLC;
  137. chip_info->plane_mask = 0x1;
  138. chip_info->plane_num = (devinfo.advancedmode & MULTI_PLANE)?2:1;
  139. chip_info->chip_num = 1;
  140. if (devinfo.advancedmode & MULTI_PLANE)
  141. chip_info->option = MTK_NAND_PLANE_MODE_SUPPORT |
  142. MTK_NAND_MULTI_READ_DIFFERENT_OFFSET;
  143. chip_info->info_version = MTK_NAND_CHIP_INFO_VERSION;
  144. return;
  145. }
  146. static void mtk_nand_dump_chip_info(struct mtk_nand_chip_info *chip_info)
  147. {
  148. nand_debug("mtk_nand_chip_info dump info here");
  149. nand_debug("data_block_num:0x%x", chip_info->data_block_num);
  150. nand_debug("data_page_num:0x%x", chip_info->data_page_num);
  151. nand_debug("data_page_size:0x%x", chip_info->data_page_size);
  152. nand_debug("data_oob_size:0x%x", chip_info->data_oob_size);
  153. nand_debug("data_block_size:0x%x", chip_info->data_block_size);
  154. nand_debug("log_block_num:0x%x", chip_info->log_block_num);
  155. nand_debug("log_page_num:0x%x", chip_info->log_page_num);
  156. nand_debug("log_page_size:0x%x", chip_info->log_page_size);
  157. nand_debug("log_block_size:0x%x", chip_info->log_block_size);
  158. nand_debug("log_oob_size:0x%x", chip_info->log_oob_size);
  159. nand_debug("slc_ratio:0x%x", chip_info->slc_ratio);
  160. nand_debug("start_block:0x%x", chip_info->start_block);
  161. nand_debug("sector_size_shift:0x%x", chip_info->sector_size_shift);
  162. nand_debug("max_keep_pages:0x%x", chip_info->max_keep_pages);
  163. nand_debug("types:0x%x", chip_info->types);
  164. nand_debug("plane_mask:0x%x", chip_info->plane_mask);
  165. nand_debug("plane_num:0x%x", chip_info->plane_num);
  166. nand_debug("chip_num:0x%x", chip_info->chip_num);
  167. nand_debug("option:0x%x", chip_info->option);
  168. }
  169. static void mtk_nand_dump_bbt_info(struct mtk_nand_chip_bbt_info *chip_bbt)
  170. {
  171. unsigned int i;
  172. nand_info("bad_block_num:%d, initial_bad_num:%d", chip_bbt->bad_block_num,
  173. chip_bbt->initial_bad_num);
  174. for (i = 0; i < chip_bbt->bad_block_num; i++)
  175. nand_info("bad_index:%d", chip_bbt->bad_block_table[i]);
  176. }
  177. static inline bool block_num_is_valid(
  178. struct mtk_nand_chip_info *info,
  179. unsigned int block)
  180. {
  181. return (block >= 0 && block <
  182. (info->data_block_num + info->log_block_num));
  183. }
  184. int mtk_chip_bbt_init(data_bmt_struct *data_bmt)
  185. {
  186. struct mtk_nand_chip_bbt_info *chip_bbt = &data_info->chip_bbt;
  187. unsigned int i, initial_bad_num;
  188. unsigned int initial_bad, ftl_mark_bad;
  189. u16 bad_block;
  190. chip_bbt->bad_block_num = data_bmt->bad_count;
  191. chip_bbt->initial_bad_num = data_bmt->bad_count;
  192. if (data_bmt->bad_count > BAD_BLOCK_MAX_NUM) {
  193. nand_err("bad block count > max(%d)", BAD_BLOCK_MAX_NUM);
  194. return -1;
  195. }
  196. initial_bad_num = 0;
  197. for (i = 0; i < data_bmt->bad_count; i++)
  198. if (data_bmt->entry[i].flag != FTL_MARK_BAD)
  199. initial_bad_num++;
  200. chip_bbt->initial_bad_num = initial_bad_num;
  201. initial_bad = 0;
  202. ftl_mark_bad = initial_bad_num;
  203. for (i = 0; i < data_bmt->bad_count; i++) {
  204. bad_block = data_bmt->entry[i].bad_index - data_bmt->start_block;
  205. if (data_bmt->entry[i].flag != FTL_MARK_BAD) {
  206. chip_bbt->bad_block_table[initial_bad] = bad_block;
  207. initial_bad++;
  208. } else {
  209. chip_bbt->bad_block_table[ftl_mark_bad] = bad_block;
  210. ftl_mark_bad++;
  211. }
  212. }
  213. for (i = data_bmt->bad_count; i < BAD_BLOCK_MAX_NUM; i++)
  214. chip_bbt->bad_block_table[i] = 0xffff;
  215. mtk_nand_dump_bbt_info(chip_bbt);
  216. return 0;
  217. }
  218. bool is_slc_block(struct mtk_nand_chip_info *info, unsigned int block)
  219. {
  220. #ifdef ALL_SLC_BUFFER
  221. int index, bit;
  222. index = block / 8;
  223. bit = block % 8;
  224. if ((info->block_type_bitmap[index] >> bit) & 1)
  225. return FALSE;
  226. return TRUE;
  227. #else
  228. return block >= info->data_block_num;
  229. #endif
  230. }
  231. static int mtk_nand_read_pages(struct mtk_nand_chip_info *info,
  232. unsigned char *data_buffer, unsigned char *oob_buffer,
  233. unsigned int block, unsigned int page,
  234. unsigned int offset, unsigned int size)
  235. {
  236. static unsigned char *fdm_buf;
  237. #ifdef MTK_FORCE_READ_FULL_PAGE
  238. static unsigned char *page_buf;
  239. #endif
  240. unsigned int page_addr, page_size, oob_size;
  241. unsigned int sect_num, start_sect;
  242. unsigned int sect_read;
  243. unsigned int backup_corrected;
  244. int ret = 0;
  245. #ifdef ALL_SLC_BUFFER
  246. bool block_type;
  247. #endif
  248. nand_debug("block:%d page:%d offset:%d size:%d",
  249. block, page, offset, size);
  250. backup_corrected = 0;
  251. #ifdef ALL_SLC_BUFFER
  252. block_type = is_slc_block(info, block);
  253. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  254. && block_type)
  255. page_addr = (block+data_info->bmt.start_block)*info->data_page_num+page*MTK_TLC_DIV;
  256. else
  257. page_addr = (block+data_info->bmt.start_block)*info->data_page_num+page;
  258. /* For log area access */
  259. if (!block_type) {
  260. devinfo.tlcControl.slcopmodeEn = FALSE;
  261. page_size = info->data_page_size;
  262. oob_size = info->log_oob_size;
  263. } else {
  264. /* nand_debug("Read SLC mode"); */
  265. devinfo.tlcControl.slcopmodeEn = TRUE;
  266. page_size = info->log_page_size;
  267. oob_size = info->log_oob_size;
  268. }
  269. #else
  270. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  271. && (block >= info->data_block_num))
  272. page_addr = (block+data_info->bmt.start_block)*info->data_page_num+page*MTK_TLC_DIV;
  273. else
  274. page_addr = (block+data_info->bmt.start_block)*info->data_page_num+page;
  275. /* For log area access */
  276. if (block < info->data_block_num) {
  277. devinfo.tlcControl.slcopmodeEn = FALSE;
  278. page_size = info->data_page_size;
  279. oob_size = info->log_oob_size;
  280. } else {
  281. /* nand_debug("Read SLC mode"); */
  282. devinfo.tlcControl.slcopmodeEn = TRUE;
  283. page_size = info->log_page_size;
  284. oob_size = info->log_oob_size;
  285. }
  286. #endif
  287. if (fdm_buf == NULL) {
  288. fdm_buf = malloc(1024);
  289. if (fdm_buf == NULL) {
  290. ret = -EINVAL;
  291. nand_err("kmalloc fdm_buf fail\n");
  292. goto exit;
  293. } else {
  294. nand_info("kmalloc success. fdm_buf:%p\n", fdm_buf);
  295. }
  296. }
  297. if (size < page_size) {
  298. /* Sector read case */
  299. sect_num = page_size >> info->sector_size_shift;
  300. start_sect = offset >> info->sector_size_shift;
  301. sect_read = size >> info->sector_size_shift;
  302. /* nand_debug("Sector read col_addr:0x%x sect_read:%d, sect_num:%d, start_sect:%d", */
  303. /* col_addr, sect_read, sect_num, start_sect); */
  304. if (page_buf == NULL) {
  305. page_buf = malloc(page_size);
  306. if (page_buf == NULL) {
  307. ret = -ENOMEM;
  308. nand_err("kmalloc page_buf fail!!!size:%d\n", page_size);
  309. goto exit;
  310. } else {
  311. nand_info("kmalloc success. page_buf:%p\n", page_buf);
  312. }
  313. }
  314. ret = nand_exec_read_page_hw(&g_nand_chip, page_addr, page_size, page_buf, fdm_buf);
  315. memcpy(data_buffer, page_buf+offset, size);
  316. memcpy(oob_buffer, fdm_buf+start_sect*g_nand_chip.nand_fdm_size,
  317. sect_read*g_nand_chip.nand_fdm_size);
  318. } else {
  319. ret = nand_exec_read_page_hw(&g_nand_chip, page_addr, page_size, data_buffer, fdm_buf);
  320. memcpy(oob_buffer, fdm_buf, oob_size);
  321. }
  322. if (ret != ERR_RTN_SUCCESS) {
  323. ret = -ENANDREAD;
  324. } else
  325. ret = 0;
  326. exit:
  327. return ret;
  328. }
  329. static bool can_multi_plane(unsigned int block0, unsigned int page0,
  330. unsigned int block1, unsigned int page1)
  331. {
  332. return ((block0 + block1) & 0x1) && (page0 == page1);
  333. }
  334. static bool is_multi_plane(struct mtk_nand_chip_info *info)
  335. {
  336. return (devinfo.advancedmode & MULTI_PLANE);
  337. }
  338. static bool is_multi_read_support(struct mtk_nand_chip_info *info)
  339. {
  340. return is_multi_plane(info) && (devinfo.vendor == VEND_MICRON);
  341. }
  342. static struct nand_work *seek_list_item(
  343. struct nand_work *cur, unsigned int offset)
  344. {
  345. struct nand_work *item;
  346. int i;
  347. i = 0;
  348. item = cur;
  349. while (i < offset) {
  350. item = item->next;
  351. i++;
  352. }
  353. return item;
  354. }
  355. static bool can_ops_multi_plane(struct mtk_nand_chip_operation *ops0,
  356. struct mtk_nand_chip_operation *ops1)
  357. {
  358. struct mtk_nand_chip_info *info = ops0->info;
  359. if (!is_multi_plane(info))
  360. return false;
  361. return can_multi_plane(ops0->block, ops0->page, ops1->block,
  362. ops1->page);
  363. }
  364. static void call_multi_work_callback(
  365. struct nand_work *cur, int count, int status)
  366. {
  367. int i;
  368. struct nand_work *work;
  369. struct mtk_nand_chip_operation *ops;
  370. work = cur;
  371. for (i = 0; i < count; i++) {
  372. if (work == NULL) {
  373. nand_err("NULL item");
  374. return;
  375. }
  376. ops = &work->ops;
  377. nand_debug("callback i:%d, block:%d page:%d",
  378. i, ops->block, ops->page);
  379. ops->callback(ops->info, ops->data_buffer,
  380. ops->oob_buffer, ops->block,
  381. ops->page, status, ops->userdata);
  382. if (i >= count)
  383. break;
  384. work = work->next;
  385. }
  386. }
  387. static void call_tlc_page_group_callback(
  388. struct nand_work *base_node, int start, int end,
  389. bool multi_plane, int status)
  390. {
  391. int i;
  392. int count = multi_plane ? 2 : 1;
  393. struct nand_work *work;
  394. work = seek_list_item(base_node, start*count);
  395. for (i = 0; i < end - start + 1; i++) {
  396. call_multi_work_callback(
  397. work, count, status);
  398. if (i >= end - start)
  399. break;
  400. if (count == 1)
  401. work = work->next;
  402. else
  403. work = work->next->next;
  404. }
  405. }
  406. static inline bool block_page_num_is_valid(
  407. struct mtk_nand_chip_info *info,
  408. unsigned int block, unsigned int page)
  409. {
  410. if (!block_num_is_valid(info, block))
  411. return false;
  412. if (page < 0)
  413. return false;
  414. #ifdef ALL_SLC_BUFFER
  415. if ((!is_slc_block(info, block) &&
  416. page < info->data_page_num) ||
  417. (is_slc_block(info, block) &&
  418. page < info->log_page_num))
  419. return true;
  420. else
  421. return false;
  422. #else
  423. if ((block < info->data_block_num &&
  424. page < info->data_page_num) ||
  425. (block >= info->data_block_num &&
  426. page < info->log_page_num))
  427. return true;
  428. else
  429. return false;
  430. #endif
  431. }
  432. /**
  433. * mtk_nand_write_pages - NAND write with ECC
  434. * @ops: mtk_nand_chip_operation structure
  435. * @lecountn: number of pages to write
  436. *
  437. * NAND write with ECC.
  438. */
  439. static int mtk_nand_write_pages(struct mtk_nand_chip_operation *ops0,
  440. struct mtk_nand_chip_operation *ops1)
  441. {
  442. struct mtk_nand_chip_info *info = &data_info->chip_info;
  443. unsigned char *fdm_buf = NULL;
  444. unsigned char *temp_page_buf = NULL;
  445. unsigned char *temp_fdm_buf = NULL;
  446. unsigned int page_addr0, page_addr1;
  447. unsigned int page_size, oob_size, sect_num;
  448. int ret = 0;
  449. if (ops0 == NULL) {
  450. nand_err("ops0 is NULL");
  451. return -EINVAL;
  452. }
  453. if (ops1 != NULL) {
  454. /* Check both in data or log area */
  455. #ifdef ALL_SLC_BUFFER
  456. if (is_slc_block(info, ops1->block) != is_slc_block(info, ops0->block)) {
  457. nand_err("do not in same area ops0->block:0x%x ops1->block:0x%x ",
  458. ops0->block, ops1->block);
  459. return -EINVAL;
  460. }
  461. #else
  462. if (((ops0->block < info->data_block_num)
  463. && (ops1->block >= info->data_block_num))
  464. || ((ops0->block >= info->data_block_num)
  465. && (ops1->block < info->data_block_num))) {
  466. nand_err("do not in same area ops0->block:0x%x ops1->block:0x%x ",
  467. ops0->block, ops1->block);
  468. return -EINVAL;
  469. }
  470. #endif
  471. if (mtk_isbad_block(ops1->block))
  472. page_addr1 = 0;
  473. else {
  474. #ifdef ALL_SLC_BUFFER
  475. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  476. && is_slc_block(info, ops1->block)) {
  477. page_addr1 = (ops1->block+data_info->bmt.start_block)*info->data_page_num
  478. + ops1->page*MTK_TLC_DIV;
  479. } else {
  480. page_addr1 = (ops1->block+data_info->bmt.start_block)*info->data_page_num
  481. + ops1->page;
  482. }
  483. #else
  484. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  485. && (ops1->block >= info->data_block_num)) {
  486. page_addr1 = (ops1->block+data_info->bmt.start_block)*info->data_page_num
  487. + ops1->page*MTK_TLC_DIV;
  488. } else {
  489. page_addr1 = (ops1->block+data_info->bmt.start_block)*info->data_page_num
  490. + ops1->page;
  491. }
  492. #endif
  493. }
  494. } else {
  495. page_addr1 = 0;
  496. }
  497. #ifdef ALL_SLC_BUFFER
  498. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  499. && is_slc_block(info, ops0->block))
  500. page_addr0 = (ops0->block+data_info->bmt.start_block)*info->data_page_num
  501. + ops0->page*MTK_TLC_DIV;
  502. else
  503. page_addr0 = (ops0->block+data_info->bmt.start_block)*info->data_page_num
  504. + ops0->page;
  505. #else
  506. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  507. && (ops0->block >= info->data_block_num))
  508. page_addr0 = (ops0->block+data_info->bmt.start_block)*info->data_page_num
  509. + ops0->page*MTK_TLC_DIV;
  510. else
  511. page_addr0 = (ops0->block+data_info->bmt.start_block)*info->data_page_num
  512. + ops0->page;
  513. #endif
  514. nand_debug("page_addr0= 0x%x page_addr1=0x%x",
  515. page_addr0, page_addr1);
  516. #ifdef ALL_SLC_BUFFER
  517. if (!is_slc_block(info, ops0->block)) {
  518. page_size = info->data_page_size;
  519. devinfo.tlcControl.slcopmodeEn = FALSE;
  520. oob_size = info->data_oob_size;
  521. } else {
  522. nand_debug("write SLC mode");
  523. page_size = info->log_page_size;
  524. devinfo.tlcControl.slcopmodeEn = TRUE;
  525. oob_size = info->log_oob_size;
  526. }
  527. #else
  528. /* For log area access */
  529. if (ops0->block < info->data_block_num) {
  530. page_size = info->data_page_size;
  531. devinfo.tlcControl.slcopmodeEn = FALSE;
  532. oob_size = info->data_oob_size;
  533. } else {
  534. nand_debug("write SLC mode");
  535. page_size = info->log_page_size;
  536. devinfo.tlcControl.slcopmodeEn = TRUE;
  537. oob_size = info->log_oob_size;
  538. }
  539. #endif
  540. sect_num = page_size/(1<<info->sector_size_shift);
  541. fdm_buf = malloc(1024);
  542. if (fdm_buf == NULL) {
  543. ret = -ENOMEM;
  544. goto exit;
  545. }
  546. memset(fdm_buf, 0xff, 1024);
  547. if (devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC) {
  548. if ((devinfo.tlcControl.normaltlc) && (devinfo.tlcControl.pPlaneEn)) {
  549. page_size /= 2;
  550. sect_num /= 2;
  551. tlc_lg_left_plane = TRUE;
  552. memcpy(fdm_buf, ops0->oob_buffer, oob_size);
  553. temp_page_buf = ops0->data_buffer;
  554. temp_fdm_buf = fdm_buf;
  555. ret = nand_exec_write_page_hw(&g_nand_chip, page_addr0,
  556. page_size, temp_page_buf, fdm_buf);
  557. if (ret != 1) {
  558. nand_err("write failed for page_addr0:0x%x", page_addr0);
  559. ret = -ENANDWRITE;
  560. goto exit;
  561. }
  562. tlc_lg_left_plane = FALSE;
  563. temp_page_buf += page_size;
  564. temp_fdm_buf += (sect_num * g_nand_chip.nand_fdm_size);
  565. ret = nand_exec_write_page_hw(&g_nand_chip, page_addr0,
  566. page_size, temp_page_buf, fdm_buf);
  567. if (ret != 1) {
  568. nand_err("write failed for page_addr0:0x%x", page_addr0);
  569. ret = -ENANDWRITE;
  570. goto exit;
  571. }
  572. if ((devinfo.advancedmode & MULTI_PLANE) && page_addr1) {
  573. nand_debug("write Multi_plane mode page_addr0:0x%x page_addr1:0x%x",
  574. page_addr0, page_addr1);
  575. tlc_lg_left_plane = TRUE;
  576. memcpy(fdm_buf, ops1->oob_buffer, oob_size);
  577. temp_page_buf = ops1->data_buffer;
  578. temp_fdm_buf = fdm_buf;
  579. ret = nand_exec_write_page_hw(&g_nand_chip, page_addr1, page_size,
  580. temp_page_buf, temp_fdm_buf);
  581. if (ret != 1) {
  582. nand_err("write failed for page_addr1:0x%x", page_addr1);
  583. ret = -ENANDWRITE;
  584. goto exit;
  585. }
  586. tlc_lg_left_plane = FALSE;
  587. temp_page_buf += page_size;
  588. temp_fdm_buf += (sect_num * g_nand_chip.nand_fdm_size);
  589. ret = nand_exec_write_page_hw(&g_nand_chip, page_addr1, page_size,
  590. temp_page_buf, temp_fdm_buf);
  591. if (ret != 1) {
  592. nand_err("write failed for page_addr1:0x%x", page_addr1);
  593. ret = -ENANDWRITE;
  594. goto exit;
  595. }
  596. }
  597. } else {
  598. memcpy(fdm_buf, ops0->oob_buffer, oob_size);
  599. temp_page_buf = ops0->data_buffer;
  600. temp_fdm_buf = fdm_buf;
  601. ret = nand_exec_write_page_hw(&g_nand_chip, page_addr0,
  602. page_size, temp_page_buf, fdm_buf);
  603. if (ret != 1) {
  604. nand_err("write failed for page_addr0:0x%x", page_addr0);
  605. ret = -ENANDWRITE;
  606. goto exit;
  607. }
  608. if ((devinfo.tlcControl.normaltlc)
  609. && ((devinfo.advancedmode & MULTI_PLANE) && page_addr1)) {
  610. nand_debug("write Multi_plane mode page_addr0:0x%x page_addr1:0x%x",
  611. page_addr0, page_addr1);
  612. memcpy(fdm_buf, ops1->oob_buffer, oob_size);
  613. temp_page_buf = ops1->data_buffer;
  614. temp_fdm_buf = fdm_buf;
  615. ret = nand_exec_write_page_hw(&g_nand_chip, page_addr1, page_size,
  616. temp_page_buf, temp_fdm_buf);
  617. if (ret != 1) {
  618. nand_err("write failed for page_addr1:0x%x", page_addr1);
  619. ret = -ENANDWRITE;
  620. goto exit;
  621. }
  622. }
  623. }
  624. } else {
  625. memcpy(fdm_buf, ops0->oob_buffer, oob_size);
  626. ret = nand_exec_write_page_hw(&g_nand_chip, page_addr0,
  627. page_size, ops0->data_buffer, fdm_buf);
  628. if (ret != 1) {
  629. nand_err("write failed for page_addr0:0x%x", page_addr0);
  630. ret = -ENANDWRITE;
  631. goto exit;
  632. }
  633. if ((devinfo.advancedmode & MULTI_PLANE) && page_addr1) {
  634. nand_debug("write Multi_plane mode page_addr0:0x%x page_addr1:0x%x",
  635. page_addr0, page_addr1);
  636. memcpy(fdm_buf, ops1->oob_buffer, oob_size);
  637. ret = nand_exec_write_page_hw(&g_nand_chip, page_addr1,
  638. page_size, ops1->data_buffer, fdm_buf);
  639. if (ret != 1) {
  640. nand_err("write failed for page_addr1:0x%x", page_addr1);
  641. ret = -ENANDWRITE;
  642. goto exit;
  643. }
  644. }
  645. }
  646. exit:
  647. free(fdm_buf);
  648. if (ret != 1) {
  649. nand_err("fail!!!ret:%d, block0:%d, page0:%d\n", ret, ops0->block, ops0->page);
  650. if (ops1)
  651. nand_err("fail!!!ret:%d, block1:%d, page1:%d\n", ret, ops1->block, ops1->page);
  652. return ret;
  653. }
  654. return 0;
  655. }
  656. static int do_multi_work_write(struct nand_work *cur, int count)
  657. {
  658. int i, status = 0;
  659. struct nand_work *work;
  660. struct mtk_nand_chip_operation *ops0, *ops1;
  661. bool multi_plane = false;
  662. bool multi_plane_en;
  663. ops0 = NULL;
  664. ops1 = NULL;
  665. work = cur;
  666. for (i = 0; i < count; i++) {
  667. if (work == NULL) {
  668. nand_err("NULL item");
  669. return -ENANDWRITE;
  670. }
  671. if (i == 0)
  672. ops0 = &work->ops;
  673. else if (i == 1)
  674. ops1 = &work->ops;
  675. if (i+1 >= count)
  676. break;
  677. work = work->next;
  678. }
  679. multi_plane_en = (devinfo.advancedmode & MULTI_PLANE) ? true : false;
  680. if (multi_plane_en) {
  681. if (ops1 != NULL)
  682. multi_plane = are_on_diff_planes(ops0->block, ops1->block);
  683. if (multi_plane)
  684. return mtk_nand_write_pages(ops0, ops1);
  685. }
  686. if (multi_plane_en)
  687. devinfo.advancedmode &= (~MULTI_PLANE);
  688. status = mtk_nand_write_pages(ops0, NULL);
  689. if (status)
  690. goto OUT;
  691. if (ops1 != NULL)
  692. status = mtk_nand_write_pages(ops1, NULL);
  693. OUT:
  694. if (multi_plane_en)
  695. devinfo.advancedmode |= MULTI_PLANE;
  696. return status;
  697. }
  698. static int do_tlc_page_group_write(struct nand_work *cur, int start,
  699. int step, NFI_TLC_PG_CYCLE program_cycle, enum TLC_MULTI_PROG_MODE prog_mode)
  700. {
  701. struct nand_work *item;
  702. int status = 0, i;
  703. int count;
  704. item = seek_list_item(cur, start * step);
  705. nand_debug("start:%d, item:%p", start, item);
  706. devinfo.tlcControl.slcopmodeEn = FALSE;
  707. tlc_program_cycle = program_cycle;
  708. count = (prog_mode == MULTI_BLOCK) ? 2 : 1;
  709. item = (prog_mode == BLOCK1_ONLY) ? item->next : item;
  710. for (i = 0; i < 3; i++) {
  711. status = do_multi_work_write(item, count);
  712. if (status)
  713. break;
  714. if (i >= 2)
  715. break;
  716. if (step == 1)
  717. item = item->next;
  718. else
  719. item = item->next->next;
  720. }
  721. return status;
  722. }
  723. static int do_tlc_wl_write(struct mtk_nand_chip_info *info, struct nand_work *start_node,
  724. enum TLC_MULTI_PROG_MODE prog_mode)
  725. {
  726. struct nand_work *work;
  727. struct mtk_nand_chip_operation *ops;
  728. int status, step;
  729. work = start_node;
  730. ops = &work->ops;
  731. if ((ops->page % MTK_TLC_DIV) != 0) {
  732. nand_err("Not TLC(3 pages) alsigned ops->page:0x%x",
  733. ops->page);
  734. return -1;
  735. }
  736. step = (devinfo.advancedmode & MULTI_PLANE) ? 2 : 1;
  737. if (ops->page == 0) {
  738. status = do_tlc_page_group_write(work, 0, step, PROGRAM_1ST_CYCLE, prog_mode);
  739. if (status)
  740. return status;
  741. status = do_tlc_page_group_write(work, 3, step, PROGRAM_1ST_CYCLE, prog_mode);
  742. if (status)
  743. return status;
  744. status = do_tlc_page_group_write(work, 0, step, PROGRAM_2ND_CYCLE, prog_mode);
  745. if (status)
  746. return status;
  747. }
  748. if ((ops->page/3 + 2) < (info->data_page_num/3)) {
  749. status = do_tlc_page_group_write(work, 6, step, PROGRAM_1ST_CYCLE, prog_mode);
  750. if (status)
  751. return status;
  752. }
  753. if ((ops->page/3 + 1) < (info->data_page_num/3)) {
  754. status = do_tlc_page_group_write(work, 3, step, PROGRAM_2ND_CYCLE, prog_mode);
  755. if (status)
  756. return status;
  757. }
  758. status = do_tlc_page_group_write(work, 0, step, PROGRAM_3RD_CYCLE, prog_mode);
  759. if (status)
  760. return status;
  761. if (ops->page == (info->data_page_num - 9)) {
  762. status = do_tlc_page_group_write(work, 6, step, PROGRAM_2ND_CYCLE, prog_mode);
  763. if (status)
  764. return status;
  765. status = do_tlc_page_group_write(work, 3, step, PROGRAM_3RD_CYCLE, prog_mode);
  766. if (status)
  767. return status;
  768. status = do_tlc_page_group_write(work, 6, step, PROGRAM_3RD_CYCLE, prog_mode);
  769. if (status)
  770. return status;
  771. }
  772. return status;
  773. }
  774. static int do_tlc_write(
  775. struct mtk_nand_chip_info *info,
  776. struct worklist_ctrl *list_ctrl,
  777. int count)
  778. {
  779. struct nand_work *work, *work1;
  780. struct mtk_nand_chip_operation *ops;
  781. int status;
  782. bool multi_plan = false;
  783. int free_count;
  784. enum TLC_MULTI_PROG_MODE prog_mode;
  785. if (count != info->max_keep_pages) {
  786. nand_err("error:count:%d max:%d",
  787. count, info->max_keep_pages);
  788. return -EINVAL;
  789. }
  790. multi_plan = (devinfo.advancedmode & MULTI_PLANE) ? true : false;
  791. work = list_ctrl->head;
  792. ops = &work->ops;
  793. nand_debug("page num:%d", ops->page);
  794. if ((ops->page % MTK_TLC_DIV) != 0) {
  795. nand_err("Not TLC(3 pages) alsigned ops->page:0x%x", ops->page);
  796. return NULL;
  797. }
  798. if (multi_plan) {
  799. work1 = work->next;
  800. prog_mode = are_on_diff_planes(work->ops.block, work1->ops.block) ? MULTI_BLOCK : BLOCK0_ONLY;
  801. } else {
  802. prog_mode = BLOCK0_ONLY;
  803. }
  804. status = do_tlc_wl_write(info, work, prog_mode);
  805. if (!status && multi_plan && (prog_mode == BLOCK0_ONLY))
  806. status = do_tlc_wl_write(info, work, BLOCK1_ONLY);
  807. call_tlc_page_group_callback(work, 0, 2, multi_plan, status);
  808. if (multi_plan)
  809. work = seek_list_item(work, 8 * 2);
  810. else
  811. work = seek_list_item(work, 8);
  812. free_count = multi_plan ? 2 : 1;
  813. free_multi_write_work(list_ctrl, (3 * free_count));
  814. ops = &work->ops;
  815. if (ops->page == (info->data_page_num - 1)) {
  816. work = list_ctrl->head;
  817. /*3~5*/
  818. call_tlc_page_group_callback(work, 0, 2,
  819. multi_plan, status);
  820. /*6~8*/
  821. call_tlc_page_group_callback(work, 3, 5,
  822. multi_plan, status);
  823. /*3~8*/
  824. free_multi_write_work(list_ctrl, (6 * free_count));
  825. }
  826. return 0;
  827. }
  828. static int mtk_nand_do_write(struct mtk_nand_chip_info *info,
  829. struct worklist_ctrl *list_ctrl, int count)
  830. {
  831. if (info->types == NAND_FLASH_TLC)
  832. return do_tlc_write(info, list_ctrl, count);
  833. nand_err("unhandled work!\n");
  834. return NULL;
  835. }
  836. static int mtk_nand_do_slc_write(
  837. struct mtk_nand_chip_info *info,
  838. struct worklist_ctrl *list_ctrl, int count)
  839. {
  840. struct mtk_nand_chip_operation *ops[2];
  841. struct nand_work *work;
  842. struct list_node *node;
  843. int i, status;
  844. if (!count)
  845. return NULL;
  846. if (count != 1 && count != 2) {
  847. nand_err("count not 1 or 2, count:%d\n", count);
  848. return NULL;
  849. }
  850. ops[0] = &list_ctrl->head->ops;
  851. if (count == 2)
  852. ops[1] = &list_ctrl->head->next->ops;
  853. else
  854. ops[1] = NULL;
  855. status = mtk_nand_write_pages(ops[0], ops[1]);
  856. call_multi_work_callback(list_ctrl->head, count, status);
  857. free_multi_write_work(list_ctrl, count);
  858. return 0;
  859. }
  860. static unsigned int complete_write_count(struct mtk_nand_chip_info *info,
  861. struct worklist_ctrl *list_ctrl)
  862. {
  863. return (list_ctrl->total_num >= info->max_keep_pages) ? info->max_keep_pages : 0;
  864. }
  865. static unsigned int complete_slc_write_count(struct mtk_nand_chip_info *info,
  866. struct worklist_ctrl *list_ctrl)
  867. {
  868. struct list_node *head;
  869. struct nand_work *work0, *work1;
  870. bool multi_op;
  871. if (!list_ctrl->head)
  872. return 0;
  873. if (!is_multi_plane(info))
  874. return 1;
  875. /* multi plane, but not ready*/
  876. if (list_ctrl->total_num != 2)
  877. return 0;
  878. /* total >= plane_num */
  879. work0 = list_ctrl->head;
  880. work1 = list_ctrl->head->next;
  881. multi_op = can_ops_multi_plane(&work0->ops, &work1->ops);
  882. return multi_op ? 2 : 1;
  883. }
  884. static void mtk_nand_dump_bmt_info(data_bmt_struct *data_bmt)
  885. {
  886. unsigned int i;
  887. nand_debug("nand_ftl_partition_info dump info here");
  888. nand_debug("bad_count:0x%x", data_bmt->bad_count);
  889. nand_debug("start_block:0x%x", data_bmt->start_block);
  890. nand_debug("end_block:0x%x", data_bmt->end_block);
  891. nand_debug("version:%d", data_bmt->version);
  892. for (i = 0; i < data_bmt->bad_count; i++) {
  893. nand_debug("bad_index:0x%x, flag:%d",
  894. data_bmt->entry[i].bad_index,
  895. data_bmt->entry[i].flag);
  896. }
  897. }
  898. /*********************************global***************************************/
  899. bool mtk_isbad_block(unsigned int block)
  900. {
  901. struct mtk_nand_chip_bbt_info *chip_bbt;
  902. unsigned int i;
  903. chip_bbt = &data_info->chip_bbt;
  904. for (i = 0; i < chip_bbt->bad_block_num; i++) {
  905. if (block == chip_bbt->bad_block_table[i]) {
  906. nand_debug("Check block:0x%x is bad", block);
  907. return TRUE;
  908. }
  909. }
  910. /* nand_debug("Check block:0x%x is Good", block); */
  911. return FALSE;
  912. }
  913. int mtk_nand_data_info_init(void)
  914. {
  915. unsigned int data_struct_size;
  916. data_struct_size = sizeof(struct mtk_nand_data_info);
  917. data_info = malloc(data_struct_size);
  918. if (data_info == NULL) {
  919. nand_err("Malloc datainfo size: 0x%x failed\n",
  920. data_struct_size);
  921. return -ENOMEM;
  922. }
  923. memset(data_info, 0, data_struct_size);
  924. return 0;
  925. }
  926. int mtk_nand_chip_read_page(struct mtk_nand_chip_info *info,
  927. unsigned char *data_buffer, unsigned char *oob_buffer,
  928. unsigned int block, unsigned int page,
  929. unsigned int offset, unsigned int size)
  930. {
  931. int ret = 0;
  932. if (data_buffer == NULL) {
  933. nand_err("data_buffer is null");
  934. return -EINVAL;
  935. }
  936. if (oob_buffer == NULL) {
  937. nand_err("oob_buffer is null");
  938. return -EINVAL;
  939. }
  940. if ((offset % (1 << info->sector_size_shift) != 0)
  941. || (size % (1 << info->sector_size_shift) != 0)) {
  942. nand_err("offset or size is invalid:offset:%d, size:%d",
  943. offset, size);
  944. return -EINVAL;
  945. }
  946. if (!block_page_num_is_valid(info, block, page)) {
  947. nand_err("block or page num is invalid:block:%d, page:%d",
  948. block, page);
  949. return -EINVAL;
  950. }
  951. if (mtk_isbad_block(block))
  952. return -ENANDBAD;
  953. ret = mtk_nand_read_pages(info, data_buffer,
  954. oob_buffer, block, page, offset, size);
  955. if (ret) {
  956. nand_err("read err:%d, block:%d, page:%d, offset:%d, size:%d\n",
  957. ret, block, page, offset, size);
  958. }
  959. return ret;
  960. }
  961. int mtk_nand_chip_read_multi_pages(struct mtk_nand_chip_info *info, int page_num,
  962. struct mtk_nand_chip_read_param *param)
  963. {
  964. struct mtk_nand_chip_read_param *p = param;
  965. int ret;
  966. if (!page_num) {
  967. nand_err("page_num is 0, so return 0\n");
  968. /* dump_stack(); */
  969. return 0;
  970. }
  971. if (page_num == 1 || !is_multi_read_support(info)) {
  972. ret = mtk_nand_chip_read_page(info, p->data_buffer, p->oob_buffer,
  973. p->block, p->page, p->offset, p->size);
  974. return ret ? ret : 1;
  975. }
  976. if (!can_multi_plane(p->block, p->page, p[1].block, p[1].page)) {
  977. ret = mtk_nand_chip_read_page(info, p->data_buffer, p->oob_buffer,
  978. p->block, p->page, p->offset, p->size);
  979. return ret ? ret : 1;
  980. }
  981. ret = mtk_nand_chip_read_page(info, p->data_buffer, p->oob_buffer,
  982. p->block, p->page, p->offset, p->size);
  983. return ret ? ret : 1;
  984. }
  985. int mtk_nand_chip_write_page(struct mtk_nand_chip_info *info,
  986. unsigned char *data_buffer, unsigned char *oob_buffer,
  987. unsigned int block, unsigned int page, bool more_page,
  988. mtk_nand_callback_func callback, void *userdata)
  989. {
  990. /* Add to worklist here*/
  991. struct nand_work *work;
  992. struct mtk_nand_chip_operation *ops;
  993. int total_num;
  994. unsigned int max_keep_pages;
  995. int page_num;
  996. int ret;
  997. nand_debug("write block:%d page:%d more_page:%d\n", block, page, more_page);
  998. if (data_buffer == NULL) {
  999. nand_err("data_buffer is null");
  1000. return -EINVAL;
  1001. }
  1002. if (oob_buffer == NULL) {
  1003. nand_err("oob_buffer is null");
  1004. return -EINVAL;
  1005. }
  1006. if (!block_page_num_is_valid(info, block, page)) {
  1007. nand_err("block or page num is invalid:block:%d, page:%d",
  1008. block, page);
  1009. return -EINVAL;
  1010. }
  1011. #ifdef ALL_SLC_BUFFER
  1012. max_keep_pages = is_slc_block(info, block) ?
  1013. info->plane_num : info->max_keep_pages;
  1014. #else
  1015. max_keep_pages = (block < info->data_block_num) ?
  1016. info->max_keep_pages : info->plane_num;
  1017. #endif
  1018. work = malloc(sizeof(struct nand_work));
  1019. if (work == NULL)
  1020. return -ENOMEM;
  1021. work->next = NULL;
  1022. ops = &work->ops;
  1023. ops->info = info;
  1024. ops->types = MTK_NAND_OP_WRITE;
  1025. ops->data_buffer = data_buffer;
  1026. ops->oob_buffer = oob_buffer;
  1027. ops->block = block;
  1028. ops->page = page;
  1029. ops->more = more_page;
  1030. ops->callback = callback;
  1031. ops->userdata = userdata;
  1032. #ifdef ALL_SLC_BUFFER
  1033. if (!is_slc_block(info, block)) {
  1034. add_work_list(&data_info->wlist_ctrl, work);
  1035. ret = complete_write_count(info, &data_info->wlist_ctrl);
  1036. if (ret)
  1037. mtk_nand_do_write(info, &data_info->wlist_ctrl, ret);
  1038. } else {
  1039. add_work_list(&data_info->swlist_ctrl, work);
  1040. ret = complete_slc_write_count(info, &data_info->swlist_ctrl);
  1041. if (ret)
  1042. mtk_nand_do_slc_write(info, &data_info->swlist_ctrl, ret);
  1043. }
  1044. #else
  1045. if (block < info->data_block_num) {
  1046. add_work_list(&data_info->wlist_ctrl, work);
  1047. ret = complete_write_count(info, &data_info->wlist_ctrl);
  1048. if (ret)
  1049. mtk_nand_do_write(info, &data_info->wlist_ctrl, ret);
  1050. } else {
  1051. add_work_list(&data_info->swlist_ctrl, work);
  1052. ret = complete_slc_write_count(info, &data_info->swlist_ctrl);
  1053. if (ret)
  1054. mtk_nand_do_slc_write(info, &data_info->swlist_ctrl, ret);
  1055. }
  1056. #endif
  1057. return 0;
  1058. }
  1059. int mtk_nand_chip_sync(struct mtk_nand_chip_info *info)
  1060. {
  1061. return 0;
  1062. }
  1063. void mtk_nand_chip_set_blk_thread(struct task_struct *thead)
  1064. {
  1065. }
  1066. const struct mtk_nand_chip_bbt_info *mtk_nand_chip_bmt(struct mtk_nand_chip_info *info)
  1067. {
  1068. if (&data_info->chip_bbt != NULL)
  1069. return &data_info->chip_bbt;
  1070. else
  1071. return 0;
  1072. }
  1073. void mtk_chip_mark_bad_block(struct mtk_nand_chip_info *info, unsigned int block)
  1074. {
  1075. struct mtk_nand_chip_bbt_info *chip_bbt = &data_info->chip_bbt;
  1076. unsigned int i;
  1077. bool success;
  1078. nand_err("markbad block:%d", block);
  1079. for (i = 0; i < chip_bbt->bad_block_num; i++) {
  1080. if (block == chip_bbt->bad_block_table[i])
  1081. return;
  1082. }
  1083. chip_bbt->bad_block_table[chip_bbt->bad_block_num++] = block;
  1084. success = update_bmt(((u64)(block + data_info->bmt.start_block)) * info->data_block_size,
  1085. FTL_MARK_BAD, NULL, NULL);
  1086. if (!success)
  1087. nand_err("mark block(%d) as bad fail!!!\n", block);
  1088. }
  1089. /*
  1090. * mtk_nand_chip_erase_block
  1091. * Erase API for nand wrapper, async mode for erase, just return success,
  1092. * put erase operation into write worklist.
  1093. * After Nand driver erase/write operation, callback function will be done.
  1094. * @block: The block to erase
  1095. * @*callback: Callback for wrapper, called after driver finish the operation.
  1096. * @* userdata: for callback function
  1097. * return : 0 on success, On error, return error num casted by ERR_PTR
  1098. */
  1099. int mtk_nand_chip_erase_block(struct mtk_nand_chip_info *info,
  1100. unsigned int block, unsigned int more_block,
  1101. mtk_nand_callback_func callback, void *userdata)
  1102. {
  1103. int total_num;
  1104. u64 offset;
  1105. bool status;
  1106. int ret_status;
  1107. nand_debug("erase block:%d more_page:%d\n", block, more_block);
  1108. if (!block_num_is_valid(info, block)) {
  1109. nand_err("block num is invalid:block:%d", block);
  1110. return -EINVAL;
  1111. }
  1112. #ifdef ALL_SLC_BUFFER
  1113. if (!is_slc_block(info, block)) {
  1114. devinfo.tlcControl.slcopmodeEn = FALSE;
  1115. } else {
  1116. nand_debug("erase SLC mode");
  1117. devinfo.tlcControl.slcopmodeEn = TRUE;
  1118. }
  1119. #else
  1120. if (block < info->data_block_num) {
  1121. devinfo.tlcControl.slcopmodeEn = FALSE;
  1122. } else {
  1123. nand_debug("erase SLC mode");
  1124. devinfo.tlcControl.slcopmodeEn = TRUE;
  1125. }
  1126. #endif
  1127. offset = (u64)((block+data_info->bmt.start_block) * info->data_page_num);
  1128. offset = offset * info->data_page_size;
  1129. status = nand_erase_hw(offset);
  1130. if (status)
  1131. ret_status = 0;
  1132. else
  1133. ret_status = -EIO;
  1134. callback(info, NULL, NULL, block, 0, ret_status, userdata);
  1135. return ret_status;
  1136. }
  1137. struct mtk_nand_chip_info *mtk_nand_chip_init(void)
  1138. {
  1139. if (&data_info->chip_info != NULL)
  1140. return &data_info->chip_info;
  1141. else
  1142. return 0;
  1143. }
  1144. int mtk_nand_ops_init(void)
  1145. {
  1146. int ret = 0;
  1147. mtk_nand_data_info_init();
  1148. ret = get_data_partition_info(&data_info->partition_info, &data_info->chip_info);
  1149. if (ret) {
  1150. nand_err("Get FTL partition info failed\n");
  1151. goto err_out;
  1152. }
  1153. mtk_nand_dump_partition_info(&data_info->partition_info);
  1154. ret = get_data_bmt(&data_info->bmt);
  1155. if (ret) {
  1156. nand_err("Get FTL bmt info failed\n");
  1157. goto err_out;
  1158. }
  1159. mtk_nand_dump_bmt_info(&data_info->bmt);
  1160. mtk_chip_info_init(&data_info->chip_info);
  1161. mtk_nand_dump_chip_info(&data_info->chip_info);
  1162. ret = mtk_chip_bbt_init(&data_info->bmt);
  1163. if (ret) {
  1164. nand_err("Get chip bbt info failed\n");
  1165. goto err_out;
  1166. }
  1167. #ifdef MTK_NAND_CHIP_TEST
  1168. mtk_chip_unit_test();
  1169. #endif
  1170. return 0;
  1171. err_out:
  1172. return ret;
  1173. }
  1174. int mtk_nand_update_block_type(int num, unsigned int *blk)
  1175. {
  1176. return mntl_update_part_tab(&data_info->chip_info, num, blk);
  1177. }