1 /*
2  * NAND Flash Controller Device Driver
3  * Copyright (c) 2009, Intel Corporation and its suppliers.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  */
19 
20 #include <linux/fs.h>
21 #include <linux/slab.h>
22 #include <linux/mtd/mtd.h>
23 #include "flash.h"
24 #include "ffsdefs.h"
25 #include "lld_emu.h"
26 #include "lld.h"
27 #if CMD_DMA
28 #include "lld_cdma.h"
29 u32 totalUsedBanks;
30 u32 valid_banks[MAX_CHANS];
31 #endif
32 
33 #define GLOB_LLD_PAGES           64
34 #define GLOB_LLD_PAGE_SIZE       (512+16)
35 #define GLOB_LLD_PAGE_DATA_SIZE  512
36 #define GLOB_LLD_BLOCKS          2048
37 
38 static struct mtd_info *spectra_mtd;
39 static int mtddev = -1;
40 module_param(mtddev, int, 0);
41 
42 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
43 * Function:     mtd_Flash_Init
44 * Inputs:       none
45 * Outputs:      PASS=0 (notice 0=ok here)
46 * Description:  Creates & initializes the flash RAM array.
47 *
48 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Flash_Init(void)49 u16 mtd_Flash_Init(void)
50 {
51 	if (mtddev == -1) {
52 		printk(KERN_ERR "No MTD device specified. Give mtddev parameter\n");
53 		return FAIL;
54 	}
55 
56 	spectra_mtd = get_mtd_device(NULL, mtddev);
57 	if (!spectra_mtd) {
58 		printk(KERN_ERR "Failed to obtain MTD device #%d\n", mtddev);
59 		return FAIL;
60 	}
61 
62 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
63 		       __FILE__, __LINE__, __func__);
64 
65 	return PASS;
66 }
67 
68 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
69 * Function:     mtd_Flash_Release
70 * Inputs:       none
71 * Outputs:      PASS=0 (notice 0=ok here)
72 * Description:          Releases the flash.
73 *
74 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Flash_Release(void)75 int mtd_Flash_Release(void)
76 {
77 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
78 		       __FILE__, __LINE__, __func__);
79 	if (!spectra_mtd)
80 		return PASS;
81 
82 	put_mtd_device(spectra_mtd);
83 	spectra_mtd = NULL;
84 
85 	return PASS;
86 }
87 
88 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
89 * Function:     mtd_Read_Device_ID
90 * Inputs:       none
91 * Outputs:      PASS=1 FAIL=0
92 * Description:  Reads the info from the controller registers.
93 *               Sets up DeviceInfo structure with device parameters
94 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
95 
mtd_Read_Device_ID(void)96 u16 mtd_Read_Device_ID(void)
97 {
98 	uint64_t tmp;
99 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
100 		       __FILE__, __LINE__, __func__);
101 
102 	if (!spectra_mtd)
103 		return FAIL;
104 
105 	DeviceInfo.wDeviceMaker = 0;
106 	DeviceInfo.wDeviceType = 8;
107 	DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
108 	tmp = spectra_mtd->size;
109 	do_div(tmp, spectra_mtd->erasesize);
110 	DeviceInfo.wTotalBlocks = tmp;
111 	DeviceInfo.wSpectraEndBlock = DeviceInfo.wTotalBlocks - 1;
112 	DeviceInfo.wPagesPerBlock = spectra_mtd->erasesize / spectra_mtd->writesize;
113 	DeviceInfo.wPageSize = spectra_mtd->writesize + spectra_mtd->oobsize;
114 	DeviceInfo.wPageDataSize = spectra_mtd->writesize;
115 	DeviceInfo.wPageSpareSize = spectra_mtd->oobsize;
116 	DeviceInfo.wBlockSize = DeviceInfo.wPageSize * DeviceInfo.wPagesPerBlock;
117 	DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * DeviceInfo.wPagesPerBlock;
118 	DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
119 						DeviceInfo.wSpectraStartBlock
120 						+ 1);
121 	DeviceInfo.MLCDevice = 0;//spectra_mtd->celltype & NAND_CI_CELLTYPE_MSK;
122 	DeviceInfo.nBitsInPageNumber =
123 		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
124 	DeviceInfo.nBitsInPageDataSize =
125 		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
126 	DeviceInfo.nBitsInBlockDataSize =
127 		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
128 
129 #if CMD_DMA
130 	totalUsedBanks = 4;
131 	valid_banks[0] = 1;
132 	valid_banks[1] = 1;
133 	valid_banks[2] = 1;
134 	valid_banks[3] = 1;
135 #endif
136 
137 	return PASS;
138 }
139 
140 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
141 * Function:     mtd_Flash_Reset
142 * Inputs:       none
143 * Outputs:      PASS=0 (notice 0=ok here)
144 * Description:          Reset the flash
145 *
146 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Flash_Reset(void)147 u16 mtd_Flash_Reset(void)
148 {
149 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
150 		       __FILE__, __LINE__, __func__);
151 
152 	return PASS;
153 }
154 
erase_callback(struct erase_info * e)155 void erase_callback(struct erase_info *e)
156 {
157 	complete((void *)e->priv);
158 }
159 
160 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
161 * Function:     mtd_Erase_Block
162 * Inputs:       Address
163 * Outputs:      PASS=0 (notice 0=ok here)
164 * Description:          Erase a block
165 *
166 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Erase_Block(u32 block_add)167 u16 mtd_Erase_Block(u32 block_add)
168 {
169 	struct erase_info erase;
170 	DECLARE_COMPLETION_ONSTACK(comp);
171 	int ret;
172 
173 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
174 		       __FILE__, __LINE__, __func__);
175 
176 	if (block_add >= DeviceInfo.wTotalBlocks) {
177 		printk(KERN_ERR "mtd_Erase_Block error! "
178 		       "Too big block address: %d\n", block_add);
179 		return FAIL;
180 	}
181 
182 	nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
183 		(int)block_add);
184 
185 	erase.mtd = spectra_mtd;
186 	erase.callback = erase_callback;
187 	erase.addr = block_add * spectra_mtd->erasesize;
188 	erase.len = spectra_mtd->erasesize;
189 	erase.priv = (unsigned long)&comp;
190 
191 	ret = spectra_mtd->erase(spectra_mtd, &erase);
192 	if (!ret) {
193 		wait_for_completion(&comp);
194 		if (erase.state != MTD_ERASE_DONE)
195 			ret = -EIO;
196 	}
197 	if (ret) {
198 		printk(KERN_WARNING "mtd_Erase_Block error! "
199 		       "erase of region [0x%llx, 0x%llx] failed\n",
200 		       erase.addr, erase.len);
201 		return FAIL;
202 	}
203 
204 	return PASS;
205 }
206 
207 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
208 * Function:     mtd_Write_Page_Main
209 * Inputs:       Write buffer address pointer
210 *               Block number
211 *               Page  number
212 *               Number of pages to process
213 * Outputs:      PASS=0 (notice 0=ok here)
214 * Description:  Write the data in the buffer to main area of flash
215 *
216 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Write_Page_Main(u8 * write_data,u32 Block,u16 Page,u16 PageCount)217 u16 mtd_Write_Page_Main(u8 *write_data, u32 Block,
218 			   u16 Page, u16 PageCount)
219 {
220 	size_t retlen;
221 	int ret = 0;
222 
223 	if (Block >= DeviceInfo.wTotalBlocks)
224 		return FAIL;
225 
226 	if (Page + PageCount > DeviceInfo.wPagesPerBlock)
227 		return FAIL;
228 
229 	nand_dbg_print(NAND_DBG_DEBUG, "mtd_Write_Page_Main: "
230 		       "lba %u Page %u PageCount %u\n",
231 		       (unsigned int)Block,
232 		       (unsigned int)Page, (unsigned int)PageCount);
233 
234 
235 	while (PageCount) {
236 		ret = spectra_mtd->write(spectra_mtd,
237 					 (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
238 					 DeviceInfo.wPageDataSize, &retlen, write_data);
239 		if (ret) {
240 			printk(KERN_ERR "%s failed %d\n", __func__, ret);
241 			return FAIL;
242 		}
243 		write_data += DeviceInfo.wPageDataSize;
244 		Page++;
245 		PageCount--;
246 	}
247 
248 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
249 		       __FILE__, __LINE__, __func__);
250 
251 	return PASS;
252 }
253 
254 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
255 * Function:     mtd_Read_Page_Main
256 * Inputs:       Read buffer address pointer
257 *               Block number
258 *               Page  number
259 *               Number of pages to process
260 * Outputs:      PASS=0 (notice 0=ok here)
261 * Description:  Read the data from the flash main area to the buffer
262 *
263 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Read_Page_Main(u8 * read_data,u32 Block,u16 Page,u16 PageCount)264 u16 mtd_Read_Page_Main(u8 *read_data, u32 Block,
265 			  u16 Page, u16 PageCount)
266 {
267 	size_t retlen;
268 	int ret = 0;
269 
270 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
271 		       __FILE__, __LINE__, __func__);
272 
273 	if (Block >= DeviceInfo.wTotalBlocks)
274 		return FAIL;
275 
276 	if (Page + PageCount > DeviceInfo.wPagesPerBlock)
277 		return FAIL;
278 
279 	nand_dbg_print(NAND_DBG_DEBUG, "mtd_Read_Page_Main: "
280 		       "lba %u Page %u PageCount %u\n",
281 		       (unsigned int)Block,
282 		       (unsigned int)Page, (unsigned int)PageCount);
283 
284 
285 	while (PageCount) {
286 		ret = spectra_mtd->read(spectra_mtd,
287 					(Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
288 					DeviceInfo.wPageDataSize, &retlen, read_data);
289 		if (ret) {
290 			printk(KERN_ERR "%s failed %d\n", __func__, ret);
291 			return FAIL;
292 		}
293 		read_data += DeviceInfo.wPageDataSize;
294 		Page++;
295 		PageCount--;
296 	}
297 
298 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
299 		       __FILE__, __LINE__, __func__);
300 
301 	return PASS;
302 }
303 
304 #ifndef ELDORA
305 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
306 * Function:     mtd_Read_Page_Main_Spare
307 * Inputs:       Write Buffer
308 *                       Address
309 *                       Buffer size
310 * Outputs:      PASS=0 (notice 0=ok here)
311 * Description:          Read from flash main+spare area
312 *
313 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Read_Page_Main_Spare(u8 * read_data,u32 Block,u16 Page,u16 PageCount)314 u16 mtd_Read_Page_Main_Spare(u8 *read_data, u32 Block,
315 				u16 Page, u16 PageCount)
316 {
317 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
318 		       __FILE__, __LINE__, __func__);
319 
320 	if (Block >= DeviceInfo.wTotalBlocks) {
321 		printk(KERN_ERR "Read Page Main+Spare "
322 		       "Error: Block Address too big\n");
323 		return FAIL;
324 	}
325 
326 	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
327 		printk(KERN_ERR "Read Page Main+Spare "
328 		       "Error: Page number %d+%d too big in block %d\n",
329 		       Page, PageCount, Block);
330 		return FAIL;
331 	}
332 
333 	nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
334 		       "No. of pages %u block %u start page %u\n",
335 		       (unsigned int)PageCount,
336 		       (unsigned int)Block, (unsigned int)Page);
337 
338 
339 	while (PageCount) {
340 		struct mtd_oob_ops ops;
341 		int ret;
342 
343 		ops.mode = MTD_OOB_AUTO;
344 		ops.datbuf = read_data;
345 		ops.len = DeviceInfo.wPageDataSize;
346 		ops.oobbuf = read_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
347 		ops.ooblen = BTSIG_BYTES;
348 		ops.ooboffs = 0;
349 
350 		ret = spectra_mtd->read_oob(spectra_mtd,
351 					    (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
352 					    &ops);
353 		if (ret) {
354 			printk(KERN_ERR "%s failed %d\n", __func__, ret);
355 			return FAIL;
356 		}
357 		read_data += DeviceInfo.wPageSize;
358 		Page++;
359 		PageCount--;
360 	}
361 
362 	return PASS;
363 }
364 
365 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
366 * Function:     mtd_Write_Page_Main_Spare
367 * Inputs:       Write buffer
368 *                       address
369 *                       buffer length
370 * Outputs:      PASS=0 (notice 0=ok here)
371 * Description:          Write the buffer to main+spare area of flash
372 *
373 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Write_Page_Main_Spare(u8 * write_data,u32 Block,u16 Page,u16 page_count)374 u16 mtd_Write_Page_Main_Spare(u8 *write_data, u32 Block,
375 				 u16 Page, u16 page_count)
376 {
377 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
378 		       __FILE__, __LINE__, __func__);
379 
380 	if (Block >= DeviceInfo.wTotalBlocks) {
381 		printk(KERN_ERR "Write Page Main + Spare "
382 		       "Error: Block Address too big\n");
383 		return FAIL;
384 	}
385 
386 	if (Page + page_count > DeviceInfo.wPagesPerBlock) {
387 		printk(KERN_ERR "Write Page Main + Spare "
388 		       "Error: Page number %d+%d too big in block %d\n",
389 		       Page, page_count, Block);
390 		WARN_ON(1);
391 		return FAIL;
392 	}
393 
394 	nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
395 		       "No. of pages %u block %u start page %u\n",
396 		       (unsigned int)page_count,
397 		       (unsigned int)Block, (unsigned int)Page);
398 
399 	while (page_count) {
400 		struct mtd_oob_ops ops;
401 		int ret;
402 
403 		ops.mode = MTD_OOB_AUTO;
404 		ops.datbuf = write_data;
405 		ops.len = DeviceInfo.wPageDataSize;
406 		ops.oobbuf = write_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
407 		ops.ooblen = BTSIG_BYTES;
408 		ops.ooboffs = 0;
409 
410 		ret = spectra_mtd->write_oob(spectra_mtd,
411 					     (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
412 					     &ops);
413 		if (ret) {
414 			printk(KERN_ERR "%s failed %d\n", __func__, ret);
415 			return FAIL;
416 		}
417 		write_data += DeviceInfo.wPageSize;
418 		Page++;
419 		page_count--;
420 	}
421 
422 	return PASS;
423 }
424 
425 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
426 * Function:     mtd_Write_Page_Spare
427 * Inputs:       Write buffer
428 *                       Address
429 *                       buffer size
430 * Outputs:      PASS=0 (notice 0=ok here)
431 * Description:          Write the buffer in the spare area
432 *
433 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Write_Page_Spare(u8 * write_data,u32 Block,u16 Page,u16 PageCount)434 u16 mtd_Write_Page_Spare(u8 *write_data, u32 Block,
435 			    u16 Page, u16 PageCount)
436 {
437 	WARN_ON(1);
438 	return FAIL;
439 }
440 
441 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
442 * Function:     mtd_Read_Page_Spare
443 * Inputs:       Write Buffer
444 *                       Address
445 *                       Buffer size
446 * Outputs:      PASS=0 (notice 0=ok here)
447 * Description:          Read data from the spare area
448 *
449 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Read_Page_Spare(u8 * read_data,u32 Block,u16 Page,u16 PageCount)450 u16 mtd_Read_Page_Spare(u8 *read_data, u32 Block,
451 			   u16 Page, u16 PageCount)
452 {
453 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
454 		       __FILE__, __LINE__, __func__);
455 
456 	if (Block >= DeviceInfo.wTotalBlocks) {
457 		printk(KERN_ERR "Read Page Spare "
458 		       "Error: Block Address too big\n");
459 		return FAIL;
460 	}
461 
462 	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
463 		printk(KERN_ERR "Read Page Spare "
464 		       "Error: Page number too big\n");
465 		return FAIL;
466 	}
467 
468 	nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
469 		       "block %u page %u (%u pages)\n",
470 		       (unsigned int)Block, (unsigned int)Page, PageCount);
471 
472 	while (PageCount) {
473 		struct mtd_oob_ops ops;
474 		int ret;
475 
476 		ops.mode = MTD_OOB_AUTO;
477 		ops.datbuf = NULL;
478 		ops.len = 0;
479 		ops.oobbuf = read_data;
480 		ops.ooblen = BTSIG_BYTES;
481 		ops.ooboffs = 0;
482 
483 		ret = spectra_mtd->read_oob(spectra_mtd,
484 					    (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
485 					    &ops);
486 		if (ret) {
487 			printk(KERN_ERR "%s failed %d\n", __func__, ret);
488 			return FAIL;
489 		}
490 
491 		read_data += DeviceInfo.wPageSize;
492 		Page++;
493 		PageCount--;
494 	}
495 
496 	return PASS;
497 }
498 
499 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
500 * Function:     mtd_Enable_Disable_Interrupts
501 * Inputs:       enable or disable
502 * Outputs:      none
503 * Description:  NOP
504 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_Enable_Disable_Interrupts(u16 INT_ENABLE)505 void mtd_Enable_Disable_Interrupts(u16 INT_ENABLE)
506 {
507 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
508 		       __FILE__, __LINE__, __func__);
509 }
510 
mtd_Get_Bad_Block(u32 block)511 u16 mtd_Get_Bad_Block(u32 block)
512 {
513 	return 0;
514 }
515 
516 #if CMD_DMA
517 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
518 * Support for CDMA functions
519 ************************************
520 *       mtd_CDMA_Flash_Init
521 *           CDMA_process_data command   (use LLD_CDMA)
522 *           CDMA_MemCopy_CMD            (use LLD_CDMA)
523 *       mtd_CDMA_execute all commands
524 *       mtd_CDMA_Event_Status
525 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_CDMA_Flash_Init(void)526 u16 mtd_CDMA_Flash_Init(void)
527 {
528 	u16 i;
529 
530 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
531 		       __FILE__, __LINE__, __func__);
532 
533 	for (i = 0; i < MAX_DESCS + MAX_CHANS; i++) {
534 		PendingCMD[i].CMD = 0;
535 		PendingCMD[i].Tag = 0;
536 		PendingCMD[i].DataAddr = 0;
537 		PendingCMD[i].Block = 0;
538 		PendingCMD[i].Page = 0;
539 		PendingCMD[i].PageCount = 0;
540 		PendingCMD[i].DataDestAddr = 0;
541 		PendingCMD[i].DataSrcAddr = 0;
542 		PendingCMD[i].MemCopyByteCnt = 0;
543 		PendingCMD[i].ChanSync[0] = 0;
544 		PendingCMD[i].ChanSync[1] = 0;
545 		PendingCMD[i].ChanSync[2] = 0;
546 		PendingCMD[i].ChanSync[3] = 0;
547 		PendingCMD[i].ChanSync[4] = 0;
548 		PendingCMD[i].Status = 3;
549 	}
550 
551 	return PASS;
552 }
553 
mtd_isr(int irq,void * dev_id)554 static void mtd_isr(int irq, void *dev_id)
555 {
556 	/* TODO:  ... */
557 }
558 
559 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
560 * Function:     CDMA_Execute_CMDs
561 * Inputs:       tag_count:  the number of pending cmds to do
562 * Outputs:      PASS/FAIL
563 * Description:  execute each command in the pending CMD array
564 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
mtd_CDMA_Execute_CMDs(u16 tag_count)565 u16 mtd_CDMA_Execute_CMDs(u16 tag_count)
566 {
567 	u16 i, j;
568 	u8 CMD;		/* cmd parameter */
569 	u8 *data;
570 	u32 block;
571 	u16 page;
572 	u16 count;
573 	u16 status = PASS;
574 
575 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
576 		       __FILE__, __LINE__, __func__);
577 
578 	nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
579 		       "Tag Count %u\n", tag_count);
580 
581 	for (i = 0; i < totalUsedBanks; i++) {
582 		PendingCMD[i].CMD = DUMMY_CMD;
583 		PendingCMD[i].Tag = 0xFF;
584 		PendingCMD[i].Block =
585 		    (DeviceInfo.wTotalBlocks / totalUsedBanks) * i;
586 
587 		for (j = 0; j <= MAX_CHANS; j++)
588 			PendingCMD[i].ChanSync[j] = 0;
589 	}
590 
591 	CDMA_Execute_CMDs(tag_count);
592 
593 #ifdef VERBOSE
594 		print_pending_cmds(tag_count);
595 #endif
596 #if DEBUG_SYNC
597 	}
598 	debug_sync_cnt++;
599 #endif
600 
601 	for (i = MAX_CHANS;
602 	     i < tag_count + MAX_CHANS; i++) {
603 		CMD = PendingCMD[i].CMD;
604 		data = PendingCMD[i].DataAddr;
605 		block = PendingCMD[i].Block;
606 		page = PendingCMD[i].Page;
607 		count = PendingCMD[i].PageCount;
608 
609 		switch (CMD) {
610 		case ERASE_CMD:
611 			mtd_Erase_Block(block);
612 			PendingCMD[i].Status = PASS;
613 			break;
614 		case WRITE_MAIN_CMD:
615 			mtd_Write_Page_Main(data, block, page, count);
616 			PendingCMD[i].Status = PASS;
617 			break;
618 		case WRITE_MAIN_SPARE_CMD:
619 			mtd_Write_Page_Main_Spare(data, block, page, count);
620 			PendingCMD[i].Status = PASS;
621 			break;
622 		case READ_MAIN_CMD:
623 			mtd_Read_Page_Main(data, block, page, count);
624 			PendingCMD[i].Status = PASS;
625 			break;
626 		case MEMCOPY_CMD:
627 			memcpy(PendingCMD[i].DataDestAddr,
628 			       PendingCMD[i].DataSrcAddr,
629 			       PendingCMD[i].MemCopyByteCnt);
630 		case DUMMY_CMD:
631 			PendingCMD[i].Status = PASS;
632 			break;
633 		default:
634 			PendingCMD[i].Status = FAIL;
635 			break;
636 		}
637 	}
638 
639 	/*
640 	 * Temperory adding code to reset PendingCMD array for basic testing.
641 	 * It should be done at the end of  event status function.
642 	 */
643 	for (i = tag_count + MAX_CHANS; i < MAX_DESCS; i++) {
644 		PendingCMD[i].CMD = 0;
645 		PendingCMD[i].Tag = 0;
646 		PendingCMD[i].DataAddr = 0;
647 		PendingCMD[i].Block = 0;
648 		PendingCMD[i].Page = 0;
649 		PendingCMD[i].PageCount = 0;
650 		PendingCMD[i].DataDestAddr = 0;
651 		PendingCMD[i].DataSrcAddr = 0;
652 		PendingCMD[i].MemCopyByteCnt = 0;
653 		PendingCMD[i].ChanSync[0] = 0;
654 		PendingCMD[i].ChanSync[1] = 0;
655 		PendingCMD[i].ChanSync[2] = 0;
656 		PendingCMD[i].ChanSync[3] = 0;
657 		PendingCMD[i].ChanSync[4] = 0;
658 		PendingCMD[i].Status = CMD_NOT_DONE;
659 	}
660 
661 	nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
662 
663 	mtd_isr(0, 0); /* This is a null isr now. Need fill it in future */
664 
665 	return status;
666 }
667 
668 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
669 * Function:     mtd_Event_Status
670 * Inputs:       none
671 * Outputs:      Event_Status code
672 * Description:  This function can also be used to force errors
673 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
674 u16 mtd_CDMA_Event_Status(void)
675 {
676 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
677 		       __FILE__, __LINE__, __func__);
678 
679 	return EVENT_PASS;
680 }
681 
682 #endif /* CMD_DMA */
683 #endif /* !ELDORA */
684