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