Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-btrfs-devel.git] / drivers / staging / spectra / lld_cdma.c
blobc6e76103d43c4a99493a12c01c7710f4d65617c0
1 /*
2 * NAND Flash Controller Device Driver
3 * Copyright (c) 2009, Intel Corporation and its suppliers.
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.
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.
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.
20 #include <linux/fs.h>
21 #include <linux/slab.h>
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"
31 #define MAX_PENDING_CMDS 4
32 #define MODE_02 (0x2 << 26)
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)
49 u8 bank;
51 nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
52 __FILE__, __LINE__, __func__);
54 if (0 == cmd)
55 nand_dbg_print(NAND_DBG_DEBUG,
56 "%s, Line %d, Illegal cmd (0)\n", __FILE__, __LINE__);
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;
70 info.flash_bank = bank;
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;
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;
95 info.pcmds_num++;
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;
104 return PASS;
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)
120 nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
121 __FILE__, __LINE__, __func__);
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;
134 info.pcmds_num++;
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;
143 return PASS;
146 #if 0
147 /* Prints the PendingCMDs array */
148 void print_pending_cmds(void)
150 u16 i;
152 nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
153 __FILE__, __LINE__, __func__);
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;
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);
221 /* Print the CDMA descriptors */
222 void print_cdma_descriptors(void)
224 struct cdma_descriptor *pc;
225 int i;
227 pc = (struct cdma_descriptor *)info.cdma_desc_buf;
229 nand_dbg_print(NAND_DBG_DEBUG, "\nWill dump cdma descriptors:\n");
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);
259 /* Print the Memory copy descriptors */
260 static void print_memcp_descriptors(void)
262 struct memcpy_descriptor *pm;
263 int i;
265 pm = (struct memcpy_descriptor *)info.memcp_desc_buf;
267 nand_dbg_print(NAND_DBG_DEBUG, "\nWill dump mem_cpy descriptors:\n");
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);
302 #endif
304 /* Reset cdma_descriptor chain to 0 */
305 static void reset_cdma_desc(int i)
307 struct cdma_descriptor *ptr;
309 BUG_ON(i >= MAX_DESCS);
311 ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
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;
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)
336 int i, j, active_chan;
337 struct cdma_descriptor *ptr;
339 nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
340 __FILE__, __LINE__, __func__);
342 ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
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;
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;
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");
372 static void cdma_trans(u16 chan)
374 u32 addr;
376 addr = info.cdma_desc;
378 iowrite32(MODE_10 | (chan << 24), FlashMem);
379 iowrite32((1 << 7) | chan, FlashMem + 0x10);
381 iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & (addr >> 16)) << 8),
382 FlashMem);
383 iowrite32((1 << 7) | (1 << 4) | 0, FlashMem + 0x10);
385 iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & addr) << 8), FlashMem);
386 iowrite32((1 << 7) | (1 << 5) | 0, FlashMem + 0x10);
388 iowrite32(MODE_10 | (chan << 24), FlashMem);
389 iowrite32((1 << 7) | (1 << 5) | (1 << 4) | 0, FlashMem + 0x10);
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)
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;
410 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
411 __FILE__, __LINE__, __func__);
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;
420 for (i = 0; i < MAX_DESCS; i++)
421 reset_cdma_desc(i);
423 pc = (struct cdma_descriptor *)info.cdma_desc_buf;
424 pm = (struct memcpy_descriptor *)info.memcp_desc_buf;
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;
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;
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;
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;
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;
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;
468 info.cdma_num++;
469 BUG_ON(info.cdma_num >= MAX_DESCS);
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;
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;
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;
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;
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;
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;
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;
540 pm[info.cdma_num].NxtPointerHi = 0;
541 pm[info.cdma_num].NxtPointerLo = 0;
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;
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;
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;
567 pc[info.cdma_num].Channel = 0;
568 pc[info.cdma_num].Status = 0;
569 pc[info.cdma_num].pcmd = i;
571 info.cdma_num++;
572 BUG_ON(info.cdma_num >= MAX_DESCS);
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;
582 pc[info.cdma_num].FlashPointerHi = ptr >> 16;
583 pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
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;
591 pc[info.cdma_num].Channel = 0;
592 pc[info.cdma_num].Status = 0;
593 pc[info.cdma_num].pcmd = i;
595 info.cdma_num++;
596 BUG_ON(info.cdma_num >= MAX_DESCS);
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);
614 iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable Interrupt */
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))
620 cdma_trans(info.flash_bank);
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;
628 info.pcmds_num = 0; /* Clear the pending cmds number to 0 */
630 return status;
633 int is_cdma_interrupt(void)
635 u32 ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma;
636 u32 int_en_mask;
637 u32 cdma_int_en_mask;
639 nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
640 __FILE__, __LINE__, __func__);
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);
650 int_en_mask = (INTR_STATUS0__ECC_ERR |
651 INTR_STATUS0__PROGRAM_FAIL |
652 INTR_STATUS0__ERASE_FAIL);
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;
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);
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;
677 static void update_event_status(void)
679 int i;
680 struct cdma_descriptor *ptr;
682 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
683 __FILE__, __LINE__, __func__);
685 ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
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;
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;
709 static u16 do_ecc_for_desc(u32 ch, u8 *buf, u16 page)
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;
721 nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
722 __FILE__, __LINE__, __func__);
724 eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
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);
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);
741 ecc_correction_info = ioread32(FlashReg + ERR_CORRECTION_INFO);
742 err_device = ((ecc_correction_info &
743 ERR_CORRECTION_INFO__DEVICE_NR) >> 8);
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;
761 } while (!(ecc_correction_info & ERR_CORRECTION_INFO__LAST_ERR_INFO));
763 return event;
766 static u16 process_ecc_int(u32 c, u16 *p_desc_num)
768 struct cdma_descriptor *ptr;
769 u16 j;
770 int event = EVENT_PASS;
772 nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
773 __FILE__, __LINE__, __func__);
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);
779 ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
781 for (j = 0; j < info.cdma_num; j++)
782 if ((ptr[j].Status & CMD_DMA_DESC_COMP) != CMD_DMA_DESC_COMP)
783 break;
785 *p_desc_num = j; /* Pass the descripter number found here */
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;
794 event = do_ecc_for_desc(c, info.pcmds[ptr[j].pcmd].DataAddr,
795 info.pcmds[ptr[j].pcmd].Page);
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);
808 if (ptr[j].pcmd != 0xff)
809 info.pcmds[ptr[j].pcmd].Status = CMD_FAIL;
810 CDMA_UpdateEventStatus();
813 return event;
816 static void process_prog_erase_fail_int(u16 desc_num)
818 struct cdma_descriptor *ptr;
820 nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
821 __FILE__, __LINE__, __func__);
823 ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
825 if (ptr[desc_num].pcmd != 0xFF)
826 info.pcmds[ptr[desc_num].pcmd].Status = CMD_FAIL;
828 CDMA_UpdateEventStatus();
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)
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;
852 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
853 __FILE__, __LINE__, __func__);
855 ecc_enable = ioread32(FlashReg + ECC_ENABLE);
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;
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;
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);
902 iowrite32(0, FlashReg + DMA_ENABLE);
903 while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
906 return event;