]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/block/spectra/lld_cdma.c
c6e76103d43c4a99493a12c01c7710f4d65617c0
[net-next-2.6.git] / drivers / block / spectra / lld_cdma.c
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 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
47 u16 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 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
118 u16 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 #if 0
147 /* Prints the PendingCMDs array */
148 void print_pending_cmds(void)
149 {
150         u16 i;
151
152         nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
153                        __FILE__, __LINE__, __func__);
154
155         for (i = 0; i < info.pcmds_num; i++) {
156                 nand_dbg_print(NAND_DBG_DEBUG, "\ni: %d\n", i);
157                 switch (info.pcmds[i].CMD) {
158                 case ERASE_CMD:
159                         nand_dbg_print(NAND_DBG_DEBUG,
160                                 "Erase Command (0x%x)\n",
161                                 info.pcmds[i].CMD);
162                         break;
163                 case WRITE_MAIN_CMD:
164                         nand_dbg_print(NAND_DBG_DEBUG,
165                                 "Write Main Command (0x%x)\n",
166                                 info.pcmds[i].CMD);
167                         break;
168                 case WRITE_MAIN_SPARE_CMD:
169                         nand_dbg_print(NAND_DBG_DEBUG,
170                                 "Write Main Spare Command (0x%x)\n",
171                                 info.pcmds[i].CMD);
172                         break;
173                 case READ_MAIN_SPARE_CMD:
174                         nand_dbg_print(NAND_DBG_DEBUG,
175                                 "Read Main Spare Command (0x%x)\n",
176                                 info.pcmds[i].CMD);
177                         break;
178                 case READ_MAIN_CMD:
179                         nand_dbg_print(NAND_DBG_DEBUG,
180                                 "Read Main Command (0x%x)\n",
181                                 info.pcmds[i].CMD);
182                         break;
183                 case MEMCOPY_CMD:
184                         nand_dbg_print(NAND_DBG_DEBUG,
185                                 "Memcopy Command (0x%x)\n",
186                                 info.pcmds[i].CMD);
187                         break;
188                 case DUMMY_CMD:
189                         nand_dbg_print(NAND_DBG_DEBUG,
190                                 "Dummy Command (0x%x)\n",
191                                 info.pcmds[i].CMD);
192                         break;
193                 default:
194                         nand_dbg_print(NAND_DBG_DEBUG,
195                                 "Illegal Command (0x%x)\n",
196                                 info.pcmds[i].CMD);
197                         break;
198                 }
199
200                 nand_dbg_print(NAND_DBG_DEBUG, "DataAddr: 0x%x\n",
201                         (u32)info.pcmds[i].DataAddr);
202                 nand_dbg_print(NAND_DBG_DEBUG, "Block: %d\n",
203                         info.pcmds[i].Block);
204                 nand_dbg_print(NAND_DBG_DEBUG, "Page: %d\n",
205                         info.pcmds[i].Page);
206                 nand_dbg_print(NAND_DBG_DEBUG, "PageCount: %d\n",
207                         info.pcmds[i].PageCount);
208                 nand_dbg_print(NAND_DBG_DEBUG, "DataDestAddr: 0x%x\n",
209                         (u32)info.pcmds[i].DataDestAddr);
210                 nand_dbg_print(NAND_DBG_DEBUG, "DataSrcAddr: 0x%x\n",
211                         (u32)info.pcmds[i].DataSrcAddr);
212                 nand_dbg_print(NAND_DBG_DEBUG, "MemCopyByteCnt: %d\n",
213                         info.pcmds[i].MemCopyByteCnt);
214                 nand_dbg_print(NAND_DBG_DEBUG, "Flags: 0x%x\n",
215                         info.pcmds[i].Flags);
216                 nand_dbg_print(NAND_DBG_DEBUG, "Status: 0x%x\n",
217                         info.pcmds[i].Status);
218         }
219 }
220
221 /* Print the CDMA descriptors */
222 void print_cdma_descriptors(void)
223 {
224         struct cdma_descriptor *pc;
225         int i;
226
227         pc = (struct cdma_descriptor *)info.cdma_desc_buf;
228
229         nand_dbg_print(NAND_DBG_DEBUG, "\nWill dump cdma descriptors:\n");
230
231         for (i = 0; i < info.cdma_num; i++) {
232                 nand_dbg_print(NAND_DBG_DEBUG, "\ni: %d\n", i);
233                 nand_dbg_print(NAND_DBG_DEBUG,
234                         "NxtPointerHi: 0x%x, NxtPointerLo: 0x%x\n",
235                         pc[i].NxtPointerHi, pc[i].NxtPointerLo);
236                 nand_dbg_print(NAND_DBG_DEBUG,
237                         "FlashPointerHi: 0x%x, FlashPointerLo: 0x%x\n",
238                         pc[i].FlashPointerHi, pc[i].FlashPointerLo);
239                 nand_dbg_print(NAND_DBG_DEBUG, "CommandType: 0x%x\n",
240                         pc[i].CommandType);
241                 nand_dbg_print(NAND_DBG_DEBUG,
242                         "MemAddrHi: 0x%x, MemAddrLo: 0x%x\n",
243                         pc[i].MemAddrHi, pc[i].MemAddrLo);
244                 nand_dbg_print(NAND_DBG_DEBUG, "CommandFlags: 0x%x\n",
245                         pc[i].CommandFlags);
246                 nand_dbg_print(NAND_DBG_DEBUG, "Channel: %d, Status: 0x%x\n",
247                         pc[i].Channel, pc[i].Status);
248                 nand_dbg_print(NAND_DBG_DEBUG,
249                         "MemCopyPointerHi: 0x%x, MemCopyPointerLo: 0x%x\n",
250                         pc[i].MemCopyPointerHi, pc[i].MemCopyPointerLo);
251                 nand_dbg_print(NAND_DBG_DEBUG,
252                         "Reserved12: 0x%x, Reserved13: 0x%x, "
253                         "Reserved14: 0x%x, pcmd: %d\n",
254                         pc[i].Reserved12, pc[i].Reserved13,
255                         pc[i].Reserved14, pc[i].pcmd);
256         }
257 }
258
259 /* Print the Memory copy descriptors */
260 static void print_memcp_descriptors(void)
261 {
262         struct memcpy_descriptor *pm;
263         int i;
264
265         pm = (struct memcpy_descriptor *)info.memcp_desc_buf;
266
267         nand_dbg_print(NAND_DBG_DEBUG, "\nWill dump mem_cpy descriptors:\n");
268
269         for (i = 0; i < info.cdma_num; i++) {
270                 nand_dbg_print(NAND_DBG_DEBUG, "\ni: %d\n", i);
271                 nand_dbg_print(NAND_DBG_DEBUG,
272                         "NxtPointerHi: 0x%x, NxtPointerLo: 0x%x\n",
273                         pm[i].NxtPointerHi, pm[i].NxtPointerLo);
274                 nand_dbg_print(NAND_DBG_DEBUG,
275                         "SrcAddrHi: 0x%x, SrcAddrLo: 0x%x\n",
276                         pm[i].SrcAddrHi, pm[i].SrcAddrLo);
277                 nand_dbg_print(NAND_DBG_DEBUG,
278                         "DestAddrHi: 0x%x, DestAddrLo: 0x%x\n",
279                         pm[i].DestAddrHi, pm[i].DestAddrLo);
280                 nand_dbg_print(NAND_DBG_DEBUG, "XferSize: %d\n",
281                         pm[i].XferSize);
282                 nand_dbg_print(NAND_DBG_DEBUG, "MemCopyFlags: 0x%x\n",
283                         pm[i].MemCopyFlags);
284                 nand_dbg_print(NAND_DBG_DEBUG, "MemCopyStatus: %d\n",
285                         pm[i].MemCopyStatus);
286                 nand_dbg_print(NAND_DBG_DEBUG, "reserved9: 0x%x\n",
287                         pm[i].reserved9);
288                 nand_dbg_print(NAND_DBG_DEBUG, "reserved10: 0x%x\n",
289                         pm[i].reserved10);
290                 nand_dbg_print(NAND_DBG_DEBUG, "reserved11: 0x%x\n",
291                         pm[i].reserved11);
292                 nand_dbg_print(NAND_DBG_DEBUG, "reserved12: 0x%x\n",
293                         pm[i].reserved12);
294                 nand_dbg_print(NAND_DBG_DEBUG, "reserved13: 0x%x\n",
295                         pm[i].reserved13);
296                 nand_dbg_print(NAND_DBG_DEBUG, "reserved14: 0x%x\n",
297                         pm[i].reserved14);
298                 nand_dbg_print(NAND_DBG_DEBUG, "reserved15: 0x%x\n",
299                         pm[i].reserved15);
300         }
301 }
302 #endif
303
304 /* Reset cdma_descriptor chain to 0 */
305 static void reset_cdma_desc(int i)
306 {
307         struct cdma_descriptor *ptr;
308
309         BUG_ON(i >= MAX_DESCS);
310
311         ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
312
313         ptr[i].NxtPointerHi = 0;
314         ptr[i].NxtPointerLo = 0;
315         ptr[i].FlashPointerHi = 0;
316         ptr[i].FlashPointerLo = 0;
317         ptr[i].CommandType = 0;
318         ptr[i].MemAddrHi = 0;
319         ptr[i].MemAddrLo = 0;
320         ptr[i].CommandFlags = 0;
321         ptr[i].Channel = 0;
322         ptr[i].Status = 0;
323         ptr[i].MemCopyPointerHi = 0;
324         ptr[i].MemCopyPointerLo = 0;
325 }
326
327 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
328 * Function:     CDMA_UpdateEventStatus
329 * Inputs:       none
330 * Outputs:      none
331 * Description:  This function update the event status of all the channels
332 *               when an error condition is reported.
333 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
334 void CDMA_UpdateEventStatus(void)
335 {
336         int i, j, active_chan;
337         struct cdma_descriptor *ptr;
338
339         nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
340                        __FILE__, __LINE__, __func__);
341
342         ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
343
344         for (j = 0; j < info.cdma_num; j++) {
345                 /* Check for the descriptor with failure */
346                 if ((ptr[j].Status & CMD_DMA_DESC_FAIL))
347                         break;
348
349         }
350
351         /* All the previous cmd's status for this channel must be good */
352         for (i = 0; i < j; i++) {
353                 if (ptr[i].pcmd != 0xff)
354                         info.pcmds[ptr[i].pcmd].Status = CMD_PASS;
355         }
356
357         /* Abort the channel with type 0 reset command. It resets the */
358         /* selected channel after the descriptor completes the flash */
359         /* operation and status has been updated for the descriptor. */
360         /* Memory Copy and Sync associated with this descriptor will */
361         /* not be executed */
362         active_chan = ioread32(FlashReg + CHNL_ACTIVE);
363         if ((active_chan & (1 << info.flash_bank)) == (1 << info.flash_bank)) {
364                 iowrite32(MODE_02 | (0 << 4), FlashMem); /* Type 0 reset */
365                 iowrite32((0xF << 4) | info.flash_bank, FlashMem + 0x10);
366         } else { /* Should not reached here */
367                 printk(KERN_ERR "Error! Used bank is not set in"
368                         " reg CHNL_ACTIVE\n");
369         }
370 }
371
372 static void cdma_trans(u16 chan)
373 {
374         u32 addr;
375
376         addr = info.cdma_desc;
377
378         iowrite32(MODE_10 | (chan << 24), FlashMem);
379         iowrite32((1 << 7) | chan, FlashMem + 0x10);
380
381         iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & (addr >> 16)) << 8),
382                 FlashMem);
383         iowrite32((1 << 7) | (1 << 4) | 0, FlashMem + 0x10);
384
385         iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & addr) << 8), FlashMem);
386         iowrite32((1 << 7) | (1 << 5) | 0, FlashMem + 0x10);
387
388         iowrite32(MODE_10 | (chan << 24), FlashMem);
389         iowrite32((1 << 7) | (1 << 5) | (1 << 4) | 0, FlashMem + 0x10);
390 }
391
392 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
393 * Function:     CDMA_Execute_CMDs (for use with CMD_DMA)
394 * Inputs:       tag_count:  the number of pending cmds to do
395 * Outputs:      PASS/FAIL
396 * Description:  Build the SDMA chain(s) by making one CMD-DMA descriptor
397 *               for each pending command, start the CDMA engine, and return.
398 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
399 u16 CDMA_Execute_CMDs(void)
400 {
401         int i, ret;
402         u64 flash_add;
403         u32 ptr;
404         dma_addr_t map_addr, next_ptr;
405         u16 status = PASS;
406         u16 tmp_c;
407         struct cdma_descriptor *pc;
408         struct memcpy_descriptor *pm;
409
410         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
411                        __FILE__, __LINE__, __func__);
412
413         /* No pending cmds to execute, just exit */
414         if (0 == info.pcmds_num) {
415                 nand_dbg_print(NAND_DBG_TRACE,
416                         "No pending cmds to execute. Just exit.\n");
417                 return PASS;
418         }
419
420         for (i = 0; i < MAX_DESCS; i++)
421                 reset_cdma_desc(i);
422
423         pc = (struct cdma_descriptor *)info.cdma_desc_buf;
424         pm = (struct memcpy_descriptor *)info.memcp_desc_buf;
425
426         info.cdma_desc = virt_to_bus(info.cdma_desc_buf);
427         info.memcp_desc = virt_to_bus(info.memcp_desc_buf);
428         next_ptr = info.cdma_desc;
429         info.cdma_num = 0;
430
431         for (i = 0; i < info.pcmds_num; i++) {
432                 if (info.pcmds[i].Block >= DeviceInfo.wTotalBlocks) {
433                         info.pcmds[i].Status = CMD_NOT_DONE;
434                         continue;
435                 }
436
437                 next_ptr += sizeof(struct cdma_descriptor);
438                 pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
439                 pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
440
441                 /* Use the Block offset within a bank */
442                 tmp_c = info.pcmds[i].Block /
443                         (DeviceInfo.wTotalBlocks / totalUsedBanks);
444                 flash_add = (u64)(info.pcmds[i].Block - tmp_c *
445                         (DeviceInfo.wTotalBlocks / totalUsedBanks)) *
446                         DeviceInfo.wBlockDataSize +
447                         (u64)(info.pcmds[i].Page) *
448                         DeviceInfo.wPageDataSize;
449
450                 ptr = MODE_10 | (info.flash_bank << 24) |
451                         (u32)GLOB_u64_Div(flash_add,
452                                 DeviceInfo.wPageDataSize);
453                 pc[info.cdma_num].FlashPointerHi = ptr >> 16;
454                 pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
455
456                 if ((info.pcmds[i].CMD == WRITE_MAIN_SPARE_CMD) ||
457                         (info.pcmds[i].CMD == READ_MAIN_SPARE_CMD)) {
458                         /* Descriptor to set Main+Spare Access Mode */
459                         pc[info.cdma_num].CommandType = 0x43;
460                         pc[info.cdma_num].CommandFlags =
461                                 (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
462                         pc[info.cdma_num].MemAddrHi = 0;
463                         pc[info.cdma_num].MemAddrLo = 0;
464                         pc[info.cdma_num].Channel = 0;
465                         pc[info.cdma_num].Status = 0;
466                         pc[info.cdma_num].pcmd = i;
467
468                         info.cdma_num++;
469                         BUG_ON(info.cdma_num >= MAX_DESCS);
470
471                         reset_cdma_desc(info.cdma_num);
472                         next_ptr += sizeof(struct cdma_descriptor);
473                         pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
474                         pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
475                         pc[info.cdma_num].FlashPointerHi = ptr >> 16;
476                         pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
477                 }
478
479                 switch (info.pcmds[i].CMD) {
480                 case ERASE_CMD:
481                         pc[info.cdma_num].CommandType = 1;
482                         pc[info.cdma_num].CommandFlags =
483                                 (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
484                         pc[info.cdma_num].MemAddrHi = 0;
485                         pc[info.cdma_num].MemAddrLo = 0;
486                         break;
487
488                 case WRITE_MAIN_CMD:
489                         pc[info.cdma_num].CommandType =
490                                 0x2100 | info.pcmds[i].PageCount;
491                         pc[info.cdma_num].CommandFlags =
492                                 (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
493                         map_addr = virt_to_bus(info.pcmds[i].DataAddr);
494                         pc[info.cdma_num].MemAddrHi = map_addr >> 16;
495                         pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
496                         break;
497
498                 case READ_MAIN_CMD:
499                         pc[info.cdma_num].CommandType =
500                                 0x2000 | info.pcmds[i].PageCount;
501                         pc[info.cdma_num].CommandFlags =
502                                 (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
503                         map_addr = virt_to_bus(info.pcmds[i].DataAddr);
504                         pc[info.cdma_num].MemAddrHi = map_addr >> 16;
505                         pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
506                         break;
507
508                 case WRITE_MAIN_SPARE_CMD:
509                         pc[info.cdma_num].CommandType =
510                                 0x2100 | info.pcmds[i].PageCount;
511                         pc[info.cdma_num].CommandFlags =
512                                 (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
513                         map_addr = virt_to_bus(info.pcmds[i].DataAddr);
514                         pc[info.cdma_num].MemAddrHi = map_addr >> 16;
515                         pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
516                         break;
517
518                 case READ_MAIN_SPARE_CMD:
519                         pc[info.cdma_num].CommandType =
520                                 0x2000 | info.pcmds[i].PageCount;
521                         pc[info.cdma_num].CommandFlags =
522                                 (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
523                         map_addr = virt_to_bus(info.pcmds[i].DataAddr);
524                         pc[info.cdma_num].MemAddrHi = map_addr >> 16;
525                         pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
526                         break;
527
528                 case MEMCOPY_CMD:
529                         pc[info.cdma_num].CommandType = 0xFFFF; /* NOP cmd */
530                         /* Set bit 11 to let the CDMA engine continue to */
531                         /* execute only after it has finished processing   */
532                         /* the memcopy descriptor.                        */
533                         /* Also set bit 10 and bit 9 to 1                  */
534                         pc[info.cdma_num].CommandFlags = 0x0E40;
535                         map_addr = info.memcp_desc + info.cdma_num *
536                                         sizeof(struct memcpy_descriptor);
537                         pc[info.cdma_num].MemCopyPointerHi = map_addr >> 16;
538                         pc[info.cdma_num].MemCopyPointerLo = map_addr & 0xffff;
539
540                         pm[info.cdma_num].NxtPointerHi = 0;
541                         pm[info.cdma_num].NxtPointerLo = 0;
542
543                         map_addr = virt_to_bus(info.pcmds[i].DataSrcAddr);
544                         pm[info.cdma_num].SrcAddrHi = map_addr >> 16;
545                         pm[info.cdma_num].SrcAddrLo = map_addr & 0xffff;
546                         map_addr = virt_to_bus(info.pcmds[i].DataDestAddr);
547                         pm[info.cdma_num].DestAddrHi = map_addr >> 16;
548                         pm[info.cdma_num].DestAddrLo = map_addr & 0xffff;
549
550                         pm[info.cdma_num].XferSize =
551                                 info.pcmds[i].MemCopyByteCnt;
552                         pm[info.cdma_num].MemCopyFlags =
553                                 (0 << 15 | 0 << 14 | 27 << 8 | 0x40);
554                         pm[info.cdma_num].MemCopyStatus = 0;
555                         break;
556
557                 case DUMMY_CMD:
558                 default:
559                         pc[info.cdma_num].CommandType = 0XFFFF;
560                         pc[info.cdma_num].CommandFlags =
561                                 (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
562                         pc[info.cdma_num].MemAddrHi = 0;
563                         pc[info.cdma_num].MemAddrLo = 0;
564                         break;
565                 }
566
567                 pc[info.cdma_num].Channel = 0;
568                 pc[info.cdma_num].Status = 0;
569                 pc[info.cdma_num].pcmd = i;
570
571                 info.cdma_num++;
572                 BUG_ON(info.cdma_num >= MAX_DESCS);
573
574                 if ((info.pcmds[i].CMD == WRITE_MAIN_SPARE_CMD) ||
575                         (info.pcmds[i].CMD == READ_MAIN_SPARE_CMD)) {
576                         /* Descriptor to set back Main Area Access Mode */
577                         reset_cdma_desc(info.cdma_num);
578                         next_ptr += sizeof(struct cdma_descriptor);
579                         pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
580                         pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
581
582                         pc[info.cdma_num].FlashPointerHi = ptr >> 16;
583                         pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
584
585                         pc[info.cdma_num].CommandType = 0x42;
586                         pc[info.cdma_num].CommandFlags =
587                                 (0 << 10) | (1 << 9) | (0 << 8) | 0x40;
588                         pc[info.cdma_num].MemAddrHi = 0;
589                         pc[info.cdma_num].MemAddrLo = 0;
590
591                         pc[info.cdma_num].Channel = 0;
592                         pc[info.cdma_num].Status = 0;
593                         pc[info.cdma_num].pcmd = i;
594
595                         info.cdma_num++;
596                         BUG_ON(info.cdma_num >= MAX_DESCS);
597                 }
598         }
599
600         /* Add a dummy descriptor at end of the CDMA chain */
601         reset_cdma_desc(info.cdma_num);
602         ptr = MODE_10 | (info.flash_bank << 24);
603         pc[info.cdma_num].FlashPointerHi = ptr >> 16;
604         pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
605         pc[info.cdma_num].CommandType = 0xFFFF; /* NOP command */
606         /* Set Command Flags for the last CDMA descriptor: */
607         /* set Continue bit (bit 9) to 0 and Interrupt bit (bit 8) to 1 */
608         pc[info.cdma_num].CommandFlags =
609                 (0 << 10) | (0 << 9) | (1 << 8) | 0x40;
610         pc[info.cdma_num].pcmd = 0xff; /* Set it to an illegal value */
611         info.cdma_num++;
612         BUG_ON(info.cdma_num >= MAX_DESCS);
613
614         iowrite32(1, FlashReg + GLOBAL_INT_ENABLE);  /* Enable Interrupt */
615
616         iowrite32(1, FlashReg + DMA_ENABLE);
617         /* Wait for DMA to be enabled before issuing the next command */
618         while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
619                 ;
620         cdma_trans(info.flash_bank);
621
622         ret = wait_for_completion_timeout(&info.complete, 50 * HZ);
623         if (!ret)
624                 printk(KERN_ERR "Wait for completion timeout "
625                         "in %s, Line %d\n", __FILE__, __LINE__);
626         status = info.ret;
627
628         info.pcmds_num = 0; /* Clear the pending cmds number to 0 */
629
630         return status;
631 }
632
633 int is_cdma_interrupt(void)
634 {
635         u32 ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma;
636         u32 int_en_mask;
637         u32 cdma_int_en_mask;
638
639         nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
640                        __FILE__, __LINE__, __func__);
641
642         /* Set the global Enable masks for only those interrupts
643          * that are supported */
644         cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
645                         DMA_INTR__DESC_COMP_CHANNEL1 |
646                         DMA_INTR__DESC_COMP_CHANNEL2 |
647                         DMA_INTR__DESC_COMP_CHANNEL3 |
648                         DMA_INTR__MEMCOPY_DESC_COMP);
649
650         int_en_mask = (INTR_STATUS0__ECC_ERR |
651                 INTR_STATUS0__PROGRAM_FAIL |
652                 INTR_STATUS0__ERASE_FAIL);
653
654         ints_b0 = ioread32(FlashReg + INTR_STATUS0) & int_en_mask;
655         ints_b1 = ioread32(FlashReg + INTR_STATUS1) & int_en_mask;
656         ints_b2 = ioread32(FlashReg + INTR_STATUS2) & int_en_mask;
657         ints_b3 = ioread32(FlashReg + INTR_STATUS3) & int_en_mask;
658         ints_cdma = ioread32(FlashReg + DMA_INTR) & cdma_int_en_mask;
659
660         nand_dbg_print(NAND_DBG_WARN, "ints_bank0 to ints_bank3: "
661                         "0x%x, 0x%x, 0x%x, 0x%x, ints_cdma: 0x%x\n",
662                         ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma);
663
664         if (ints_b0 || ints_b1 || ints_b2 || ints_b3 || ints_cdma) {
665                 return 1;
666         } else {
667                 iowrite32(ints_b0, FlashReg + INTR_STATUS0);
668                 iowrite32(ints_b1, FlashReg + INTR_STATUS1);
669                 iowrite32(ints_b2, FlashReg + INTR_STATUS2);
670                 iowrite32(ints_b3, FlashReg + INTR_STATUS3);
671                 nand_dbg_print(NAND_DBG_DEBUG,
672                         "Not a NAND controller interrupt! Ignore it.\n");
673                 return 0;
674         }
675 }
676
677 static void update_event_status(void)
678 {
679         int i;
680         struct cdma_descriptor *ptr;
681
682         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
683                        __FILE__, __LINE__, __func__);
684
685         ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
686
687         for (i = 0; i < info.cdma_num; i++) {
688                 if (ptr[i].pcmd != 0xff)
689                         info.pcmds[ptr[i].pcmd].Status = CMD_PASS;
690                 if ((ptr[i].CommandType == 0x41) ||
691                         (ptr[i].CommandType == 0x42) ||
692                         (ptr[i].CommandType == 0x43))
693                         continue;
694
695                 switch (info.pcmds[ptr[i].pcmd].CMD) {
696                 case READ_MAIN_SPARE_CMD:
697                         Conv_Main_Spare_Data_Phy2Log_Format(
698                                 info.pcmds[ptr[i].pcmd].DataAddr,
699                                 info.pcmds[ptr[i].pcmd].PageCount);
700                         break;
701                 case READ_SPARE_CMD:
702                         Conv_Spare_Data_Phy2Log_Format(
703                                 info.pcmds[ptr[i].pcmd].DataAddr);
704                         break;
705                 }
706         }
707 }
708
709 static u16 do_ecc_for_desc(u32 ch, u8 *buf, u16 page)
710 {
711         u16 event = EVENT_NONE;
712         u16 err_byte;
713         u16 err_page = 0;
714         u8 err_sector;
715         u8 err_device;
716         u16 ecc_correction_info;
717         u16 err_address;
718         u32 eccSectorSize;
719         u8 *err_pos;
720
721         nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
722                        __FILE__, __LINE__, __func__);
723
724         eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
725
726         do {
727                 if (0 == ch)
728                         err_page = ioread32(FlashReg + ERR_PAGE_ADDR0);
729                 else if (1 == ch)
730                         err_page = ioread32(FlashReg + ERR_PAGE_ADDR1);
731                 else if (2 == ch)
732                         err_page = ioread32(FlashReg + ERR_PAGE_ADDR2);
733                 else if (3 == ch)
734                         err_page = ioread32(FlashReg + ERR_PAGE_ADDR3);
735
736                 err_address = ioread32(FlashReg + ECC_ERROR_ADDRESS);
737                 err_byte = err_address & ECC_ERROR_ADDRESS__OFFSET;
738                 err_sector = ((err_address &
739                         ECC_ERROR_ADDRESS__SECTOR_NR) >> 12);
740
741                 ecc_correction_info = ioread32(FlashReg + ERR_CORRECTION_INFO);
742                 err_device = ((ecc_correction_info &
743                         ERR_CORRECTION_INFO__DEVICE_NR) >> 8);
744
745                 if (ecc_correction_info & ERR_CORRECTION_INFO__ERROR_TYPE) {
746                         event = EVENT_UNCORRECTABLE_DATA_ERROR;
747                 } else {
748                         event = EVENT_CORRECTABLE_DATA_ERROR_FIXED;
749                         if (err_byte < ECC_SECTOR_SIZE) {
750                                 err_pos = buf +
751                                         (err_page - page) *
752                                         DeviceInfo.wPageDataSize +
753                                         err_sector * eccSectorSize +
754                                         err_byte *
755                                         DeviceInfo.wDevicesConnected +
756                                         err_device;
757                                 *err_pos ^= ecc_correction_info &
758                                         ERR_CORRECTION_INFO__BYTEMASK;
759                         }
760                 }
761         } while (!(ecc_correction_info & ERR_CORRECTION_INFO__LAST_ERR_INFO));
762
763         return event;
764 }
765
766 static u16 process_ecc_int(u32 c, u16 *p_desc_num)
767 {
768         struct cdma_descriptor *ptr;
769         u16 j;
770         int event = EVENT_PASS;
771
772         nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
773                        __FILE__, __LINE__, __func__);
774
775         if (c != info.flash_bank)
776                 printk(KERN_ERR "Error!info.flash_bank is %d, while c is %d\n",
777                                 info.flash_bank, c);
778
779         ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
780
781         for (j = 0; j < info.cdma_num; j++)
782                 if ((ptr[j].Status & CMD_DMA_DESC_COMP) != CMD_DMA_DESC_COMP)
783                         break;
784
785         *p_desc_num = j; /* Pass the descripter number found here */
786
787         if (j >= info.cdma_num) {
788                 printk(KERN_ERR "Can not find the correct descriptor number "
789                         "when ecc interrupt triggered!"
790                         "info.cdma_num: %d, j: %d\n", info.cdma_num, j);
791                 return EVENT_UNCORRECTABLE_DATA_ERROR;
792         }
793
794         event = do_ecc_for_desc(c, info.pcmds[ptr[j].pcmd].DataAddr,
795                 info.pcmds[ptr[j].pcmd].Page);
796
797         if (EVENT_UNCORRECTABLE_DATA_ERROR == event) {
798                 printk(KERN_ERR "Uncorrectable ECC error!"
799                         "info.cdma_num: %d, j: %d, "
800                         "pending cmd CMD: 0x%x, "
801                         "Block: 0x%x, Page: 0x%x, PageCount: 0x%x\n",
802                         info.cdma_num, j,
803                         info.pcmds[ptr[j].pcmd].CMD,
804                         info.pcmds[ptr[j].pcmd].Block,
805                         info.pcmds[ptr[j].pcmd].Page,
806                         info.pcmds[ptr[j].pcmd].PageCount);
807
808                 if (ptr[j].pcmd != 0xff)
809                         info.pcmds[ptr[j].pcmd].Status = CMD_FAIL;
810                 CDMA_UpdateEventStatus();
811         }
812
813         return event;
814 }
815
816 static void process_prog_erase_fail_int(u16 desc_num)
817 {
818         struct cdma_descriptor *ptr;
819
820         nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
821                        __FILE__, __LINE__, __func__);
822
823         ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
824
825         if (ptr[desc_num].pcmd != 0xFF)
826                 info.pcmds[ptr[desc_num].pcmd].Status = CMD_FAIL;
827
828         CDMA_UpdateEventStatus();
829 }
830
831 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
832 * Function:     CDMA_Event_Status (for use with CMD_DMA)
833 * Inputs:       none
834 * Outputs:      Event_Status code
835 * Description:  This function is called after an interrupt has happened
836 *               It reads the HW status register and ...tbd
837 *               It returns the appropriate event status
838 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
839 u16  CDMA_Event_Status(void)
840 {
841         u32 ints_addr[4] = {INTR_STATUS0, INTR_STATUS1,
842                 INTR_STATUS2, INTR_STATUS3};
843         u32 dma_intr_bit[4] = {DMA_INTR__DESC_COMP_CHANNEL0,
844                 DMA_INTR__DESC_COMP_CHANNEL1,
845                 DMA_INTR__DESC_COMP_CHANNEL2,
846                 DMA_INTR__DESC_COMP_CHANNEL3};
847         u32 cdma_int_status, int_status;
848         u32 ecc_enable = 0;
849         u16 event = EVENT_PASS;
850         u16 cur_desc = 0;
851
852         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
853                        __FILE__, __LINE__, __func__);
854
855         ecc_enable = ioread32(FlashReg + ECC_ENABLE);
856
857         while (1) {
858                 int_status = ioread32(FlashReg + ints_addr[info.flash_bank]);
859                 if (ecc_enable && (int_status & INTR_STATUS0__ECC_ERR)) {
860                         event = process_ecc_int(info.flash_bank, &cur_desc);
861                         iowrite32(INTR_STATUS0__ECC_ERR,
862                                 FlashReg + ints_addr[info.flash_bank]);
863                         if (EVENT_UNCORRECTABLE_DATA_ERROR == event) {
864                                 nand_dbg_print(NAND_DBG_WARN,
865                                         "ints_bank0 to ints_bank3: "
866                                         "0x%x, 0x%x, 0x%x, 0x%x, "
867                                         "ints_cdma: 0x%x\n",
868                                         ioread32(FlashReg + INTR_STATUS0),
869                                         ioread32(FlashReg + INTR_STATUS1),
870                                         ioread32(FlashReg + INTR_STATUS2),
871                                         ioread32(FlashReg + INTR_STATUS3),
872                                         ioread32(FlashReg + DMA_INTR));
873                                 break;
874                         }
875                 } else if (int_status & INTR_STATUS0__PROGRAM_FAIL) {
876                         printk(KERN_ERR "NAND program fail interrupt!\n");
877                         process_prog_erase_fail_int(cur_desc);
878                         event = EVENT_PROGRAM_FAILURE;
879                         break;
880                 } else if (int_status & INTR_STATUS0__ERASE_FAIL) {
881                         printk(KERN_ERR "NAND erase fail interrupt!\n");
882                         process_prog_erase_fail_int(cur_desc);
883                         event = EVENT_ERASE_FAILURE;
884                         break;
885                 } else {
886                         cdma_int_status = ioread32(FlashReg + DMA_INTR);
887                         if (cdma_int_status & dma_intr_bit[info.flash_bank]) {
888                                 iowrite32(dma_intr_bit[info.flash_bank],
889                                         FlashReg + DMA_INTR);
890                                 update_event_status();
891                                 event = EVENT_PASS;
892                                 break;
893                         }
894                 }
895         }
896
897         int_status = ioread32(FlashReg + ints_addr[info.flash_bank]);
898         iowrite32(int_status, FlashReg + ints_addr[info.flash_bank]);
899         cdma_int_status = ioread32(FlashReg + DMA_INTR);
900         iowrite32(cdma_int_status, FlashReg + DMA_INTR);
901
902         iowrite32(0, FlashReg + DMA_ENABLE);
903         while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
904                 ;
905
906         return event;
907 }
908
909
910