• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/spectra/
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
23#include "spectraswconfig.h"
24#include "lld.h"
25#include "lld_nand.h"
26#include "lld_cdma.h"
27#include "lld_emu.h"
28#include "flash.h"
29#include "nand_regs.h"
30
31#define MAX_PENDING_CMDS    4
32#define MODE_02             (0x2 << 26)
33
34/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
35* Function:     CDMA_Data_Cmd
36* Inputs:   cmd code (aligned for hw)
37*               data: pointer to source or destination
38*               block: block address
39*               page: page address
40*               num: num pages to transfer
41* Outputs:      PASS
42* Description:  This function takes the parameters and puts them
43*                   into the "pending commands" array.
44*               It does not parse or validate the parameters.
45*               The array index is same as the tag.
46*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
47u16 CDMA_Data_CMD(u8 cmd, u8 *data, u32 block, u16 page, u16 num, u16 flags)
48{
49	u8 bank;
50
51	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
52		       __FILE__, __LINE__, __func__);
53
54	if (0 == cmd)
55		nand_dbg_print(NAND_DBG_DEBUG,
56		"%s, Line %d, Illegal cmd (0)\n", __FILE__, __LINE__);
57
58	/* If a command of another bank comes, then first execute */
59	/* pending commands of the current bank, then set the new */
60	/* bank as current bank */
61	bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
62	if (bank != info.flash_bank) {
63		nand_dbg_print(NAND_DBG_WARN,
64			"Will access new bank. old bank: %d, new bank: %d\n",
65			info.flash_bank, bank);
66		if (CDMA_Execute_CMDs()) {
67			printk(KERN_ERR "CDMA_Execute_CMDs fail!\n");
68			return FAIL;
69		}
70		info.flash_bank = bank;
71	}
72
73	info.pcmds[info.pcmds_num].CMD = cmd;
74	info.pcmds[info.pcmds_num].DataAddr = data;
75	info.pcmds[info.pcmds_num].Block = block;
76	info.pcmds[info.pcmds_num].Page = page;
77	info.pcmds[info.pcmds_num].PageCount = num;
78	info.pcmds[info.pcmds_num].DataDestAddr = 0;
79	info.pcmds[info.pcmds_num].DataSrcAddr = 0;
80	info.pcmds[info.pcmds_num].MemCopyByteCnt = 0;
81	info.pcmds[info.pcmds_num].Flags = flags;
82	info.pcmds[info.pcmds_num].Status = 0xB0B;
83
84	switch (cmd) {
85	case WRITE_MAIN_SPARE_CMD:
86		Conv_Main_Spare_Data_Log2Phy_Format(data, num);
87		break;
88	case WRITE_SPARE_CMD:
89		Conv_Spare_Data_Log2Phy_Format(data);
90		break;
91	default:
92		break;
93	}
94
95	info.pcmds_num++;
96
97	if (info.pcmds_num >= MAX_PENDING_CMDS) {
98		if (CDMA_Execute_CMDs()) {
99			printk(KERN_ERR "CDMA_Execute_CMDs fail!\n");
100			return FAIL;
101		}
102	}
103
104	return PASS;
105}
106
107/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
108* Function:     CDMA_MemCopy_CMD
109* Inputs:       dest: pointer to destination
110*               src:  pointer to source
111*               count: num bytes to transfer
112* Outputs:      PASS
113* Description:  This function takes the parameters and puts them
114*                   into the "pending commands" array.
115*               It does not parse or validate the parameters.
116*               The array index is same as the tag.
117*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
118u16 CDMA_MemCopy_CMD(u8 *dest, u8 *src, u32 byte_cnt, u16 flags)
119{
120	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
121		       __FILE__, __LINE__, __func__);
122
123	info.pcmds[info.pcmds_num].CMD = MEMCOPY_CMD;
124	info.pcmds[info.pcmds_num].DataAddr = 0;
125	info.pcmds[info.pcmds_num].Block = 0;
126	info.pcmds[info.pcmds_num].Page = 0;
127	info.pcmds[info.pcmds_num].PageCount = 0;
128	info.pcmds[info.pcmds_num].DataDestAddr = dest;
129	info.pcmds[info.pcmds_num].DataSrcAddr = src;
130	info.pcmds[info.pcmds_num].MemCopyByteCnt = byte_cnt;
131	info.pcmds[info.pcmds_num].Flags = flags;
132	info.pcmds[info.pcmds_num].Status = 0xB0B;
133
134	info.pcmds_num++;
135
136	if (info.pcmds_num >= MAX_PENDING_CMDS) {
137		if (CDMA_Execute_CMDs()) {
138			printk(KERN_ERR "CDMA_Execute_CMDs fail!\n");
139			return FAIL;
140		}
141	}
142
143	return PASS;
144}
145
146
147/* Reset cdma_descriptor chain to 0 */
148static void reset_cdma_desc(int i)
149{
150	struct cdma_descriptor *ptr;
151
152	BUG_ON(i >= MAX_DESCS);
153
154	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
155
156	ptr[i].NxtPointerHi = 0;
157	ptr[i].NxtPointerLo = 0;
158	ptr[i].FlashPointerHi = 0;
159	ptr[i].FlashPointerLo = 0;
160	ptr[i].CommandType = 0;
161	ptr[i].MemAddrHi = 0;
162	ptr[i].MemAddrLo = 0;
163	ptr[i].CommandFlags = 0;
164	ptr[i].Channel = 0;
165	ptr[i].Status = 0;
166	ptr[i].MemCopyPointerHi = 0;
167	ptr[i].MemCopyPointerLo = 0;
168}
169
170/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
171* Function:     CDMA_UpdateEventStatus
172* Inputs:       none
173* Outputs:      none
174* Description:  This function update the event status of all the channels
175*               when an error condition is reported.
176*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
177void CDMA_UpdateEventStatus(void)
178{
179	int i, j, active_chan;
180	struct cdma_descriptor *ptr;
181
182	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
183		       __FILE__, __LINE__, __func__);
184
185	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
186
187	for (j = 0; j < info.cdma_num; j++) {
188		/* Check for the descriptor with failure */
189		if ((ptr[j].Status & CMD_DMA_DESC_FAIL))
190			break;
191
192	}
193
194	/* All the previous cmd's status for this channel must be good */
195	for (i = 0; i < j; i++) {
196		if (ptr[i].pcmd != 0xff)
197			info.pcmds[ptr[i].pcmd].Status = CMD_PASS;
198	}
199
200	/* Abort the channel with type 0 reset command. It resets the */
201	/* selected channel after the descriptor completes the flash */
202	/* operation and status has been updated for the descriptor. */
203	/* Memory Copy and Sync associated with this descriptor will */
204	/* not be executed */
205	active_chan = ioread32(FlashReg + CHNL_ACTIVE);
206	if ((active_chan & (1 << info.flash_bank)) == (1 << info.flash_bank)) {
207		iowrite32(MODE_02 | (0 << 4), FlashMem); /* Type 0 reset */
208		iowrite32((0xF << 4) | info.flash_bank, FlashMem + 0x10);
209	} else { /* Should not reached here */
210		printk(KERN_ERR "Error! Used bank is not set in"
211			" reg CHNL_ACTIVE\n");
212	}
213}
214
215static void cdma_trans(u16 chan)
216{
217	u32 addr;
218
219	addr = info.cdma_desc;
220
221	iowrite32(MODE_10 | (chan << 24), FlashMem);
222	iowrite32((1 << 7) | chan, FlashMem + 0x10);
223
224	iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & (addr >> 16)) << 8),
225		FlashMem);
226	iowrite32((1 << 7) | (1 << 4) | 0, FlashMem + 0x10);
227
228	iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & addr) << 8), FlashMem);
229	iowrite32((1 << 7) | (1 << 5) | 0, FlashMem + 0x10);
230
231	iowrite32(MODE_10 | (chan << 24), FlashMem);
232	iowrite32((1 << 7) | (1 << 5) | (1 << 4) | 0, FlashMem + 0x10);
233}
234
235/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
236* Function:     CDMA_Execute_CMDs (for use with CMD_DMA)
237* Inputs:       tag_count:  the number of pending cmds to do
238* Outputs:      PASS/FAIL
239* Description:  Build the SDMA chain(s) by making one CMD-DMA descriptor
240*               for each pending command, start the CDMA engine, and return.
241*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
242u16 CDMA_Execute_CMDs(void)
243{
244	int i, ret;
245	u64 flash_add;
246	u32 ptr;
247	dma_addr_t map_addr, next_ptr;
248	u16 status = PASS;
249	u16 tmp_c;
250	struct cdma_descriptor *pc;
251	struct memcpy_descriptor *pm;
252
253	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
254		       __FILE__, __LINE__, __func__);
255
256	/* No pending cmds to execute, just exit */
257	if (0 == info.pcmds_num) {
258		nand_dbg_print(NAND_DBG_TRACE,
259			"No pending cmds to execute. Just exit.\n");
260		return PASS;
261	}
262
263	for (i = 0; i < MAX_DESCS; i++)
264		reset_cdma_desc(i);
265
266	pc = (struct cdma_descriptor *)info.cdma_desc_buf;
267	pm = (struct memcpy_descriptor *)info.memcp_desc_buf;
268
269	info.cdma_desc = virt_to_bus(info.cdma_desc_buf);
270	info.memcp_desc = virt_to_bus(info.memcp_desc_buf);
271	next_ptr = info.cdma_desc;
272	info.cdma_num = 0;
273
274	for (i = 0; i < info.pcmds_num; i++) {
275		if (info.pcmds[i].Block >= DeviceInfo.wTotalBlocks) {
276			info.pcmds[i].Status = CMD_NOT_DONE;
277			continue;
278		}
279
280		next_ptr += sizeof(struct cdma_descriptor);
281		pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
282		pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
283
284		/* Use the Block offset within a bank */
285		tmp_c = info.pcmds[i].Block /
286			(DeviceInfo.wTotalBlocks / totalUsedBanks);
287		flash_add = (u64)(info.pcmds[i].Block - tmp_c *
288			(DeviceInfo.wTotalBlocks / totalUsedBanks)) *
289			DeviceInfo.wBlockDataSize +
290			(u64)(info.pcmds[i].Page) *
291			DeviceInfo.wPageDataSize;
292
293		ptr = MODE_10 | (info.flash_bank << 24) |
294			(u32)GLOB_u64_Div(flash_add,
295				DeviceInfo.wPageDataSize);
296		pc[info.cdma_num].FlashPointerHi = ptr >> 16;
297		pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
298
299		if ((info.pcmds[i].CMD == WRITE_MAIN_SPARE_CMD) ||
300			(info.pcmds[i].CMD == READ_MAIN_SPARE_CMD)) {
301			/* Descriptor to set Main+Spare Access Mode */
302			pc[info.cdma_num].CommandType = 0x43;
303			pc[info.cdma_num].CommandFlags =
304				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
305			pc[info.cdma_num].MemAddrHi = 0;
306			pc[info.cdma_num].MemAddrLo = 0;
307			pc[info.cdma_num].Channel = 0;
308			pc[info.cdma_num].Status = 0;
309			pc[info.cdma_num].pcmd = i;
310
311			info.cdma_num++;
312			BUG_ON(info.cdma_num >= MAX_DESCS);
313
314			reset_cdma_desc(info.cdma_num);
315			next_ptr += sizeof(struct cdma_descriptor);
316			pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
317			pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
318			pc[info.cdma_num].FlashPointerHi = ptr >> 16;
319			pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
320		}
321
322		switch (info.pcmds[i].CMD) {
323		case ERASE_CMD:
324			pc[info.cdma_num].CommandType = 1;
325			pc[info.cdma_num].CommandFlags =
326				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
327			pc[info.cdma_num].MemAddrHi = 0;
328			pc[info.cdma_num].MemAddrLo = 0;
329			break;
330
331		case WRITE_MAIN_CMD:
332			pc[info.cdma_num].CommandType =
333				0x2100 | info.pcmds[i].PageCount;
334			pc[info.cdma_num].CommandFlags =
335				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
336			map_addr = virt_to_bus(info.pcmds[i].DataAddr);
337			pc[info.cdma_num].MemAddrHi = map_addr >> 16;
338			pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
339			break;
340
341		case READ_MAIN_CMD:
342			pc[info.cdma_num].CommandType =
343				0x2000 | info.pcmds[i].PageCount;
344			pc[info.cdma_num].CommandFlags =
345				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
346			map_addr = virt_to_bus(info.pcmds[i].DataAddr);
347			pc[info.cdma_num].MemAddrHi = map_addr >> 16;
348			pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
349			break;
350
351		case WRITE_MAIN_SPARE_CMD:
352			pc[info.cdma_num].CommandType =
353				0x2100 | info.pcmds[i].PageCount;
354			pc[info.cdma_num].CommandFlags =
355				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
356			map_addr = virt_to_bus(info.pcmds[i].DataAddr);
357			pc[info.cdma_num].MemAddrHi = map_addr >> 16;
358			pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
359			break;
360
361		case READ_MAIN_SPARE_CMD:
362			pc[info.cdma_num].CommandType =
363				0x2000 | info.pcmds[i].PageCount;
364			pc[info.cdma_num].CommandFlags =
365				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
366			map_addr = virt_to_bus(info.pcmds[i].DataAddr);
367			pc[info.cdma_num].MemAddrHi = map_addr >> 16;
368			pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
369			break;
370
371		case MEMCOPY_CMD:
372			pc[info.cdma_num].CommandType = 0xFFFF; /* NOP cmd */
373			/* Set bit 11 to let the CDMA engine continue to */
374			/* execute only after it has finished processing   */
375			/* the memcopy descriptor.                        */
376			/* Also set bit 10 and bit 9 to 1                  */
377			pc[info.cdma_num].CommandFlags = 0x0E40;
378			map_addr = info.memcp_desc + info.cdma_num *
379					sizeof(struct memcpy_descriptor);
380			pc[info.cdma_num].MemCopyPointerHi = map_addr >> 16;
381			pc[info.cdma_num].MemCopyPointerLo = map_addr & 0xffff;
382
383			pm[info.cdma_num].NxtPointerHi = 0;
384			pm[info.cdma_num].NxtPointerLo = 0;
385
386			map_addr = virt_to_bus(info.pcmds[i].DataSrcAddr);
387			pm[info.cdma_num].SrcAddrHi = map_addr >> 16;
388			pm[info.cdma_num].SrcAddrLo = map_addr & 0xffff;
389			map_addr = virt_to_bus(info.pcmds[i].DataDestAddr);
390			pm[info.cdma_num].DestAddrHi = map_addr >> 16;
391			pm[info.cdma_num].DestAddrLo = map_addr & 0xffff;
392
393			pm[info.cdma_num].XferSize =
394				info.pcmds[i].MemCopyByteCnt;
395			pm[info.cdma_num].MemCopyFlags =
396				(0 << 15 | 0 << 14 | 27 << 8 | 0x40);
397			pm[info.cdma_num].MemCopyStatus = 0;
398			break;
399
400		case DUMMY_CMD:
401		default:
402			pc[info.cdma_num].CommandType = 0XFFFF;
403			pc[info.cdma_num].CommandFlags =
404				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
405			pc[info.cdma_num].MemAddrHi = 0;
406			pc[info.cdma_num].MemAddrLo = 0;
407			break;
408		}
409
410		pc[info.cdma_num].Channel = 0;
411		pc[info.cdma_num].Status = 0;
412		pc[info.cdma_num].pcmd = i;
413
414		info.cdma_num++;
415		BUG_ON(info.cdma_num >= MAX_DESCS);
416
417		if ((info.pcmds[i].CMD == WRITE_MAIN_SPARE_CMD) ||
418			(info.pcmds[i].CMD == READ_MAIN_SPARE_CMD)) {
419			/* Descriptor to set back Main Area Access Mode */
420			reset_cdma_desc(info.cdma_num);
421			next_ptr += sizeof(struct cdma_descriptor);
422			pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
423			pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
424
425			pc[info.cdma_num].FlashPointerHi = ptr >> 16;
426			pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
427
428			pc[info.cdma_num].CommandType = 0x42;
429			pc[info.cdma_num].CommandFlags =
430				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
431			pc[info.cdma_num].MemAddrHi = 0;
432			pc[info.cdma_num].MemAddrLo = 0;
433
434			pc[info.cdma_num].Channel = 0;
435			pc[info.cdma_num].Status = 0;
436			pc[info.cdma_num].pcmd = i;
437
438			info.cdma_num++;
439			BUG_ON(info.cdma_num >= MAX_DESCS);
440		}
441	}
442
443	/* Add a dummy descriptor at end of the CDMA chain */
444	reset_cdma_desc(info.cdma_num);
445	ptr = MODE_10 | (info.flash_bank << 24);
446	pc[info.cdma_num].FlashPointerHi = ptr >> 16;
447	pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
448	pc[info.cdma_num].CommandType = 0xFFFF; /* NOP command */
449	/* Set Command Flags for the last CDMA descriptor: */
450	/* set Continue bit (bit 9) to 0 and Interrupt bit (bit 8) to 1 */
451	pc[info.cdma_num].CommandFlags =
452		(0 << 10) | (0 << 9) | (1 << 8) | 0x40;
453	pc[info.cdma_num].pcmd = 0xff; /* Set it to an illegal value */
454	info.cdma_num++;
455	BUG_ON(info.cdma_num >= MAX_DESCS);
456
457	iowrite32(1, FlashReg + GLOBAL_INT_ENABLE);  /* Enable Interrupt */
458
459	iowrite32(1, FlashReg + DMA_ENABLE);
460	/* Wait for DMA to be enabled before issuing the next command */
461	while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
462		;
463	cdma_trans(info.flash_bank);
464
465	ret = wait_for_completion_timeout(&info.complete, 50 * HZ);
466	if (!ret)
467		printk(KERN_ERR "Wait for completion timeout "
468			"in %s, Line %d\n", __FILE__, __LINE__);
469	status = info.ret;
470
471	info.pcmds_num = 0; /* Clear the pending cmds number to 0 */
472
473	return status;
474}
475
476int is_cdma_interrupt(void)
477{
478	u32 ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma;
479	u32 int_en_mask;
480	u32 cdma_int_en_mask;
481
482	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
483		       __FILE__, __LINE__, __func__);
484
485	/* Set the global Enable masks for only those interrupts
486	 * that are supported */
487	cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
488			DMA_INTR__DESC_COMP_CHANNEL1 |
489			DMA_INTR__DESC_COMP_CHANNEL2 |
490			DMA_INTR__DESC_COMP_CHANNEL3 |
491			DMA_INTR__MEMCOPY_DESC_COMP);
492
493	int_en_mask = (INTR_STATUS0__ECC_ERR |
494		INTR_STATUS0__PROGRAM_FAIL |
495		INTR_STATUS0__ERASE_FAIL);
496
497	ints_b0 = ioread32(FlashReg + INTR_STATUS0) & int_en_mask;
498	ints_b1 = ioread32(FlashReg + INTR_STATUS1) & int_en_mask;
499	ints_b2 = ioread32(FlashReg + INTR_STATUS2) & int_en_mask;
500	ints_b3 = ioread32(FlashReg + INTR_STATUS3) & int_en_mask;
501	ints_cdma = ioread32(FlashReg + DMA_INTR) & cdma_int_en_mask;
502
503	nand_dbg_print(NAND_DBG_WARN, "ints_bank0 to ints_bank3: "
504			"0x%x, 0x%x, 0x%x, 0x%x, ints_cdma: 0x%x\n",
505			ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma);
506
507	if (ints_b0 || ints_b1 || ints_b2 || ints_b3 || ints_cdma) {
508		return 1;
509	} else {
510		iowrite32(ints_b0, FlashReg + INTR_STATUS0);
511		iowrite32(ints_b1, FlashReg + INTR_STATUS1);
512		iowrite32(ints_b2, FlashReg + INTR_STATUS2);
513		iowrite32(ints_b3, FlashReg + INTR_STATUS3);
514		nand_dbg_print(NAND_DBG_DEBUG,
515			"Not a NAND controller interrupt! Ignore it.\n");
516		return 0;
517	}
518}
519
520static void update_event_status(void)
521{
522	int i;
523	struct cdma_descriptor *ptr;
524
525	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
526		       __FILE__, __LINE__, __func__);
527
528	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
529
530	for (i = 0; i < info.cdma_num; i++) {
531		if (ptr[i].pcmd != 0xff)
532			info.pcmds[ptr[i].pcmd].Status = CMD_PASS;
533		if ((ptr[i].CommandType == 0x41) ||
534			(ptr[i].CommandType == 0x42) ||
535			(ptr[i].CommandType == 0x43))
536			continue;
537
538		switch (info.pcmds[ptr[i].pcmd].CMD) {
539		case READ_MAIN_SPARE_CMD:
540			Conv_Main_Spare_Data_Phy2Log_Format(
541				info.pcmds[ptr[i].pcmd].DataAddr,
542				info.pcmds[ptr[i].pcmd].PageCount);
543			break;
544		case READ_SPARE_CMD:
545			Conv_Spare_Data_Phy2Log_Format(
546				info.pcmds[ptr[i].pcmd].DataAddr);
547			break;
548		}
549	}
550}
551
552static u16 do_ecc_for_desc(u32 ch, u8 *buf, u16 page)
553{
554	u16 event = EVENT_NONE;
555	u16 err_byte;
556	u16 err_page = 0;
557	u8 err_sector;
558	u8 err_device;
559	u16 ecc_correction_info;
560	u16 err_address;
561	u32 eccSectorSize;
562	u8 *err_pos;
563
564	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
565		       __FILE__, __LINE__, __func__);
566
567	eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
568
569	do {
570		if (0 == ch)
571			err_page = ioread32(FlashReg + ERR_PAGE_ADDR0);
572		else if (1 == ch)
573			err_page = ioread32(FlashReg + ERR_PAGE_ADDR1);
574		else if (2 == ch)
575			err_page = ioread32(FlashReg + ERR_PAGE_ADDR2);
576		else if (3 == ch)
577			err_page = ioread32(FlashReg + ERR_PAGE_ADDR3);
578
579		err_address = ioread32(FlashReg + ECC_ERROR_ADDRESS);
580		err_byte = err_address & ECC_ERROR_ADDRESS__OFFSET;
581		err_sector = ((err_address &
582			ECC_ERROR_ADDRESS__SECTOR_NR) >> 12);
583
584		ecc_correction_info = ioread32(FlashReg + ERR_CORRECTION_INFO);
585		err_device = ((ecc_correction_info &
586			ERR_CORRECTION_INFO__DEVICE_NR) >> 8);
587
588		if (ecc_correction_info & ERR_CORRECTION_INFO__ERROR_TYPE) {
589			event = EVENT_UNCORRECTABLE_DATA_ERROR;
590		} else {
591			event = EVENT_CORRECTABLE_DATA_ERROR_FIXED;
592			if (err_byte < ECC_SECTOR_SIZE) {
593				err_pos = buf +
594					(err_page - page) *
595					DeviceInfo.wPageDataSize +
596					err_sector * eccSectorSize +
597					err_byte *
598					DeviceInfo.wDevicesConnected +
599					err_device;
600				*err_pos ^= ecc_correction_info &
601					ERR_CORRECTION_INFO__BYTEMASK;
602			}
603		}
604	} while (!(ecc_correction_info & ERR_CORRECTION_INFO__LAST_ERR_INFO));
605
606	return event;
607}
608
609static u16 process_ecc_int(u32 c, u16 *p_desc_num)
610{
611	struct cdma_descriptor *ptr;
612	u16 j;
613	int event = EVENT_PASS;
614
615	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
616		       __FILE__, __LINE__, __func__);
617
618	if (c != info.flash_bank)
619		printk(KERN_ERR "Error!info.flash_bank is %d, while c is %d\n",
620				info.flash_bank, c);
621
622	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
623
624	for (j = 0; j < info.cdma_num; j++)
625		if ((ptr[j].Status & CMD_DMA_DESC_COMP) != CMD_DMA_DESC_COMP)
626			break;
627
628	*p_desc_num = j; /* Pass the descripter number found here */
629
630	if (j >= info.cdma_num) {
631		printk(KERN_ERR "Can not find the correct descriptor number "
632			"when ecc interrupt triggered!"
633			"info.cdma_num: %d, j: %d\n", info.cdma_num, j);
634		return EVENT_UNCORRECTABLE_DATA_ERROR;
635	}
636
637	event = do_ecc_for_desc(c, info.pcmds[ptr[j].pcmd].DataAddr,
638		info.pcmds[ptr[j].pcmd].Page);
639
640	if (EVENT_UNCORRECTABLE_DATA_ERROR == event) {
641		printk(KERN_ERR "Uncorrectable ECC error!"
642			"info.cdma_num: %d, j: %d, "
643			"pending cmd CMD: 0x%x, "
644			"Block: 0x%x, Page: 0x%x, PageCount: 0x%x\n",
645			info.cdma_num, j,
646			info.pcmds[ptr[j].pcmd].CMD,
647			info.pcmds[ptr[j].pcmd].Block,
648			info.pcmds[ptr[j].pcmd].Page,
649			info.pcmds[ptr[j].pcmd].PageCount);
650
651		if (ptr[j].pcmd != 0xff)
652			info.pcmds[ptr[j].pcmd].Status = CMD_FAIL;
653		CDMA_UpdateEventStatus();
654	}
655
656	return event;
657}
658
659static void process_prog_erase_fail_int(u16 desc_num)
660{
661	struct cdma_descriptor *ptr;
662
663	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
664		       __FILE__, __LINE__, __func__);
665
666	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
667
668	if (ptr[desc_num].pcmd != 0xFF)
669		info.pcmds[ptr[desc_num].pcmd].Status = CMD_FAIL;
670
671	CDMA_UpdateEventStatus();
672}
673
674/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
675* Function:     CDMA_Event_Status (for use with CMD_DMA)
676* Inputs:       none
677* Outputs:      Event_Status code
678* Description:  This function is called after an interrupt has happened
679*               It reads the HW status register and ...tbd
680*               It returns the appropriate event status
681*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
682u16  CDMA_Event_Status(void)
683{
684	u32 ints_addr[4] = {INTR_STATUS0, INTR_STATUS1,
685		INTR_STATUS2, INTR_STATUS3};
686	u32 dma_intr_bit[4] = {DMA_INTR__DESC_COMP_CHANNEL0,
687		DMA_INTR__DESC_COMP_CHANNEL1,
688		DMA_INTR__DESC_COMP_CHANNEL2,
689		DMA_INTR__DESC_COMP_CHANNEL3};
690	u32 cdma_int_status, int_status;
691	u32 ecc_enable = 0;
692	u16 event = EVENT_PASS;
693	u16 cur_desc = 0;
694
695	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
696		       __FILE__, __LINE__, __func__);
697
698	ecc_enable = ioread32(FlashReg + ECC_ENABLE);
699
700	while (1) {
701		int_status = ioread32(FlashReg + ints_addr[info.flash_bank]);
702		if (ecc_enable && (int_status & INTR_STATUS0__ECC_ERR)) {
703			event = process_ecc_int(info.flash_bank, &cur_desc);
704			iowrite32(INTR_STATUS0__ECC_ERR,
705				FlashReg + ints_addr[info.flash_bank]);
706			if (EVENT_UNCORRECTABLE_DATA_ERROR == event) {
707				nand_dbg_print(NAND_DBG_WARN,
708					"ints_bank0 to ints_bank3: "
709					"0x%x, 0x%x, 0x%x, 0x%x, "
710					"ints_cdma: 0x%x\n",
711					ioread32(FlashReg + INTR_STATUS0),
712					ioread32(FlashReg + INTR_STATUS1),
713					ioread32(FlashReg + INTR_STATUS2),
714					ioread32(FlashReg + INTR_STATUS3),
715					ioread32(FlashReg + DMA_INTR));
716				break;
717			}
718		} else if (int_status & INTR_STATUS0__PROGRAM_FAIL) {
719			printk(KERN_ERR "NAND program fail interrupt!\n");
720			process_prog_erase_fail_int(cur_desc);
721			event = EVENT_PROGRAM_FAILURE;
722			break;
723		} else if (int_status & INTR_STATUS0__ERASE_FAIL) {
724			printk(KERN_ERR "NAND erase fail interrupt!\n");
725			process_prog_erase_fail_int(cur_desc);
726			event = EVENT_ERASE_FAILURE;
727			break;
728		} else {
729			cdma_int_status = ioread32(FlashReg + DMA_INTR);
730			if (cdma_int_status & dma_intr_bit[info.flash_bank]) {
731				iowrite32(dma_intr_bit[info.flash_bank],
732					FlashReg + DMA_INTR);
733				update_event_status();
734				event = EVENT_PASS;
735				break;
736			}
737		}
738	}
739
740	int_status = ioread32(FlashReg + ints_addr[info.flash_bank]);
741	iowrite32(int_status, FlashReg + ints_addr[info.flash_bank]);
742	cdma_int_status = ioread32(FlashReg + DMA_INTR);
743	iowrite32(cdma_int_status, FlashReg + DMA_INTR);
744
745	iowrite32(0, FlashReg + DMA_ENABLE);
746	while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
747		;
748
749	return event;
750}
751